Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an example with generics in README and lib.rs doc #159

Merged
merged 1 commit into from
Jul 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 20 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Nutype is a proc macro that allows adding extra constraints like _sanitization_


* [Quick start](#quick-start)
* [Inner types](#inner-types) ([String](#string) | [Integer](#integer) | [Float](#float) | [Other](#other-inner-types))
* [Inner types](#inner-types) ([String](#string) | [Integer](#integer) | [Float](#float) | [Other](#other-inner-types-and-generics))
* [Custom](#custom-sanitizers) ([sanitizers](#custom-sanitizers) | [validators](#custom-validators))
* [Recipes](#recipes)
* [Breaking constraints with new_unchecked](#breaking-constraints-with-new_unchecked)
Expand Down Expand Up @@ -212,55 +212,42 @@ This can be done applying by `finite` validation. For example:
struct Size(f64);
```

## Other inner types
## Other inner types and generics

For any other type it is possible to define custom sanitizers with `with` and custom
validations with `predicate`:

```rs
```rust
use nutype::nutype;

#[nutype(
derive(Debug, PartialEq, Deref, AsRef),
derive(Debug, PartialEq, AsRef, Deref),
sanitize(with = |mut guests| { guests.sort(); guests }),
validate(predicate = |guests| !guests.is_empty() ),
)]
pub struct GuestList(Vec<String>);
```

// Empty list is not allowed
assert_eq!(
GuestList::try_new(vec![]),
Err(GuestListError::PredicateViolated)
);
It's also possible to use generics:

// Create the list of our guests
let guest_list = GuestList::try_new(vec![
"Seneca".to_string(),
"Marcus Aurelius".to_string(),
"Socrates".to_string(),
"Epictetus".to_string(),
]).unwrap();
```rust
#[nutype(
sanitize(with = |mut v| { v.sort(); v }),
validate(predicate = |vec| !vec.is_empty()),
derive(Debug, PartialEq, AsRef, Deref),
)]
struct SortedNotEmptyVec<T: Ord>(Vec<T>);

// The list is sorted (thanks to sanitize)
assert_eq!(
guest_list.as_ref(),
&[
"Epictetus".to_string(),
"Marcus Aurelius".to_string(),
"Seneca".to_string(),
"Socrates".to_string(),
]
);
let wise_friends = SortedNotEmptyVec::try_new(vec!["Seneca", "Zeno", "Plato"]).unwrap();
assert_eq!(wise_friends.as_ref(), &["Plato", "Seneca", "Zeno"]);
assert_eq!(wise_friends.len(), 3);

// Since GuestList derives Deref, we can use methods from `Vec<T>`
// due to deref coercion (if it's a good idea or not, it's left up to you to decide!).
assert_eq!(guest_list.len(), 4);
let numbers = SortedNotEmptyVec::try_new(vec![4, 2, 7, 1]).unwrap();
assert_eq!(numbers.as_ref(), &[1, 2, 4, 7]);
assert_eq!(numbers.len(), 4);
```

for guest in guest_list.iter() {
println!("{guest}");
}

```

## Custom sanitizers

Expand Down
15 changes: 6 additions & 9 deletions dummy/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@ fn main() {
Err(SortedNotEmptyVecError::PredicateViolated)
);

let wise_friends =
SortedNotEmptyVec::try_new(vec!["Seneca", "Zeno", "Socrates", "Epictetus", "Plato"])
.unwrap();
let wise_friends = SortedNotEmptyVec::try_new(vec!["Seneca", "Zeno", "Plato"]).unwrap();
assert_eq!(wise_friends.as_ref(), &["Plato", "Seneca", "Zeno"]);
assert_eq!(wise_friends.len(), 3);

assert_eq!(
wise_friends.as_ref(),
&["Epictetus", "Plato", "Seneca", "Socrates", "Zeno"]
);

assert_eq!(wise_friends.len(), 5);
let numbers = SortedNotEmptyVec::try_new(vec![4, 2, 7, 1]).unwrap();
assert_eq!(numbers.as_ref(), &[1, 2, 4, 7]);
assert_eq!(numbers.len(), 4);
}
48 changes: 18 additions & 30 deletions nutype/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
//! struct Size(f64);
//! ```
//!
//! ## Other inner types
//! ## Other inner types and generics
//!
//! For any other type it is possible to define custom sanitizers with `with` and custom
//! validations with `predicate`:
Expand All @@ -252,45 +252,33 @@
//! use nutype::nutype;
//!
//! #[nutype(
//! derive(Debug, PartialEq, Deref, AsRef),
//! derive(Debug, PartialEq, AsRef, Deref),
//! sanitize(with = |mut guests| { guests.sort(); guests }),
//! validate(predicate = |guests| !guests.is_empty() ),
//! )]
//! pub struct GuestList(Vec<String>);
//!
//! // Empty list is not allowed
//! assert_eq!(
//! GuestList::try_new(vec![]),
//! Err(GuestListError::PredicateViolated)
//! );
//! ```
//!
//! // Create the list of our guests
//! let guest_list = GuestList::try_new(vec![
//! "Seneca".to_string(),
//! "Marcus Aurelius".to_string(),
//! "Socrates".to_string(),
//! "Epictetus".to_string(),
//! ]).unwrap();
//! It's also possible to use generics:
//!
//! // The list is sorted (thanks to sanitize)
//! assert_eq!(
//! guest_list.as_ref(),
//! &[
//! "Epictetus".to_string(),
//! "Marcus Aurelius".to_string(),
//! "Seneca".to_string(),
//! "Socrates".to_string(),
//! ]
//! );
//! ```
//! use nutype::nutype;
//!
//! // Since GuestList derives Deref, we can use methods from `Vec<T>`
//! // due to deref coercion (if it's a good idea or not, it's left up to you to decide!).
//! assert_eq!(guest_list.len(), 4);
//! #[nutype(
//! sanitize(with = |mut v| { v.sort(); v }),
//! validate(predicate = |vec| !vec.is_empty()),
//! derive(Debug, PartialEq, AsRef, Deref),
//! )]
//! struct SortedNotEmptyVec<T: Ord>(Vec<T>);
//!
//! for guest in guest_list.iter() {
//! println!("{guest}");
//! }
//! let wise_friends = SortedNotEmptyVec::try_new(vec!["Seneca", "Zeno", "Plato"]).unwrap();
//! assert_eq!(wise_friends.as_ref(), &["Plato", "Seneca", "Zeno"]);
//! assert_eq!(wise_friends.len(), 3);
//!
//! let numbers = SortedNotEmptyVec::try_new(vec![4, 2, 7, 1]).unwrap();
//! assert_eq!(numbers.as_ref(), &[1, 2, 4, 7]);
//! assert_eq!(numbers.len(), 4);
//! ```
//!
//! ## Custom sanitizers
Expand Down
Loading