aboutsummaryrefslogtreecommitdiff
path: root/src/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.rs')
-rw-r--r--src/util.rs47
1 files changed, 29 insertions, 18 deletions
diff --git a/src/util.rs b/src/util.rs
index a0d0d1b..b17b071 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -30,26 +30,38 @@ pub enum LogLevel {
DebugL2,
}
+pub fn str_from_ptr<'a>(ptr: *const c_char) -> Result<&'a str, Error> {
+ unsafe { CStr::from_ptr(ptr) }.to_str().map_err(Error::from)
+}
+
pub fn owned_str_from_ptr(ptr: *const c_char) -> Result<String, Error> {
- unsafe { CStr::from_ptr(ptr) }
- .to_str()
- .map(String::from)
- .map_err(Error::from)
+ str_from_ptr(ptr).map(ToOwned::to_owned)
}
-pub fn result_from_string(ptr: *const c_char) -> Result<String, Error> {
+pub fn run_with_string<R, F>(ptr: *const c_char, op: F) -> Result<R, Error>
+where
+ F: FnOnce(&str) -> Result<R, Error>,
+{
if ptr.is_null() {
- return Err(Error::UnexpectedError);
+ return Err(Error::UnexpectedError(
+ "libnitrokey returned a null pointer".to_owned(),
+ ));
}
- let s = owned_str_from_ptr(ptr)?;
+ let result = str_from_ptr(ptr).and_then(op);
unsafe { free(ptr as *mut c_void) };
- // An empty string can both indicate an error or be a valid return value. In this case, we
- // have to check the last command status to decide what to return.
- if s.is_empty() {
- get_last_result().map(|_| s)
- } else {
- Ok(s)
- }
+ result
+}
+
+pub fn result_from_string(ptr: *const c_char) -> Result<String, Error> {
+ run_with_string(ptr, |s| {
+ // An empty string can both indicate an error or be a valid return value. In this case, we
+ // have to check the last command status to decide what to return.
+ if s.is_empty() {
+ get_last_result().map(|_| s.to_owned())
+ } else {
+ Ok(s.to_owned())
+ }
+ })
}
pub fn result_or_error<T>(value: T) -> Result<T, Error> {
@@ -69,10 +81,9 @@ pub fn get_last_result() -> Result<(), Error> {
}
pub fn get_last_error() -> Error {
- match get_last_result() {
- Ok(()) => Error::UnexpectedError,
- Err(err) => err,
- }
+ get_last_result().err().unwrap_or_else(|| {
+ Error::UnexpectedError("Expected an error, but command status is zero".to_owned())
+ })
}
pub fn generate_password(length: usize) -> Result<CString, Error> {