1#![cfg(feature = "serde")]
2#![doc = include_str!("../doc/serdes.md")]
3
4mod array;
5mod slice;
6mod utils;
7
8use core::fmt::{
9 self,
10 Formatter,
11};
12
13use serde::de::{
14 Deserialize,
15 Deserializer,
16 Visitor,
17};
18
19type Result<S> = core::result::Result<
21 <S as serde::Serializer>::Ok,
22 <S as serde::Serializer>::Error,
23>;
24
25static FIELDS: &[&str] = &["order", "head", "bits", "data"];
27
28enum Field {
30 Order,
32 Head,
34 Bits,
36 Data,
38}
39
40struct FieldVisitor;
42
43impl<'de> Deserialize<'de> for Field {
44 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
45 where D: Deserializer<'de> {
46 deserializer.deserialize_identifier(FieldVisitor)
47 }
48}
49
50impl<'de> Visitor<'de> for FieldVisitor {
51 type Value = Field;
52
53 fn expecting(&self, fmt: &mut Formatter) -> fmt::Result {
54 fmt.write_str("field_identifier")
55 }
56
57 fn visit_str<E>(self, value: &str) -> core::result::Result<Self::Value, E>
58 where E: serde::de::Error {
59 match value {
60 "order" => Ok(Field::Order),
61 "head" => Ok(Field::Head),
62 "bits" => Ok(Field::Bits),
63 "data" => Ok(Field::Data),
64 _ => Err(serde::de::Error::unknown_field(value, FIELDS)),
65 }
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use serde::{
72 Deserialize,
73 Serialize,
74 };
75 use static_assertions::*;
76
77 use crate::prelude::*;
78
79 #[test]
80 fn trait_impls() {
81 use core::{
82 cell::Cell,
83 sync::atomic::*,
84 };
85
86 use radium::types::*;
87 macro_rules! check_impl {
88 ($($ord:ident @ $($sto:ty),+);+ $(;)?) => {{ $( $(
89 assert_impl_all!(BitSlice<$sto, $ord>: Serialize);
90 assert_impl_all!(BitArray<$sto, $ord>: Serialize, Deserialize<'static>);
91 assert_impl_all!(BitArray<[$sto; 32], $ord>: Serialize, Deserialize<'static>);
92
93 #[cfg(feature = "alloc")] {
94 assert_impl_all!(BitBox<$sto, $ord>: Serialize, Deserialize<'static>);
95 assert_impl_all!(BitVec<$sto, $ord>: Serialize, Deserialize<'static>);
96 }
97 )+ )+ }};
98 }
99
100 assert_impl_all!(&BitSlice<u8, Lsb0>: Deserialize<'static>);
101 assert_impl_all!(&BitSlice<u8, Msb0>: Deserialize<'static>);
102 assert_impl_all!(&BitSlice<u8, LocalBits>: Deserialize<'static>);
103
104 check_impl! {
105 Lsb0 @ u8, u16, u32, usize;
106 Msb0 @ u8, u16, u32, usize;
107 LocalBits @ u8, u16, u32, usize;
108 Lsb0 @ Cell<u8>, Cell<u16>, Cell<u32>, Cell<usize>;
109 Msb0 @ Cell<u8>, Cell<u16>, Cell<u32>, Cell<usize>;
110 LocalBits @ Cell<u8>, Cell<u16>, Cell<u32>, Cell<usize>;
111 Lsb0 @ RadiumU8, RadiumU16, RadiumU32, RadiumUsize;
112 Msb0 @ RadiumU8, RadiumU16, RadiumU32, RadiumUsize;
113 LocalBits @ RadiumU8, RadiumU16, RadiumU32, RadiumUsize;
114 }
115 radium::if_atomic! {
116 if atomic(8) {
117 check_impl! {
118 Lsb0 @ AtomicU8;
119 Msb0 @ AtomicU8;
120 LocalBits @ AtomicU8;
121 }
122 }
123 if atomic(16) {
124 check_impl! {
125 Lsb0 @ AtomicU16;
126 Msb0 @ AtomicU16;
127 LocalBits @ AtomicU16;
128 }
129 }
130 if atomic(32) {
131 check_impl! {
132 Lsb0 @ AtomicU32;
133 Msb0 @ AtomicU32;
134 LocalBits @ AtomicU32;
135 }
136 }
137 if atomic(ptr) {
138 check_impl! {
139 Lsb0 @ AtomicUsize;
140 Msb0 @ AtomicUsize;
141 LocalBits @ AtomicUsize;
142 }
143 }
144 }
145 #[cfg(target_pointer_width = "64")]
146 check_impl! {
147 Lsb0 @ u64, RadiumU64;
148 Msb0 @ u64, RadiumU64;
149 LocalBits @ u64, RadiumU64;
150 }
151 #[cfg(target_pointer_width = "64")]
152 radium::if_atomic!(if atomic(64) {
153 check_impl! {
154 Lsb0 @ AtomicU64;
155 Msb0 @ AtomicU64;
156 LocalBits @ AtomicU64;
157 }
158 });
159 }
160}