pub struct StateSet<T, S> { /* private fields */ }
Expand description

A high-level set of flat values based on the low-level key-value store, which is the interface provided by the chain.

In most situations, this collection should be preferred over BTreeSet and HashSet since it will be more efficient to lookup and update since costs to lookup and update will grow very slowly with the size of the collection. In contrast, using BTreeSet and HashSet almost always entails their serialization, which is linear in the size of the collection.

The cost of updates to the set are dependent on the serialized size of the value T.

New sets can be constructed using the new_set method on the StateBuilder.

/// In an init method:
let mut set1 = state_builder.new_set();

/// In a receive method:
let mut set2 = host.state_builder().new_set();

§Type parameters

The set StateSet<T, S> is parametrized by the type of values T, and the type of the low-level state S. In line with other Rust collections, e.g., BTreeSet and HashSet constructing the stateset via new_set does not require anything specific from T. However most operations do require that T implements Serialize.

Since StateSet<T, S> itself does not implement Serialize sets cannot be nested. If this is really required then a custom solution should be devised using the operations on S (see HasStateApi).

§Low-level state S

The type parameter S is extra compared to usual Rust collections. As mentioned above it specifies the low-level state implementation. This library provides two such implementations. The “external” one (StateApi), which is the implementation supported by external host functions provided by the chain, and a test one. The latter one is only useful for testing with the deprecated test_infrastructure module.

In user code this type parameter should generally be treated as boilerplate, and contract entrypoints should always be stated in terms of a generic type S that implements HasStateApi and defaults to StateApi, unless you intend to use the deprecated testing library.

§Example
#[derive(Serial, DeserialWithState)]
#[concordium(state_parameter = "S")]
struct MyState<S: HasStateApi = StateApi> {
    inner: StateSet<u64, S>,
}
#[init(contract = "mycontract")]
fn contract_init(_ctx: &InitContext, state_builder: &mut StateBuilder) -> InitResult<MyState> {
    Ok(MyState {
        inner: state_builder.new_set(),
    })
}

#[receive(contract = "mycontract", name = "receive", return_value = "bool")]
fn contract_receive(_ctx: &ReceiveContext, host: &Host<MyState>) -> ReceiveResult<bool> {
    let state = host.state();
    Ok(state.inner.contains(&0))
}

§Caution

StateSets must be explicitly deleted when they are no longer needed, otherwise they will remain in the contract’s state, albeit unreachable.

struct MyState<S: HasStateApi = StateApi> {
    inner: StateSet<u64, S>,
}
fn incorrect_replace(state_builder: &mut StateBuilder, state: &mut MyState) {
    // The following is incorrect. The old value of `inner` is not properly deleted.
    // from the state.
    state.inner = state_builder.new_set(); // ⚠️
}

Instead, either the set should be cleared or explicitly deleted.

fn correct_replace(state_builder: &mut StateBuilder, state: &mut MyState) {
    state.inner.clear();
}

Or alternatively

fn correct_replace(state_builder: &mut StateBuilder, state: &mut MyState) {
    let old_set = mem::replace(&mut state.inner, state_builder.new_set());
    old_set.delete()
}

Implementations§

source§

impl<T, S> StateSet<T, S>
where T: Serialize, S: HasStateApi,

source

pub fn insert(&mut self, value: T) -> bool

Adds a value to the set. If the set did not have this value, true is returned. Otherwise, false.

source

pub fn is_empty(&self) -> bool

Returns true if the set contains no elements.

source

pub fn contains(&self, value: &T) -> bool

Returns true if the set contains a value.

source

pub fn clear(&mut self)

Clears the set, removing all values. This also includes values pointed at, if V, for example, is a StateBox.

source

pub fn remove(&mut self, value: &T) -> bool

Removes a value from the set. Returns whether the value was present in the set.

source§

impl<T, S: HasStateApi> StateSet<T, S>

source

pub fn iter(&self) -> StateSetIter<'_, T, S>

Get an iterator over the elements in the StateSet. The iterator returns elements in increasing order, where elements are ordered lexicographically via their serializations.

Trait Implementations§

source§

impl<T: Debug, S: Debug> Debug for StateSet<T, S>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T, S> Deletable for StateSet<T, S>
where S: HasStateApi,

source§

fn delete(self)

Delete all items that this type owns in the state.
source§

impl<T, S> DeserialWithState<S> for StateSet<T, S>

source§

fn deserial_with_state<R: Read>(state: &S, source: &mut R) -> ParseResult<Self>

Attempt to read a structure from a given source and state, failing if an error occurs during deserialization or reading.
source§

impl<T, S> Serial for StateSet<T, S>

source§

fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err>

Attempt to write the structure into the provided writer, failing if only part of the structure could be written. Read more

Auto Trait Implementations§

§

impl<T, S> Freeze for StateSet<T, S>
where S: Freeze,

§

impl<T, S> RefUnwindSafe for StateSet<T, S>

§

impl<T, S> Send for StateSet<T, S>
where S: Send, T: Send,

§

impl<T, S> Sync for StateSet<T, S>
where S: Sync, T: Sync,

§

impl<T, S> Unpin for StateSet<T, S>
where S: Unpin, T: Unpin,

§

impl<T, S> UnwindSafe for StateSet<T, S>
where S: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.