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_bool() {
94 assert_decoded::<bool>(&mut chunks![0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], |x| {
95 assert!(*x)
96 });
97 assert_decoded::<bool>(&mut chunks![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], |x| {
98 assert!(!*x)
99 });
100 }
101
102 #[test]
103 fn decode_ints() {
104 assert_decoded::<u8>(&mut chunks![0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], |x| {
105 assert_eq!(*x, 0xa3u8)
106 });
107 assert_decoded::<i8>(&mut chunks![0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], |x| {
108 assert_eq!(*x, -0x45i8)
109 });
110
111 assert_decoded::<WireU16>(
112 &mut chunks![0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
113 |x| assert_eq!(*x, 0x1234u16),
114 );
115 assert_decoded::<WireI16>(
116 &mut chunks![0xcc, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
117 |x| assert_eq!(*x, -0x1234i16),
118 );
119
120 assert_decoded::<WireU32>(
121 &mut chunks![0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00],
122 |x| assert_eq!(*x, 0x12345678u32),
123 );
124 assert_decoded::<WireI32>(
125 &mut chunks![0x88, 0xa9, 0xcb, 0xed, 0x00, 0x00, 0x00, 0x00],
126 |x| assert_eq!(*x, -0x12345678i32),
127 );
128
129 assert_decoded::<WireU64>(
130 &mut chunks![0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
131 |x| assert_eq!(*x, 0x123456789abcdef0u64),
132 );
133 assert_decoded::<WireI64>(
134 &mut chunks![0x10, 0x21, 0x43, 0x65, 0x87, 0xa9, 0xcb, 0xed],
135 |x| assert_eq!(*x, -0x123456789abcdef0i64),
136 );
137 }
138
139 #[test]
140 fn decode_floats() {
141 assert_decoded::<WireF32>(
142 &mut chunks![0xdb, 0x0f, 0x49, 0x40, 0x00, 0x00, 0x00, 0x00],
143 |x| assert_eq!(*x, ::core::f32::consts::PI),
144 );
145 assert_decoded::<WireF64>(
146 &mut chunks![0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40],
147 |x| assert_eq!(*x, ::core::f64::consts::PI),
148 );
149 }
150
151 #[test]
152 fn decode_box() {
153 assert_decoded::<WireBox<WireU64>>(
154 &mut chunks![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
155 |x| assert_eq!(x.as_ref(), None),
156 );
157 assert_decoded::<WireBox<WireU64>>(
158 &mut chunks![
159 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56,
160 0x34, 0x12,
161 ],
162 |x| assert_eq!(*x.as_ref().unwrap(), 0x123456789abcdef0u64),
163 );
164 }
165
166 #[test]
167 fn decode_vec() {
168 assert_decoded::<WireOptionalVector<WireU32>>(
169 &mut chunks![
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x00, 0x00,
172 ],
173 |x| assert!(x.as_ref().is_none()),
174 );
175 assert_decoded::<WireVector<WireU32>>(
176 &mut chunks![
177 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
178 0xff, 0xff, 0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a,
179 ],
180 |x| assert_eq!(x.as_slice(), [0x12345678, 0x9abcdef0].as_slice(),),
181 );
182 assert_decoded::<WireVector<WireU32>>(
183 &mut chunks![
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
185 0xff, 0xff,
186 ],
187 |x| assert_eq!(x.len(), 0),
188 );
189 }
190
191 #[test]
192 fn decode_string() {
193 assert_decoded::<WireOptionalString>(
194 &mut chunks![
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00,
197 ],
198 |x| assert!(x.is_none()),
199 );
200 assert_decoded::<WireString>(
201 &mut chunks![
202 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
203 0xff, 0xff, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00,
204 ],
205 |x| assert_eq!(x.as_str(), "0123"),
206 );
207 assert_decoded::<WireString>(
208 &mut chunks![
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
210 0xff, 0xff,
211 ],
212 |x| assert_eq!(x.len(), 0),
213 );
214 }
215}