Crate once_cell_no_std

Crate once_cell_no_std 

Source
Expand description

§Overview

once_cell_no_std provides a no_std OnceCell type that implements Sync and can be used in statics. It does not use spinlocks or any other form of blocking. Instead, concurrent initialization is reported as an explicit ConcurrentInitialization error that the caller can handle as it likes.

OnceCell might store arbitrary non-Copy types, can be assigned to at most once and provide direct access to the stored contents. In a nutshell, API looks roughly like this:

impl OnceCell<T> {
    fn new() -> OnceCell<T> { ... }
    fn set(&self, value: T) -> Result<Result<(), T>, ConcurrentInitialization> { ... }
    fn get(&self) -> Option<&T> { ... }
}

Note that the set method requires only a shared reference, so it can also be used in non-mutable statics.

§Example

use std::{env, io};

use once_cell_no_std::OnceCell;

#[derive(Debug)]
pub struct Logger {
    // ...
}
static INSTANCE: OnceCell<Logger> = OnceCell::new();

impl Logger {
    pub fn global() -> &'static Logger {
        INSTANCE.get().expect("logger is not initialized")
    }

    fn from_cli(args: env::Args) -> Result<Logger, std::io::Error> {
       // ...
    }
}

fn main() {
    let logger = Logger::from_cli(env::args()).unwrap();
    INSTANCE.set(logger).unwrap();
    // use `Logger::global()` from now on
}

§Implementation details

The implementation is heavily based on the once_cell crate by @matklad, especially the implementation for parking-lot.

This crate was forked from the great once_cell crate. The original once_cell crate provides two flavors of OnceCell types: unsync::OnceCell and sync::OnceCell. The following table compares the types against once_cell_no_std::OnceCell:

once_cell_no_std::OnceCellonce_cell::sync::OnceCellonce_cell::unsync::OnceCell
implements Syncyesyesno
concurrent initialization leads toConcurrentInitialization error returnedthread blockedcannot happen
no_std supportedyespartially (requires critical-section implementation)yes

Parts of once_cell API are included into std/core as of Rust 1.70.0. The following table compares once_cell_no_std::OnceCell against the core::cell::OnceCell and std::sync::OnceLock types:

once_cell_no_std::OnceCellstd::sync::OnceLockcore::cell::OnceCell
implements Syncyesyesno
concurrent initialization leads toConcurrentInitialization error returnedthread blockedcannot happen
no_std supportedyesnoyes

For more related crates, check out the README of once_cell.

Modules§

error

Structs§

OnceCell
A thread-safe cell which can be written to only once.