1use crate::*;
42use std::{
43 convert::{Infallible, TryFrom},
44 fmt,
45};
46
47#[cfg(feature = "L2")]
48pub use L2 as Len;
49#[cfg(not(feature = "L2"))]
50pub use L3 as Len;
51
52macro_rules! def {
53 [$name:ident($ty:ty), BITS: $BITS:literal, TryFromErr: $err: ty, $encoder:item, $decoder:item] => {
54 #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
55 pub struct $name(pub $ty);
56 impl $name {
57 pub const MAX: $name = $name((1 << $BITS) - 1);
58 pub const BITS: u32 = $BITS;
59 }
60 impl Encoder for $name { #[inline] $encoder }
61 impl Decoder<'_> for $name { #[inline] $decoder }
62 impl TryFrom<usize> for $name {
63 type Error = String;
64 #[inline] fn try_from(num: usize) -> std::result::Result<Self, Self::Error> {
65 if num > (1 << $BITS) - 1 {
66 Err(format!("Max payload length is {}, But got {num}", Self::MAX.0))
67 } else {
68 Ok(Self(num as $ty))
69 }
70 }
71 }
72 impl TryFrom<$name> for usize {
73 type Error = $err;
74 #[inline] fn try_from(num: $name) -> std::result::Result<Self, Self::Error> { TryFrom::try_from(num.0) }
75 }
76 impl From<$ty> for $name { fn from(num: $ty) -> Self { Self(num) } }
77 impl fmt::Display for $name {
78 #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) }
79 }
80 impl core::ops::Deref for $name {
81 type Target = $ty;
82 #[inline] fn deref(&self) -> &Self::Target { &self.0 }
83 }
84 impl core::ops::DerefMut for $name {
85 #[inline] fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
86 }
87 };
88}
89
90def!(
91 L2(u16),
92 BITS: 15,
93 TryFromErr: Infallible,
94 fn encoder(&self, c: &mut impl Write) -> io::Result<()> {
95 let num = self.0;
96 let b1 = num as u8;
97 if num < 128 { c.write_all(&[b1]) }
99 else {
100 debug_assert!(num <= 0x7FFF);
101 let b1 = 0x80 | b1; let b2 = (num >> 7) as u8; c.write_all(&[b1, b2])
104 }
105 },
106 fn decoder(c: &mut &[u8]) -> Result<Self> {
107 let mut num = u8::decoder(c)? as u16;
108 if num >> 7 == 1 {
110 let snd = u8::decoder(c)? as u16;
111 num = (num & 0x7F) | snd << 7; }
113 Ok(Self(num))
114 }
115);
116
117def!(
118 L3(u32),
119 BITS: 22,
120 TryFromErr: std::num::TryFromIntError,
121 fn encoder(&self, c: &mut impl Write) -> io::Result<()> {
122 let num = self.0;
123 let b1 = num as u8;
124 if num < 128 { c.write_all(&[b1]) }
125 else {
126 let b1 = b1 & 0x3F; let b2 = (num >> 6) as u8; if num < 0x4000 {
129 c.write_all(&[0x80 | b1, b2])
131 }
132 else {
133 debug_assert!(num <= 0x3FFFFF);
134 let b3 = (num >> 14) as u8; c.write_all(&[0xC0 | b1, b2, b3])
137 }
138 }
139 },
140 fn decoder(c: &mut &[u8]) -> Result<Self> {
141 let num = u8::decoder(c)? as u32;
142 let num = if num >> 7 == 0 { num }
144 else if num >> 6 == 2 {
146 let b2 = u8::decoder(c)? as u32;
147 (num & 0x3F) | b2 << 6
148 } else {
149 let [b2, b3] = <&[u8; 2]>::decoder(c)?;
151 (num & 0x3F) | (*b2 as u32) << 6 | (*b3 as u32) << 14 };
155 Ok(Self(num))
156 }
157);
158
159#[cfg(test)]
160mod tests {
161 use super::*;
162
163 macro_rules! assert_len {
164 [$len: expr, $expect: expr] => {
165 let bytes = $len.encode();
166 assert_eq!(bytes, $expect);
167 assert_eq!($len, Decoder::decode(&bytes).unwrap());
168 };
169 }
170
171 #[test]
172 fn l2() {
173 assert_len!(L2(0), [0]);
174 assert_len!(L2(127), [127]);
175
176 assert_len!(L2(128), [128, 1]);
177 assert_len!(L2(32767), [255, 255]);
178 }
179
180 #[test]
181 fn l3() {
182 assert_len!(L3(0), [0]);
183 assert_len!(L3(127), [127]);
184
185 assert_len!(L3(128), [128, 2]);
186 assert_len!(L3(16383), [191, 255]);
187
188 assert_len!(L3(16384), [192, 0, 1]);
189 assert_len!(L3(4194303), [255, 255, 255]);
190 }
191}