diff --git a/src/database/error.rs b/src/database/error.rs index a67be49..cd9e097 100644 --- a/src/database/error.rs +++ b/src/database/error.rs @@ -25,9 +25,14 @@ impl Error { use std::str::from_utf8; use std::ffi::CStr; - let err_string = from_utf8(CStr::from_ptr(message).to_bytes()).unwrap().to_string(); + let err_string = from_utf8(CStr::from_ptr(message).to_bytes()) + .map(|s| s.to_string()); leveldb_free(message as *mut c_void); - Error::new(err_string) + + match err_string { + Ok(err_string) => Error::new(err_string), + Err(_) => Error::new("The error returned by LevelDB is not valid UTF-8".into()) + } } } diff --git a/src/database/mod.rs b/src/database/mod.rs index 2f9ac3c..f759884 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -8,6 +8,8 @@ use self::options::{Options, c_options}; use self::error::Error; use std::ffi::CString; use libc::c_char; +#[cfg(unix)] +use std::os::unix::ffi::OsStrExt; use std::path::Path; @@ -108,7 +110,14 @@ impl Database { pub fn open(name: &Path, options: Options) -> Result, Error> { let mut error = ptr::null_mut(); unsafe { - let c_string = CString::new(name.to_str().unwrap()).unwrap(); + #[cfg(unix)] + let c_string = CString::new(name.as_os_str().as_bytes()).unwrap(); + #[cfg(not(unix))] + let c_string = CString::new( + name.to_str() + .ok_or_else(|| Error::new("Path is not valid Unicode".into()))?, + ) + .unwrap(); let c_options = c_options(&options, None); let db = leveldb_open(c_options as *const leveldb_options_t, c_string.as_bytes_with_nul().as_ptr() as *const c_char,