zonbi

Type-Erase tools for non-'static types

5 unstable releases

0.3.2 May 9, 2024
0.3.1 May 9, 2024
0.3.0 May 9, 2024
0.2.0 May 7, 2024
0.1.0 May 4, 2024
Download history 60/week @ 2024-07-29 8/week @ 2024-09-23 3/week @ 2024-09-30

119 downloads per month

MIT/Apache

11KB
90 lines

Zonbi

This is an experiment to make it possible to type-erase non-'static types.

How it works

With #[derive(Zonbi)], the type gets an implementation for getting a version of the type where all lifetimes are replaced with the given one. Manual implementation is unsafe because the user must assure that the Casted type is the same as the one of the implementer.

This is used in ZonbiId, a wrapper around TypeId, which different from its inside value, has the additional definition of behaviour for non-'static types. ZonbiId is unique for every type, excluding its lifetimes. Under the hood, it just uses the Zonbi trait to get the 'static version of the type and gets its TypeId.

To hold such type-erased value inside for example a box, you can create a Cage<'life, Z> of the zonbi Z and then hold that in a dyn AnyZonbi<'life> with the associated minimal lifetime. Every zonbi that lives for at least 'life can be upcasted into this trait and downcasted back into it with all the lifetimes being this mininal 'life one.

Example

use zonbi::*;

#[derive(Zonbi)]
struct MyStruct<'a> {
    val: &'a NonCopyI32,
}

type_map(&NonCopyI32(42));

fn type_map<'a>(a: &'a NonCopyI32) {
    let my_struct = MyStruct { val: a };

    let mut type_map: HashMap<ZonbiId, Box<dyn AnyZonbi<'a>>> = HashMap::new();
    let id = ZonbiId::of::<MyStruct>();

    type_map.insert(id, Box::new(Cage::new(my_struct)));

    let r: &MyStruct<'a> = type_map[&id].downcast_ref::<MyStruct<'a>>().unwrap();
    assert_eq!(r.val, &NonCopyI32(42));
}

This is a broken down snippet of the type_map example.

License

Dual-licensed under Apache-2.0 and MIT

Dependencies

~235–680KB
~16K SLoC