nutype_test_util 0.1.3

Ergonomically create newtypes in tests
Documentation

nutype_test_util

nutype crate allows you to create newtypes in an ergonomic way. However, using these newtypes in tests leads to a lot of boilerplate:

// in `#[cfg(test)]`
Remote {
    repo: Repo::try_new("helix-editor/helix").unwrap(),
    pr_number: PrNumber::new(NonZeroU32::new(15).unwrap()),
    commit: Some(Commit::try_new("1a2b3c4d").unwrap()),
}

Tests should be low-effort to write and you should not be punished this hard for wanting more type safety in your code.

This crate provides a proc macro#[nutype_test_util::derive(From)] which generates From impls for your newtypes. It makes the test syntax much easier to type:

// in `#[cfg(test)]`
Remote {
    repo: "helix-editor/helix".into(),
    pr_number: 15.into(),
    commit: Some("1a2b3c4d".into()),
}

You use it like this:

#[nutype_test_util::derive(From)]
#[nutype(validate(non_empty))]
struct Repo(String);

#[nutype_test_util::derive(From)]
#[nutype]
struct PrNumber(NonZeroU32);

#[nutype_test_util::derive(From)]
#[nutype(validate(non_empty, predicate = is_valid_commit_hash))]
struct Commit(String)

The above generates code like this:

#[cfg(test)]
impl<T: Into<String>> ::core::convert::From<T> for Repo {
    fn from(value: T) -> Self {
        let value: String = value.into();
        Self::try_new(value).unwrap()
    }
}

#[cfg(test)]
impl<T: Into<u32>> ::core::convert::From<T> for PrNumber {
    fn from(value: T) -> Self {
        let value: u32 = value.into();
        Self::new(::core::num::NonZeroU32::new(value).unwrap())
    }
}

#[cfg(test)]
impl<T: Into<String>> ::core::convert::From<T> for Commit {
    fn from(value: T) -> Self {
        let value: String = value.into();
        Self::try_new(value).unwrap()
    }
}