1use serde::{Deserialize, Serialize, Serializer};
17
18pub mod le {
33    use serde::{Deserialize, Deserializer, Serialize, Serializer};
34
35    use super::LE;
36
37    pub fn serialize<S, T>(val: &T, serializer: S) -> Result<S::Ok, S::Error>
39    where
40        S: Serializer,
41        T: Copy,
42        LE<T>: Serialize,
43    {
44        LE(*val).serialize(serializer)
45    }
46
47    pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
49    where
50        D: Deserializer<'de>,
51        LE<T>: Deserialize<'de>,
52    {
53        LE::<T>::deserialize(deserializer).map(|x| x.0)
54    }
55}
56
57pub mod be {
72    use serde::{Deserialize, Deserializer, Serialize, Serializer};
73
74    use super::BE;
75
76    pub fn serialize<S, T>(val: &T, serializer: S) -> Result<S::Ok, S::Error>
78    where
79        S: Serializer,
80        T: Copy,
81        BE<T>: Serialize,
82    {
83        BE(*val).serialize(serializer)
84    }
85
86    pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
88    where
89        D: Deserializer<'de>,
90        BE<T>: Deserialize<'de>,
91    {
92        BE::<T>::deserialize(deserializer).map(|x| x.0)
93    }
94}
95
96#[doc(hidden)]
97pub struct LE<T>(T);
98
99#[doc(hidden)]
100pub struct BE<T>(T);
101
102macro_rules! impl_fixint {
103    ($( $int:ty ),*) => {
104        $(
105            impl Serialize for LE<$int> {
106                #[inline]
107                fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
108                where
109                    S: Serializer,
110                {
111                    self.0.to_le_bytes().serialize(serializer)
112                }
113            }
114
115            impl<'de> Deserialize<'de> for LE<$int> {
116                #[inline]
117                fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
118                where
119                    D: serde::Deserializer<'de>,
120                {
121                    <_ as Deserialize>::deserialize(deserializer)
122                        .map(<$int>::from_le_bytes)
123                        .map(Self)
124                }
125            }
126
127            impl Serialize for BE<$int> {
128                #[inline]
129                fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
130                where
131                    S: Serializer,
132                {
133                    self.0.to_be_bytes().serialize(serializer)
134                }
135            }
136
137            impl<'de> Deserialize<'de> for BE<$int> {
138                #[inline]
139                fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
140                where
141                    D: serde::Deserializer<'de>,
142                {
143                    <_ as Deserialize>::deserialize(deserializer)
144                        .map(<$int>::from_be_bytes)
145                        .map(Self)
146                }
147            }
148        )*
149    };
150}
151
152impl_fixint![i16, i32, i64, i128, u16, u32, u64, u128];
153
154#[cfg(test)]
155mod tests {
156    use serde::{Deserialize, Serialize};
157
158    #[test]
159    fn test_little_endian() {
160        #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
161        pub struct DefinitelyLE {
162            #[serde(with = "crate::fixint::le")]
163            x: u16,
164        }
165
166        let input = DefinitelyLE { x: 0xABCD };
167        let mut buf = [0; 32];
168        let serialized = crate::to_slice(&input, &mut buf).unwrap();
169        assert_eq!(serialized, &[0xCD, 0xAB]);
170
171        let deserialized: DefinitelyLE = crate::from_bytes(serialized).unwrap();
172        assert_eq!(deserialized, input);
173    }
174
175    #[test]
176    fn test_big_endian() {
177        #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
178        pub struct DefinitelyBE {
179            #[serde(with = "crate::fixint::be")]
180            x: u16,
181        }
182
183        let input = DefinitelyBE { x: 0xABCD };
184        let mut buf = [0; 32];
185        let serialized = crate::to_slice(&input, &mut buf).unwrap();
186        assert_eq!(serialized, &[0xAB, 0xCD]);
187
188        let deserialized: DefinitelyBE = crate::from_bytes(serialized).unwrap();
189        assert_eq!(deserialized, input);
190    }
191}