Macro oysterpack_macros::op_newtype
source · macro_rules! op_newtype {
(
$(#[$outer:meta])*
$Name:ident($T:ty)
) => { ... };
(
$(#[$outer:meta])*
pub $Name:ident($T:ty)
) => { ... };
(
$(#[$outer:meta])*
pub $Name:ident(pub $T:ty)
) => { ... };
(
$(#[$outer:meta])*
($($struct_vis:tt)*) $Name:ident(($($field_vis:tt)*) $T:ty)
) => { ... };
}
Expand description
Defines a new type for the specified type.
- visibility can be specified for the new type and the underlying field
- provides a public constructor function named :
pub fn new(value: $T) -> Self
- implements the following traits
- Debug
- From<T> - where T = underlying type
- Deref, where Target = underlying type
- metadata attributes can be specified on the new type
Examples
#[macro_use]
extern crate oysterpack_macros;
extern crate serde;
#[macro_use]
extern crate serde_derive;
pub mod foo {
op_newtype! {
/// A is private
A(u128)
}
op_newtype! {
/// B is public
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub B(u128)
}
op_newtype! {
/// C and the underlying value are public
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub C(pub u128)
}
}
// will not compile because foo::A is private
// let _ = foo::A::new(1);
// the `new` function constructor is provided
let b1 = foo::B::new(1);
// From trait is implemented
let _ = foo::B::from(1);
let b2: foo::B = 1.into();
// this works because PartialEq was derived for the foo::B
assert_eq!(b1,b2);
// foo::C can be declared as consts because its underlying field is also public
const C_1 : foo::C = foo::C(1);
const C_2 : foo::C = foo::C(2);
// this works because Deref is implemented and foo::C and foo::B both have the same underlying type
assert_eq!(*C_1,*b1);
assert!(C_1 < C_2);