From 5afb34b2487cf0fc0ebe20cd127a575f0624e7d5 Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Wed, 3 Aug 2022 09:51:02 +0000 Subject: Add methods to construct errors from Rust strings. This is more convenient in most cases than a CStr, and will let callers stop duplicating the code to convert it. Bug: 234019127 Test: atest compos_key_tests MicrodroidHostTestCases MicrodroidTestApp libbinder_rs-internal_test Change-Id: Idc6684f22f33d4ff79d2326499d089dc85e213ea --- libs/binder/rust/src/error.rs | 57 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/libs/binder/rust/src/error.rs b/libs/binder/rust/src/error.rs index 2598ebc804..f6b09ed8fe 100644 --- a/libs/binder/rust/src/error.rs +++ b/libs/binder/rust/src/error.rs @@ -18,7 +18,7 @@ use crate::binder::AsNative; use crate::sys; use std::error; -use std::ffi::CStr; +use std::ffi::{CStr, CString}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::result; @@ -104,6 +104,10 @@ unsafe impl Sync for Status {} // A thread-local `AStatus` would not be valid. unsafe impl Send for Status {} +fn to_cstring>(message: T) -> Option { + CString::new(message.as_ref()).ok() +} + impl Status { /// Create a status object representing a successful transaction. pub fn ok() -> Self { @@ -146,6 +150,11 @@ impl Status { Self(ptr) } + /// Creates a status object from a service specific error. + pub fn new_service_specific_error_str>(err: i32, message: Option) -> Status { + Self::new_service_specific_error(err, message.and_then(to_cstring).as_deref()) + } + /// Create a status object from an exception code pub fn new_exception(exception: ExceptionCode, message: Option<&CStr>) -> Status { if let Some(message) = message { @@ -158,6 +167,14 @@ impl Status { } } + /// Creates a status object from an exception code and message. + pub fn new_exception_str>( + exception: ExceptionCode, + message: Option, + ) -> Status { + Self::new_exception(exception, message.and_then(to_cstring).as_deref()) + } + /// Create a status object from a raw `AStatus` pointer. /// /// # Safety @@ -371,3 +388,41 @@ unsafe impl AsNative for Status { self.0 } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn make_service_specific_error() { + let status = Status::new_service_specific_error_str(-42, Some("message")); + + assert!(!status.is_ok()); + assert_eq!(status.exception_code(), ExceptionCode::SERVICE_SPECIFIC); + assert_eq!(status.service_specific_error(), -42); + assert_eq!( + status.get_description(), + "Status(-8, EX_SERVICE_SPECIFIC): '-42: message'".to_string() + ); + } + + #[test] + fn make_exception() { + let status = Status::new_exception_str(ExceptionCode::ILLEGAL_STATE, Some("message")); + + assert!(!status.is_ok()); + assert_eq!(status.exception_code(), ExceptionCode::ILLEGAL_STATE); + assert_eq!(status.service_specific_error(), 0); + assert_eq!(status.get_description(), "Status(-5, EX_ILLEGAL_STATE): 'message'".to_string()); + } + + #[test] + fn make_exception_null() { + let status = Status::new_exception_str(ExceptionCode::ILLEGAL_STATE, Some("one\0two")); + + assert!(!status.is_ok()); + assert_eq!(status.exception_code(), ExceptionCode::ILLEGAL_STATE); + assert_eq!(status.service_specific_error(), 0); + assert_eq!(status.get_description(), "Status(-5, EX_ILLEGAL_STATE): ''".to_string()); + } +} -- cgit v1.2.3-59-g8ed1b