@@ -8,18 +8,21 @@ use serde_at::HexStr;
88/// [`atat_derive`]: https://crates.io/crates/atat_derive
99pub trait AtatLen {
1010 const LEN : usize ;
11+ const ESCAPED_LEN : usize ;
1112}
1213
1314#[ cfg( feature = "bytes" ) ]
1415impl < const N : usize > AtatLen for heapless_bytes:: Bytes < N > {
1516 const LEN : usize = N ;
17+ const ESCAPED_LEN : usize = N ;
1618}
1719
1820macro_rules! impl_length {
1921 ( $type: ty, $len: expr) => {
2022 #[ allow( clippy:: use_self) ]
2123 impl AtatLen for $type {
2224 const LEN : usize = $len;
25+ const ESCAPED_LEN : usize = $len;
2326 }
2427 } ;
2528}
@@ -51,27 +54,32 @@ impl_length!(HexStr<u128>, 130);
5154
5255impl < const T : usize > AtatLen for String < T > {
5356 const LEN : usize = 1 + T + 1 ;
57+ const ESCAPED_LEN : usize = 3 * T + 2 ;
5458}
5559
5660impl < T : AtatLen > AtatLen for Option < T > {
5761 const LEN : usize = T :: LEN ;
62+ const ESCAPED_LEN : usize = T :: ESCAPED_LEN ;
5863}
5964
6065impl < T : AtatLen > AtatLen for & T {
6166 const LEN : usize = T :: LEN ;
67+ const ESCAPED_LEN : usize = T :: ESCAPED_LEN ;
6268}
6369
6470impl < T , const L : usize > AtatLen for Vec < T , L >
6571where
6672 T : AtatLen ,
6773{
6874 const LEN : usize = L * <T as AtatLen >:: LEN ;
75+ const ESCAPED_LEN : usize = L * <T as AtatLen >:: ESCAPED_LEN ;
6976}
7077
7178// 0x F:F:F:F
7279// uN = (2 + (N*4) - 1) * 2 bytes
7380impl < const L : usize > AtatLen for HexStr < [ u8 ; L ] > {
7481 const LEN : usize = ( 2 + L * 4 - 1 ) * 2 ;
82+ const ESCAPED_LEN : usize = ( 2 + L * 4 - 1 ) * 2 ;
7583}
7684
7785// Currently, stable rust (version at the time of writing: 1.93)
@@ -81,6 +89,7 @@ macro_rules! impl_nonzero_length {
8189 ( $type: ty) => {
8290 impl AtatLen for NonZero <$type> {
8391 const LEN : usize = <$type as AtatLen >:: LEN ;
92+ const ESCAPED_LEN : usize = <$type as AtatLen >:: ESCAPED_LEN ;
8493 }
8594 } ;
8695}
@@ -202,8 +211,18 @@ mod tests {
202211 assert_eq ! ( <f32 as AtatLen >:: LEN , 42 ) ;
203212 assert_eq ! ( <f64 as AtatLen >:: LEN , 312 ) ;
204213
214+ // For non-string primitives, ESCAPED_LEN == LEN
215+ assert_eq ! ( <u8 as AtatLen >:: ESCAPED_LEN , 3 ) ;
216+ assert_eq ! ( <i64 as AtatLen >:: ESCAPED_LEN , 20 ) ;
217+
218+ // String<T>: LEN = 1 + T + 1 (quotes), ESCAPED_LEN = 3*T + 2
219+ assert_eq ! ( <String <10 > as AtatLen >:: LEN , 12 ) ;
220+ assert_eq ! ( <String <10 > as AtatLen >:: ESCAPED_LEN , 32 ) ;
221+
205222 assert_eq ! ( <SimpleEnum as AtatLen >:: LEN , 3 ) ;
206223 assert_eq ! ( <SimpleEnumU32 as AtatLen >:: LEN , 10 ) ;
224+ assert_eq ! ( <SimpleEnum as AtatLen >:: ESCAPED_LEN , 3 ) ;
225+ assert_eq ! ( <SimpleEnumU32 as AtatLen >:: ESCAPED_LEN , 10 ) ;
207226
208227 assert_eq ! ( <HexStr <u8 > as AtatLen >:: LEN , 10 ) ;
209228 assert_eq ! ( <HexStr <u16 > as AtatLen >:: LEN , 18 ) ;
@@ -214,18 +233,31 @@ mod tests {
214233 #[ cfg( feature = "hex_str_arrays" ) ]
215234 {
216235 assert_eq ! ( <HexStr <[ u8 ; 16 ] > as AtatLen >:: LEN , 130 ) ;
236+ assert_eq ! ( <HexStr <[ u8 ; 16 ] > as AtatLen >:: ESCAPED_LEN , 130 ) ;
217237 }
218238
219239 // (fields) + (n_fields - 1)
220- // (3 + (1 + 128 + 1) + 2 + (1 + 150 + 1) + 3 + 10 + 3 + (10*5)) + 7
240+ // (3 + (1 + 128 + 1) + 2 + (1 + 150 + 1) + 3 + 10 + 3) + 6
221241 assert_eq ! (
222242 <LengthTester <' _> as AtatLen >:: LEN ,
223243 ( 3 + ( 1 + 128 + 1 ) + 2 + ( 1 + 150 + 1 ) + 3 + 10 + 3 ) + 6
224244 ) ;
245+ // ESCAPED_LEN: String<128> -> 3*128+2=386, &str len=150 -> 3*150+2=452
246+ // (3 + 386 + 2 + 452 + 3 + 10 + 3) + 6
247+ assert_eq ! (
248+ <LengthTester <' _> as AtatLen >:: ESCAPED_LEN ,
249+ ( 3 + ( 3 * 128 + 2 ) + 2 + ( 3 * 150 + 2 ) + 3 + 10 + 3 ) + 6
250+ ) ;
225251 assert_eq ! (
226252 <MixedEnum <' _> as AtatLen >:: LEN ,
227253 ( 3 + 3 + ( 1 + 10 + 1 ) + 20 + 10 ) + 4
228254 ) ;
255+ // ESCAPED_LEN: String<10> -> 3*10+2=32
256+ // max variant AdvancedTuple: (3 + 32 + 20 + 10) + 4 separators = 69
257+ assert_eq ! (
258+ <MixedEnum <' _> as AtatLen >:: ESCAPED_LEN ,
259+ 3 + ( 3 + 32 + 20 + 10 ) + 4
260+ ) ;
229261 }
230262
231263 #[ test]
0 commit comments