1#[cfg(feature = "alloc")]
4mod alloc;
5mod core;
6#[cfg(feature = "std")]
7mod std;
8
9#[cfg(feature = "alloc")]
10use crate::AlignedVec;
11use crate::{
12 ser::{ScratchSpace, Serializer, SharedSerializeRegistry},
13 AlignedBytes, Archive, ArchiveUnsized, Fallible, Infallible,
14};
15use ::core::{alloc::Layout, fmt, ptr::NonNull};
16
17#[doc(inline)]
18#[cfg(feature = "alloc")]
19pub use self::alloc::*;
20#[doc(inline)]
21pub use self::core::*;
22#[doc(inline)]
23#[cfg(feature = "std")]
24pub use self::std::*;
25
26#[derive(Debug)]
28pub enum CompositeSerializerError<S, C, H> {
29 SerializerError(S),
31 ScratchSpaceError(C),
33 SharedError(H),
35}
36
37impl<S, C, H> fmt::Display for CompositeSerializerError<S, C, H>
38where
39 S: fmt::Display,
40 C: fmt::Display,
41 H: fmt::Display,
42{
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 match self {
45 Self::SerializerError(e) => write!(f, "serialization error: {}", e),
46 Self::ScratchSpaceError(e) => write!(f, "scratch space error: {}", e),
47 Self::SharedError(e) => write!(f, "shared memory error: {}", e),
48 }
49 }
50}
51
52#[cfg(feature = "std")]
53const _: () = {
54 use ::std::error::Error;
55
56 impl<S, C, H> Error for CompositeSerializerError<S, C, H>
57 where
58 S: Error + 'static,
59 C: Error + 'static,
60 H: Error + 'static,
61 {
62 fn source(&self) -> Option<&(dyn Error + 'static)> {
63 match self {
64 Self::SerializerError(e) => Some(e as &dyn Error),
65 Self::ScratchSpaceError(e) => Some(e as &dyn Error),
66 Self::SharedError(e) => Some(e as &dyn Error),
67 }
68 }
69 }
70};
71
72#[derive(Debug)]
74pub struct CompositeSerializer<S = Infallible, C = Infallible, H = Infallible> {
75 serializer: S,
76 scratch: C,
77 shared: H,
78}
79
80impl<S, C, H> CompositeSerializer<S, C, H> {
81 #[inline]
83 pub fn new(serializer: S, scratch: C, shared: H) -> Self {
84 Self {
85 serializer,
86 scratch,
87 shared,
88 }
89 }
90
91 #[inline]
93 pub fn into_components(self) -> (S, C, H) {
94 (self.serializer, self.scratch, self.shared)
95 }
96
97 #[inline]
101 pub fn into_serializer(self) -> S {
102 self.serializer
103 }
104}
105
106impl<S: Default, C: Default, H: Default> Default for CompositeSerializer<S, C, H> {
107 #[inline]
108 fn default() -> Self {
109 Self {
110 serializer: S::default(),
111 scratch: C::default(),
112 shared: H::default(),
113 }
114 }
115}
116
117impl<S: Fallible, C: Fallible, H: Fallible> Fallible for CompositeSerializer<S, C, H> {
118 type Error = CompositeSerializerError<S::Error, C::Error, H::Error>;
119}
120
121impl<S: Serializer, C: Fallible, H: Fallible> Serializer for CompositeSerializer<S, C, H> {
122 #[inline]
123 fn pos(&self) -> usize {
124 self.serializer.pos()
125 }
126
127 #[inline]
128 fn write(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
129 self.serializer
130 .write(bytes)
131 .map_err(CompositeSerializerError::SerializerError)
132 }
133
134 #[inline]
135 fn pad(&mut self, padding: usize) -> Result<(), Self::Error> {
136 self.serializer
137 .pad(padding)
138 .map_err(CompositeSerializerError::SerializerError)
139 }
140
141 #[inline]
142 fn align(&mut self, align: usize) -> Result<usize, Self::Error> {
143 self.serializer
144 .align(align)
145 .map_err(CompositeSerializerError::SerializerError)
146 }
147
148 #[inline]
149 fn align_for<T>(&mut self) -> Result<usize, Self::Error> {
150 self.serializer
151 .align_for::<T>()
152 .map_err(CompositeSerializerError::SerializerError)
153 }
154
155 #[inline]
156 unsafe fn resolve_aligned<T: Archive + ?Sized>(
157 &mut self,
158 value: &T,
159 resolver: T::Resolver,
160 ) -> Result<usize, Self::Error> {
161 self.serializer
162 .resolve_aligned::<T>(value, resolver)
163 .map_err(CompositeSerializerError::SerializerError)
164 }
165
166 #[inline]
167 unsafe fn resolve_unsized_aligned<T: ArchiveUnsized + ?Sized>(
168 &mut self,
169 value: &T,
170 to: usize,
171 metadata_resolver: T::MetadataResolver,
172 ) -> Result<usize, Self::Error> {
173 self.serializer
174 .resolve_unsized_aligned(value, to, metadata_resolver)
175 .map_err(CompositeSerializerError::SerializerError)
176 }
177}
178
179impl<S: Fallible, C: ScratchSpace, H: Fallible> ScratchSpace for CompositeSerializer<S, C, H> {
180 #[inline]
181 unsafe fn push_scratch(&mut self, layout: Layout) -> Result<NonNull<[u8]>, Self::Error> {
182 self.scratch
183 .push_scratch(layout)
184 .map_err(CompositeSerializerError::ScratchSpaceError)
185 }
186
187 #[inline]
188 unsafe fn pop_scratch(&mut self, ptr: NonNull<u8>, layout: Layout) -> Result<(), Self::Error> {
189 self.scratch
190 .pop_scratch(ptr, layout)
191 .map_err(CompositeSerializerError::ScratchSpaceError)
192 }
193}
194
195impl<S: Fallible, C: Fallible, H: SharedSerializeRegistry> SharedSerializeRegistry
196 for CompositeSerializer<S, C, H>
197{
198 #[inline]
199 fn get_shared_ptr(&self, value: *const u8) -> Option<usize> {
200 self.shared.get_shared_ptr(value)
201 }
202
203 #[inline]
204 fn add_shared_ptr(&mut self, value: *const u8, pos: usize) -> Result<(), Self::Error> {
205 self.shared
206 .add_shared_ptr(value, pos)
207 .map_err(CompositeSerializerError::SharedError)
208 }
209}
210
211pub type CoreSerializer<const S: usize, const C: usize> = CompositeSerializer<
217 BufferSerializer<AlignedBytes<S>>,
218 BufferScratch<AlignedBytes<C>>,
219 Infallible,
220>;
221
222#[cfg(feature = "alloc")]
230pub type AllocSerializer<const N: usize> = CompositeSerializer<
231 AlignedSerializer<AlignedVec>,
232 FallbackScratch<HeapScratch<N>, AllocScratch>,
233 SharedSerializeMap,
234>;