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