wiwi::nominal

Macro nominal_mod

Source
macro_rules! nominal_mod {
    {
		$(
			$mod_vis:vis mod $mod_name:ident {
				$( nominal!($item_vis:vis $name:ident, wraps: $( ref <$($lifetimes:lifetime),+> )? $type:ty); )*
			}
		)*
	} => { ... };
}
Expand description

Declare many new nominal types (aliases), in a module

Usage is more or less identical to nominal, but you define a module inside the macro invocation. Because this macro creates a new module (with the name you specify), and the created module is only used for defining these nominal types, there can be nothing else in there, which we take advantage of to create a marker submodule to define marker types in. This way it can have a new namespace just for the marker types, so reusing the newtype name won’t collide with anything else.

So, all of that is to say this macro also saves you a bit of boilerplate declaring names for the newtype ZSTs.

§Examples

nominal_mod! {
   pub mod nominal {
      nominal!(pub NewType, wraps: String);
   }
}

let item = nominal::NewType::new(String::new());

Still creating newtypes as expected:

nominal_mod! {
   pub mod nominal {
      nominal!(pub NewType, wraps: String);
      nominal!(pub AnotherNewType, wraps: String);
   }
}

let item: nominal::NewType = nominal::NewType::new(String::new());
// this won't compile
let another_item: nominal::NewType = nominal::AnotherNewType::new(String::new());

Still “just” a type alias:


let item: nominal::NewType = Nominal::new(String::new());

Created marker structs are in a marker submodule:


let item: Nominal<String, nominal::marker::NewType> = nominal::NewType::new(String::new());
let item: Nominal<String, nominal::marker::AnotherNewType> = nominal::AnotherNewType::new(String::new());