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