1mod bool;
4mod bytes;
5mod float;
6mod int;
7mod map;
8mod null;
9mod seq;
10mod string;
11mod unit;
12
13#[cfg(any(test, feature = "testing"))]
14use proptest::prelude::*;
15#[cfg(any(test, feature = "testing"))]
16use proptest_derive::Arbitrary;
17
18use crate::marker::Marker;
19
20pub use self::{
21 bool::BoolHeader,
22 bytes::BytesHeader,
23 float::FloatHeader,
24 int::{CompactIntHeader, ExtendedIntHeader, IntHeader},
25 map::{CompactMapHeader, ExtendedMapHeader, MapHeader},
26 null::NullHeader,
27 seq::{CompactSeqHeader, ExtendedSeqHeader, SeqHeader},
28 string::{CompactStringHeader, ExtendedStringHeader, StringHeader},
29 unit::UnitHeader,
30};
31
32#[cfg(any(test, feature = "testing"))]
33pub(crate) fn arbitrary_len() -> impl Strategy<Value = usize> {
34 proptest::prop_oneof![
35 proptest::num::u8::ANY.prop_map(|len| len as usize),
36 proptest::num::u16::ANY.prop_map(|len| len as usize),
37 proptest::num::u32::ANY.prop_map(|len| len as usize),
38 proptest::num::u64::ANY.prop_map(|len| len as usize),
39 ]
40}
41
42#[cfg_attr(any(test, feature = "testing"), derive(Arbitrary))]
44#[derive(Copy, Clone, Eq, PartialEq, Debug)]
45pub enum Header {
46 Int(IntHeader),
48
49 String(StringHeader),
51
52 Seq(SeqHeader),
54
55 Map(MapHeader),
61
62 Float(FloatHeader),
64
65 Bytes(BytesHeader),
67
68 Bool(BoolHeader),
70
71 Unit(UnitHeader),
73
74 Null(NullHeader),
76}
77
78impl Default for Header {
79 #[inline]
80 fn default() -> Self {
81 Self::Null(NullHeader)
82 }
83}
84
85impl From<IntHeader> for Header {
86 #[inline]
87 fn from(value: IntHeader) -> Self {
88 Self::Int(value)
89 }
90}
91
92impl From<StringHeader> for Header {
93 #[inline]
94 fn from(value: StringHeader) -> Self {
95 Self::String(value)
96 }
97}
98
99impl From<SeqHeader> for Header {
100 #[inline]
101 fn from(value: SeqHeader) -> Self {
102 Self::Seq(value)
103 }
104}
105
106impl From<MapHeader> for Header {
107 #[inline]
108 fn from(value: MapHeader) -> Self {
109 Self::Map(value)
110 }
111}
112
113impl From<FloatHeader> for Header {
114 #[inline]
115 fn from(value: FloatHeader) -> Self {
116 Self::Float(value)
117 }
118}
119
120impl From<BytesHeader> for Header {
121 #[inline]
122 fn from(value: BytesHeader) -> Self {
123 Self::Bytes(value)
124 }
125}
126
127impl From<BoolHeader> for Header {
128 #[inline]
129 fn from(value: BoolHeader) -> Self {
130 Self::Bool(value)
131 }
132}
133
134impl From<UnitHeader> for Header {
135 #[inline]
136 fn from(value: UnitHeader) -> Self {
137 Self::Unit(value)
138 }
139}
140
141impl From<NullHeader> for Header {
142 #[inline]
143 fn from(value: NullHeader) -> Self {
144 Self::Null(value)
145 }
146}
147
148impl Header {
149 pub fn marker(&self) -> Marker {
151 match self {
152 Header::Int(_) => Marker::Int,
153 Header::String(_) => Marker::String,
154 Header::Seq(_) => Marker::Seq,
155 Header::Map(_) => Marker::Map,
156 Header::Float(_) => Marker::Float,
157 Header::Bytes(_) => Marker::Bytes,
158 Header::Bool(_) => Marker::Bool,
159 Header::Unit(_) => Marker::Unit,
160 Header::Null(_) => Marker::Null,
161 }
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use proptest::prelude::*;
168 use test_log::test;
169
170 use crate::{
171 config::EncoderConfig,
172 decoder::Decoder,
173 encoder::Encoder,
174 io::{SliceReader, VecWriter},
175 };
176
177 use super::*;
178
179 proptest! {
180 #[test]
181 fn encode_decode_roundtrip(header in Header::arbitrary(), config in EncoderConfig::arbitrary()) {
182 let mut encoded: Vec<u8> = Vec::new();
183 let writer = VecWriter::new(&mut encoded);
184 let mut encoder = Encoder::new(writer, config);
185 encoder.encode_header(&header).unwrap();
186
187 let reader = SliceReader::new(&encoded);
188 let mut decoder = Decoder::from_reader(reader);
189 let decoded = decoder.decode_header().unwrap();
190 prop_assert_eq!(&decoded, &header);
191 }
192 }
193}