1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
use std::error::Error; use std::marker::PhantomData; use super::null_ptr_error; use super::{FromForeign, InputType, ReturnType, Slice, ToForeign}; pub struct StrMarshaler<'a>(&'a PhantomData<()>); impl InputType for StrMarshaler<'_> { type Foreign = Slice<u8>; type ForeignTraitObject = (); } impl ReturnType for StrMarshaler<'_> { type Foreign = Slice<u8>; type ForeignTraitObject = (); #[inline(always)] fn foreign_default() -> Self::Foreign { Slice::default() } } impl<'a> ToForeign<&'a str, Slice<u8>> for StrMarshaler<'a> { type Error = Box<dyn Error>; #[inline(always)] fn to_foreign(input: &'a str) -> Result<Slice<u8>, Self::Error> { let bytes = input.to_owned().into_boxed_str().into_boxed_bytes(); let len = bytes.len(); Ok(Slice { data: Box::into_raw(bytes) as _, len, }) } } impl<'a> FromForeign<Slice<u8>, &'a str> for StrMarshaler<'a> { type Error = Box<dyn Error>; #[inline(always)] unsafe fn from_foreign(slice: Slice<u8>) -> Result<&'a str, Self::Error> { if slice.data.is_null() { return Err(null_ptr_error()); } let r = std::slice::from_raw_parts(slice.data as _, slice.len); std::str::from_utf8(r).map_err(|e| Box::new(e) as _) } } impl<'a> FromForeign<Slice<u8>, Option<&'a str>> for StrMarshaler<'a> { type Error = Box<dyn Error>; #[inline(always)] unsafe fn from_foreign(slice: Slice<u8>) -> Result<Option<&'a str>, Self::Error> { if slice.data.is_null() { return Ok(None); } let r = std::slice::from_raw_parts(slice.data as _, slice.len); std::str::from_utf8(r) .map(Some) .map_err(|e| Box::new(e) as _) } }