An open API service indexing awesome lists of open source software.

https://github.com/schell/broomdog

๐Ÿงน๐Ÿ• Rust library providing a map of type-erased values with indefinite loanership semantics
https://github.com/schell/broomdog

Last synced: about 2 months ago
JSON representation

๐Ÿงน๐Ÿ• Rust library providing a map of type-erased values with indefinite loanership semantics

Awesome Lists containing this project

README

        

# broomdog ๐Ÿงน๐Ÿ•

`broomdog` is a Rust library providing a map of type-erased values with indefinite loanership semantics.

## what is a type map?

`broomdog`'s type map is a map of `std::any::TypeId` keys to type-erased values.
There may be at most one value for each key, which means the map stores singleton values of different types.

## why another type map library?

`broomdog` provides the usual map-like API, and then some.
Notably `broomdog` provides "indefinite loanership".

### wtf is indefinite loanership?

It's a wordsmush that roughly means you can borrow a value from the map without
a lifetime.

#### wtf is a loaned value?

A loaned value is a smart pointer to a value that you can `deref` or `deref_mut`.

You may only have one exclusive (write) loan of any one type at a time, but you may have as many non-exclusive (read) loans of the same type as you like. You may also have **multiple exclusive loans of _different_ types at the same time**.

After an exclusive loan is dropped you may make another exclusive loan of the same type, or multiple non-exclusive loans of that type.

This allows you to make multiple loans of different types at the same time, without map borrow conflicts - so long as you don't try to share an exclusive loan of the same type at the same time.

Furthermore, `broomdog` has nice descriptive errors with the names of the types (more even, if compiled with `debug_assertions`).

## uses

Type erased maps have many uses, but `broomdog` was built to facilitate the following:

* singleton resource storage layer for [`apecs`](https://github.com/schell/apecs)'s system schedule runner (`apecs` is an ECS library)
* singleton resource storage layer for [`renderling`](https://github.com/schell/renderling)'s render node schedule runner (part of the render graph)

It works particularly well with [`dagga`](https://github.com/schell/dagga), which is a DAG scheduler. In fact, `dagga` and `broomdog` are joined in [`moongraph`](https://github.com/schell/moongraph) with some nice helpers to form a DAG scheduling, resource management and execution library.

Together it's possible to define and run an extensible system of functions that share mutable resources, some of which may run in parallel.

## why (the heck) did you name it `broomdog`

* "broomdog" is the name of the part broom / part dog character in Alice in Wonderland that erases the path as it walks along it.

* I think names should be funny.

* It's my library, oh well ๐Ÿ˜.

# example

```rust
use broomdog::{TypeMap, TypeKey};

let mut map = TypeMap::default();
assert!(map.insert_value(0usize).unwrap().is_none());
assert!(map.insert_value(0.0f32).unwrap().is_none());
assert!(map.insert_value("hello").unwrap().is_none());

{
let num_usize = map.get_value_mut::().unwrap().unwrap();
*num_usize += 666;
}
assert_eq!(666, *map.get_value::().unwrap().unwrap());
assert_eq!("hello", *map.get_value::<&str>().unwrap().unwrap());

{
let loan = map.loan(TypeKey::new::()).unwrap().unwrap();
assert_eq!(666, *loan.downcast_ref::().unwrap());
let loan2 = map.loan(TypeKey::new::()).unwrap().unwrap();
assert_eq!(666, *loan2.downcast_ref::().unwrap());

let mut loan_mut = map.loan_mut(TypeKey::new::<&str>()).unwrap().unwrap();
let word = loan_mut.downcast_mut::<&str>().unwrap();
assert_eq!("hello", *word);
*word = "goodbye";
}

map.unify().unwrap();
```