TypeStore

Struct TypeStore 

Source
pub struct TypeStore { /* private fields */ }
Expand description

A thread-safe container that stores exactly one value per type.

TypeStore provides a simple way to store and retrieve values using their type as the key. This is useful for dependency injection, service locators, and managing application-wide state without explicit key management.

Unlike TypeMap which uses explicit keys, TypeStore uses the type itself as the key, meaning you can only store one value of each type.

§Examples

use sovran_typemap::{TypeStore, MapError};

#[derive(Clone, Debug)]
struct DatabaseConfig {
    host: String,
    port: u16,
}

#[derive(Clone, Debug)]
struct AppConfig {
    name: String,
    debug: bool,
}

fn main() -> Result<(), MapError> {
    let store = TypeStore::new();

    // Store configurations by type
    store.set(DatabaseConfig {
        host: "localhost".to_string(),
        port: 5432,
    })?;

    store.set(AppConfig {
        name: "MyApp".to_string(),
        debug: true,
    })?;

    // Retrieve by type - no key needed
    let db_config = store.get::<DatabaseConfig>()?;
    println!("Database: {}:{}", db_config.host, db_config.port);

    // Modify in place
    store.with_mut::<AppConfig, _, _>(|cfg| {
        cfg.debug = false;
    })?;

    Ok(())
}

Implementations§

Source§

impl TypeStore

Source

pub fn new() -> Self

Creates a new, empty TypeStore.

§Examples
use sovran_typemap::TypeStore;

let store = TypeStore::new();
Source

pub fn set<V>(&self, value: V) -> Result<(), MapError>
where V: 'static + Any + Send + Sync,

Stores a value, using its type as the key.

If a value of this type already exists, it will be replaced.

§Errors

Returns MapError::LockError if the internal lock cannot be acquired.

§Examples
let store = TypeStore::new();

store.set(42i32)?;
store.set("hello".to_string())?;
store.set(vec![1, 2, 3])?;

// Overwrites the previous i32
store.set(100i32)?;
assert_eq!(store.get::<i32>()?, 100);
Source

pub fn set_with<V, F>(&self, f: F) -> Result<(), MapError>
where V: 'static + Any + Send + Sync, F: FnOnce() -> V,

Stores a value generated by a closure.

This is useful for lazy initialization or when value construction should only happen if the lock can be acquired.

§Errors

Returns MapError::LockError if the internal lock cannot be acquired.

§Examples
let store = TypeStore::new();

// Lazily construct a value
store.set_with(|| {
    vec![1, 2, 3, 4, 5]
})?;

store.with::<Vec<i32>, _, _>(|v| {
    assert_eq!(v.len(), 5);
})?;
Source

pub fn get<V>(&self) -> Result<V, MapError>
where V: 'static + Clone,

Retrieves a clone of a value by its type.

§Errors
  • Returns MapError::LockError if the internal lock cannot be acquired
  • Returns MapError::KeyNotFound if no value of this type exists
§Examples
let store = TypeStore::new();
store.set(42i32)?;

let value = store.get::<i32>()?;
assert_eq!(value, 42);

// Type not found
match store.get::<String>() {
    Err(MapError::KeyNotFound(type_name)) => {
        println!("No value of type: {}", type_name);
    }
    _ => {}
}
Source

pub fn with<V: 'static, F, R>(&self, f: F) -> Result<R, MapError>
where F: FnOnce(&V) -> R,

Accesses a value by type with a read-only closure.

§Errors
  • Returns MapError::LockError if the internal lock cannot be acquired
  • Returns MapError::KeyNotFound if no value of this type exists
§Examples
let store = TypeStore::new();
store.set(vec![1, 2, 3, 4, 5])?;

let sum = store.with::<Vec<i32>, _, _>(|numbers| {
    numbers.iter().sum::<i32>()
})?;
assert_eq!(sum, 15);
Source

pub fn with_mut<V: 'static, F, R>(&self, f: F) -> Result<R, MapError>
where F: FnOnce(&mut V) -> R,

Accesses a value by type with a read-write closure.

§Errors
  • Returns MapError::LockError if the internal lock cannot be acquired
  • Returns MapError::KeyNotFound if no value of this type exists
§Examples
let store = TypeStore::new();
store.set(vec![1, 2, 3])?;

store.with_mut::<Vec<i32>, _, _>(|numbers| {
    numbers.push(4);
    numbers.push(5);
})?;

let len = store.with::<Vec<i32>, _, _>(|v| v.len())?;
assert_eq!(len, 5);
Source

pub fn remove<V: 'static>(&self) -> Result<bool, MapError>

Removes a value by its type.

§Errors

Returns MapError::LockError if the internal lock cannot be acquired.

§Returns

Returns Ok(true) if a value was removed, Ok(false) if no value of that type existed.

§Examples
let store = TypeStore::new();
store.set(42i32)?;

assert!(store.remove::<i32>()?);
assert!(!store.remove::<i32>()?); // Already removed
Source

pub fn contains<V: 'static>(&self) -> Result<bool, MapError>

Checks if a value of the given type exists.

§Errors

Returns MapError::LockError if the internal lock cannot be acquired.

§Examples
let store = TypeStore::new();

assert!(!store.contains::<i32>()?);
store.set(42i32)?;
assert!(store.contains::<i32>()?);
Source

pub fn len(&self) -> Result<usize, MapError>

Gets the number of values in the store.

§Errors

Returns MapError::LockError if the internal lock cannot be acquired.

§Examples
let store = TypeStore::new();
assert_eq!(store.len()?, 0);

store.set(42i32)?;
store.set("hello".to_string())?;
assert_eq!(store.len()?, 2);
Source

pub fn is_empty(&self) -> Result<bool, MapError>

Checks if the store is empty.

§Errors

Returns MapError::LockError if the internal lock cannot be acquired.

§Examples
let store = TypeStore::new();
assert!(store.is_empty()?);

store.set(42i32)?;
assert!(!store.is_empty()?);

Trait Implementations§

Source§

impl Clone for TypeStore

Source§

fn clone(&self) -> TypeStore

Returns a duplicate of the value. Read more
1.0.0§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TypeStore

Source§

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

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

impl Default for TypeStore

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneAny for T
where T: Clone + Any + Send + Sync,

Source§

fn clone_any(&self) -> Box<dyn CloneAny>

Clone this value into a boxed trait object.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Get a reference to the underlying Any.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Get a mutable reference to the underlying Any.
§

impl<T> CloneToUninit for T
where T: Clone,

§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

fn into(self) -> U

Calls U::from(self).

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

§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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.
§

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

Performs the conversion.