Skip to content

Commit

Permalink
Add an example with a newtype with generics
Browse files Browse the repository at this point in the history
  • Loading branch information
greyblake committed May 31, 2024
1 parent 6d5e676 commit fbfb7e8
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### v0.x.x - 2024-xx-xx

* Support newtypes with generics


### v0.4.2 - 2024-04-07

* Support `no_std` ( the dependency needs to be declared as `nutype = { default-features = false }` )
Expand Down
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ members = [
"examples/serde_complex",
"examples/string_bounded_len",
"examples/string_regex_email",
"examples/string_arbitrary",
"examples/string_arbitrary", "examples/any_generics",
]
9 changes: 9 additions & 0 deletions examples/any_generics/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "any_generics"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
nutype = { path = "../../nutype" }
30 changes: 30 additions & 0 deletions examples/any_generics/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use nutype::nutype;
use std::borrow::Cow;

#[nutype(
validate(predicate = |vec| !vec.is_empty()),
derive(Debug),
)]
struct NotEmpty<T>(Vec<T>);

#[nutype(

Check failure on line 10 in examples/any_generics/src/main.rs

View workflow job for this annotation

GitHub Actions / Clippy

using a reference to `Cow` is not recommended
derive(Debug),
validate(predicate = |s| s.len() > 3),
)]
struct Clarabelle<'b>(Cow<'b, str>);

fn main() {
{
let v = NotEmpty::new(vec![1, 2, 3]).unwrap();
assert_eq!(v.into_inner(), vec![1, 2, 3]);
}
{
let err = NotEmpty::<i32>::new(vec![]).unwrap_err();
assert_eq!(err, NotEmptyError::PredicateViolated);
}

{
let c1 = Clarabelle::new(Cow::Borrowed("Muu")).unwrap();
assert_eq!(c1.into_inner(), Cow::Borrowed("Muu"));
}
}
101 changes: 101 additions & 0 deletions test_suite/tests/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,3 +382,104 @@ mod new_unchecked {
assert_eq!(line_point.into_inner(), Point::new(3, 4));
}
}

#[cfg(test)]
mod with_generics {
use super::*;

#[test]
fn test_generic_with_validate() {
#[nutype(
validate(predicate = |v| !v.is_empty()),
derive(Debug)
)]
struct NonEmptyVec<T>(Vec<T>);

{
let vec = NonEmptyVec::new(vec![1, 2, 3]).unwrap();
assert_eq!(vec.into_inner(), vec![1, 2, 3]);
}

{
let vec = NonEmptyVec::new(vec![5]).unwrap();
assert_eq!(vec.into_inner(), vec![5]);
}

{
let vec: Vec<u8> = vec![];
let err = NonEmptyVec::new(vec).unwrap_err();
assert_eq!(err, NonEmptyVecError::PredicateViolated);
}
}

#[test]
fn test_generic_with_sanitize() {
#[nutype(
sanitize(with = |mut v| { v.truncate(2); v }),
derive(Debug)
)]
struct UpToTwo<T>(Vec<T>);

{
let vec = UpToTwo::new(vec![1, 2, 3]);
assert_eq!(vec.into_inner(), vec![1, 2]);
}

{
let vec = UpToTwo::new(vec![5]);
assert_eq!(vec.into_inner(), vec![5]);
}
}

#[test]
fn test_generic_with_sanitize_and_validate() {
#[nutype(
sanitize(with = |mut v| { v.truncate(2); v }),
validate(predicate = |v| !v.is_empty()),
derive(Debug)
)]
struct OneOrTwo<T>(Vec<T>);

{
let vec = OneOrTwo::new(vec![1, 2, 3]).unwrap();
assert_eq!(vec.into_inner(), vec![1, 2]);
}

{
let vec = OneOrTwo::new(vec![5]).unwrap();
assert_eq!(vec.into_inner(), vec![5]);
}

{
let vec: Vec<u8> = vec![];
let err = OneOrTwo::new(vec).unwrap_err();
assert_eq!(err, OneOrTwoError::PredicateViolated);
}
}

// TODO
// #[test]
// fn test_generic_with_boundaries_and_sanitize() {
// #[nutype(
// sanitize(with = |v| { v.sort(); v }),
// derive(Debug)
// )]
// struct SortedVec<T: Ord>(Vec<T>);

// {
// let vec = NonEmptyVec::new(vec![1, 2, 3]).unwrap();
// assert_eq!(vec.into_inner(), vec![1, 2, 3]);
// }

// {
// let vec = NonEmptyVec::new(vec![5]).unwrap();
// assert_eq!(vec.into_inner(), vec![5]);
// }

// {
// let vec: Vec<u8> = vec![];
// let err = NonEmptyVec::new(vec).unwrap_err();
// assert_eq!(err, NonEmptyVecError::PredicateViolated);
// }
// }
}

0 comments on commit fbfb7e8

Please sign in to comment.