Skip to main content

nu_utils/
container.rs

1use std::{
2    borrow::Cow,
3    collections::{BTreeMap, BTreeSet, HashMap, HashSet, LinkedList, VecDeque},
4    hash::Hash,
5    ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive},
6};
7
8/// A minimal abstraction for membership checks across container-like types.
9///
10/// This trait unifies `contains` behavior for common collections, strings,
11/// ranges, and maps, letting generic code ask "does this container contain
12/// this item?" without caring about the concrete type.
13///
14/// The associated `Item` type represents the element or key being queried.
15/// For maps, this is the key type; for `str`/`String`, it is `str`.
16pub trait Container {
17    type Item: ?Sized;
18
19    fn contains(&self, item: &Self::Item) -> bool;
20}
21
22impl<C: Container + ?Sized> Container for &C {
23    type Item = C::Item;
24
25    fn contains(&self, item: &Self::Item) -> bool {
26        C::contains(self, item)
27    }
28}
29
30impl Container for str {
31    type Item = str;
32
33    fn contains(&self, item: &str) -> bool {
34        str::contains(self, item)
35    }
36}
37
38impl Container for String {
39    type Item = str;
40
41    fn contains(&self, item: &Self::Item) -> bool {
42        self.as_str().contains(item)
43    }
44}
45
46impl<T: PartialEq, const N: usize> Container for [T; N] {
47    type Item = T;
48
49    fn contains(&self, item: &Self::Item) -> bool {
50        self.as_slice().contains(item)
51    }
52}
53
54impl<T: PartialEq> Container for [T] {
55    type Item = T;
56
57    fn contains(&self, item: &T) -> bool {
58        <[T]>::contains(self, item)
59    }
60}
61
62impl<T: PartialEq> Container for Vec<T> {
63    type Item = T;
64
65    fn contains(&self, item: &Self::Item) -> bool {
66        self.as_slice().contains(item)
67    }
68}
69
70impl<T: PartialEq> Container for VecDeque<T> {
71    type Item = T;
72
73    fn contains(&self, item: &T) -> bool {
74        VecDeque::contains(self, item)
75    }
76}
77
78impl<T: PartialEq> Container for LinkedList<T> {
79    type Item = T;
80
81    fn contains(&self, item: &T) -> bool {
82        LinkedList::contains(self, item)
83    }
84}
85
86impl<T: Eq + Hash> Container for HashSet<T> {
87    type Item = T;
88
89    fn contains(&self, item: &T) -> bool {
90        HashSet::contains(self, item)
91    }
92}
93
94impl<T: Ord> Container for BTreeSet<T> {
95    type Item = T;
96
97    fn contains(&self, item: &T) -> bool {
98        BTreeSet::contains(self, item)
99    }
100}
101
102impl<K: Eq + Hash, V> Container for HashMap<K, V> {
103    type Item = K;
104
105    fn contains(&self, item: &K) -> bool {
106        HashMap::contains_key(self, item)
107    }
108}
109
110impl<K: Ord, V> Container for BTreeMap<K, V> {
111    type Item = K;
112
113    fn contains(&self, item: &K) -> bool {
114        BTreeMap::contains_key(self, item)
115    }
116}
117
118impl<T: PartialOrd> Container for Range<T> {
119    type Item = T;
120
121    fn contains(&self, item: &T) -> bool {
122        Range::contains(self, item)
123    }
124}
125
126impl<T: PartialOrd> Container for RangeInclusive<T> {
127    type Item = T;
128
129    fn contains(&self, item: &T) -> bool {
130        RangeInclusive::contains(self, item)
131    }
132}
133
134impl<T: PartialOrd> Container for RangeFrom<T> {
135    type Item = T;
136
137    fn contains(&self, item: &T) -> bool {
138        RangeFrom::contains(self, item)
139    }
140}
141
142impl<T: PartialOrd> Container for RangeTo<T> {
143    type Item = T;
144
145    fn contains(&self, item: &T) -> bool {
146        RangeTo::contains(self, item)
147    }
148}
149
150impl<T: PartialOrd> Container for RangeToInclusive<T> {
151    type Item = T;
152
153    fn contains(&self, item: &T) -> bool {
154        RangeToInclusive::contains(self, item)
155    }
156}
157
158impl<'a, C> Container for Cow<'a, C>
159where
160    C: Container + ToOwned + ?Sized,
161{
162    type Item = C::Item;
163
164    fn contains(&self, item: &Self::Item) -> bool {
165        self.as_ref().contains(item)
166    }
167}