pub struct UserLabels<const E: usize, const N: usize = 4> { /* private fields */ }Expand description
Shared registry of every endpoint’s UserLabel LabelList.
Persisted as a single TLV blob under USER_LABELS_KEY — every
successful write to any UserLabelHandler re-serialises the whole
registry and stores it. Read paths take the lock briefly to copy
labels into the TLV builder.
Const generics:
E— max number of endpoints that may have aLabelList. Bound on the in-memoryVecof per-endpoint slots.N— max number ofLabelEntryrows per endpoint. Bound on each slot’s innerVec. Defaults to 4.
Lock holds are bounded — the Mutex<RefCell<_>> is never held
across an .await, so the registry is sound under a work-stealing
executor.
Implementations§
Source§impl<const E: usize, const N: usize> UserLabels<E, N>
impl<const E: usize, const N: usize> UserLabels<E, N>
Sourcepub const fn new() -> UserLabels<E, N>
pub const fn new() -> UserLabels<E, N>
Create an empty registry. Call Self::load_persist at
application startup to populate it from KV.
Prefer Self::init for non-trivial E * N so the
registry’s storage can be initialised in-place (typically in a
StaticCell) instead of being constructed on the stack and
moved. The two paths produce structurally identical instances.
Sourcepub fn init() -> impl Init<UserLabels<E, N>>
pub fn init() -> impl Init<UserLabels<E, N>>
Return an in-place initialiser for an empty registry. Use this
when E * N * size_of::<LabelEntry> is large enough that
stack-constructing a Self::new instance and moving it into
long-lived storage would overflow the stack or bloat
.rodata. Typical usage:
static USER_LABELS: StaticCell<UserLabels<8, 4>> = StaticCell::new();
let user_labels = USER_LABELS.uninit().init_with(UserLabels::init());Sourcepub async fn load_persist<S>(
&self,
store: S,
buf: &mut [u8],
) -> Result<(), Error>where
S: KvBlobStore,
pub async fn load_persist<S>(
&self,
store: S,
buf: &mut [u8],
) -> Result<(), Error>where
S: KvBlobStore,
Re-hydrate the registry from store under USER_LABELS_KEY.
Call once at application startup, before exposing the data
model to commissioners, so subsequent reads see the labels
written before the last reboot.
Missing key (first boot, or persistence cleared) is not an error — the registry simply stays empty.
Trait Implementations§
Auto Trait Implementations§
impl<const E: usize, const N: usize = 4> !Freeze for UserLabels<E, N>
impl<const E: usize, const N: usize = 4> !RefUnwindSafe for UserLabels<E, N>
impl<const E: usize, const N: usize = 4> !Sync for UserLabels<E, N>
impl<const E: usize, const N: usize> Send for UserLabels<E, N>
impl<const E: usize, const N: usize> Unpin for UserLabels<E, N>
impl<const E: usize, const N: usize> UnsafeUnpin for UserLabels<E, N>
impl<const E: usize, const N: usize> UnwindSafe for UserLabels<E, N>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more