1use core::{
2 alloc::{Layout, LayoutError},
3 ffi::{c_char, CStr},
4 ptr,
5};
6
7use ptr_meta::Pointee;
8use rancor::Fallible;
9
10use crate::{
11 primitive::ArchivedUsize,
12 ser::Writer,
13 traits::{ArchivePointee, LayoutRaw},
14 ArchiveUnsized, ArchivedMetadata, DeserializeUnsized, Portable,
15 SerializeUnsized,
16};
17
18impl LayoutRaw for CStr {
21 #[inline]
22 fn layout_raw(
23 metadata: <Self as Pointee>::Metadata,
24 ) -> Result<Layout, LayoutError> {
25 Layout::array::<c_char>(metadata)
26 }
27}
28
29unsafe impl Portable for CStr {}
32
33impl ArchiveUnsized for CStr {
34 type Archived = CStr;
35
36 #[inline]
37 fn archived_metadata(&self) -> ArchivedMetadata<Self> {
38 ArchivedUsize::from_native(ptr_meta::metadata(self) as _)
39 }
40}
41
42impl ArchivePointee for CStr {
43 type ArchivedMetadata = ArchivedUsize;
44
45 #[inline]
46 fn pointer_metadata(
47 archived: &Self::ArchivedMetadata,
48 ) -> <Self as Pointee>::Metadata {
49 <[u8]>::pointer_metadata(archived)
50 }
51}
52
53impl<S: Fallible + Writer + ?Sized> SerializeUnsized<S> for CStr {
54 fn serialize_unsized(&self, serializer: &mut S) -> Result<usize, S::Error> {
55 let result = serializer.pos();
56 serializer.write(self.to_bytes_with_nul())?;
57 Ok(result)
58 }
59}
60
61impl<D: Fallible + ?Sized> DeserializeUnsized<CStr, D> for CStr {
62 unsafe fn deserialize_unsized(
63 &self,
64 _: &mut D,
65 out: *mut CStr,
66 ) -> Result<(), D::Error> {
67 let slice = self.to_bytes_with_nul();
68 unsafe {
76 ptr::copy_nonoverlapping(
77 slice.as_ptr(),
78 out.cast::<u8>(),
79 slice.len(),
80 );
81 }
82 Ok(())
83 }
84
85 fn deserialize_metadata(&self) -> <CStr as Pointee>::Metadata {
86 ptr_meta::metadata(self)
87 }
88}