Skip to main content

serde_shape/impls/
wrapper.rs

1// Copyright 2026 FastLabs Developers
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use alloc::borrow::Cow;
16use alloc::borrow::ToOwned;
17use alloc::boxed::Box;
18use alloc::rc::Rc;
19use alloc::rc::Weak as RcWeak;
20#[cfg(target_has_atomic = "ptr")]
21use alloc::sync::Arc;
22#[cfg(target_has_atomic = "ptr")]
23use alloc::sync::Weak as ArcWeak;
24use core::cell::Cell;
25use core::cell::RefCell;
26use core::cmp::Reverse;
27use core::marker::PhantomData;
28use core::num::Saturating;
29use core::num::Wrapping;
30
31use crate::DeserializeShape;
32use crate::DeserializeShapeContext;
33use crate::SerializeShape;
34use crate::SerializeShapeContext;
35use crate::ShapeRef;
36
37macro_rules! transparent_shape {
38    (
39        $(
40            ($($generics:tt)*) $ty:ty
41            where
42                serialize { $($serialize_bounds:tt)* }
43                deserialize { $($deserialize_bounds:tt)* }
44            => $inner:ty;
45        )+
46    ) => {
47        $(
48            impl<$($generics)*> SerializeShape for $ty
49            where
50                $($serialize_bounds)*
51            {
52                fn serialize_shape_in(context: &mut SerializeShapeContext) -> ShapeRef {
53                    <$inner as SerializeShape>::serialize_shape_in(context)
54                }
55            }
56
57            impl<$($generics)*> DeserializeShape for $ty
58            where
59                $($deserialize_bounds)*
60            {
61                fn deserialize_shape_in(context: &mut DeserializeShapeContext) -> ShapeRef {
62                    <$inner as DeserializeShape>::deserialize_shape_in(context)
63                }
64            }
65        )+
66    };
67}
68
69transparent_shape! {
70    (T) Box<T>
71    where
72        serialize { T: SerializeShape + ?Sized }
73        deserialize { T: DeserializeShape }
74    => T;
75
76    (T) Cell<T>
77    where
78        serialize { T: Copy + SerializeShape }
79        deserialize { T: Copy + DeserializeShape }
80    => T;
81
82    (T) RefCell<T>
83    where
84        serialize { T: SerializeShape + ?Sized }
85        deserialize { T: DeserializeShape }
86    => T;
87
88    (T) Wrapping<T>
89    where
90        serialize { T: SerializeShape }
91        deserialize { T: DeserializeShape }
92    => T;
93
94    (T) Reverse<T>
95    where
96        serialize { T: SerializeShape }
97        deserialize { T: DeserializeShape }
98    => T;
99}
100
101impl<T> SerializeShape for &T
102where
103    T: SerializeShape + ?Sized,
104{
105    fn serialize_shape_in(context: &mut SerializeShapeContext) -> ShapeRef {
106        T::serialize_shape_in(context)
107    }
108}
109
110impl<T> SerializeShape for &mut T
111where
112    T: SerializeShape + ?Sized,
113{
114    fn serialize_shape_in(context: &mut SerializeShapeContext) -> ShapeRef {
115        T::serialize_shape_in(context)
116    }
117}
118
119impl DeserializeShape for &str {
120    fn deserialize_shape_in(_context: &mut DeserializeShapeContext) -> ShapeRef {
121        ShapeRef::String
122    }
123}
124
125impl DeserializeShape for &[u8] {
126    fn deserialize_shape_in(_context: &mut DeserializeShapeContext) -> ShapeRef {
127        ShapeRef::Bytes
128    }
129}
130
131impl<T> SerializeShape for Saturating<T>
132where
133    T: SerializeShape,
134{
135    fn serialize_shape_in(context: &mut SerializeShapeContext) -> ShapeRef {
136        T::serialize_shape_in(context)
137    }
138}
139
140macro_rules! saturating_deserialize_shape {
141    ($($ty:ty),+ $(,)?) => {
142        $(
143            impl DeserializeShape for Saturating<$ty> {
144                fn deserialize_shape_in(context: &mut DeserializeShapeContext) -> ShapeRef {
145                    <$ty as DeserializeShape>::deserialize_shape_in(context)
146                }
147            }
148        )+
149    };
150}
151
152saturating_deserialize_shape!(
153    i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize,
154);
155
156impl<T> DeserializeShape for Box<[T]>
157where
158    T: DeserializeShape,
159{
160    fn deserialize_shape_in(context: &mut DeserializeShapeContext) -> ShapeRef {
161        ShapeRef::Seq(Box::new(T::deserialize_shape_in(context)))
162    }
163}
164
165impl DeserializeShape for Box<str> {
166    fn deserialize_shape_in(_context: &mut DeserializeShapeContext) -> ShapeRef {
167        ShapeRef::String
168    }
169}
170
171macro_rules! shared_pointer_shape {
172    ($strong:ident, $weak:ident) => {
173        impl<T> SerializeShape for $strong<T>
174        where
175            T: SerializeShape + ?Sized,
176        {
177            fn serialize_shape_in(context: &mut SerializeShapeContext) -> ShapeRef {
178                T::serialize_shape_in(context)
179            }
180        }
181
182        impl<T> DeserializeShape for $strong<T>
183        where
184            T: ?Sized,
185            Box<T>: DeserializeShape,
186        {
187            fn deserialize_shape_in(context: &mut DeserializeShapeContext) -> ShapeRef {
188                <Box<T> as DeserializeShape>::deserialize_shape_in(context)
189            }
190        }
191
192        impl<T> SerializeShape for $weak<T>
193        where
194            T: SerializeShape + ?Sized,
195        {
196            fn serialize_shape_in(context: &mut SerializeShapeContext) -> ShapeRef {
197                ShapeRef::Option(Box::new(T::serialize_shape_in(context)))
198            }
199        }
200
201        impl<T> DeserializeShape for $weak<T>
202        where
203            T: DeserializeShape,
204        {
205            fn deserialize_shape_in(context: &mut DeserializeShapeContext) -> ShapeRef {
206                ShapeRef::Option(Box::new(T::deserialize_shape_in(context)))
207            }
208        }
209    };
210}
211
212shared_pointer_shape!(Rc, RcWeak);
213
214#[cfg(target_has_atomic = "ptr")]
215shared_pointer_shape!(Arc, ArcWeak);
216
217#[cfg(feature = "std")]
218impl DeserializeShape for Box<std::path::Path> {
219    fn deserialize_shape_in(_context: &mut DeserializeShapeContext) -> ShapeRef {
220        ShapeRef::String
221    }
222}
223
224#[cfg(feature = "std")]
225impl DeserializeShape for &std::path::Path {
226    fn deserialize_shape_in(_context: &mut DeserializeShapeContext) -> ShapeRef {
227        ShapeRef::String
228    }
229}
230
231#[cfg(feature = "std")]
232transparent_shape! {
233    (T) std::sync::Mutex<T>
234    where
235        serialize { T: SerializeShape + ?Sized }
236        deserialize { T: DeserializeShape }
237    => T;
238
239    (T) std::sync::RwLock<T>
240    where
241        serialize { T: SerializeShape + ?Sized }
242        deserialize { T: DeserializeShape }
243    => T;
244}
245
246impl<T> SerializeShape for Cow<'_, T>
247where
248    T: ToOwned + SerializeShape + ?Sized,
249{
250    fn serialize_shape_in(context: &mut SerializeShapeContext) -> ShapeRef {
251        T::serialize_shape_in(context)
252    }
253}
254
255impl<T> DeserializeShape for Cow<'_, T>
256where
257    T: ToOwned + ?Sized,
258    T::Owned: DeserializeShape,
259{
260    fn deserialize_shape_in(context: &mut DeserializeShapeContext) -> ShapeRef {
261        T::Owned::deserialize_shape_in(context)
262    }
263}
264
265impl<T> SerializeShape for PhantomData<T> {
266    fn serialize_shape_in(_context: &mut SerializeShapeContext) -> ShapeRef {
267        ShapeRef::Unit
268    }
269}
270
271impl<T> DeserializeShape for PhantomData<T> {
272    fn deserialize_shape_in(_context: &mut DeserializeShapeContext) -> ShapeRef {
273        ShapeRef::Unit
274    }
275}