Crate hv_alchemy[][src]

Expand description

Heavy Alchemy - The black arts of transmutation, wrapped for your safe usage and enjoyment.

Functionality for dynamically examining and manipulating dyn Trait objects. This is done mainly through TypeTable, which is a bit like a superpowered TypeId that also allows you to ask whether the type it pertains to implements some object safe trait. If you can write it as a dyn Trait, then you can try to get a DynVtable corresponding to that trait’s implementation for the type the TypeTable corresponds to.

A few basic relationships:

  • TypeTable => one per type, potentially many DynVtables per TypeTable
    • A single TypeTable provides all the information necessary to dynamically allocate, deallocate, drop, and manipulate the type it corresponds to.
  • Type => just a wrapper around TypeTable that adds the type, for use in dynamically dispatching over Type<T>. Useful for when you want to represent the type of an object in a way that can be Box<dyn Any> or Box<dyn AlchemicalAny>’d.
  • DynVtable => at most one per pair of types (object-safe trait dyn type, implementor type.) Contains the necessary metadata to reconstruct a *const or *mut dyn Trait for the object-safe trait type it pertains to, pointing to the implementor type it pertains to.

Non-object-safe traits can also be represented using this crate, but they have to be done through blanket-impl’d object-safe traits. For a couple of builtin examples, the Clone trait is represented through CloneProxy, and the Copy trait is represented through CopyProxy. Although you cannot directly see a type as Clone or Copy through its DynVtable, you can still do equivalent things (and make use of the consequences of a type being Clone or Copy.) Also see try_clone and try_copy.

Traits

Several traits are used to safely represent the transmutations used inside this crate. The two most important ones, which govern whether or not a type can be seen as a dyn Trait for some Trait, are Alchemy and Alchemical. The Alchemy trait represents a dyn Trait type/an object-safe trait, while Alchemical<U> is blanket-implemented for all types which implement and can be converted to dyn objects of some trait U (which is a dyn Trait type.)

There are also a handful of other convenient traits included:

Caveats

In order for an TypeTable to be useful with respect to some object-safe trait U implemented for some type T, that trait’s impl for T has to be registered with the global static registry, which is initialized at program runtime. There are a number of ways to do this, but the most convenient is Type::add (and also the related mark_copy and mark_clone) traits. It’s always a good idea to add the copy/clone markings and also dyn Send and dyn Sync if they can be applied! Note that it is impossible to add a trait which is unimplemented by T, so you don’t have to worry about causing unsafety or anything with such. This library should (unless some soundness bug has escaped my notice) be completely safe as long as it is kept to its safe API.

Structs

A type-erased pointer which knows about some set of vtables belonging to the type of the object it points to.

A vtable for some type T’s implementation of some object-safe trait U.

A statically-typed wrapper around an TypeTable which corresponds to the parameter type T. Most of the time you’ll want to use this when interfacing w/ TypeTables, because it lets you call almost every method on TypeTable without having to specify T every time.

A table of information about a type, effectively acting as a superpowered TypeId.

Traits

An auto-implemented marker trait indicating that a type is a subtype of/is convertible to some type U. In most cases, this means that Self implements some Trait such that U is dyn Trait and a reference to Self can be converted to a reference to dyn Trait/U.

A superpowered version of Any which provides a TypeTable rather than a TypeId.

An object-unsafe extension trait which provides

An auto-implemented marker trait indicating that a type is a trait object type.

An object-safe clone trait. Useful to have around as a marker for when a type is Clone, and for easily/efficiently performing the clone.

An object-safe copy trait. Useful to have around as a marker for when a type is Copy, and for easily/efficiently performing the copy.

An object-safe From trait (Self from T), for converting some T into a dynamically-known type for which you only have its TypeTable.

An object-safe Into trait (Self into T), for converting some dynamic Self type into a statically-known type.

An object-safe trait which contains a method that will only be called if its T: Clone bound can be proven for the argument type T.

An object-safe trait which contains a method that will only be called if its T: Copy bound can be proven for the argument type T.

An object-safe trait which contains a method that will only be called if its T: Send bound can be proven for the argument type T.

An object-safe trait which contains a method that will only be called if its T: Sync bound can be proven for the argument type T.

Functions

Returns true if the values were moved.

Convenience function for marking some T as being convertible into some U.

Returns true if the values were moved.

Convenience function for getting the Type for some T.