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
Collection
and add items to it. There are the following methods:new_default
: Creates a newCollection
with a default capacity. Normally, this means that the collection will be expandable.with_capacity
: Creates a newCollection
with 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 newCollection
with 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 theCollection
and 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 aItemRef
to the an item in theCollection
. The item should be the same as the one returned byremove
.peek_mut
: Returns aItemMut
to the an item in theCollection
. The item should be the same as the one returned byremove
.get
: Returns aItemRef
to the an item at the specified index in theCollection
.get_mut
: Returns aItemMut
to the an item at the specified index in theCollection
.find
: Returns an index to the an item in theCollection
that matches the specified item.contains
: Returns true if theCollection
contains the specified item.len
: Returns the number of items in theCollection
.is_empty
: Returnstrue
if theCollection
is 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 newCollection
from an iterator.IntoIterator
: Creates an iterator from aCollection
.Default
: Creates a newCollection
with a default capacity. Uses thenew_default
method.Extend
: Extends aCollection
with items from an iterator. Uses theadd
method.Display
: Converts aCollection
to a string. Uses theiter
method.NewMacro
: Adds a macro for easy creation of a newCollection
with the same syntax as the array creation syntax.Drop
: Drops theCollection
while avoiding memory leaks.Index
: Allows indexing into aCollection
. However, this this trait could be incompatible with theget
andget_mut
methods.
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));