facet_postcard/
raw_postcard.rs1extern crate alloc;
2
3use alloc::{borrow::Cow, vec::Vec};
4
5use facet_core::{OpaqueSerialize, PtrConst, Shape};
6
7#[derive(Debug, Clone)]
12pub enum RawPostcard<'a> {
13 Borrowed(&'a [u8]),
15 Owned(Vec<u8>),
17}
18
19impl<'a> RawPostcard<'a> {
20 pub const fn borrowed(bytes: &'a [u8]) -> Self {
22 Self::Borrowed(bytes)
23 }
24
25 pub fn owned(bytes: Vec<u8>) -> Self {
27 Self::Owned(bytes)
28 }
29
30 pub fn as_bytes(&self) -> &[u8] {
32 match self {
33 Self::Borrowed(bytes) => bytes,
34 Self::Owned(bytes) => bytes,
35 }
36 }
37
38 pub fn to_opaque_serialize(&self) -> OpaqueSerialize {
40 match self {
41 Self::Borrowed(bytes) => opaque_encoded_borrowed(bytes),
42 Self::Owned(bytes) => opaque_encoded_owned(bytes),
43 }
44 }
45}
46
47impl<'a> From<&'a [u8]> for RawPostcard<'a> {
48 fn from(value: &'a [u8]) -> Self {
49 Self::Borrowed(value)
50 }
51}
52
53impl<'a> From<Vec<u8>> for RawPostcard<'a> {
54 fn from(value: Vec<u8>) -> Self {
55 Self::Owned(value)
56 }
57}
58
59impl<'a> From<Cow<'a, [u8]>> for RawPostcard<'a> {
60 fn from(value: Cow<'a, [u8]>) -> Self {
61 match value {
62 Cow::Borrowed(bytes) => Self::Borrowed(bytes),
63 Cow::Owned(bytes) => Self::Owned(bytes),
64 }
65 }
66}
67
68#[repr(transparent)]
69struct RawPostcardBorrowed<'a>(&'a [u8]);
70
71#[repr(transparent)]
72struct RawPostcardOwned(Vec<u8>);
73
74static RAW_POSTCARD_BORROWED_SHAPE: Shape =
75 Shape::builder_for_sized::<RawPostcardBorrowed<'static>>("RawPostcardBorrowed").build();
76
77static RAW_POSTCARD_OWNED_SHAPE: Shape =
78 Shape::builder_for_sized::<RawPostcardOwned>("RawPostcardOwned").build();
79
80pub fn opaque_encoded_borrowed(bytes: &&[u8]) -> OpaqueSerialize {
86 OpaqueSerialize {
87 ptr: PtrConst::new((bytes as *const &[u8]).cast::<RawPostcardBorrowed<'_>>()),
88 shape: &RAW_POSTCARD_BORROWED_SHAPE,
89 }
90}
91
92pub fn opaque_encoded_owned(bytes: &Vec<u8>) -> OpaqueSerialize {
97 OpaqueSerialize {
98 ptr: PtrConst::new((bytes as *const Vec<u8>).cast::<RawPostcardOwned>()),
99 shape: &RAW_POSTCARD_OWNED_SHAPE,
100 }
101}
102
103pub(crate) unsafe fn try_decode_passthrough_bytes<'a>(
104 ptr: PtrConst,
105 shape: &'static Shape,
106) -> Option<&'a [u8]> {
107 if shape == &RAW_POSTCARD_BORROWED_SHAPE {
108 let borrowed: &'a RawPostcardBorrowed<'a> = unsafe { ptr.get() };
109 return Some(borrowed.0);
110 }
111 if shape == &RAW_POSTCARD_OWNED_SHAPE {
112 let owned: &'a RawPostcardOwned = unsafe { ptr.get() };
113 return Some(owned.0.as_slice());
114 }
115 None
116}