Macro new_type_derive::new_type_pair[][src]

macro_rules! new_type_pair {
    (   $(#[$ometa:meta])*
        pub struct $otype:ident($itype:ty);

        $(#[$rmeta:meta])*
        pub struct $rtype:ident($stype:ty);
    ) => { ... };
}

Creates a wrapper new type around a chosen owned type, along with a matching reference type. The reference type must implement NewTypeRef.

In order to add additional implementation for both types, add an impl block for the reference type after the macro invocation.

This macro can currently only build new types on str string slices.

Example

use new_type_derive::NewTypeRef;

new_type_pair! {
   #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
   /// Add your type documentation here
   pub struct MyNewType(String);

   #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
   /// And add similar documentation for the reference type
   pub struct MyNewTypeRef(str);
}

impl NewTypeRef for MyNewTypeRef {
    type Owned = MyNewType;
    type InnerRef = str;
    type ValidationError = String;

    fn validate(value: &Self::InnerRef) -> Result<(), Self::ValidationError> {
        if value.is_empty() {
            return Err(String::from("Bad string"));
        }
        Ok(())
    }

    fn to_owned(&self) -> Self::Owned {
        let inner = self.inner.into();
        MyNewType { inner }
    }
}

impl MyNewTypeRef {
    pub fn len(&self) -> usize {
        self.inner.len()
    }
}

assert!(MyNewTypeRef::try_as_ref("").is_err());
assert!(MyNewType::try_from("Test").is_ok());
assert_eq!(
    MyNewType::try_from("X").unwrap(),
    MyNewTypeRef::try_as_ref("X").unwrap(),
);
assert_eq!(
    MyNewType::try_from("X").unwrap(),
    MyNewType::from(MyNewTypeRef::try_as_ref("X").unwrap()),
);
assert_eq!("X", MyNewType::try_from("X").unwrap(),);
assert_eq!(1, MyNewType::try_from("X").unwrap().as_ref().len(),);