The Rust framework provides various storage mappers you can use. Deciding which one to use for every situation is critical for performance. There will be a comparison section after each mapper is described.
Note: All the storage mappers support additional key arguments.
General purpose mappers
SingleValueMapper
Stores a single value. Examples:
fn single_value(&self) -> SingleValueMapper<Type>;
fn single_value_with_single_key_arg(&self, key_arg: Type1) -> SingleValueMapper<Type2>;
fn single_value_with_multi_key_arg(&self, key_arg1: Type1, key_arg2: Type2) -> SingleValueMapper<Type3>;
Keep in mind there is no way of iterating over all key_arg
s, so if you need to do that, consider using another mapper.
Available methods:
get
fn get() -> Type
Reads the value from storage and deserializes it to the given Type
. For numerical types and vector types, this will return the default value for empty storage, i.e. 0 and empty vec respectively. For custom structs, this will signal an error if trying to read from empty storage.
set
fn set(value: &Type)
Sets the stored value to the provided value
argument. For base Rust numerical types, the reference is not needed.
is_empty
fn is_empty() -> bool
Returns true
is the storage entry is empty. Usually used when storing struct types to prevent crashes on get()
.
set_if_empty
fn set_if_empty(value: &Type)
Sets the value only if the storage for that value is currently empty. Usually used in #init functions to not overwrite values on contract upgrade.
clear
fn clear()
Clears the entry.
update
fn update<R, F: FnOnce(&mut Type) -> R>(f: F) -> R
Takes a closure as argument, applies that closure to the currently stored value, saves the new value, and returns any value the given closure might return. Examples:
Incrementing a value:
fn my_value(&self) -> SingleValueMapper<BigUint>;
self.my_value().update(|val| *val += 1);
Modifying a struct's field:
pub struct MyStruct {
pub field_1: u64,
pub field_2: u32
}
fn my_value(&self) -> SingleValueMapper<MyStruct>;
self.my_value().update(|val| val.field1 = 5);
Returning a value from the closure:
fn my_value(&self) -> SingleValueMapper<BigUint>;
let new_val = self.my_value().update(|val| {
*val += 1;
*val
});
raw_byte_length
fn raw_byte_length() -> usize
Returns the raw byte length of the stored value. This should be rarely used.
VecMapper
Stores elements of the same type, each under their own storage key. Allows acces by index for said items. Keep in mind indexes start at 1 for VecMapper. Examples:
fn my_vec(&self) -> VecMapper<Type>;
fn my_vec_with_args(&self, arg: Type1) -> VecMapper<Type2>;
Available methods:
push
fn push(elem: &T)
Stores the element at index len
and increments len
afterwards.
get
fn get(index: usize) -> Type
Gets the element at the specific index. Valid indexes are 1 to len
, both ends included. Attempting to read from an invalid index will signal an error.
set
fn set(index: usize, value: &Type)
Sets the element at the given index. Index must be in inclusive range 1 to len
.
clear_entry
fn clear_entry(index: usize)
Clears the entry at the given index. This does not decrease the length.
is_empty
fn is_empty() -> bool
Returns true
if the mapper has no elements stored.
len
fn len() -> usize
Returns the number of items stored in the mapper.
extend_from_slice
fn extend_from_slice(slice: &[Type])
Pushes all elements from the given slice at the end of the mapper. More efficient than manual for
of push
, as the internal length is only read and updated once.
swap_remove
fn swap_remove(index: usize)
Removes the element at index
, moves the last element to index
and decreases the len
by 1. There is no way of removing an element and preserving the order.
clear
fn clear()
Clears all the elements from the mapper. This function can run out of gas for big collections.
iter
fn iter() -> Iter<Type>
Provides an iterator over all the elements.
SetMapper
Stores a set of values, with no duplicates being allowed. It also provides methods for checking if a value already exists in the set. Values order is given by their order of insertion.
Unless you need to maintain the order of the elements, consider using UnorderedSetMapper
or WhitelistMapper
instead, as they're more efficient.
Examples:
fn my_set(&self) -> SetMapper<Type>;
Available methods:
insert
fn insert(value: Type) -> bool
Insers the value into the set. Returns false
if the item was already present.
remove
fn remove(value: &Type)
Removes the value from the set. Returns false
if the set did not contain the value.
contains
fn contains(value: &Type) -> bool
Returns true
if the mapper contains the given value.
is_empty
fn is_empty() -> bool
Returns true
if the mapper has no elements stored.
len
fn len() -> usize
Returns the number of items stored in the mapper.
clear
fn clear()
Clears all the elements from the mapper. This function can run out of gas for big collections.
iter
fn iter() -> Iter<Type>
Returns an iterator over all the stored elements.