1use std::collections::{BTreeMap, BTreeSet, VecDeque};
25use std::hash::Hash;
26use std::io;
27use std::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8};
28
29use amplify::ascii::AsciiString;
30use amplify::confinement::Confined;
31#[cfg(feature = "float")]
32use amplify::num::apfloat::{ieee, Float};
33use amplify::num::{i1024, i256, i512, u1024, u24, u256, u40, u48, u512, u56};
34use amplify::{Array, Wrapper};
35
36use crate::stl::AsciiSym;
37use crate::{
38 DecodeError, DefineUnion, Primitive, RString, ReadRaw, ReadTuple, ReadUnion, RestrictedCharSet,
39 Sizing, StrictDecode, StrictDumb, StrictEncode, StrictProduct, StrictStruct, StrictSum,
40 StrictTuple, StrictType, StrictUnion, TypeName, TypedRead, TypedWrite, WriteRaw, WriteTuple,
41 WriteUnion, LIB_EMBEDDED,
42};
43
44pub trait DecodeRawLe: Sized {
45 fn decode_raw_le(reader: &mut (impl ReadRaw + ?Sized)) -> Result<Self, DecodeError>;
46}
47
48#[derive(
49 Wrapper, WrapperMut, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default, From
50)]
51#[wrapper(Display, FromStr, Octal, BitOps)]
52#[wrapper_mut(BitAssign)]
53#[derive(StrictType, StrictDecode)]
54#[strict_type(lib = LIB_EMBEDDED, crate = crate)]
55pub struct Byte(u8);
56
57impl StrictEncode for Byte {
58 fn strict_encode<W: TypedWrite>(&self, mut writer: W) -> io::Result<W> {
59 unsafe {
60 writer = writer.register_primitive(Primitive::BYTE);
61 writer.raw_writer().write_raw::<1>([self.0])?;
62 }
63 Ok(writer)
64 }
65}
66
67macro_rules! encode_num {
68 ($ty:ty, $id:ident) => {
69 impl $crate::StrictType for $ty {
70 const STRICT_LIB_NAME: &'static str = $crate::LIB_EMBEDDED;
71 fn strict_name() -> Option<TypeName> { Some(tn!(stringify!($id))) }
72 }
73 impl $crate::StrictEncode for $ty {
74 fn strict_encode<W: TypedWrite>(&self, mut writer: W) -> io::Result<W> {
75 unsafe {
76 writer = writer.register_primitive(Primitive::$id);
77 writer.raw_writer().write_raw_array(self.to_le_bytes())?;
78 }
79 Ok(writer)
80 }
81 }
82 impl $crate::DecodeRawLe for $ty {
83 fn decode_raw_le(reader: &mut (impl ReadRaw + ?Sized)) -> Result<Self, DecodeError> {
84 let buf = reader.read_raw_array::<{ Self::BITS as usize / 8 }>()?;
85 Ok(Self::from_le_bytes(buf))
86 }
87 }
88 impl $crate::StrictDecode for $ty {
89 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
90 Self::decode_raw_le(unsafe { reader.raw_reader() })
91 }
92 }
93 };
94}
95
96macro_rules! encode_nonzero {
97 ($ty:ty, $p:ty, $id:ident) => {
98 impl $crate::StrictType for $ty {
99 const STRICT_LIB_NAME: &'static str = $crate::LIB_EMBEDDED;
100 fn strict_name() -> Option<TypeName> { Some(tn!(stringify!($id))) }
101 }
102 impl $crate::StrictEncode for $ty {
103 fn strict_encode<W: TypedWrite>(&self, mut writer: W) -> io::Result<W> {
104 unsafe {
105 writer = writer.register_primitive(Primitive::$id);
106 writer.raw_writer().write_raw_array(self.get().to_le_bytes())?;
107 }
108 Ok(writer)
109 }
110 }
111 impl $crate::StrictDecode for $ty {
112 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
113 let buf =
114 unsafe { reader.raw_reader().read_raw_array::<{ Self::BITS as usize / 8 }>()? };
115 let v = <$p>::from_le_bytes(buf);
116 Self::new(v).ok_or(DecodeError::ZeroNatural)
117 }
118 }
119 };
120}
121
122macro_rules! encode_float {
123 ($ty:ty, $len:literal, $id:ident) => {
124 #[cfg(feature = "float")]
125 impl $crate::StrictType for $ty {
126 const STRICT_LIB_NAME: &'static str = $crate::LIB_EMBEDDED;
127 fn strict_name() -> Option<TypeName> { Some(tn!(stringify!($id))) }
128 }
129 #[cfg(feature = "float")]
130 impl $crate::StrictEncode for $ty {
131 fn strict_encode<W: TypedWrite>(&self, mut writer: W) -> io::Result<W> {
132 let mut be = [0u8; $len];
133 be.copy_from_slice(&self.to_bits().to_le_bytes()[..$len]);
134 unsafe {
135 writer = writer.register_primitive(Primitive::$id);
136 writer.raw_writer().write_raw_array(be)?;
137 }
138 Ok(writer)
139 }
140 }
141 #[cfg(feature = "float")]
142 impl $crate::StrictDecode for $ty {
143 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
144 const BYTES: usize = <$ty>::BITS / 8;
145 let mut inner = [0u8; 32];
146 let buf = unsafe { reader.raw_reader().read_raw_array::<BYTES>()? };
147 inner[..BYTES].copy_from_slice(&buf[..]);
148 let bits = u256::from_le_bytes(inner);
149 Ok(Self::from_bits(bits))
150 }
151 }
152 };
153}
154
155encode_num!(u8, U8);
156encode_num!(u16, U16);
157encode_num!(u24, U24);
158encode_num!(u32, U32);
159encode_num!(u40, U40);
160encode_num!(u48, U48);
161encode_num!(u56, U56);
162encode_num!(u64, U64);
163encode_num!(u128, U128);
164encode_num!(u256, U256);
165encode_num!(u512, U512);
166encode_num!(u1024, U1024);
167
168encode_num!(i8, I8);
169encode_num!(i16, I16);
170encode_num!(i32, I32);
171encode_num!(i64, I64);
172encode_num!(i128, I128);
173encode_num!(i256, I256);
174encode_num!(i512, I512);
175encode_num!(i1024, I1024);
176
177encode_nonzero!(NonZeroU8, u8, N8);
178encode_nonzero!(NonZeroU16, u16, N16);
179encode_nonzero!(NonZeroU32, u32, U32);
180encode_nonzero!(NonZeroU64, u64, U64);
181encode_nonzero!(NonZeroU128, u128, U128);
182
183encode_float!(ieee::Half, 2, F16);
184encode_float!(ieee::Single, 4, F32);
185encode_float!(ieee::Double, 8, F64);
186encode_float!(ieee::X87DoubleExtended, 10, F80);
187encode_float!(ieee::Quad, 16, F128);
188encode_float!(ieee::Oct, 32, F256);
189
190impl<T> StrictType for Box<T>
191where T: StrictType
192{
193 const STRICT_LIB_NAME: &'static str = T::STRICT_LIB_NAME;
194}
195impl<T> StrictSum for Box<T>
196where T: StrictSum
197{
198 const ALL_VARIANTS: &'static [(u8, &'static str)] = T::ALL_VARIANTS;
199 fn variant_name(&self) -> &'static str { self.as_ref().variant_name() }
200}
201impl<T> StrictProduct for Box<T> where T: Default + StrictProduct {}
202impl<T> StrictUnion for Box<T> where T: Default + StrictUnion {}
203impl<T> StrictTuple for Box<T>
204where T: Default + StrictTuple
205{
206 const FIELD_COUNT: u8 = T::FIELD_COUNT;
207}
208impl<T> StrictStruct for Box<T>
209where T: Default + StrictStruct
210{
211 const ALL_FIELDS: &'static [&'static str] = T::ALL_FIELDS;
212}
213impl<T> StrictEncode for Box<T>
214where T: StrictEncode
215{
216 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> {
217 self.as_ref().strict_encode(writer)
218 }
219}
220impl<T> StrictDecode for Box<T>
221where T: StrictDecode
222{
223 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
224 T::strict_decode(reader).map(Box::new)
225 }
226}
227
228impl<T> StrictType for Option<T>
229where T: StrictType
230{
231 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
232 fn strict_name() -> Option<TypeName> { None }
233}
234impl<T> StrictSum for Option<T>
235where T: StrictType
236{
237 const ALL_VARIANTS: &'static [(u8, &'static str)] = &[(0u8, "none"), (1u8, "some")];
238 fn variant_name(&self) -> &'static str {
239 match self {
240 None => "none",
241 Some(_) => "some",
242 }
243 }
244}
245impl<T> StrictUnion for Option<T> where T: StrictType {}
246impl<T: StrictEncode + StrictDumb> StrictEncode for Option<T> {
247 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> {
248 writer.write_union::<Self>(|u| {
249 let u = u.define_unit(vname!("none")).define_newtype::<T>(vname!("some")).complete();
250
251 Ok(match self {
252 None => u.write_unit(vname!("none")),
253 Some(val) => u.write_newtype(vname!("some"), val),
254 }?
255 .complete())
256 })
257 }
258}
259impl<T: StrictDecode> StrictDecode for Option<T> {
260 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
261 reader.read_union(|field_name, u| match field_name.as_str() {
262 "none" => Ok(None),
263 "some" => u.read_tuple(|r| r.read_field().map(Some)),
264 _ => unreachable!("unknown option field"),
265 })
266 }
267}
268
269impl StrictType for () {
270 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
271 fn strict_name() -> Option<TypeName> { None }
272}
273impl StrictEncode for () {
274 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> {
275 Ok(unsafe { writer.register_primitive(Primitive::UNIT) })
276 }
277}
278impl StrictDecode for () {
279 fn strict_decode(_reader: &mut impl TypedRead) -> Result<Self, DecodeError> { Ok(()) }
280}
281
282impl<A: StrictType, B: StrictType> StrictType for (A, B) {
283 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
284 fn strict_name() -> Option<TypeName> { None }
285}
286impl<A: StrictType + Default, B: StrictType + Default> StrictProduct for (A, B) {}
287impl<A: StrictType + Default, B: StrictType + Default> StrictTuple for (A, B) {
288 const FIELD_COUNT: u8 = 2;
289}
290impl<A: StrictEncode + Default, B: StrictEncode + Default> StrictEncode for (A, B) {
291 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> {
292 writer.write_tuple::<Self>(|w| Ok(w.write_field(&self.0)?.write_field(&self.1)?.complete()))
293 }
294}
295impl<A: StrictDecode + Default, B: StrictDecode + Default> StrictDecode for (A, B) {
296 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
297 reader.read_tuple(|r| {
298 let a = r.read_field()?;
299 let b = r.read_field()?;
300 Ok((a, b))
301 })
302 }
303}
304
305impl<A: StrictType, B: StrictType, C: StrictType> StrictType for (A, B, C) {
306 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
307 fn strict_name() -> Option<TypeName> { None }
308}
309impl<A: StrictType + Default, B: StrictType + Default, C: StrictType + Default> StrictProduct
310 for (A, B, C)
311{
312}
313impl<A: StrictType + Default, B: StrictType + Default, C: StrictType + Default> StrictTuple
314 for (A, B, C)
315{
316 const FIELD_COUNT: u8 = 3;
317}
318impl<A: StrictEncode + Default, B: StrictEncode + Default, C: StrictEncode + Default> StrictEncode
319 for (A, B, C)
320{
321 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> {
322 writer.write_tuple::<Self>(|w| {
323 Ok(w.write_field(&self.0)?.write_field(&self.1)?.write_field(&self.2)?.complete())
324 })
325 }
326}
327impl<A: StrictDecode + Default, B: StrictDecode + Default, C: StrictDecode + Default> StrictDecode
328 for (A, B, C)
329{
330 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
331 reader.read_tuple(|r| {
332 let a = r.read_field()?;
333 let b = r.read_field()?;
334 let c = r.read_field()?;
335 Ok((a, b, c))
336 })
337 }
338}
339
340impl<T: StrictType + Copy + StrictDumb, const LEN: usize> StrictType for [T; LEN] {
341 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
342 fn strict_name() -> Option<TypeName> { None }
343}
344impl<T: StrictEncode + Copy + StrictDumb, const LEN: usize> StrictEncode for [T; LEN] {
345 fn strict_encode<W: TypedWrite>(&self, mut writer: W) -> io::Result<W> {
346 for item in self {
347 writer = item.strict_encode(writer)?;
348 }
349 Ok(unsafe {
350 if T::strict_name() == u8::strict_name() {
351 writer.register_array(&Byte::strict_dumb(), LEN as u16)
352 } else {
353 writer.register_array(&T::strict_dumb(), LEN as u16)
354 }
355 })
356 }
357}
358impl<T: StrictDecode + Copy + StrictDumb, const LEN: usize> StrictDecode for [T; LEN] {
359 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
360 let mut ar = [T::strict_dumb(); LEN];
361 for c in ar.iter_mut() {
362 *c = T::strict_decode(reader)?;
363 }
364 Ok(ar)
365 }
366}
367
368impl<T: StrictType + StrictDumb + Copy, const LEN: usize, const REVERSE_STR: bool> StrictType
369 for Array<T, LEN, REVERSE_STR>
370{
371 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
372 fn strict_name() -> Option<TypeName> { None }
373}
374impl<T: StrictEncode + StrictDumb + Copy, const LEN: usize, const REVERSE_STR: bool> StrictEncode
375 for Array<T, LEN, REVERSE_STR>
376{
377 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> {
378 self.as_inner().strict_encode(writer)
379 }
380}
381impl<T: StrictDecode + StrictDumb + Copy, const LEN: usize, const REVERSE_STR: bool> StrictDecode
382 for Array<T, LEN, REVERSE_STR>
383{
384 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
385 <[T; LEN]>::strict_decode(reader).map(Self::from_inner)
386 }
387}
388
389impl<const MIN_LEN: usize, const MAX_LEN: usize> StrictType for Confined<String, MIN_LEN, MAX_LEN> {
390 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
391 fn strict_name() -> Option<TypeName> { None }
392}
393impl<const MIN_LEN: usize, const MAX_LEN: usize> StrictEncode
394 for Confined<String, MIN_LEN, MAX_LEN>
395{
396 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> {
397 unsafe {
398 writer
399 .register_unicode(Sizing::new(MIN_LEN as u64, MAX_LEN as u64))
400 .write_string::<MAX_LEN>(self.as_bytes())
401 }
402 }
403}
404impl<const MIN_LEN: usize, const MAX_LEN: usize> StrictDecode
405 for Confined<String, MIN_LEN, MAX_LEN>
406{
407 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
408 let bytes = unsafe { reader.read_string::<MAX_LEN>()? };
409 let s = String::from_utf8(bytes)?;
410 Confined::try_from(s).map_err(DecodeError::from)
411 }
412}
413
414impl<const MIN_LEN: usize, const MAX_LEN: usize> StrictType
415 for Confined<AsciiString, MIN_LEN, MAX_LEN>
416{
417 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
418 fn strict_name() -> Option<TypeName> { None }
419}
420impl<const MIN_LEN: usize, const MAX_LEN: usize> StrictEncode
421 for Confined<AsciiString, MIN_LEN, MAX_LEN>
422{
423 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> {
424 unsafe {
425 writer
426 .register_list(
427 &AsciiSym::strict_dumb(),
428 Sizing::new(MIN_LEN as u64, MAX_LEN as u64),
429 )
430 .write_string::<MAX_LEN>(self.as_bytes())
431 }
432 }
433}
434impl<const MIN_LEN: usize, const MAX_LEN: usize> StrictDecode
435 for Confined<AsciiString, MIN_LEN, MAX_LEN>
436{
437 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
438 let bytes = unsafe { reader.read_string::<MAX_LEN>()? };
439 let s = AsciiString::from_ascii(bytes).map_err(|err| err.ascii_error())?;
440 Confined::try_from(s).map_err(DecodeError::from)
441 }
442}
443
444impl<C1: RestrictedCharSet, C: RestrictedCharSet, const MIN_LEN: usize, const MAX_LEN: usize>
445 StrictType for RString<C1, C, MIN_LEN, MAX_LEN>
446{
447 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
448 fn strict_name() -> Option<TypeName> { None }
449}
450impl<C1: RestrictedCharSet, C: RestrictedCharSet, const MIN_LEN: usize, const MAX_LEN: usize>
451 StrictDumb for RString<C1, C, MIN_LEN, MAX_LEN>
452{
453 fn strict_dumb() -> Self {
454 Self::try_from(format!(
455 "{}{}",
456 C1::strict_dumb(),
457 String::from_utf8(vec![C::strict_dumb().into(); MIN_LEN - 1]).expect("dumb")
458 ))
459 .expect("dumb")
460 }
461}
462impl<C1: RestrictedCharSet, C: RestrictedCharSet, const MIN_LEN: usize, const MAX_LEN: usize>
463 StrictEncode for RString<C1, C, MIN_LEN, MAX_LEN>
464{
465 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> {
466 debug_assert_ne!(
467 MIN_LEN, 0,
468 "Restricted string type can't have minimum length equal to zero"
469 );
470 let sizing = Sizing::new(MIN_LEN as u64, MAX_LEN as u64);
471 unsafe {
472 writer
473 .register_rstring(&C::strict_dumb(), &C1::strict_dumb(), sizing)
474 .write_string::<MAX_LEN>(self.as_bytes())
475 }
476 }
477}
478impl<C1: RestrictedCharSet, C: RestrictedCharSet, const MIN_LEN: usize, const MAX_LEN: usize>
479 StrictDecode for RString<C1, C, MIN_LEN, MAX_LEN>
480{
481 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
482 let bytes = unsafe { reader.read_string::<MAX_LEN>()? };
483 RString::try_from(bytes).map_err(|e| DecodeError::DataIntegrityError(e.to_string()))
484 }
485}
486
487impl<T: StrictType, const MIN_LEN: usize, const MAX_LEN: usize> StrictType
488 for Confined<Vec<T>, MIN_LEN, MAX_LEN>
489{
490 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
491 fn strict_name() -> Option<TypeName> { None }
492}
493impl<T: StrictEncode + StrictDumb, const MIN_LEN: usize, const MAX_LEN: usize> StrictEncode
494 for Confined<Vec<T>, MIN_LEN, MAX_LEN>
495{
496 fn strict_encode<W: TypedWrite>(&self, mut writer: W) -> io::Result<W> {
497 let sizing = Sizing::new(MIN_LEN as u64, MAX_LEN as u64);
498 writer = unsafe {
499 writer = writer.write_collection::<Vec<T>, MIN_LEN, MAX_LEN>(self)?;
500 if T::strict_name() == u8::strict_name() {
501 writer.register_list(&Byte::strict_dumb(), sizing)
502 } else {
503 writer.register_list(&T::strict_dumb(), sizing)
504 }
505 };
506 Ok(writer)
507 }
508}
509impl<T: StrictDecode, const MIN_LEN: usize, const MAX_LEN: usize> StrictDecode
510 for Confined<Vec<T>, MIN_LEN, MAX_LEN>
511{
512 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
513 let len = unsafe { reader.raw_reader().read_raw_len::<MAX_LEN>()? };
514 let mut col = Vec::<T>::with_capacity(len);
515 for _ in 0..len {
516 col.push(StrictDecode::strict_decode(reader)?);
517 }
518 Confined::try_from(col).map_err(DecodeError::from)
519 }
520}
521
522impl<T: StrictType, const MIN_LEN: usize, const MAX_LEN: usize> StrictType
523 for Confined<VecDeque<T>, MIN_LEN, MAX_LEN>
524{
525 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
526 fn strict_name() -> Option<TypeName> { None }
527}
528impl<T: StrictEncode + StrictDumb, const MIN_LEN: usize, const MAX_LEN: usize> StrictEncode
529 for Confined<VecDeque<T>, MIN_LEN, MAX_LEN>
530{
531 fn strict_encode<W: TypedWrite>(&self, mut writer: W) -> io::Result<W> {
532 let sizing = Sizing::new(MIN_LEN as u64, MAX_LEN as u64);
533 writer = unsafe {
534 writer = writer.write_collection::<VecDeque<T>, MIN_LEN, MAX_LEN>(self)?;
535 if T::strict_name() == u8::strict_name() {
536 writer.register_list(&Byte::strict_dumb(), sizing)
537 } else {
538 writer.register_list(&T::strict_dumb(), sizing)
539 }
540 };
541 Ok(writer)
542 }
543}
544impl<T: StrictDecode, const MIN_LEN: usize, const MAX_LEN: usize> StrictDecode
545 for Confined<VecDeque<T>, MIN_LEN, MAX_LEN>
546{
547 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
548 let len = unsafe { reader.raw_reader().read_raw_len::<MAX_LEN>()? };
549 let mut col = VecDeque::<T>::with_capacity(len);
550 for _ in 0..len {
551 col.push_back(StrictDecode::strict_decode(reader)?);
552 }
553 Confined::try_from(col).map_err(DecodeError::from)
554 }
555}
556
557impl<T: StrictType + Ord, const MIN_LEN: usize, const MAX_LEN: usize> StrictType
558 for Confined<BTreeSet<T>, MIN_LEN, MAX_LEN>
559{
560 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
561 fn strict_name() -> Option<TypeName> { None }
562}
563impl<T: StrictEncode + Ord + StrictDumb, const MIN_LEN: usize, const MAX_LEN: usize> StrictEncode
564 for Confined<BTreeSet<T>, MIN_LEN, MAX_LEN>
565{
566 fn strict_encode<W: TypedWrite>(&self, mut writer: W) -> io::Result<W> {
567 unsafe {
568 writer = writer.write_collection::<BTreeSet<T>, MIN_LEN, MAX_LEN>(self)?;
569 }
570 Ok(unsafe {
571 writer.register_set(&T::strict_dumb(), Sizing::new(MIN_LEN as u64, MAX_LEN as u64))
572 })
573 }
574}
575impl<T: StrictDecode + Ord, const MIN_LEN: usize, const MAX_LEN: usize> StrictDecode
576 for Confined<BTreeSet<T>, MIN_LEN, MAX_LEN>
577{
578 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
579 let len = unsafe { reader.raw_reader().read_raw_len::<MAX_LEN>()? };
580 let mut col = BTreeSet::<T>::new();
581 for _ in 0..len {
582 let item = StrictDecode::strict_decode(reader)?;
583 if matches!(col.last(), Some(last) if last > &item) {
584 return Err(DecodeError::BrokenSetOrder);
585 }
586 if !col.insert(item) {
587 return Err(DecodeError::RepeatedSetValue);
588 }
589 }
590 Confined::try_from(col).map_err(DecodeError::from)
591 }
592}
593
594impl<K: StrictType + Ord + Hash, V: StrictType, const MIN_LEN: usize, const MAX_LEN: usize>
595 StrictType for Confined<BTreeMap<K, V>, MIN_LEN, MAX_LEN>
596{
597 const STRICT_LIB_NAME: &'static str = LIB_EMBEDDED;
598 fn strict_name() -> Option<TypeName> { None }
599}
600impl<
601 K: StrictEncode + Ord + Hash + StrictDumb,
602 V: StrictEncode + StrictDumb,
603 const MIN_LEN: usize,
604 const MAX_LEN: usize,
605 > StrictEncode for Confined<BTreeMap<K, V>, MIN_LEN, MAX_LEN>
606{
607 fn strict_encode<W: TypedWrite>(&self, mut writer: W) -> io::Result<W> {
608 unsafe {
609 writer.raw_writer().write_raw_len::<MAX_LEN>(self.len())?;
610 }
611 for (k, v) in self {
612 writer = k.strict_encode(writer)?;
613 writer = v.strict_encode(writer)?
614 }
615 Ok(unsafe {
616 writer.register_map(
617 &K::strict_dumb(),
618 &V::strict_dumb(),
619 Sizing::new(MIN_LEN as u64, MAX_LEN as u64),
620 )
621 })
622 }
623}
624impl<
625 K: StrictDecode + Ord + Hash + StrictDumb,
626 V: StrictDecode + StrictDumb,
627 const MIN_LEN: usize,
628 const MAX_LEN: usize,
629 > StrictDecode for Confined<BTreeMap<K, V>, MIN_LEN, MAX_LEN>
630{
631 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
632 let len = unsafe { reader.raw_reader().read_raw_len::<MAX_LEN>()? };
633 let mut col = BTreeMap::new();
634 for _ in 0..len {
635 let key = StrictDecode::strict_decode(reader)?;
636 let val = StrictDecode::strict_decode(reader)?;
637 if matches!(col.last_key_value(), Some((last, _)) if last > &key) {
638 return Err(DecodeError::BrokenMapOrder);
639 }
640 if col.insert(key, val).is_some() {
641 return Err(DecodeError::RepeatedMapValue);
642 }
643 }
644 Confined::try_from(col).map_err(DecodeError::from)
645 }
646}