Expand description

The main feature of this crate is the macro new! which can be used to generate special unique and anonymous types. In other words those are types that cannot be named and that are guardanteed to always be different from every other type.

The Unique trait can be used in trait bounds for requiring a type to be generated from the new! macro.

Those types can then be used to “tag” other types to make them uniquely identifiable.

Tagging

To require a type to be uniquely identifiable simply add a generic with the Unique trait bound:

struct Struct<Tag: unique_type::Unique> {
    // other fields ...
    _marker: PhantomData<Tag>,
}

Then when a value of that type is used, the new! macro can be used to declare the unique type for that value:

let value = Struct::<unique_type::new!()>::new(/* ... */);

Identifying

Requiring two (or more) parameters/fields to have the same tag is as easy as using the same generic for both of them:

fn foo<Tag: unique_type::Unique>(a: Struct<Tag>, b: Struct<Tag>) {
    todo!()
}

Now calling this function with two values that don’t have the same tag will result in a compiler error:

let a: Struct<unique_type::new!()> = todo!();
let b: Struct<unique_type::new!()> = todo!();
// a and b now have two different tags
foo(a, b)

Macros

Generates a unique type that implements the Unique trait

Traits

An interface for reqiring unique types