Skip to main content

State

State<T> is the SDK abstraction for storing one typed value under one fixed key. This page explains each operation in detail.

Declare

State is declared as a handle bound to a key and a type. There are two ways to create one:

  1. As a module-level constant at compile time - when the key is a fixed string known when writing the code:
use myrmic_sdk::db::state::State;

const THRESHOLD: State<f32> = State::new_const("threshold");
  1. At runtime-from within a handler-when the key is dynamic and depends on information available only while the program is running:
let state = State::<f32>::new(&device_id);

Both bind to the default scope - private to the cell. To use a custom scope, pass it explicitly using new_const_in or new_in:

use myrmic_sdk::db::Scope;

// Compile time - private with a custom schema
const THRESHOLD: State<f32> = State::new_const_in(
"threshold",
Scope::private_in(Some("config")),
);

// Runtime - public, shared across cells using the same scope
let state = State::<f32>::new_in(
&device_id,
Scope::public("my-app"),
);

Write

The state handle exposes a save method. It takes a reference to the value and writes it to the runtime database under the handle's key, overwriting any existing value.

THRESHOLD.save(&30.0)?;

To write under a different key without declaring a separate handle, use save_to. It takes the key and a reference to the value:

THRESHOLD.save_to("threshold-zone-a", &30.0)?;

Read

The state handle exposes a load method. It reads the value from the runtime database and returns it, or None if no value has been stored yet - provide a fallback to handle that case.

let value = THRESHOLD.load()?.unwrap_or(25.0);

To read from a different key without declaring a separate handle, use load_from. It takes the key and returns the value the same way:

let value = THRESHOLD.load_from("threshold-zone-a")?.unwrap_or(25.0);

Modify

Modifying a stored value is a read-change-write cycle. The state handle provides several methods for this, grouped by how the mutation is expressed.

Closure

A closure-based approach passes the current value by mutable reference, runs the closure on it, and saves the result back.

The state handle exposes a modify method. It applies the closure to the stored value, saves the result, and returns the updated value - or None if nothing was stored:

let updated = THRESHOLD.modify(|value| {
*value += 1.0;
})?;

To apply the closure on a different key, use modify_at:

let updated = THRESHOLD.modify_at("threshold-zone-a", |value| {
*value += 1.0;
})?;

Guard

A guard follows Rust's RAII pattern - it loads the value, lets you mutate it directly, and saves it back automatically when it is dropped.

The state handle exposes a guard method. It returns a guard only when a value is already stored - None if nothing is there:

if let Some(mut guard) = THRESHOLD.guard()? {
*guard += 1.0;
}

To open a guard on a different key, use guard_at:

if let Some(mut guard) = THRESHOLD.guard_at("threshold-zone-a")? {
*guard += 1.0;
}

To always get a guard - even when nothing is stored yet - use guard_or_default. It falls back to the type's default when nothing is stored and then yields the guard:

let mut guard = THRESHOLD.guard_or_default()?;
*guard += 1.0;

To do the same on a different key, use guard_or_default_at:

let mut guard = THRESHOLD.guard_or_default_at("threshold-zone-a")?;
*guard += 1.0;

Upsert

Upsert ensures a value is always present - it returns what is stored, or saves the type's default and returns it if nothing is there.

The state handle exposes an upsert method:

let value = THRESHOLD.upsert()?;

To do the same on a different key, use upsert_at:

let value = THRESHOLD.upsert_at("threshold-zone-a")?;

To apply a closure before saving - starting from the type's default when nothing is stored - use upsert_with. It always runs the closure and returns the updated value:

let value = THRESHOLD.upsert_with(|value| {
*value += 1.0;
})?;

To do the same on a different key, use upsert_with_at:

let value = THRESHOLD.upsert_with_at("threshold-zone-a", |value| {
*value += 1.0;
})?;

See also

Cookie Policy