Expand description
Slots object that provides strict access control for the stored data.
Data type that stores values and returns a key that can be used to manipulate the stored values. Values can be read by anyone but can only be modified using the key.
Store data
When a piece of data is stored in the collection, a Key
object is
returned. This key represents the owner of the stored data:
it is required to modify or remove (take out) the stored data.
To ensure the stored data is always valid as long as the key exists, the key can’t be cloned.
use slots::slots::Slots;
let mut slots: Slots<_, 2> = Slots::new(); // Capacity of 2 elements
// Store elements
let k1 = slots.store(2).unwrap();
let k2 = slots.store(4).unwrap();
assert_eq!(true, slots.is_full());
// Now that the collection is full, the next store will fail and
// return an Err object that holds the original value we wanted to store.
let k3 = slots.store(8);
assert_eq!(k3.err(), Some(8));
// Storage statistics
assert_eq!(2, slots.capacity()); // this instance can hold at most 2 elements
assert_eq!(2, slots.count()); // there are currently 2 elements stored
Remove data
Removing data from a Slots collection invalidates its key. Because of this,
the take
method consumes the key.
// initially we have 2 elements in the collection
assert_eq!(2, slots.count());
// remove an element
slots.take(k);
// removing also decreases the count of stored elements
assert_eq!(1, slots.count());
let k1 = slots.store(2).unwrap();
slots.take(k1); // k1 is consumed and can no longer be used
slots.take(k1); // trying to use it again will cause a compile error
Access stored data
The key can be used to read or modify the stored data. This is done by passing a FnOnce
closure
to the read
and modify
methods. Whatever the closures return, will be returned by the methods.
let k2 = slots.store(4).unwrap();
// Read element without modification
// closure can be used to transform element
assert_eq!(3, slots.read(&k2, |&e| e - 1));
// Modify a stored element and return a derivative
assert_eq!(3, slots.modify(&k2, |e| {
*e = 2 + *e;
3
}));
// The value behind k2 has changed
assert_eq!(6, slots.read(&k2, |&e| e));
Read using a numerical index
It’s possible to extract the index of the allocated slot from the Key
object, using the index
method.
Because this returns a number with the usize
type, it is not guaranteed to refer to valid data.
let k1 = slots.store(2).unwrap();
let idx = k1.index();
slots.take(k1); // idx no longer points to valid data
assert_eq!(None, slots.try_read(idx, |&e| e*2)); // reading from a freed slot fails