1use core::borrow::{Borrow, BorrowMut};
19use core::fmt::{self, Display, Formatter, LowerHex, UpperHex};
20use core::str::FromStr;
21use core::hash::Hash;
22use core::ops::{
23    Deref, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
24};
25use alloc::vec::Vec;
26use alloc::string::String;
27use alloc::borrow::ToOwned;
28use alloc::collections::{btree_map, BTreeMap, BTreeSet, VecDeque};
29use alloc::collections::vec_deque::Drain;
30use core::slice::SliceIndex;
31use core::ops::RangeBounds;
32#[cfg(feature = "std")]
33use std::{
34    io,
35    collections::{hash_map, HashMap, HashSet},
36};
37use amplify_num::hex;
38use amplify_num::hex::{FromHex, ToHex};
39use ascii::{AsAsciiStrError, AsciiChar, AsciiString};
40
41use crate::num::u24;
42
43pub trait Collection: FromIterator<Self::Item> + Extend<Self::Item> {
46    type Item;
48
49    fn with_capacity(capacity: usize) -> Self;
51
52    fn len(&self) -> usize;
54
55    #[inline]
57    fn is_empty(&self) -> bool {
58        self.len() == 0
59    }
60
61    fn push(&mut self, elem: Self::Item);
63
64    fn clear(&mut self);
66}
67
68pub trait KeyedCollection: Collection<Item = (Self::Key, Self::Value)> {
71    type Key: Eq + Hash;
73    type Value;
75    type Entry<'a>
76    where
77        Self: 'a;
78
79    fn contains_key(&self, key: &Self::Key) -> bool;
81
82    fn get(&self, key: &Self::Key) -> Option<&Self::Value>;
84
85    fn get_mut(&mut self, key: &Self::Key) -> Option<&mut Self::Value>;
87
88    fn iter(&self) -> impl Iterator<Item = (&Self::Key, &Self::Value)>;
90
91    fn iter_mut(&mut self) -> impl Iterator<Item = (&Self::Key, &mut Self::Value)>;
93
94    fn values_mut(&mut self) -> impl Iterator<Item = &mut Self::Value>;
96
97    fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value>;
100
101    fn remove(&mut self, key: &Self::Key) -> Option<Self::Value>;
104
105    fn entry(&mut self, key: Self::Key) -> Self::Entry<'_>;
108
109    fn retain(&mut self, f: impl FnMut(&Self::Key, &mut Self::Value) -> bool);
115}
116
117impl Collection for String {
120    type Item = char;
121
122    fn with_capacity(capacity: usize) -> Self {
123        Self::with_capacity(capacity)
124    }
125
126    fn len(&self) -> usize {
127        self.len()
128    }
129
130    fn push(&mut self, elem: Self::Item) {
131        self.push(elem)
132    }
133
134    fn clear(&mut self) {
135        self.clear()
136    }
137}
138
139impl Collection for AsciiString {
140    type Item = AsciiChar;
141
142    fn with_capacity(capacity: usize) -> Self {
143        Self::with_capacity(capacity)
144    }
145
146    fn len(&self) -> usize {
147        self.len()
148    }
149
150    fn push(&mut self, elem: Self::Item) {
151        self.push(elem)
152    }
153
154    fn clear(&mut self) {
155        self.clear()
156    }
157}
158
159impl<T> Collection for Vec<T> {
160    type Item = T;
161
162    fn with_capacity(capacity: usize) -> Self {
163        Self::with_capacity(capacity)
164    }
165
166    fn len(&self) -> usize {
167        self.len()
168    }
169
170    fn push(&mut self, elem: Self::Item) {
171        self.push(elem)
172    }
173
174    fn clear(&mut self) {
175        self.clear()
176    }
177}
178
179impl<T> Collection for VecDeque<T> {
180    type Item = T;
181
182    fn with_capacity(capacity: usize) -> Self {
183        Self::with_capacity(capacity)
184    }
185
186    fn len(&self) -> usize {
187        self.len()
188    }
189
190    fn push(&mut self, elem: Self::Item) {
191        self.push_back(elem)
192    }
193
194    fn clear(&mut self) {
195        self.clear()
196    }
197}
198
199#[cfg(feature = "std")]
200impl<T: Eq + Hash> Collection for HashSet<T> {
201    type Item = T;
202
203    fn with_capacity(capacity: usize) -> Self {
204        Self::with_capacity(capacity)
205    }
206
207    fn len(&self) -> usize {
208        self.len()
209    }
210
211    fn push(&mut self, elem: Self::Item) {
212        self.insert(elem);
213    }
214
215    fn clear(&mut self) {
216        self.clear()
217    }
218}
219
220impl<T: Ord> Collection for BTreeSet<T> {
221    type Item = T;
222
223    #[doc(hidden)]
224    fn with_capacity(_capacity: usize) -> Self {
225        BTreeSet::new()
226    }
227
228    fn len(&self) -> usize {
229        self.len()
230    }
231
232    fn push(&mut self, elem: Self::Item) {
233        self.insert(elem);
234    }
235
236    fn clear(&mut self) {
237        self.clear()
238    }
239}
240
241#[cfg(feature = "std")]
242impl<K: Eq + Hash, V> Collection for HashMap<K, V> {
243    type Item = (K, V);
244
245    fn with_capacity(capacity: usize) -> Self {
246        Self::with_capacity(capacity)
247    }
248
249    fn len(&self) -> usize {
250        self.len()
251    }
252
253    fn push(&mut self, elem: Self::Item) {
254        HashMap::insert(self, elem.0, elem.1);
255    }
256
257    fn clear(&mut self) {
258        self.clear()
259    }
260}
261
262#[cfg(feature = "std")]
263impl<K: Eq + Hash, V> KeyedCollection for HashMap<K, V> {
264    type Key = K;
265    type Value = V;
266    type Entry<'a>
267        = hash_map::Entry<'a, K, V>
268    where
269        K: 'a,
270        V: 'a;
271
272    fn contains_key(&self, key: &Self::Key) -> bool {
273        HashMap::contains_key(self, key)
274    }
275
276    fn get(&self, key: &Self::Key) -> Option<&Self::Value> {
277        HashMap::get(self, key)
278    }
279
280    fn get_mut(&mut self, key: &Self::Key) -> Option<&mut Self::Value> {
281        HashMap::get_mut(self, key)
282    }
283
284    fn iter(&self) -> impl Iterator<Item = (&Self::Key, &Self::Value)> {
285        HashMap::iter(self)
286    }
287
288    fn iter_mut(&mut self) -> impl Iterator<Item = (&Self::Key, &mut Self::Value)> {
289        HashMap::iter_mut(self)
290    }
291
292    fn values_mut(&mut self) -> impl Iterator<Item = &mut Self::Value> {
293        HashMap::values_mut(self)
294    }
295
296    fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value> {
297        HashMap::insert(self, key, value)
298    }
299
300    fn remove(&mut self, key: &Self::Key) -> Option<Self::Value> {
301        HashMap::remove(self, key)
302    }
303
304    fn entry(&mut self, key: Self::Key) -> Self::Entry<'_> {
305        HashMap::entry(self, key)
306    }
307
308    fn retain(&mut self, f: impl FnMut(&K, &mut V) -> bool) {
309        HashMap::retain(self, f)
310    }
311}
312
313impl<K: Ord + Hash, V> Collection for BTreeMap<K, V> {
314    type Item = (K, V);
315
316    #[doc(hidden)]
317    fn with_capacity(_capacity: usize) -> Self {
318        BTreeMap::new()
319    }
320
321    fn len(&self) -> usize {
322        self.len()
323    }
324
325    fn push(&mut self, elem: Self::Item) {
326        BTreeMap::insert(self, elem.0, elem.1);
327    }
328
329    fn clear(&mut self) {
330        self.clear()
331    }
332}
333
334impl<K: Ord + Hash, V> KeyedCollection for BTreeMap<K, V> {
335    type Key = K;
336    type Value = V;
337    type Entry<'a>
338        = btree_map::Entry<'a, K, V>
339    where
340        K: 'a,
341        V: 'a;
342
343    fn contains_key(&self, key: &Self::Key) -> bool {
344        BTreeMap::contains_key(self, key)
345    }
346
347    fn get(&self, key: &Self::Key) -> Option<&Self::Value> {
348        BTreeMap::get(self, key)
349    }
350
351    fn get_mut(&mut self, key: &Self::Key) -> Option<&mut Self::Value> {
352        BTreeMap::get_mut(self, key)
353    }
354
355    fn iter(&self) -> impl Iterator<Item = (&Self::Key, &Self::Value)> {
356        BTreeMap::iter(self)
357    }
358
359    fn iter_mut(&mut self) -> impl Iterator<Item = (&Self::Key, &mut Self::Value)> {
360        BTreeMap::iter_mut(self)
361    }
362
363    fn values_mut(&mut self) -> impl Iterator<Item = &mut Self::Value> {
364        BTreeMap::values_mut(self)
365    }
366
367    fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value> {
368        BTreeMap::insert(self, key, value)
369    }
370
371    fn remove(&mut self, key: &Self::Key) -> Option<Self::Value> {
372        BTreeMap::remove(self, key)
373    }
374
375    fn entry(&mut self, key: Self::Key) -> Self::Entry<'_> {
376        BTreeMap::entry(self, key)
377    }
378
379    fn retain(&mut self, f: impl FnMut(&K, &mut V) -> bool) {
380        BTreeMap::retain(self, f)
381    }
382}
383
384#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
388pub enum Error {
389    Undersize {
392        len: usize,
394        min_len: usize,
397    },
398
399    Oversize {
402        len: usize,
404        max_len: usize,
407    },
408
409    OutOfBoundary {
411        index: usize,
413        len: usize,
415    },
416}
417
418impl Display for Error {
419    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
420        match self {
421            Error::Undersize { len, min_len } => write!(
422                f,
423                "operation results in collection size {len} less than lower boundary \
424                 of {min_len}, which is prohibited"
425            ),
426            Error::Oversize { len, max_len } => write!(
427                f,
428                "operation results in collection size {len} exceeding {max_len}, \
429                which is prohibited"
430            ),
431            Error::OutOfBoundary { index, len } => write!(
432                f,
433                "attempt to access the element at {index} which is outside of the \
434                collection length boundary {len}"
435            ),
436        }
437    }
438}
439
440#[cfg(feature = "std")]
441impl std::error::Error for Error {}
442
443#[derive(Clone, Copy, PartialEq, Eq, Debug)]
445pub enum AsciiError {
446    Ascii(AsAsciiStrError),
448
449    Confinement(Error),
451}
452
453impl From<AsAsciiStrError> for AsciiError {
454    fn from(err: AsAsciiStrError) -> Self {
455        AsciiError::Ascii(err)
456    }
457}
458
459impl From<Error> for AsciiError {
460    fn from(err: Error) -> Self {
461        AsciiError::Confinement(err)
462    }
463}
464
465impl Display for AsciiError {
466    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
467        match self {
468            AsciiError::Ascii(e) => Display::fmt(e, f),
469            AsciiError::Confinement(e) => Display::fmt(e, f),
470        }
471    }
472}
473
474#[cfg(feature = "std")]
475impl std::error::Error for AsciiError {}
476
477pub const ZERO: usize = 0;
481pub const ONE: usize = 1;
483pub const U8: usize = u8::MAX as usize;
485pub const U16: usize = u16::MAX as usize;
487pub const U24: usize = 0xFFFFFFusize;
489pub const U32: usize = u32::MAX as usize;
491pub const U64: usize = u64::MAX as usize;
493
494#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
498#[cfg_attr(
499    feature = "serde",
500    derive(Serialize, Deserialize),
501    serde(crate = "serde_crate")
502)]
503pub struct Confined<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize>(C);
504
505impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> Deref
506    for Confined<C, MIN_LEN, MAX_LEN>
507{
508    type Target = C;
509
510    fn deref(&self) -> &Self::Target {
511        &self.0
512    }
513}
514
515impl<C, const MIN_LEN: usize, const MAX_LEN: usize> AsRef<[C::Item]>
516    for Confined<C, MIN_LEN, MAX_LEN>
517where
518    C: Collection + AsRef<[C::Item]>,
519{
520    fn as_ref(&self) -> &[C::Item] {
521        self.0.as_ref()
522    }
523}
524
525impl<C, const MIN_LEN: usize, const MAX_LEN: usize> AsMut<[C::Item]>
526    for Confined<C, MIN_LEN, MAX_LEN>
527where
528    C: Collection + AsMut<[C::Item]>,
529{
530    fn as_mut(&mut self) -> &mut [C::Item] {
531        self.0.as_mut()
532    }
533}
534
535impl<C, const MIN_LEN: usize, const MAX_LEN: usize> Borrow<[C::Item]>
536    for Confined<C, MIN_LEN, MAX_LEN>
537where
538    C: Collection + Borrow<[C::Item]>,
539{
540    fn borrow(&self) -> &[C::Item] {
541        self.0.borrow()
542    }
543}
544
545impl<C, const MIN_LEN: usize, const MAX_LEN: usize> BorrowMut<[C::Item]>
546    for Confined<C, MIN_LEN, MAX_LEN>
547where
548    C: Collection + BorrowMut<[C::Item]>,
549{
550    fn borrow_mut(&mut self) -> &mut [C::Item] {
551        self.0.borrow_mut()
552    }
553}
554
555impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> IntoIterator
556    for Confined<C, MIN_LEN, MAX_LEN>
557where
558    C: IntoIterator,
559{
560    type Item = <C as IntoIterator>::Item;
561    type IntoIter = <C as IntoIterator>::IntoIter;
562
563    fn into_iter(self) -> Self::IntoIter {
564        self.0.into_iter()
565    }
566}
567
568impl<'c, C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> IntoIterator
569    for &'c Confined<C, MIN_LEN, MAX_LEN>
570where
571    &'c C: IntoIterator,
572{
573    type Item = <&'c C as IntoIterator>::Item;
574    type IntoIter = <&'c C as IntoIterator>::IntoIter;
575
576    fn into_iter(self) -> Self::IntoIter {
577        self.0.into_iter()
578    }
579}
580
581impl<'c, C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> IntoIterator
582    for &'c mut Confined<C, MIN_LEN, MAX_LEN>
583where
584    &'c mut C: IntoIterator,
585{
586    type Item = <&'c mut C as IntoIterator>::Item;
587    type IntoIter = <&'c mut C as IntoIterator>::IntoIter;
588
589    fn into_iter(self) -> Self::IntoIter {
590        self.0.into_iter()
591    }
592}
593
594impl<'c, C, const MIN_LEN: usize, const MAX_LEN: usize> Confined<C, MIN_LEN, MAX_LEN>
595where
596    C: Collection + 'c,
597    &'c mut C: IntoIterator<Item = &'c mut <C as Collection>::Item>,
598{
599    pub fn iter_mut(&'c mut self) -> <&'c mut C as IntoIterator>::IntoIter {
603        let coll = &mut self.0;
604        coll.into_iter()
605    }
606}
607
608impl<C, const MIN_LEN: usize, const MAX_LEN: usize> Confined<C, MIN_LEN, MAX_LEN>
609where
610    C: KeyedCollection,
611{
612    pub fn values_mut(&mut self) -> impl Iterator<Item = &mut C::Value> {
614        let coll = &mut self.0;
615        coll.values_mut()
616    }
617
618    pub fn keyed_values_mut(&mut self) -> impl Iterator<Item = (&C::Key, &mut C::Value)> {
620        let coll = &mut self.0;
621        coll.iter_mut()
622    }
623}
624
625impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> Index<usize>
626    for Confined<C, MIN_LEN, MAX_LEN>
627where
628    C: Index<usize, Output = C::Item>,
629{
630    type Output = C::Item;
631
632    fn index(&self, index: usize) -> &Self::Output {
633        self.0.index(index)
634    }
635}
636
637impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> IndexMut<usize>
638    for Confined<C, MIN_LEN, MAX_LEN>
639where
640    C: IndexMut<usize, Output = C::Item>,
641{
642    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
643        self.0.index_mut(index)
644    }
645}
646
647impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> Index<Range<usize>>
648    for Confined<C, MIN_LEN, MAX_LEN>
649where
650    C: Index<Range<usize>, Output = [C::Item]>,
651{
652    type Output = [C::Item];
653
654    fn index(&self, index: Range<usize>) -> &Self::Output {
655        self.0.index(index)
656    }
657}
658
659impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> IndexMut<Range<usize>>
660    for Confined<C, MIN_LEN, MAX_LEN>
661where
662    C: IndexMut<Range<usize>, Output = [C::Item]>,
663{
664    fn index_mut(&mut self, index: Range<usize>) -> &mut Self::Output {
665        self.0.index_mut(index)
666    }
667}
668
669impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> Index<RangeTo<usize>>
670    for Confined<C, MIN_LEN, MAX_LEN>
671where
672    C: Index<RangeTo<usize>, Output = [C::Item]>,
673{
674    type Output = [C::Item];
675
676    fn index(&self, index: RangeTo<usize>) -> &Self::Output {
677        self.0.index(index)
678    }
679}
680
681impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> IndexMut<RangeTo<usize>>
682    for Confined<C, MIN_LEN, MAX_LEN>
683where
684    C: IndexMut<RangeTo<usize>, Output = [C::Item]>,
685{
686    fn index_mut(&mut self, index: RangeTo<usize>) -> &mut Self::Output {
687        self.0.index_mut(index)
688    }
689}
690
691impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> Index<RangeFrom<usize>>
692    for Confined<C, MIN_LEN, MAX_LEN>
693where
694    C: Index<RangeFrom<usize>, Output = [C::Item]>,
695{
696    type Output = [C::Item];
697
698    fn index(&self, index: RangeFrom<usize>) -> &Self::Output {
699        self.0.index(index)
700    }
701}
702
703impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> IndexMut<RangeFrom<usize>>
704    for Confined<C, MIN_LEN, MAX_LEN>
705where
706    C: IndexMut<RangeFrom<usize>, Output = [C::Item]>,
707{
708    fn index_mut(&mut self, index: RangeFrom<usize>) -> &mut Self::Output {
709        self.0.index_mut(index)
710    }
711}
712
713impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> Index<RangeInclusive<usize>>
714    for Confined<C, MIN_LEN, MAX_LEN>
715where
716    C: Index<RangeInclusive<usize>, Output = [C::Item]>,
717{
718    type Output = [C::Item];
719
720    fn index(&self, index: RangeInclusive<usize>) -> &Self::Output {
721        self.0.index(index)
722    }
723}
724
725impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> IndexMut<RangeInclusive<usize>>
726    for Confined<C, MIN_LEN, MAX_LEN>
727where
728    C: IndexMut<RangeInclusive<usize>, Output = [C::Item]>,
729{
730    fn index_mut(&mut self, index: RangeInclusive<usize>) -> &mut Self::Output {
731        self.0.index_mut(index)
732    }
733}
734
735impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> Index<RangeToInclusive<usize>>
736    for Confined<C, MIN_LEN, MAX_LEN>
737where
738    C: Index<RangeToInclusive<usize>, Output = [C::Item]>,
739{
740    type Output = [C::Item];
741
742    fn index(&self, index: RangeToInclusive<usize>) -> &Self::Output {
743        self.0.index(index)
744    }
745}
746
747impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> IndexMut<RangeToInclusive<usize>>
748    for Confined<C, MIN_LEN, MAX_LEN>
749where
750    C: IndexMut<RangeToInclusive<usize>, Output = [C::Item]>,
751{
752    fn index_mut(&mut self, index: RangeToInclusive<usize>) -> &mut Self::Output {
753        self.0.index_mut(index)
754    }
755}
756
757impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> Index<RangeFull>
758    for Confined<C, MIN_LEN, MAX_LEN>
759where
760    C: Index<RangeFull, Output = [C::Item]>,
761{
762    type Output = [C::Item];
763
764    fn index(&self, index: RangeFull) -> &Self::Output {
765        self.0.index(index)
766    }
767}
768
769impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> IndexMut<RangeFull>
770    for Confined<C, MIN_LEN, MAX_LEN>
771where
772    C: IndexMut<RangeFull, Output = [C::Item]>,
773{
774    fn index_mut(&mut self, index: RangeFull) -> &mut Self::Output {
775        self.0.index_mut(index)
776    }
777}
778
779impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> Display
780    for Confined<C, MIN_LEN, MAX_LEN>
781where
782    C: Display,
783{
784    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
785        self.0.fmt(f)
786    }
787}
788
789impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> FromStr
790    for Confined<C, MIN_LEN, MAX_LEN>
791where
792    C: FromStr,
793{
794    type Err = C::Err;
795
796    fn from_str(s: &str) -> Result<Self, Self::Err> {
797        C::from_str(s).map(Self)
798    }
799}
800
801impl<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize> Confined<C, MIN_LEN, MAX_LEN> {
802    fn does_fit_confinement(col: &C) -> Result<(), Error> {
803        let len = col.len();
804        if len < MIN_LEN {
805            return Err(Error::Undersize {
806                len,
807                min_len: MIN_LEN,
808            });
809        }
810        if len > MAX_LEN {
811            return Err(Error::Oversize {
812                len,
813                max_len: MAX_LEN,
814            });
815        }
816        Ok(())
817    }
818
819    pub fn from_checked(col: C) -> Self {
825        Self::try_from(col).expect("collection size mismatch, use try_from instead")
826    }
827
828    #[deprecated(since = "4.7.0", note = "use `from_checked`")]
829    pub fn from_collection_unsafe(col: C) -> Self {
830        Self::from_checked(col)
831    }
832
833    pub fn try_from(col: C) -> Result<Self, Error> {
838        Self::does_fit_confinement(&col)?;
839        Ok(Self(col))
840    }
841
842    pub fn try_from_iter<I: IntoIterator<Item = C::Item>>(iter: I) -> Result<Self, Error> {
846        let mut col = C::with_capacity(MIN_LEN);
847        for item in iter {
848            col.push(item);
849        }
850        Self::try_from(col)
851    }
852
853    pub fn from_iter_checked<I: IntoIterator<Item = C::Item>>(iter: I) -> Self {
861        Self::from_checked(iter.into_iter().collect())
862    }
863
864    #[deprecated(since = "4.7.0", note = "use `from_iter_checked`")]
865    pub fn from_iter_unsafe<I: IntoIterator<Item = C::Item>>(iter: I) -> Self {
866        Self::from_iter_checked(iter)
867    }
868
869    #[deprecated(since = "4.7.0", note = "use as_unconfined method")]
871    pub fn as_inner(&self) -> &C {
872        &self.0
873    }
874
875    pub fn as_unconfined(&self) -> &C {
877        &self.0
878    }
879
880    #[deprecated(since = "4.7.0", note = "use to_unconfined method")]
882    pub fn to_inner(&self) -> C
883    where
884        C: Clone,
885    {
886        self.0.clone()
887    }
888
889    pub fn to_unconfined(&self) -> C
891    where
892        C: Clone,
893    {
894        self.0.clone()
895    }
896
897    #[deprecated(since = "4.7.0", note = "use release method")]
899    pub fn into_inner(self) -> C {
900        self.0
901    }
902
903    pub fn push(&mut self, elem: C::Item) -> Result<(), Error> {
906        let len = self.len();
907        if len == MAX_LEN || len + 1 > MAX_LEN {
908            return Err(Error::Oversize {
909                len: len + 1,
910                max_len: MAX_LEN,
911            });
912        }
913        self.0.push(elem);
914        Ok(())
915    }
916
917    pub fn extend<T: IntoIterator<Item = C::Item>>(&mut self, iter: T) -> Result<(), Error> {
921        for elem in iter {
922            self.push(elem)?;
923        }
924        Ok(())
925    }
926
927    #[deprecated(since = "4.7.0", note = "use release method")]
929    pub fn unbox(self) -> C {
930        self.0
931    }
932
933    pub fn release(self) -> C {
935        self.0
936    }
937
938    pub fn with_mut(mut self, f: impl FnOnce(&mut Self)) -> Result<Self, Error> {
941        f(&mut self);
942        Self::does_fit_confinement(&self)?;
943        Ok(self)
944    }
945
946    pub fn as_mut_checked(&mut self, f: impl FnOnce(&mut Self)) {
949        f(self);
950        Self::does_fit_confinement(self).expect("confinement broken");
951    }
952}
953
954impl<C: Collection, const MAX_LEN: usize> Confined<C, ZERO, MAX_LEN>
955where
956    C: Default,
957{
958    pub fn new() -> Self {
960        Self::default()
961    }
962
963    pub fn with_capacity(capacity: usize) -> Self {
966        Self(C::with_capacity(capacity))
967    }
968
969    pub fn clear(&mut self) {
971        self.0.clear()
972    }
973}
974
975impl<C: Collection, const MAX_LEN: usize> Default for Confined<C, ZERO, MAX_LEN>
976where
977    C: Default,
978{
979    fn default() -> Self {
980        Self(C::default())
981    }
982}
983
984impl<C: Collection, const MAX_LEN: usize> Confined<C, ONE, MAX_LEN>
985where
986    C: Default,
987{
988    pub fn with(elem: C::Item) -> Self {
991        let mut c = C::default();
992        c.push(elem);
993        Self(c)
994    }
995}
996
997impl<C: Collection, const MIN_LEN: usize> Confined<C, MIN_LEN, U8>
998where
999    C: Default,
1000{
1001    pub fn len_u8(&self) -> u8 {
1005        self.len() as u8
1006    }
1007}
1008
1009impl<C: Collection, const MIN_LEN: usize> Confined<C, MIN_LEN, U16>
1010where
1011    C: Default,
1012{
1013    pub fn len_u16(&self) -> u16 {
1017        self.len() as u16
1018    }
1019}
1020
1021impl<C: Collection, const MIN_LEN: usize> Confined<C, MIN_LEN, U24>
1022where
1023    C: Default,
1024{
1025    pub fn len_u24(&self) -> u24 {
1029        u24::try_from(self.len() as u32).expect("confinement broken")
1030    }
1031}
1032
1033impl<C: Collection, const MIN_LEN: usize> Confined<C, MIN_LEN, U32>
1034where
1035    C: Default,
1036{
1037    pub fn len_u32(&self) -> u32 {
1041        self.len() as u32
1042    }
1043}
1044
1045impl<C: KeyedCollection, const MIN_LEN: usize, const MAX_LEN: usize> Confined<C, MIN_LEN, MAX_LEN> {
1046    pub fn get_mut(&mut self, key: &C::Key) -> Option<&mut C::Value> {
1048        self.0.get_mut(key)
1049    }
1050
1051    pub fn insert(&mut self, key: C::Key, value: C::Value) -> Result<Option<C::Value>, Error> {
1055        let len = self.len();
1056        if len == MAX_LEN || len + 1 > MAX_LEN {
1057            return Err(Error::Oversize {
1058                len: len + 1,
1059                max_len: MAX_LEN,
1060            });
1061        }
1062        Ok(self.0.insert(key, value))
1063    }
1064
1065    pub fn entry(&mut self, key: C::Key) -> Result<C::Entry<'_>, Error> {
1069        let len = self.len();
1070        if len == MAX_LEN && !self.0.contains_key(&key) {
1071            return Err(Error::Oversize {
1072                len: len + 1,
1073                max_len: MAX_LEN,
1074            });
1075        }
1076        Ok(self.0.entry(key))
1077    }
1078
1079    pub fn try_retain(
1089        &mut self,
1090        f: impl FnMut(&C::Key, &mut C::Value) -> bool,
1091    ) -> Result<(), Error> {
1092        self.0.retain(f);
1093        if self.0.len() < MIN_LEN {
1094            return Err(Error::Undersize {
1095                len: self.0.len(),
1096                min_len: MIN_LEN,
1097            });
1098        }
1099        Ok(())
1100    }
1101}
1102
1103impl<C: KeyedCollection, const MAX_LEN: usize> Confined<C, ZERO, MAX_LEN> {
1104    pub fn retain(&mut self, f: impl FnMut(&C::Key, &mut C::Value) -> bool) {
1110        self.0.retain(f)
1111    }
1112}
1113
1114impl<C: KeyedCollection, const MAX_LEN: usize> Confined<C, ONE, MAX_LEN>
1115where
1116    C: Default,
1117{
1118    pub fn with_key_value(key: C::Key, value: C::Value) -> Self {
1121        let mut c = C::default();
1122        c.insert(key, value);
1123        Self(c)
1124    }
1125}
1126
1127impl<const MIN_LEN: usize, const MAX_LEN: usize> TryFrom<&str>
1128    for Confined<String, MIN_LEN, MAX_LEN>
1129{
1130    type Error = Error;
1131
1132    fn try_from(value: &str) -> Result<Self, Self::Error> {
1133        Self::try_from(value.to_owned())
1134    }
1135}
1136
1137impl<const MIN_LEN: usize, const MAX_LEN: usize> TryFrom<&str>
1138    for Confined<AsciiString, MIN_LEN, MAX_LEN>
1139{
1140    type Error = AsciiError;
1141
1142    fn try_from(value: &str) -> Result<Self, Self::Error> {
1143        let a = AsciiString::from_str(value)?;
1144        Self::try_from(a).map_err(AsciiError::from)
1145    }
1146}
1147
1148impl<const MAX_LEN: usize> Confined<String, ZERO, MAX_LEN> {
1149    pub fn pop(&mut self) -> Option<char> {
1152        self.0.pop()
1153    }
1154}
1155
1156impl<const MIN_LEN: usize, const MAX_LEN: usize> Confined<String, MIN_LEN, MAX_LEN> {
1157    pub fn remove(&mut self, index: usize) -> Result<char, Error> {
1161        let len = self.len();
1162        if self.is_empty() || len <= MIN_LEN {
1163            return Err(Error::Undersize {
1164                len,
1165                min_len: MIN_LEN,
1166            });
1167        }
1168        if index >= len {
1169            return Err(Error::OutOfBoundary { index, len });
1170        }
1171        Ok(self.0.remove(index))
1172    }
1173}
1174
1175impl<const MAX_LEN: usize> Confined<AsciiString, ZERO, MAX_LEN> {
1176    pub fn pop(&mut self) -> Option<AsciiChar> {
1179        self.0.pop()
1180    }
1181}
1182
1183impl<const MIN_LEN: usize, const MAX_LEN: usize> Confined<AsciiString, MIN_LEN, MAX_LEN> {
1184    pub fn remove(&mut self, index: usize) -> Result<AsciiChar, Error> {
1188        let len = self.len();
1189        if self.is_empty() || len <= MIN_LEN {
1190            return Err(Error::Undersize {
1191                len,
1192                min_len: MIN_LEN,
1193            });
1194        }
1195        if index >= len {
1196            return Err(Error::OutOfBoundary { index, len });
1197        }
1198        Ok(self.0.remove(index))
1199    }
1200}
1201
1202impl<T, const MIN_LEN: usize, const MAX_LEN: usize> Confined<Vec<T>, MIN_LEN, MAX_LEN> {
1203    #[inline]
1210    pub fn from_slice_checked(slice: &[T]) -> Self
1211    where
1212        T: Clone,
1213    {
1214        assert!(slice.len() > MIN_LEN && slice.len() <= MAX_LEN);
1215        Self(slice.to_vec())
1216    }
1217
1218    #[deprecated(since = "4.7.0", note = "use `from_slice_checked`")]
1219    #[inline]
1220    pub fn from_slice_unsafe(slice: &[T]) -> Self
1221    where
1222        T: Clone,
1223    {
1224        Self::from_slice_checked(slice)
1225    }
1226
1227    #[inline]
1229    pub fn try_from_slice(slice: &[T]) -> Result<Self, Error>
1230    where
1231        T: Clone,
1232    {
1233        Self::try_from(slice.to_vec())
1234    }
1235
1236    #[inline]
1238    pub fn as_slice(&self) -> &[T] {
1239        &self.0
1240    }
1241
1242    #[inline]
1244    pub fn into_vec(self) -> Vec<T> {
1245        self.0
1246    }
1247
1248    #[inline]
1250    pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
1251    where
1252        I: SliceIndex<[T]>,
1253    {
1254        self.0.get_mut(index)
1255    }
1256}
1257
1258impl<T, const MAX_LEN: usize> Confined<Vec<T>, ZERO, MAX_LEN> {
1259    #[inline]
1262    pub fn pop(&mut self) -> Option<T> {
1263        self.0.pop()
1264    }
1265}
1266
1267impl<T, const MIN_LEN: usize, const MAX_LEN: usize> Confined<Vec<T>, MIN_LEN, MAX_LEN> {
1268    pub fn remove(&mut self, index: usize) -> Result<T, Error> {
1273        let len = self.len();
1274        if self.is_empty() || len <= MIN_LEN {
1275            return Err(Error::Undersize {
1276                len,
1277                min_len: MIN_LEN,
1278            });
1279        }
1280        if index >= len {
1281            return Err(Error::OutOfBoundary { index, len });
1282        }
1283        Ok(self.0.remove(index))
1284    }
1285
1286    pub fn iter(&self) -> core::slice::Iter<T> {
1290        self.0.iter()
1291    }
1292}
1293
1294impl<T, const MIN_LEN: usize, const MAX_LEN: usize> Confined<VecDeque<T>, MIN_LEN, MAX_LEN> {
1295    pub fn pop_front(&mut self) -> Option<T> {
1298        self.0.pop_front()
1299    }
1300
1301    pub fn pop_back(&mut self) -> Option<T> {
1304        self.0.pop_back()
1305    }
1306}
1307
1308impl<T, const MIN_LEN: usize, const MAX_LEN: usize> Confined<VecDeque<T>, MIN_LEN, MAX_LEN> {
1309    pub fn push_front(&mut self, elem: T) -> Result<(), Error> {
1312        let len = self.len();
1313        if len == MAX_LEN || len + 1 > MAX_LEN {
1314            return Err(Error::Oversize {
1315                len: len + 1,
1316                max_len: MAX_LEN,
1317            });
1318        }
1319        self.0.push_front(elem);
1320        Ok(())
1321    }
1322
1323    #[deprecated(since = "4.7.1", note = "use `push_front`")]
1324    pub fn push_from(&mut self, elem: T) -> Result<(), Error> {
1325        self.push_front(elem)
1326    }
1327
1328    pub fn push_back(&mut self, elem: T) -> Result<(), Error> {
1331        let len = self.len();
1332        if len == MAX_LEN || len + 1 > MAX_LEN {
1333            return Err(Error::Oversize {
1334                len: len + 1,
1335                max_len: MAX_LEN,
1336            });
1337        }
1338        self.0.push_back(elem);
1339        Ok(())
1340    }
1341
1342    pub fn remove(&mut self, index: usize) -> Result<T, Error> {
1347        let len = self.len();
1348        if self.is_empty() || len <= MIN_LEN {
1349            return Err(Error::Undersize {
1350                len,
1351                min_len: MIN_LEN,
1352            });
1353        }
1354        if index >= len {
1355            return Err(Error::OutOfBoundary { index, len });
1356        }
1357        Ok(self.0.remove(index).expect("element within the length"))
1358    }
1359
1360    pub fn drain<R: RangeBounds<usize>>(&mut self, range: R) -> Drain<'_, T> {
1378        self.0.drain(range)
1379    }
1380
1381    pub fn truncate(&mut self, len: usize) {
1387        self.0.truncate(len)
1388    }
1389}
1390
1391#[cfg(feature = "std")]
1392impl<T: Hash + Eq, const MIN_LEN: usize, const MAX_LEN: usize>
1393    Confined<HashSet<T>, MIN_LEN, MAX_LEN>
1394{
1395    pub fn remove(&mut self, elem: &T) -> Result<bool, Error> {
1400        if !self.0.contains(elem) {
1401            return Ok(false);
1402        }
1403        let len = self.len();
1404        if self.is_empty() || len <= MIN_LEN {
1405            return Err(Error::Undersize {
1406                len,
1407                min_len: MIN_LEN,
1408            });
1409        }
1410        Ok(self.0.remove(elem))
1411    }
1412
1413    pub fn take(&mut self, elem: &T) -> Result<Option<T>, Error> {
1418        if !self.0.contains(elem) {
1419            return Ok(None);
1420        }
1421        let len = self.len();
1422        if self.is_empty() || len <= MIN_LEN {
1423            return Err(Error::Undersize {
1424                len,
1425                min_len: MIN_LEN,
1426            });
1427        }
1428        Ok(self.0.take(elem))
1429    }
1430}
1431
1432impl<T: Ord, const MIN_LEN: usize, const MAX_LEN: usize> Confined<BTreeSet<T>, MIN_LEN, MAX_LEN> {
1433    pub fn remove(&mut self, elem: &T) -> Result<bool, Error> {
1438        if !self.0.contains(elem) {
1439            return Ok(false);
1440        }
1441        let len = self.len();
1442        if self.is_empty() || len <= MIN_LEN {
1443            return Err(Error::Undersize {
1444                len,
1445                min_len: MIN_LEN,
1446            });
1447        }
1448        Ok(self.0.remove(elem))
1449    }
1450
1451    pub fn take(&mut self, elem: &T) -> Result<Option<T>, Error> {
1456        if !self.0.contains(elem) {
1457            return Ok(None);
1458        }
1459        let len = self.len();
1460        if self.is_empty() || len - 1 <= MIN_LEN {
1461            return Err(Error::Undersize {
1462                len,
1463                min_len: MIN_LEN,
1464            });
1465        }
1466        Ok(self.0.take(elem))
1467    }
1468}
1469
1470#[cfg(feature = "std")]
1471impl<K: Hash + Eq, V, const MIN_LEN: usize, const MAX_LEN: usize>
1472    Confined<HashMap<K, V>, MIN_LEN, MAX_LEN>
1473{
1474    pub fn remove(&mut self, key: &K) -> Result<Option<V>, Error> {
1479        if !self.0.contains_key(key) {
1480            return Ok(None);
1481        }
1482        let len = self.len();
1483        if self.is_empty() || len <= MIN_LEN {
1484            return Err(Error::Undersize {
1485                len,
1486                min_len: MIN_LEN,
1487            });
1488        }
1489        Ok(self.0.remove(key))
1490    }
1491
1492    pub fn into_keys(self) -> hash_map::IntoKeys<K, V> {
1496        self.0.into_keys()
1497    }
1498
1499    pub fn into_values(self) -> hash_map::IntoValues<K, V> {
1503        self.0.into_values()
1504    }
1505}
1506
1507impl<K: Ord + Hash, V, const MIN_LEN: usize, const MAX_LEN: usize>
1508    Confined<BTreeMap<K, V>, MIN_LEN, MAX_LEN>
1509{
1510    pub fn remove(&mut self, key: &K) -> Result<Option<V>, Error> {
1515        if !self.0.contains_key(key) {
1516            return Ok(None);
1517        }
1518        let len = self.len();
1519        if self.is_empty() || len <= MIN_LEN {
1520            return Err(Error::Undersize {
1521                len,
1522                min_len: MIN_LEN,
1523            });
1524        }
1525        Ok(self.0.remove(key))
1526    }
1527
1528    pub fn into_keys(self) -> btree_map::IntoKeys<K, V> {
1532        self.0.into_keys()
1533    }
1534
1535    pub fn into_values(self) -> btree_map::IntoValues<K, V> {
1539        self.0.into_values()
1540    }
1541}
1542
1543#[cfg(feature = "std")]
1545impl<const MAX_LEN: usize> io::Write for Confined<Vec<u8>, ZERO, MAX_LEN> {
1546    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1547        if buf.len() + self.len() >= MAX_LEN {
1548            return Err(io::Error::from(io::ErrorKind::OutOfMemory));
1549        }
1550        self.0.extend(buf);
1551        Ok(buf.len())
1552    }
1553
1554    fn flush(&mut self) -> io::Result<()> {
1555        Ok(())
1557    }
1558}
1559
1560impl<const MIN_LEN: usize, const MAX_LEN: usize> LowerHex for Confined<Vec<u8>, MIN_LEN, MAX_LEN> {
1563    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1564        f.write_str(&self.0.to_hex())
1565    }
1566}
1567
1568impl<const MIN_LEN: usize, const MAX_LEN: usize> UpperHex for Confined<Vec<u8>, MIN_LEN, MAX_LEN> {
1569    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1570        f.write_str(&self.0.to_hex().to_uppercase())
1571    }
1572}
1573
1574impl<const MIN_LEN: usize, const MAX_LEN: usize> FromHex for Confined<Vec<u8>, MIN_LEN, MAX_LEN> {
1575    fn from_byte_iter<I>(iter: I) -> Result<Self, hex::Error>
1576    where
1577        I: Iterator<Item = Result<u8, hex::Error>> + ExactSizeIterator + DoubleEndedIterator,
1578    {
1579        Vec::<u8>::from_byte_iter(iter).map(Self)
1580    }
1581}
1582
1583pub type TinyString = Confined<String, ZERO, U8>;
1587pub type SmallString = Confined<String, ZERO, U16>;
1589pub type MediumString = Confined<String, ZERO, U24>;
1591pub type LargeString = Confined<String, ZERO, U32>;
1593pub type ConfinedString<const MIN: usize = 0, const MAX: usize = U64> = Confined<String, MIN, MAX>;
1595pub type NonEmptyString<const MAX: usize = U64> = Confined<String, ONE, MAX>;
1597
1598pub type TinyAscii = Confined<AsciiString, ZERO, U8>;
1600pub type SmallAscii = Confined<AsciiString, ZERO, U16>;
1602pub type MediumAscii = Confined<AsciiString, ZERO, U24>;
1604pub type LargeAscii = Confined<AsciiString, ZERO, U32>;
1606pub type ConfinedAscii<const MIN: usize = 0, const MAX: usize = U64> =
1608    Confined<AsciiString, MIN, MAX>;
1609pub type NonEmptyAscii<const MAX: usize = U64> = Confined<AsciiString, ONE, MAX>;
1611
1612pub type TinyBlob = Confined<Vec<u8>, ZERO, U8>;
1614pub type SmallBlob = Confined<Vec<u8>, ZERO, U16>;
1616pub type MediumBlob = Confined<Vec<u8>, ZERO, U24>;
1618pub type LargeBlob = Confined<Vec<u8>, ZERO, U32>;
1620pub type ConfinedBlob<const MIN: usize = 0, const MAX: usize = U64> = Confined<Vec<u8>, MIN, MAX>;
1622pub type NonEmptyBlob<const MAX: usize = U64> = Confined<Vec<u8>, ONE, MAX>;
1624
1625pub type TinyVec<T> = Confined<Vec<T>, ZERO, U8>;
1627pub type SmallVec<T> = Confined<Vec<T>, ZERO, U16>;
1629pub type MediumVec<T> = Confined<Vec<T>, ZERO, U24>;
1631pub type LargeVec<T> = Confined<Vec<T>, ZERO, U32>;
1633pub type ConfinedVec<T, const MIN: usize = 0, const MAX: usize = U64> = Confined<Vec<T>, MIN, MAX>;
1635pub type NonEmptyVec<T, const MAX: usize = U64> = Confined<Vec<T>, ONE, MAX>;
1637
1638pub type TinyDeque<T> = Confined<VecDeque<T>, ZERO, U8>;
1640pub type SmallDeque<T> = Confined<VecDeque<T>, ZERO, U16>;
1642pub type MediumDeque<T> = Confined<VecDeque<T>, ZERO, U24>;
1644pub type LargeDeque<T> = Confined<VecDeque<T>, ZERO, U32>;
1646pub type ConfinedDeque<T, const MIN: usize = 0, const MAX: usize = U64> =
1648    Confined<VecDeque<T>, MIN, MAX>;
1649pub type NonEmptyDeque<T, const MAX: usize = U64> = Confined<VecDeque<T>, ONE, MAX>;
1651
1652#[cfg(feature = "std")]
1654pub type TinyHashSet<T> = Confined<HashSet<T>, ZERO, U8>;
1655#[cfg(feature = "std")]
1657pub type SmallHashSet<T> = Confined<HashSet<T>, ZERO, U16>;
1658#[cfg(feature = "std")]
1660pub type MediumHashSet<T> = Confined<HashSet<T>, ZERO, U24>;
1661#[cfg(feature = "std")]
1663pub type LargeHashSet<T> = Confined<HashSet<T>, ZERO, U32>;
1664#[cfg(feature = "std")]
1665pub type ConfinedHashSet<T, const MIN: usize = 0, const MAX: usize = U64> =
1667    Confined<HashSet<T>, MIN, MAX>;
1668#[cfg(feature = "std")]
1670pub type NonEmptyHashSet<T, const MAX: usize = U64> = Confined<HashSet<T>, ONE, MAX>;
1671
1672pub type TinyOrdSet<T> = Confined<BTreeSet<T>, ZERO, U8>;
1674pub type SmallOrdSet<T> = Confined<BTreeSet<T>, ZERO, U16>;
1676pub type MediumOrdSet<T> = Confined<BTreeSet<T>, ZERO, U24>;
1678pub type LargeOrdSet<T> = Confined<BTreeSet<T>, ZERO, U32>;
1680pub type ConfinedOrdSet<T, const MIN: usize = 0, const MAX: usize = U64> =
1682    Confined<BTreeSet<T>, MIN, MAX>;
1683pub type NonEmptyOrdSet<T, const MAX: usize = U64> = Confined<BTreeSet<T>, ONE, MAX>;
1685
1686#[cfg(feature = "std")]
1688pub type TinyHashMap<K, V> = Confined<HashMap<K, V>, ZERO, U8>;
1689#[cfg(feature = "std")]
1691pub type SmallHashMap<K, V> = Confined<HashMap<K, V>, ZERO, U16>;
1692#[cfg(feature = "std")]
1694pub type MediumHashMap<K, V> = Confined<HashMap<K, V>, ZERO, U24>;
1695#[cfg(feature = "std")]
1697pub type LargeHashMap<K, V> = Confined<HashMap<K, V>, ZERO, U32>;
1698#[cfg(feature = "std")]
1699pub type ConfinedHashMap<K, V, const MIN: usize = 0, const MAX: usize = U64> =
1701    Confined<HashSet<K, V>, MIN, MAX>;
1702#[cfg(feature = "std")]
1704pub type NonEmptyHashMap<K, V, const MAX: usize = U64> = Confined<HashMap<K, V>, ONE, MAX>;
1705
1706pub type TinyOrdMap<K, V> = Confined<BTreeMap<K, V>, ZERO, U8>;
1708pub type SmallOrdMap<K, V> = Confined<BTreeMap<K, V>, ZERO, U16>;
1710pub type MediumOrdMap<K, V> = Confined<BTreeMap<K, V>, ZERO, U24>;
1712pub type LargeOrdMap<K, V> = Confined<BTreeMap<K, V>, ZERO, U32>;
1714pub type ConfinedOrdMap<K, V, const MIN: usize = 0, const MAX: usize = U64> =
1716    Confined<BTreeMap<K, V>, MIN, MAX>;
1717pub type NonEmptyOrdMap<K, V, const MAX: usize = U64> = Confined<BTreeMap<K, V>, ONE, MAX>;
1719
1720#[macro_export]
1722#[deprecated(since = "4.7.0", note = "use size-specific macros")]
1723macro_rules! confined_s {
1724    () => {
1725        $crate::confinement::Confined::<String>::new()
1726    };
1727    ($s:literal) => {
1728        $crate::confinement::Confined::try_from(s!($s))
1729            .expect("inline confined_s literal exceeds confinement length")
1730            .into()
1731    };
1732}
1733
1734#[macro_export]
1736macro_rules! tiny_s {
1737    () => {
1738        $crate::confinement::TinyString::new()
1739    };
1740    ($lit:literal) => {
1741        $crate::confinement::TinyString::try_from(s!($lit))
1742            .expect("static string for tiny_s literal cis too long")
1743    };
1744}
1745
1746#[macro_export]
1748macro_rules! small_s {
1749    () => {
1750        $crate::confinement::SmallString::new()
1751    };
1752    ($lit:literal) => {
1753        $crate::confinement::SmallString::try_from(s!($lit))
1754            .expect("static string for small_s literal cis too long")
1755    };
1756}
1757
1758#[macro_export]
1760macro_rules! medium_s {
1761    () => {
1762        $crate::confinement::MediumString::new()
1763    };
1764    ($lit:literal) => {
1765        $crate::confinement::MediumString::try_from(s!($lit))
1766            .expect("static string for medium_s literal cis too long")
1767    };
1768}
1769
1770#[macro_export]
1772#[deprecated(since = "4.7.0", note = "use size-specific macros")]
1773macro_rules! confined_blob {
1774    () => {
1775        $crate::confinement::ConfinedBlob::new()
1776    };
1777    ($elem:expr; $n:expr) => (
1778        $crate::confinement::ConfinedBlob::try_from(vec![$elem; $n])
1779            .expect("inline confined_blob contains invalid number of items")
1780    );
1781    ($($x:expr),+ $(,)?) => (
1782        $crate::confinement::ConfinedBlob::try_from(vec![$($x,)+])
1783            .expect("inline confined_blob contains invalid number of items")
1784            .into()
1785    )
1786}
1787
1788#[macro_export]
1790macro_rules! tiny_blob {
1791    () => {
1792        $crate::confinement::TinyBlob::new()
1793    };
1794    ($elem:expr; $n:expr) => (
1795        $crate::confinement::TinyBlob::try_from(vec![$elem; $n])
1796            .expect("inline tiny_blob contains invalid number of items")
1797    );
1798    ($($x:expr),+ $(,)?) => (
1799        $crate::confinement::TinyBlob::try_from(vec![$($x,)+])
1800            .expect("inline tiny_blob contains invalid number of items")
1801    )
1802}
1803
1804#[macro_export]
1806macro_rules! small_blob {
1807    () => {
1808        $crate::confinement::SmallBlob::new()
1809    };
1810    ($elem:expr; $n:expr) => (
1811        $crate::confinement::SmallBlob::try_from(vec![$elem; $n])
1812            .expect("inline small_blob contains invalid number of items")
1813    );
1814    ($($x:expr),+ $(,)?) => (
1815        $crate::confinement::SmallBlob::try_from(vec![$($x,)+])
1816            .expect("inline small_blob contains invalid number of items")
1817    )
1818}
1819
1820#[macro_export]
1822macro_rules! medium_blob {
1823    () => {
1824        $crate::confinement::MediumBlob::new()
1825    };
1826    ($elem:expr; $n:expr) => (
1827        $crate::confinement::MediumBlob::try_from(vec![$elem; $n])
1828            .expect("inline medium_blob contains invalid number of items")
1829    );
1830    ($($x:expr),+ $(,)?) => (
1831        $crate::confinement::MediumBlob::try_from(vec![$($x,)+])
1832            .expect("inline medium_blob contains invalid number of items")
1833    )
1834}
1835
1836#[macro_export]
1838#[deprecated(since = "4.7.0", note = "use size-specific macros")]
1839macro_rules! confined_vec {
1840    () => {
1841        $crate::confinement::Confined::<Vec<_>>::new()
1842    };
1843    ($elem:expr; $n:expr) => (
1844        $crate::confinement::Confined::try_from(vec![$elem; $n])
1845            .expect("inline confined_vec literal contains invalid number of items")
1846    );
1847    ($($x:expr),+ $(,)?) => (
1848        $crate::confinement::Confined::try_from(vec![$($x,)+])
1849            .expect("inline confined_vec literal contains invalid number of items")
1850            .into()
1851    )
1852}
1853
1854#[macro_export]
1856macro_rules! tiny_vec {
1857    () => {
1858        $crate::confinement::TinyVec::new()
1859    };
1860    ($elem:expr; $n:expr) => (
1861        $crate::confinement::TinyVec::try_from(vec![$elem; $n])
1862            .expect("inline tiny_vec literal contains invalid number of items")
1863    );
1864    ($($x:expr),+ $(,)?) => (
1865        $crate::confinement::TinyVec::try_from(vec![$($x,)+])
1866            .expect("inline tiny_vec literal contains invalid number of items")
1867    )
1868}
1869
1870#[macro_export]
1872macro_rules! small_vec {
1873    () => {
1874        $crate::confinement::SmallVec::new()
1875    };
1876    ($elem:expr; $n:expr) => (
1877        $crate::confinement::SmallVec::try_from(vec![$elem; $n])
1878            .expect("inline small_vec literal contains invalid number of items")
1879    );
1880    ($($x:expr),+ $(,)?) => (
1881        $crate::confinement::SmallVec::try_from(vec![$($x,)+])
1882            .expect("inline small_vec literal contains invalid number of items")
1883    )
1884}
1885
1886#[macro_export]
1888macro_rules! medium_vec {
1889    () => {
1890        $crate::confinement::MediumVec::new()
1891    };
1892    ($elem:expr; $n:expr) => (
1893        $crate::confinement::MediumVec::try_from(vec![$elem; $n])
1894            .expect("inline medium_vec literal contains invalid number of items")
1895    );
1896    ($($x:expr),+ $(,)?) => (
1897        $crate::confinement::MediumVec::try_from(vec![$($x,)+])
1898            .expect("inline medium_vec literal contains invalid number of items")
1899    )
1900}
1901
1902#[macro_export]
1904#[deprecated(since = "4.7.0", note = "use size-specific macros")]
1905macro_rules! confined_set {
1906    () => {
1907        $crate::confinement::Confined::<HashSet<_>>::new()
1908    };
1909    ($($x:expr),+ $(,)?) => (
1910        $crate::confinement::Confined::try_from(set![$($x,)+])
1911            .expect("inline confined_set literal contains invalid number of items")
1912            .into()
1913    )
1914}
1915
1916#[macro_export]
1918macro_rules! tiny_set {
1919    () => {
1920        $crate::confinement::TinyHashSet::new()
1921    };
1922    ($($x:expr),+ $(,)?) => (
1923        $crate::confinement::TinyHashSet::try_from(set![$($x,)+])
1924            .expect("inline tiny_set literal contains invalid number of items")
1925    )
1926}
1927
1928#[macro_export]
1930macro_rules! small_set {
1931    () => {
1932        $crate::confinement::SmallHashSet::new()
1933    };
1934    ($($x:expr),+ $(,)?) => (
1935        $crate::confinement::SmallHashSet::try_from(set![$($x,)+])
1936            .expect("inline small_set literal contains invalid number of items")
1937    )
1938}
1939
1940#[macro_export]
1942macro_rules! medium_set {
1943    () => {
1944        $crate::confinement::MediumHashSet::new()
1945    };
1946    ($($x:expr),+ $(,)?) => (
1947        $crate::confinement::MediumHashSet::try_from(set![$($x,)+])
1948            .expect("inline medium_set literal contains invalid number of items")
1949    )
1950}
1951
1952#[macro_export]
1954#[deprecated(since = "4.7.0", note = "use size-specific macros")]
1955macro_rules! confined_bset {
1956    () => {
1957        $crate::confinement::Confined::<BTreeSet<_>>::new()
1958    };
1959    ($($x:expr),+ $(,)?) => (
1960        $crate::confinement::Confined::try_from(bset![$($x,)+])
1961            .expect("inline confined_bset literal contains invalid number of items")
1962            .into()
1963    )
1964}
1965
1966#[macro_export]
1968macro_rules! tiny_bset {
1969    () => {
1970        $crate::confinement::TinyOrdSet::new()
1971    };
1972    ($($x:expr),+ $(,)?) => (
1973        $crate::confinement::TinyOrdSet::try_from(bset![$($x,)+])
1974            .expect("inline tiny_bset literal contains invalid number of items")
1975    )
1976}
1977
1978#[macro_export]
1980macro_rules! small_bset {
1981    () => {
1982        $crate::confinement::SmallOrdSet::new()
1983    };
1984    ($($x:expr),+ $(,)?) => (
1985        $crate::confinement::SmallOrdSet::try_from(bset![$($x,)+])
1986            .expect("inline small_bset literal contains invalid number of items")
1987    )
1988}
1989
1990#[macro_export]
1992macro_rules! medium_bset {
1993    () => {
1994        $crate::confinement::MediumOrdSet::new()
1995    };
1996    ($($x:expr),+ $(,)?) => (
1997        $crate::confinement::MediumOrdSet::try_from(bset![$($x,)+])
1998            .expect("inline medium_bset literal contains invalid number of items")
1999    )
2000}
2001
2002#[macro_export]
2004#[deprecated(since = "4.7.0", note = "use size-specific macros")]
2005macro_rules! confined_map {
2006    () => {
2007        $crate::confinement::Confined::<HashMap<_, _>>::new()
2008    };
2009    ($($key:expr => $value:expr),+ $(,)?) => (
2010        $crate::confinement::Confined::try_from(map!{ $($key => $value),+ })
2011            .expect("inline confined_map literal contains invalid number of items")
2012            .into()
2013    )
2014}
2015
2016#[macro_export]
2018macro_rules! tiny_map {
2019    () => {
2020        $crate::confinement::TinyHashMap::new()
2021    };
2022    { $($key:expr => $value:expr),+ $(,)? } => {
2023        $crate::confinement::TinyHashMap::try_from(map!{ $($key => $value,)+ })
2024            .expect("inline tiny_map literal contains invalid number of items")
2025    }
2026}
2027
2028#[macro_export]
2030macro_rules! small_map {
2031    () => {
2032        $crate::confinement::SmallHashMap::new()
2033    };
2034    { $($key:expr => $value:expr),+ $(,)? } => {
2035        $crate::confinement::SmallHashMap::try_from(map!{ $($key => $value,)+ })
2036            .expect("inline small_map literal contains invalid number of items")
2037    }
2038}
2039
2040#[macro_export]
2042macro_rules! medium_map {
2043    () => {
2044        $crate::confinement::MediumHashMap::new()
2045    };
2046    { $($key:expr => $value:expr),+ $(,)? } => {
2047        $crate::confinement::MediumHashMap::try_from(map!{ $($key => $value,)+ })
2048            .expect("inline medium_map literal contains invalid number of items")
2049    }
2050}
2051
2052#[macro_export]
2054#[deprecated(since = "4.7.0", note = "use size-specific macros")]
2055macro_rules! confined_bmap {
2056    () => {
2057        $crate::confinement::Confined::<BTreeMap<_, _>>::new()
2058    };
2059    ($($key:expr => $value:expr),+ $(,)?) => (
2060        $crate::confinement::Confined::try_from(bmap!{ $($key => $value),+ })
2061            .expect("inline confined_bmap literal contains invalid number of items")
2062            .into()
2063    )
2064}
2065
2066#[macro_export]
2068macro_rules! tiny_bmap {
2069    () => {
2070        $crate::confinement::TinyOrdMap::new()
2071    };
2072    { $($key:expr => $value:expr),+ $(,)? } => {
2073        $crate::confinement::TinyOrdMap::try_from(bmap!{ $($key => $value,)+ })
2074            .expect("inline tiny_bmap literal contains invalid number of items")
2075    }
2076}
2077
2078#[macro_export]
2080macro_rules! small_bmap {
2081    () => {
2082        $crate::confinement::SmallOrdMap::new()
2083    };
2084    { $($key:expr => $value:expr),+ $(,)? } => {
2085        $crate::confinement::SmallOrdMap::try_from(bmap!{ $($key => $value,)+ })
2086            .expect("inline small_bmap literal contains invalid number of items")
2087    }
2088}
2089
2090#[macro_export]
2092macro_rules! medium_bmap {
2093    () => {
2094        $crate::confinement::MediumOrdMap::new()
2095    };
2096    { $($key:expr => $value:expr),+ $(,)? } => {
2097        $crate::confinement::MediumOrdMap::try_from(bmap!{ $($key => $value,)+ })
2098            .expect("inline medium_bmap literal contains invalid number of items")
2099    }
2100}
2101
2102#[cfg(test)]
2103mod test {
2104    use super::*;
2105
2106    #[test]
2107    fn fits_max() {
2108        let mut s = TinyString::new();
2109        assert!(s.is_empty());
2110        for _ in 1..=255 {
2111            s.push('a').unwrap();
2112        }
2113        assert_eq!(s.len_u8(), u8::MAX);
2114        assert_eq!(s.len_u8(), s.len() as u8);
2115        assert!(!s.is_empty());
2116
2117        let mut vec = TinyVec::new();
2118        let mut deque = TinyDeque::new();
2119        let mut set = TinyHashSet::new();
2120        let mut bset = TinyOrdSet::new();
2121        let mut map = TinyHashMap::new();
2122        let mut bmap = TinyOrdMap::new();
2123        assert!(vec.is_empty());
2124        assert!(deque.is_empty());
2125        assert!(set.is_empty());
2126        assert!(bset.is_empty());
2127        assert!(map.is_empty());
2128        assert!(bmap.is_empty());
2129        for index in 1..=255 {
2130            vec.push(5u8).unwrap();
2131            deque.push(5u8).unwrap();
2132            set.push(index).unwrap();
2133            bset.push(5u8).unwrap();
2134            map.insert(5u8, 'a').unwrap();
2135            bmap.insert(index, 'a').unwrap();
2136        }
2137        assert_eq!(vec.len_u8(), u8::MAX);
2138        assert_eq!(deque.len_u8(), u8::MAX);
2139        assert_eq!(set.len_u8(), u8::MAX);
2140        assert_eq!(bset.len_u8(), 1);
2141        assert_eq!(map.len_u8(), 1);
2142        assert_eq!(bmap.len_u8(), u8::MAX);
2143
2144        vec.clear();
2145        assert!(vec.is_empty());
2146    }
2147
2148    #[test]
2149    #[should_panic(expected = "Oversize")]
2150    fn cant_go_above_max() {
2151        let mut s = TinyString::new();
2152        for _ in 1..=256 {
2153            s.push('a').unwrap();
2154        }
2155    }
2156
2157    #[test]
2158    #[should_panic(expected = "Undersize")]
2159    fn cant_go_below_min() {
2160        let mut s = NonEmptyString::<U8>::with('a');
2161        s.remove(0).unwrap();
2162    }
2163
2164    #[test]
2165    fn entry() {
2166        let mut col = tiny_bmap!(0u16 => 'a');
2167        assert!(matches!(
2168            col.entry(0).unwrap(),
2169            btree_map::Entry::Occupied(_)
2170        ));
2171        assert!(matches!(col.entry(1).unwrap(), btree_map::Entry::Vacant(_)));
2172        for idx in 1..u8::MAX {
2173            col.insert(idx as u16, 'b').unwrap();
2174        }
2175        assert!(matches!(
2176            col.entry(2).unwrap(),
2177            btree_map::Entry::Occupied(_)
2178        ));
2179        assert!(col.entry(256).is_err());
2180    }
2181
2182    #[test]
2183    fn macros() {
2184        tiny_vec!() as TinyVec<&str>;
2185        tiny_vec!("a", "b", "c");
2186        small_vec!("a", "b", "c");
2187
2188        tiny_set!() as TinyHashSet<&str>;
2189        tiny_set!("a", "b", "c");
2190        tiny_bset!() as TinyOrdSet<&str>;
2191        tiny_bset!("a", "b", "c");
2192        tiny_map!() as TinyHashMap<&str, u8>;
2193        tiny_map!("a" => 1, "b" => 2, "c" => 3);
2194        tiny_bmap!() as TinyOrdMap<&str, u8>;
2195        tiny_bmap!("a" => 1, "b" => 2, "c" => 3);
2196
2197        small_set!("a", "b", "c");
2198        small_bset!("a", "b", "c");
2199        small_map!("a" => 1, "b" => 2, "c" => 3);
2200        small_bmap!("a" => 1, "b" => 2, "c" => 3);
2201    }
2202
2203    #[test]
2204    fn iter_mut_btree() {
2205        let mut coll = tiny_bmap!(1 => "one");
2206        for (_index, item) in &mut coll {
2207            *item = "two";
2208        }
2209        assert_eq!(coll.get(&1), Some(&"two"));
2210        for (_index, item) in coll.keyed_values_mut() {
2211            *item = "three";
2212        }
2213        assert_eq!(coll.get(&1), Some(&"three"));
2214        for item in coll.values_mut() {
2215            *item = "four";
2216        }
2217        assert_eq!(coll.get(&1), Some(&"four"));
2218        *coll.get_mut(&1).unwrap() = "five";
2219        assert_eq!(coll.get(&1), Some(&"five"));
2220    }
2221}