Trait trait_based_collection::collection::Collection
source · [−]pub trait Collection<'a, T>: Iterators<'a, T> {
Show 14 methods
fn new_default() -> Self
where
Self: Sized;
fn add(&mut self, value: T);
fn remove(&mut self) -> Option<T>;
fn len(&self) -> usize;
fn with_capacity(capacity: usize) -> Self
where
Self: Sized,
{ ... }
fn with_approximate_capacity(approx_capacity: usize) -> Self
where
Self: Sized,
{ ... }
fn clear(&mut self) { ... }
fn peek(&'a self) -> Option<Self::ItemRef> { ... }
fn peek_mut(&'a mut self) -> Option<Self::ItemMut> { ... }
fn get(&'a self, index: usize) -> Option<Self::ItemRef> { ... }
fn get_mut(&'a mut self, index: usize) -> Option<Self::ItemMut> { ... }
fn find(&'a self, value: &T) -> Option<usize>
where
T: PartialEq,
{ ... }
fn contains(&'a self, value: &T) -> bool
where
T: PartialEq,
{ ... }
fn is_empty(&self) -> bool { ... }
}Expand description
This is the trait that all implementations of a collection must implement. A Collection is a
data structure that can be used to store a collection of items.
The Collection is generic over any type without the need of any extra traits. This allows
the user to create a collection of any type that they want.
The trait provides a number of methods that can be used to create, manipulate, and retrieve
items from the Collection. The methods are divided into three groups:
- Creation: These methods are used to create a new
Collectionand add items to it. There are the following methods:new_default: Creates a newCollectionwith a default capacity. Normally, this means that the collection will be expandable.with_capacity: Creates a newCollectionwith a specific capacity. This method is useful if you want to avoid the expense of resizing the collection when adding items.with_approximate_capacity: Creates a newCollectionwith a capacity that is close to the specified capacity but could be larger. This method is useful if you want to avoid some of the expense of resizing the collection when adding items.
For more information about capacity, see the trait FixedSizeCollection which is used to
create collections with a fixed capacity (i.e. the collection will not be easily expandable).
-
Manipulation: These methods are used to add, remove, and retrieve items from the
Collection. There are the following methods:add: Adds an item to theCollection.remove: Removes an item from theCollectionand returns the ownership of the item.clear: Removes all items from theCollection.
-
Retrieval: These methods are used to retrieve items or information from the
Collection. There are the following methods:peek: Returns aItemRefto the an item in theCollection. The item should be the same as the one returned byremove.peek_mut: Returns aItemMutto the an item in theCollection. The item should be the same as the one returned byremove.get: Returns aItemRefto the an item at the specified index in theCollection.get_mut: Returns aItemMutto the an item at the specified index in theCollection.find: Returns an index to the an item in theCollectionthat matches the specified item.contains: Returns true if theCollectioncontains the specified item.len: Returns the number of items in theCollection.is_empty: Returnstrueif theCollectionis empty.
As briefly mentioned above, the Collection is intended for all types of data structures.
However, if the the amount of items in the collection is known, it is possible to create a
FixedSizeCollection which can be used to create a collection with a fixed capacity. This is
mainly for implementation of data structures using arrays.
Examples
A simple example of creating a Collection by using a wrapper around the Vec data
structure with the minimum amount of code (by using the default implementation of the
different methods):
use trait_based_collection::{prelude::*, macros::All};
#[derive(All)]
struct MyCollection<T> {
data: Vec<T>,
}
impl<'a, T: 'a> Iterators<'a, T> for MyCollection<T> {
type ItemRef = &'a T;
type ItemMut = &'a mut T;
type Iter = std::slice::Iter<'a, T>;
type IterMut = std::slice::IterMut<'a, T>;
fn iter(&'a self) -> Self::Iter {
self.data.iter()
}
fn iter_mut(&'a mut self) -> Self::IterMut {
self.data.iter_mut()
}
}
impl<'a, T: 'a> Collection<'a, T> for MyCollection<T> {
fn new_default() -> Self where Self: Sized {
MyCollection {
data: Vec::new(),
}
}
fn add(&mut self, value: T) {
self.data.push(value);
}
fn remove(&mut self) -> Option<T> {
self.data.pop()
}
fn len(&self) -> usize {
self.data.len()
}
}Derivable Traits
The Collection trait allows the easy implementation of several traits that can be derived
through the derive macro. These traits can be generically implemented by using the methods
in the Collection trait. Currently, the following traits are derivable:
FromIterator: Creates a newCollectionfrom an iterator.IntoIterator: Creates an iterator from aCollection.Default: Creates a newCollectionwith a default capacity. Uses thenew_defaultmethod.Extend: Extends aCollectionwith items from an iterator. Uses theaddmethod.Display: Converts aCollectionto a string. Uses theitermethod.NewMacro: Adds a macro for easy creation of a newCollectionwith the same syntax as the array creation syntax.Drop: Drops theCollectionwhile avoiding memory leaks.Index: Allows indexing into aCollection. However, this this trait could be incompatible with thegetandget_mutmethods.
Special mention to the All derive macro, which can be used to derive all traits at once.
For more information about the derivable traits, see the Collection Macros module.
Safety
The implementation of the Collection trait could be unsafe as some of the methods in the
trait need the use of unsafe code. However, the different implementations of the Collection
should ensure that the behavior is safe.
Required Methods
sourcefn new_default() -> Selfwhere
Self: Sized,
fn new_default() -> Selfwhere
Self: Sized,
Creates a new Collection with a default capacity.
Generally, this means that the collection will be expandable. This method is useful if you don’t know the amount of items that will be added to the collection . The default capacity will depend on the implementation of the collection .
Examples
Example using the Queue:
use trait_based_collection::{prelude::*, Queue};
let mut queue: Queue<i32> = Queue::new_default();sourcefn add(&mut self, value: T)
fn add(&mut self, value: T)
Adds an item to the Collection.
Examples
Example using the Stack:
use trait_based_collection::{prelude::*, Stack};
let mut stack = Stack::new_default();
stack.add(10);
assert_eq!(stack.len(), 1);sourcefn remove(&mut self) -> Option<T>
fn remove(&mut self) -> Option<T>
Removes an item from the Collection.
The item that will be removed will depend on the type of data structure. For example,
the Stack type will remove the last item added to the stack. The Queue type will
remove the first item added to the queue.
Examples
Example using the ArrayStack:
use trait_based_collection::{import, ArrayStack};
import!();
let mut stack = array_stack![0, 1, 2, 3, 4];
for i in (0..5).rev() {
assert_eq!(stack.remove().unwrap(), i);
}
assert_eq!(stack.remove(), None);sourcefn len(&self) -> usize
fn len(&self) -> usize
Returns the number of items in the Collection.
Examples
Example using the CircularDeque:
use trait_based_collection::{prelude::*, CircularDeque};
let mut queue = CircularDeque::new_default();
assert_eq!(queue.len(), 0);
for i in 0..10 {
queue.add(i);
}
assert_eq!(queue.len(), 10);Provided Methods
sourcefn with_capacity(capacity: usize) -> Selfwhere
Self: Sized,
fn with_capacity(capacity: usize) -> Selfwhere
Self: Sized,
Creates a new Collection with a specific capacity.
This method is useful if you want to avoid the expense of resizing the collection when adding items. The capacity will be the specified capacity.
This method is especially useful for collections of FixedSizeCollection types. As
linked based data structures don’t have an extra cost for adding items, they can be used
with an unlimited capacity.
Panics
This method will panic if the specified capacity is equal to zero.
Examples
Example using the Deque:
use trait_based_collection::{prelude::*, Deque};
let mut deque: Deque<usize> = Deque::with_capacity(10);sourcefn with_approximate_capacity(approx_capacity: usize) -> Selfwhere
Self: Sized,
fn with_approximate_capacity(approx_capacity: usize) -> Selfwhere
Self: Sized,
Creates a new Collection with a capacity that is at least the specified capacity.
This method is useful if you want to avoid the expense of resizing the collection when adding items. The capacity will be the specified capacity, with the capacity to be increased if needed.
This method is especially useful for collections of FixedSizeCollection types. As
linked based data structures don’t have an extra cost for adding items, they can be used
with an unlimited capacity.
Panics
This method will panic if the specified capacity is equal to zero.
Examples
Example using the CircularDeque:
use trait_based_collection::{prelude::*, CircularDeque};
let mut circular_deque: CircularDeque<usize> = CircularDeque::with_approximate_capacity(10);sourcefn clear(&mut self)
fn clear(&mut self)
Clears all items from the Collection while keeping the capacity.
This method is useful if you want to reuse the collection . It will not free any memory.
Examples
Example using the Queue:
use trait_based_collection::{prelude::*, Queue};
let mut queue = Queue::new_default();
queue.add(0);
assert!(!queue.is_empty());
queue.clear();
assert!(queue.is_empty());sourcefn peek_mut(&'a mut self) -> Option<Self::ItemMut>
fn peek_mut(&'a mut self) -> Option<Self::ItemMut>
Returns a mutable reference of the item that will be removed next.
Examples
Example using the CircularDeque:
use trait_based_collection::{import, CircularDeque};
import!();
let mut queue = circular_deque![0, 1, 2, 3, 4];
assert_eq!(queue.peek(), Some(&0));sourcefn get(&'a self, index: usize) -> Option<Self::ItemRef>
fn get(&'a self, index: usize) -> Option<Self::ItemRef>
Returns a immutable reference to the n-th item in the Collection.
This should return the same item as if we removed n-1 items from the Collection and
returned the last item.
Examples
Example using the Stack:
use trait_based_collection::{import, Stack};
import!();
let mut stack = stack![0, 1, 2, 3, 4];
assert_eq!(stack.get(3), Some(&1));sourcefn get_mut(&'a mut self, index: usize) -> Option<Self::ItemMut>
fn get_mut(&'a mut self, index: usize) -> Option<Self::ItemMut>
Returns a mutable reference to the n-th item in the Collection.
This should return the same item as if we removed n-1 items from the Collection and
returned the last item.
Examples
Example using the ArrayStack:
use trait_based_collection::{import, ArrayStack};
import!();
let mut stack = array_stack![0, 1, 2, 3, 4];
assert_eq!(stack.get_mut(1), Some(&mut 3));sourcefn find(&'a self, value: &T) -> Option<usize>where
T: PartialEq,
fn find(&'a self, value: &T) -> Option<usize>where
T: PartialEq,
Searches for an item in the Collection and returns its index if found.
Returns None if the item is not found.
The default implementation uses iter to find the item with a linear search.
Examples
Example using the Queue:
use trait_based_collection::{import, Queue};
import!();
let mut queue = queue![4, 1, 0, 2, 3];
assert_eq!(queue.find(&2), Some(3));sourcefn contains(&'a self, value: &T) -> boolwhere
T: PartialEq,
fn contains(&'a self, value: &T) -> boolwhere
T: PartialEq,
Checks if an item is in the Collection.
The default implementation uses find to check if the item is in the collection .
Examples
Example using the Deque:
use trait_based_collection::{import, Deque};
import!();
let mut queue = deque![0, 1, 2, 3, 4];
assert!(queue.contains(&3));