vitaminc_protected/exportable/
safe_serialize.rs1use std::num::{
2 NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
3 NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
4};
5
6use crate::Controlled;
7use serde::ser::SerializeTuple;
8use serde::{Serialize, Serializer};
9
10pub trait SafeSerialize {
16 fn safe_serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
17 where
18 S: Serializer;
19}
20
21impl<T> SafeSerialize for T
23where
24 T::Inner: SafeSerialize,
25 T: Controlled,
26{
27 fn safe_serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
28 where
29 S: Serializer,
30 {
31 self.risky_ref().safe_serialize(serializer)
32 }
33}
34
35macro_rules! impl_safe_serialize {
37 ($type:ty, $serialize_fn:ident $($cast:tt)*) => {
38 impl SafeSerialize for $type {
39 #[inline]
40 fn safe_serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
41 where
42 S: Serializer,
43 {
44 serializer.$serialize_fn(*self $($cast)*)
45 }
46 }
47 };
48}
49
50impl_safe_serialize!(u8, serialize_u8);
51impl_safe_serialize!(u16, serialize_u16);
52impl_safe_serialize!(u32, serialize_u32);
53impl_safe_serialize!(u64, serialize_u64);
54impl_safe_serialize!(u128, serialize_u128);
55impl_safe_serialize!(usize, serialize_u64 as u64);
56impl_safe_serialize!(i8, serialize_i8);
57impl_safe_serialize!(i16, serialize_i16);
58impl_safe_serialize!(i32, serialize_i32);
59impl_safe_serialize!(i64, serialize_i64);
60impl_safe_serialize!(i128, serialize_i128);
61impl_safe_serialize!(isize, serialize_i64 as i64);
62impl_safe_serialize!(f32, serialize_f32);
63impl_safe_serialize!(f64, serialize_f64);
64impl_safe_serialize!(char, serialize_char);
65impl_safe_serialize!(bool, serialize_bool);
66
67impl SafeSerialize for String {
68 #[inline]
69 fn safe_serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70 where
71 S: Serializer,
72 {
73 serializer.serialize_str(self)
74 }
75}
76
77impl<const N: usize> SafeSerialize for [u8; N] {
78 fn safe_serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
79 where
80 S: Serializer,
81 {
82 serializer.serialize_bytes(self)
83 }
84}
85
86macro_rules! impl_safe_serialize_nonzero {
87 ($type:ty, $serialize_fn:ident $($cast:tt)*) => {
88 impl SafeSerialize for $type {
89 #[inline]
90 fn safe_serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
91 where
92 S: Serializer,
93 {
94 serializer.$serialize_fn(self.get() $($cast)*)
95 }
96 }
97 };
98}
99
100impl_safe_serialize_nonzero!(NonZeroU8, serialize_u8);
101impl_safe_serialize_nonzero!(NonZeroU16, serialize_u16);
102impl_safe_serialize_nonzero!(NonZeroU32, serialize_u32);
103impl_safe_serialize_nonzero!(NonZeroU64, serialize_u64);
104impl_safe_serialize_nonzero!(NonZeroU128, serialize_u128);
105impl_safe_serialize_nonzero!(NonZeroUsize, serialize_u64 as u64);
106impl_safe_serialize_nonzero!(NonZeroI8, serialize_i8);
107impl_safe_serialize_nonzero!(NonZeroI16, serialize_i16);
108impl_safe_serialize_nonzero!(NonZeroI32, serialize_i32);
109impl_safe_serialize_nonzero!(NonZeroI64, serialize_i64);
110impl_safe_serialize_nonzero!(NonZeroI128, serialize_i128);
111impl_safe_serialize_nonzero!(NonZeroIsize, serialize_i64 as i64);
112
113macro_rules! tuple_impls {
114 ($($len:expr => ($($n:tt $name:ident)+))+) => {
115 $(
116 #[cfg_attr(docsrs, doc(hidden))]
117 impl<$($name),+> SafeSerialize for ($($name,)+)
118 where
119 $($name: SafeSerialize + Serialize,)+
120 {
121 tuple_impl_body!($len => ($($n)+));
122 }
123 )+
124 };
125}
126
127macro_rules! tuple_impl_body {
128 ($len:expr => ($($n:tt)+)) => {
129 #[inline]
130 fn safe_serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
131 where
132 S: Serializer,
133 {
134 let mut tuple = serializer.serialize_tuple($len)?;
135 $(
136 tuple.serialize_element(&self.$n)?;
137 )+
138 tuple.end()
139 }
140 };
141}
142impl<T> SafeSerialize for (T,)
144where
145 T: Serialize + SafeSerialize,
146{
147 tuple_impl_body!(1 => (0));
148}
149
150tuple_impls! {
151 2 => (0 T0 1 T1)
152 3 => (0 T0 1 T1 2 T2)
153 4 => (0 T0 1 T1 2 T2 3 T3)
154 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
155 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
156 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
157 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
158 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
159 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
160}