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}