4 releases
Uses new Rust 2024
| 0.1.3 | Jun 29, 2025 |
|---|---|
| 0.1.2 | Jun 29, 2025 |
| 0.1.1 | Jun 29, 2025 |
| 0.1.0 | Jun 29, 2025 |
#2655 in Rust patterns
25KB
286 lines
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()
}
}
Dependencies
~120–495KB
~12K SLoC