macro_rules! handle_type {
    ( $(#[$attrs:meta])* $v:vis $name:ident: 64 ; $($rest:tt)* ) => { ... };
    ( $(#[$attrs:meta])* $v:vis $name:ident: $n:literal / 32 ; $($rest:tt)* ) => { ... };
    () => { ... };
}
Expand description

Generates one or more new types implementing Handle.

This can help in avoiding use of the wrong handle with an object pool.

This macro takes a semicolon-separated list, where each entry must match one of two formats:

  • ($meta)* ($vis)? $name: 64 generates a handle type that is identical to DefaultHandle, with 32 bits each for the index and generation.
  • ($meta)* ($vis)? $name: $i / 32 generates a 32-bit handle with $i bits used for the index, and the remainder used for the generation count.

($meta)* stands for any number of attributes, including doc comments, and ($vis)? is an optional visibility specifier (i.e. pub or pub(crate)).

Examples

use coca::{handle_type, collections::pool::Handle};
handle_type! {
    A: 12 / 32;
    /// Documentation for `B` goes here.
    pub B: 16 / 32;
    D: 64;
}

assert_eq!(A::MAX_INDEX, 4095);
assert_eq!(A::MAX_GENERATION, 1_048_575);

assert_eq!(B::MAX_INDEX, 65535);
assert_eq!(B::MAX_GENERATION, 65535);

assert_eq!(D::MAX_INDEX, 4_294_967_295);
assert_eq!(D::MAX_GENERATION, 4_294_967_295);

Note that the maximum number of bits you can reserve for the index is 16. This is enforced with a static assertion:

handle_type!{ C: 20 / 32; } // attempt to compute `0_usize - 1_usize`, which would overflow