use crate::{Error, Result};
use std::ffi::{CStr, CString, c_char};
use std::path::Path;
use std::slice;
pub(crate) trait PathToStr<'a> {
fn to_str(&'a self) -> Result<&'a str>;
}
impl<'a, P> PathToStr<'a> for P
where
P: AsRef<Path>,
{
fn to_str(&'a self) -> Result<&'a str> {
self.as_ref().to_str().ok_or(Error::InvalidUtf8Str(None))
}
}
pub(crate) trait RawToStr {
unsafe fn to_str<'a>(self) -> Result<&'a str>;
}
impl RawToStr for *const c_char {
unsafe fn to_str<'a>(self) -> Result<&'a str> {
unsafe { CStr::from_ptr(self) }
.to_str()
.map_err(|e| Error::InvalidUtf8Str(Some(e)))
}
}
impl RawToStr for (*const c_char, u32) {
unsafe fn to_str<'a>(self) -> Result<&'a str> {
let bytes = unsafe { slice::from_raw_parts(self.0 as *const u8, self.1 as usize) };
CStr::from_bytes_with_nul(bytes)
.map_err(Error::CStrConv)?
.to_str()
.map_err(|e| Error::InvalidUtf8Str(Some(e)))
}
}
pub(crate) trait IntoCString {
fn into_cstring(self) -> Result<CString>;
}
impl<T> IntoCString for T
where
T: Into<Vec<u8>>,
{
fn into_cstring(self) -> Result<CString> {
CString::new(self).map_err(Error::CStringConv)
}
}
pub(crate) trait IntoCHandle {
fn into_handle(self) -> u32;
}