1mod error;
8
9pub use self::error::*;
10
11use crate::{Slot, WireF32, WireF64, WireI16, WireI32, WireI64, WireU16, WireU32, WireU64};
12
13pub unsafe trait Decode<D: ?Sized> {
20 fn decode(slot: Slot<'_, Self>, decoder: &mut D) -> Result<(), DecodeError>;
25}
26
27macro_rules! impl_primitive {
28 ($ty:ty) => {
29 unsafe impl<D: ?Sized> Decode<D> for $ty {
30 #[inline]
31 fn decode(_: Slot<'_, Self>, _: &mut D) -> Result<(), DecodeError> {
32 Ok(())
33 }
34 }
35 };
36}
37
38macro_rules! impl_primitives {
39 ($($ty:ty),* $(,)?) => {
40 $(
41 impl_primitive!($ty);
42 )*
43 }
44}
45
46impl_primitives! {
47 i8,
48 WireI16,
49 WireI32,
50 WireI64,
51
52 u8,
53 WireU16,
54 WireU32,
55 WireU64,
56
57 WireF32,
58 WireF64,
59}
60
61unsafe impl<D: ?Sized> Decode<D> for bool {
62 #[inline]
63 fn decode(slot: Slot<'_, Self>, _: &mut D) -> Result<(), DecodeError> {
64 let value = unsafe { slot.as_ptr().cast::<u8>().read() };
65 match value {
66 0 | 1 => (),
67 invalid => return Err(DecodeError::InvalidBool(invalid)),
68 }
69 Ok(())
70 }
71}
72
73unsafe impl<D: ?Sized, T: Decode<D>, const N: usize> Decode<D> for [T; N] {
74 fn decode(mut slot: Slot<'_, Self>, decoder: &mut D) -> Result<(), DecodeError> {
75 for i in 0..N {
76 T::decode(slot.index(i), decoder)?;
77 }
78 Ok(())
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use crate::{chunks, WireF32, WireF64, WireI16, WireI32, WireI64, WireU16, WireU32, WireU64};
85
86 use crate::testing::assert_decoded;
87 use crate::wire::{WireBox, WireString, WireVector};
88 use crate::{WireOptionalString, WireOptionalVector};
89
90 #[test]
91 fn decode_bool() {
92 assert_decoded::<bool>(&mut chunks![0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], |x| {
93 assert!(*x)
94 });
95 assert_decoded::<bool>(&mut chunks![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], |x| {
96 assert!(!*x)
97 });
98 }
99
100 #[test]
101 fn decode_ints() {
102 assert_decoded::<u8>(&mut chunks![0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], |x| {
103 assert_eq!(*x, 0xa3u8)
104 });
105 assert_decoded::<i8>(&mut chunks![0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], |x| {
106 assert_eq!(*x, -0x45i8)
107 });
108
109 assert_decoded::<WireU16>(
110 &mut chunks![0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
111 |x| assert_eq!(*x, 0x1234u16),
112 );
113 assert_decoded::<WireI16>(
114 &mut chunks![0xcc, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
115 |x| assert_eq!(*x, -0x1234i16),
116 );
117
118 assert_decoded::<WireU32>(
119 &mut chunks![0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00],
120 |x| assert_eq!(*x, 0x12345678u32),
121 );
122 assert_decoded::<WireI32>(
123 &mut chunks![0x88, 0xa9, 0xcb, 0xed, 0x00, 0x00, 0x00, 0x00],
124 |x| assert_eq!(*x, -0x12345678i32),
125 );
126
127 assert_decoded::<WireU64>(
128 &mut chunks![0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
129 |x| assert_eq!(*x, 0x123456789abcdef0u64),
130 );
131 assert_decoded::<WireI64>(
132 &mut chunks![0x10, 0x21, 0x43, 0x65, 0x87, 0xa9, 0xcb, 0xed],
133 |x| assert_eq!(*x, -0x123456789abcdef0i64),
134 );
135 }
136
137 #[test]
138 fn decode_floats() {
139 assert_decoded::<WireF32>(
140 &mut chunks![0xdb, 0x0f, 0x49, 0x40, 0x00, 0x00, 0x00, 0x00],
141 |x| assert_eq!(*x, ::core::f32::consts::PI),
142 );
143 assert_decoded::<WireF64>(
144 &mut chunks![0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40],
145 |x| assert_eq!(*x, ::core::f64::consts::PI),
146 );
147 }
148
149 #[test]
150 fn decode_box() {
151 assert_decoded::<WireBox<WireU64>>(
152 &mut chunks![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
153 |x| assert_eq!(x.as_ref(), None),
154 );
155 assert_decoded::<WireBox<WireU64>>(
156 &mut chunks![
157 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56,
158 0x34, 0x12,
159 ],
160 |x| assert_eq!(*x.as_ref().unwrap(), 0x123456789abcdef0u64),
161 );
162 }
163
164 #[test]
165 fn decode_vec() {
166 assert_decoded::<WireOptionalVector<WireU32>>(
167 &mut chunks![
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00,
170 ],
171 |x| assert!(x.as_ref().is_none()),
172 );
173 assert_decoded::<WireVector<WireU32>>(
174 &mut chunks![
175 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
176 0xff, 0xff, 0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a,
177 ],
178 |x| assert_eq!(x.as_slice(), [0x12345678, 0x9abcdef0].as_slice(),),
179 );
180 assert_decoded::<WireVector<WireU32>>(
181 &mut chunks![
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
183 0xff, 0xff,
184 ],
185 |x| assert_eq!(x.len(), 0),
186 );
187 }
188
189 #[test]
190 fn decode_string() {
191 assert_decoded::<WireOptionalString>(
192 &mut chunks![
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00,
195 ],
196 |x| assert!(x.is_none()),
197 );
198 assert_decoded::<WireString>(
199 &mut chunks![
200 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
201 0xff, 0xff, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00,
202 ],
203 |x| assert_eq!(x.as_str(), "0123"),
204 );
205 assert_decoded::<WireString>(
206 &mut chunks![
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
208 0xff, 0xff,
209 ],
210 |x| assert_eq!(x.len(), 0),
211 );
212 }
213}