cc_traits/lib.rs
1//! This crate provide traits to describe common operations available on data structures.
2//! This is particularly useful when building new types on top of generic data structures without relying on the actual implementation of the underlying data structure.
3//!
4//! Here is an example of the kind of traits provided by this crate:
5//! ```rust
6//! # use cc_traits::Collection;
7//! /// Mutable collection where new elements can be inserted.
8//! pub trait Insert: Collection {
9//! /// The output of the insertion function.
10//! type Output;
11//!
12//! /// Insert a new element in the collection.
13//! fn insert(&mut self, element: Self::Item) -> Self::Output;
14//! }
15//! ```
16//!
17//! # Usage
18//!
19//! Such traits can be used to define collections with special properties,
20//! independently of the actual internal data structure.
21//! For instance the following code defines an `Ordered<S>` stack collection,
22//! guarantying the well-sortedness of the elements in the stack.
23//!
24//! ```rust
25//! use cc_traits::{
26//! Collection,
27//! Back,
28//! PushBack
29//! };
30//!
31//! /// Ordered stack.
32//! pub struct Ordered<S> {
33//! inner: S
34//! }
35//!
36//! impl<S> Ordered<S> {
37//! pub fn new() -> Self where S: Default {
38//! Ordered {
39//! inner: S::default()
40//! }
41//! }
42//! }
43//!
44//! impl<S> Ordered<S> {
45//! /// Push the given element on the stack iff it is grater or equal
46//! /// to every other element already in the stack.
47//! pub fn try_push<T>(&mut self, element: T) -> Result<(), T>
48//! where
49//! T: PartialOrd,
50//! S: Collection<Item=T> + Back + PushBack, // `S` must be a stack providing `back` and `push_back`.
51//! for<'a> S::ItemRef<'a>: PartialOrd<&'a T> // The reference type must be comparable with other reference types.
52//! {
53//! if self.inner.back().map(|back| back <= &element).unwrap_or(true) {
54//! self.inner.push_back(element);
55//! Ok(())
56//! } else {
57//! Err(element)
58//! }
59//! }
60//! }
61//!
62//! #[cfg(feature = "std")]
63//! fn ordered_stack_usage<S>()
64//! where
65//! S: Default + Collection<Item = i32> + Back + PushBack,
66//! for<'a> S::ItemRef<'a>: PartialOrd<&'a i32>,
67//! {
68//! let mut ordered: Ordered<S> = Ordered::new();
69//! assert!(ordered.try_push(1).is_ok());
70//! assert!(ordered.try_push(2).is_ok());
71//! assert!(ordered.try_push(0).is_err());
72//! }
73//!
74//! #[cfg(feature = "std")]
75//! ordered_stack_usage::<Vec<i32>>(); // a `Vec` is a stack so it works.
76//!
77//! #[cfg(feature = "std")]
78//! use std::collections::VecDeque;
79//! #[cfg(feature = "std")]
80//! ordered_stack_usage::<VecDeque<i32>>(); // a `VecDeque` is also a stack.
81//! ```
82//!
83//! # Trait aliases
84//!
85//! By enabling the `nightly` you can get access to
86//! some trait alias definitions that can be useful to reduce the
87//! verbosity of your code.
88//! Here is an example of such aliases defining the common interface of stacks:
89//! ```ignore
90//! pub trait Stack<T> = Collection<Item=T> + Len + Back;
91//! pub trait StackMut<T> = Stack<T> + BackMut + PushBack + PopBack;
92//! ```
93//!
94//! As of version 0.8.0, those traits are also available without the `nightly`
95//! feature as regular trait definitions.
96//!
97//! # Standard library
98//!
99//! By default, all the traits defined in this crate are implemented (when relevant)
100//! for the standard library collections.
101//! You can disable it by using the `nostd` feature.
102//!
103//! # Foreign implementations
104//!
105//! In addition to the standard library,
106//! traits are implemented for
107//! some popular crates if you enable the feature of the same name.
108//! Here are the supported crates:
109//!
110//! - [`slab`](https://crates.io/crates/slab) providing the `Slab` collection.
111//! - [`smallvec`](https://crates.io/crates/smallvec) providing the `SmallVec` collection.
112//! - [`serde_json`](https://crates.io/crates/serde_json) providing the `Map<String, Value>` collection for JSON objects.
113//! - [`ijson`](https://crates.io/crates/ijson) providing the `IObject` and `IArray` collections.
114#![cfg_attr(not(feature = "std"), no_std)]
115#![cfg_attr(feature = "nightly", feature(trait_alias))]
116
117#[cfg(feature = "alloc")]
118extern crate alloc;
119extern crate core;
120
121mod impls;
122mod macros;
123
124#[cfg(feature = "nightly")]
125mod alias;
126#[cfg(feature = "nightly")]
127pub use alias::*;
128
129#[cfg(not(feature = "nightly"))]
130mod non_alias;
131#[cfg(not(feature = "nightly"))]
132pub use non_alias::*;
133
134use core::ops::{Deref, DerefMut};
135
136/// Abstract collection.
137pub trait Collection {
138 /// Type of the items of the collection.
139 type Item;
140}
141
142/// Abstract collection that can be immutably referenced.
143pub trait CollectionRef: Collection {
144 /// Type of references to items of the collection.
145 type ItemRef<'a>: Clone + Deref<Target = Self::Item>
146 where
147 Self: 'a;
148
149 /// Changes an item reference into a shorter lived reference.
150 ///
151 /// Item references are [covariant](https://doc.rust-lang.org/nomicon/subtyping.html#variance) with
152 /// regard to the defined lifetime parameter `'a`.
153 /// Since this cannot be directly expressed by the type system, this associated function
154 /// allows one to explicitly shorten the reference's lifetime.
155 ///
156 /// You can use the [`covariant_item_ref!`] macro to automatically
157 /// implement this function.
158 fn upcast_item_ref<'short, 'long: 'short>(r: Self::ItemRef<'long>) -> Self::ItemRef<'short>
159 where
160 Self: 'long;
161}
162
163/// Collection where each item reference can be converted into a standard
164/// "simple" rust reference.
165///
166/// This trait is particularly useful to avoid having to include where bounds
167/// of the form `for<'r> T::ItemRef<'r>: Into<&'r T::Item>`, which can
168/// currently lead the compiler to try to prove `T: 'static`
169/// (see https://github.com/rust-lang/rust/pull/96709#issuecomment-1182403490)
170/// for more details.
171pub trait SimpleCollectionRef: CollectionRef {
172 fn into_ref<'r>(r: Self::ItemRef<'r>) -> &'r Self::Item
173 where
174 Self: 'r;
175}
176
177/// Abstract collection that can be mutably referenced.
178pub trait CollectionMut: Collection {
179 /// Type of mutable references to items of the collection.
180 type ItemMut<'a>: DerefMut<Target = Self::Item>
181 where
182 Self: 'a;
183
184 /// Changes an item mutable reference into a shorter lived mutable reference.
185 ///
186 /// See the [`CollectionRef::upcast_item_ref`] function for more information.
187 /// You can use the [`covariant_item_mut!`] macro to automatically
188 /// implement this function.
189 fn upcast_item_mut<'short, 'long: 'short>(r: Self::ItemMut<'long>) -> Self::ItemMut<'short>
190 where
191 Self: 'long;
192}
193
194/// Collection where each item reference can be converted into a standard
195/// "simple" rust reference.
196///
197/// This trait is particularly useful to avoid having to include where bounds
198/// of the form `for<'r> T::ItemMut<'r>: Into<&'r mut T::Item>`, which can
199/// currently lead the compiler to try to prove `T: 'static`
200/// (see https://github.com/rust-lang/rust/pull/96709#issuecomment-1182403490)
201/// for more details.
202pub trait SimpleCollectionMut: CollectionMut {
203 fn into_mut<'r>(r: Self::ItemMut<'r>) -> &'r mut Self::Item
204 where
205 Self: 'r;
206}
207
208/// Abstract keyed collection.
209pub trait Keyed: Collection {
210 /// Type of the keys indexing each item of the collection.
211 type Key;
212}
213
214/// Abstract keyed collection whose key can be referenced.
215pub trait KeyedRef: Keyed {
216 /// Type of references to keys of the collection.
217 type KeyRef<'a>: Clone + Deref<Target = Self::Key>
218 where
219 Self: 'a;
220
221 /// Changes a key reference into a shorter lived reference.
222 ///
223 /// See the [`CollectionRef::upcast_item_ref`] function for more information.
224 /// You can use the [`covariant_key_ref!`] macro to automatically
225 /// implement this function.
226 fn upcast_key_ref<'short, 'long: 'short>(r: Self::KeyRef<'long>) -> Self::KeyRef<'short>
227 where
228 Self: 'long;
229}
230
231/// Keyed collection where each key reference can be converted into a standard
232/// "simple" rust reference.
233///
234/// This trait is particularly useful to avoid having to include where bounds
235/// of the form `for<'r> T::KeyRef<'r>: Into<&'r T::Key>`, which can
236/// currently lead the compiler to try to prove `T: 'static`
237/// (see https://github.com/rust-lang/rust/pull/96709#issuecomment-1182403490)
238/// for more details.
239pub trait SimpleKeyedRef: KeyedRef {
240 fn into_ref<'r>(r: Self::KeyRef<'r>) -> &'r Self::Key
241 where
242 Self: 'r;
243}
244
245/// Collection that can be created with a minimum given capacity.
246pub trait WithCapacity {
247 /// Creates a new instance of `Self` with the given minimum capacity.
248 fn with_capacity(capacity: usize) -> Self;
249}
250
251/// Sized collection.
252pub trait Len {
253 /// Returns the number of elements in the collection.
254 fn len(&self) -> usize;
255
256 /// Checks if the collection is empty.
257 fn is_empty(&self) -> bool {
258 self.len() == 0
259 }
260}
261
262/// Collection with known capacity.
263pub trait Capacity {
264 /// Returns the current capacity of the collection.
265 ///
266 /// This corresponds to the number of elements the collection can hold without reallocation.
267 fn capacity(&self) -> usize;
268}
269
270/// Collection that can extend their capacity.
271pub trait Reserve {
272 /// Reserve enough memory for `edditional` more elements.
273 fn reserve(&mut self, additional: usize);
274}
275
276/// Queryable collection.
277pub trait Get<T>: CollectionRef {
278 /// Returns a reference to the item stored behind the given key (if any).
279 fn get(&self, key: T) -> Option<Self::ItemRef<'_>>;
280
281 /// Checks if the collection contains an item behind the given key.
282 fn contains(&self, key: T) -> bool {
283 self.get(key).is_some()
284 }
285}
286
287/// Mutably queryable collection.
288pub trait GetMut<T>: Get<T> + CollectionMut {
289 /// Returns a mutable reference to the item stored behind the given key (if any).
290 fn get_mut(&mut self, key: T) -> Option<Self::ItemMut<'_>>;
291}
292
293/// Queryable map.
294pub trait GetKeyValue<T>: CollectionRef + KeyedRef {
295 /// Returns the key-value pair matching the given `key`.
296 fn get_key_value(&self, key: T) -> Option<(Self::KeyRef<'_>, Self::ItemRef<'_>)>;
297}
298
299/// Mutably queryable map.
300pub trait GetKeyValueMut<T>: CollectionMut + KeyedRef {
301 /// Returns the key-value pair matching the given `key`, with a mutable reference to the value.
302 fn get_key_value_mut(&mut self, key: T) -> Option<(Self::KeyRef<'_>, Self::ItemMut<'_>)>;
303}
304
305/// Collection exposing a reference to its front element.
306pub trait Front: CollectionRef {
307 /// Get a reference to the front element of the collection.
308 fn front(&self) -> Option<Self::ItemRef<'_>>;
309}
310
311impl<T: Get<usize> + Len> Front for T {
312 fn front(&self) -> Option<Self::ItemRef<'_>> {
313 match self.len() {
314 0 => None,
315 _ => self.get(0),
316 }
317 }
318}
319
320/// Collection exposing a reference to its back element.
321pub trait Back: CollectionRef {
322 /// Get a reference to the back element of the collection.
323 fn back(&self) -> Option<Self::ItemRef<'_>>;
324}
325
326impl<T: Get<usize> + Len> Back for T {
327 fn back(&self) -> Option<Self::ItemRef<'_>> {
328 match self.len() {
329 0 => None,
330 l => self.get(l - 1),
331 }
332 }
333}
334
335/// Collection exposing a mutable reference to its front element.
336pub trait FrontMut: CollectionMut {
337 /// Get a mutable reference to the front element of the collection.
338 fn front_mut(&mut self) -> Option<Self::ItemMut<'_>>;
339}
340
341impl<T: GetMut<usize> + Len> FrontMut for T {
342 fn front_mut(&mut self) -> Option<Self::ItemMut<'_>> {
343 match self.len() {
344 0 => None,
345 _ => self.get_mut(0),
346 }
347 }
348}
349
350/// Collection exposing a mutable reference to its back element.
351pub trait BackMut: CollectionMut {
352 /// Get a mutable reference to the back element of the collection.
353 fn back_mut(&mut self) -> Option<Self::ItemMut<'_>>;
354}
355
356impl<T: GetMut<usize> + Len> BackMut for T {
357 fn back_mut(&mut self) -> Option<Self::ItemMut<'_>> {
358 match self.len() {
359 0 => None,
360 l => self.get_mut(l - 1),
361 }
362 }
363}
364
365/// Mutable collection where new elements can be inserted.
366pub trait Insert: Collection {
367 /// The output of the insertion function.
368 type Output;
369
370 /// Insert a new element in the collection.
371 fn insert(&mut self, element: Self::Item) -> Self::Output;
372}
373
374/// Mutable map where new new key-value pairs can be inserted.
375pub trait MapInsert<K>: Collection {
376 /// The output of the insertion function.
377 type Output;
378
379 /// Insert a new key-value pair in the collection.
380 fn insert(&mut self, key: K, value: Self::Item) -> Self::Output;
381}
382
383/// Mutable collection where new elements can be pushed on the front.
384pub trait PushFront: Collection {
385 /// The output of the push function.
386 type Output;
387
388 /// Push a new element on the front of the collection.
389 fn push_front(&mut self, element: Self::Item) -> Self::Output;
390}
391
392/// Mutable collection where new elements can be pushed on the back.
393pub trait PushBack: Collection {
394 /// The output of the push function.
395 type Output;
396
397 /// Push a new element on the back of the collection.
398 fn push_back(&mut self, element: Self::Item) -> Self::Output;
399}
400
401/// Mutable collection where elements can be removed from.
402pub trait Remove<T>: Collection {
403 /// Remove the element identified by the given `key`.
404 fn remove(&mut self, key: T) -> Option<Self::Item>;
405}
406
407/// Mutable collection where elements can be popped from the front.
408pub trait PopFront: Collection {
409 /// Remove the front element of the collection and return it (if any).
410 fn pop_front(&mut self) -> Option<Self::Item>;
411}
412
413/// Mutable collection where elements can be popped from the back.
414pub trait PopBack: Collection {
415 /// Remove the back element of the collection and return it (if any).
416 fn pop_back(&mut self) -> Option<Self::Item>;
417}
418
419/// Clearable collection.
420pub trait Clear {
421 /// Remove all the elements of the collection.
422 fn clear(&mut self);
423}
424
425/// Iterable collection.
426pub trait Iter: CollectionRef {
427 /// Iterator type.
428 type Iter<'a>: Iterator<Item = Self::ItemRef<'a>>
429 where
430 Self: 'a;
431
432 /// Create an iterator over the items of the collection.
433 fn iter(&self) -> Self::Iter<'_>;
434}
435
436/// Mutably iterable collection.
437pub trait IterMut: CollectionMut {
438 /// Iterator type.
439 type IterMut<'a>: Iterator<Item = Self::ItemMut<'a>>
440 where
441 Self: 'a;
442
443 /// Create an iterator over the mutable items of the collection.
444 fn iter_mut(&mut self) -> Self::IterMut<'_>;
445}
446
447pub trait MapIter: KeyedRef + CollectionRef {
448 type Iter<'a>: Iterator<Item = (Self::KeyRef<'a>, Self::ItemRef<'a>)>
449 where
450 Self: 'a;
451
452 fn iter(&self) -> Self::Iter<'_>;
453}
454
455pub trait MapIterMut: KeyedRef + CollectionMut {
456 type IterMut<'a>: Iterator<Item = (Self::KeyRef<'a>, Self::ItemMut<'a>)>
457 where
458 Self: 'a;
459
460 fn iter_mut(&mut self) -> Self::IterMut<'_>;
461}