use crate::*;
use std::{
convert::TryFrom,
error::Error,
ffi::{CString, IntoStringError, NulError},
fmt, slice,
};
impl apk_blob_t {
pub fn new(string: &str) -> Self {
apk_blob_t {
len: string.len() as std::os::raw::c_long,
ptr: CString::new(string).unwrap().into_raw(),
}
}
}
#[derive(Debug)]
pub enum ApkBlobConvertError {
NullError(String),
UTF8Error(String),
}
impl From<IntoStringError> for ApkBlobConvertError {
fn from(e: IntoStringError) -> Self {
Self::UTF8Error(e.to_string())
}
}
impl From<NulError> for ApkBlobConvertError {
fn from(e: NulError) -> Self {
Self::NullError(e.to_string())
}
}
impl fmt::Display for ApkBlobConvertError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ApkBlobConvertError::NullError(e) | ApkBlobConvertError::UTF8Error(e) => {
write!(f, "{}", e)
}
}
}
}
impl Error for ApkBlobConvertError {}
impl TryFrom<&apk_blob_t> for String {
type Error = ApkBlobConvertError;
fn try_from(blob: &apk_blob_t) -> Result<Self, Self::Error> {
unsafe {
let slice = slice::from_raw_parts::<u8>(blob.ptr.cast(), blob.len as usize);
Ok(CString::new(slice)?.into_string()?)
}
}
}
impl Copy for apk_blob_t {}
impl Clone for apk_blob_t {
fn clone(&self) -> Self {
Self {
len: self.len,
ptr: self.ptr,
}
}
}