Expand description
Seventy is a simple newtype sanitizer and validator.
The seventy
procedural macro is provided to automatically
implement sanitization, validation, and other logic.
§Sanitizing
Sanitization mutates a target. Sanitization is run before validation.
§Examples
The example below sanitizes the inner string by trimming surrounding whitespace.
use seventy::{builtins::string::*, seventy, Newtype};
#[seventy(sanitize(trim))]
pub struct Username(String);
assert_eq!(
Username::try_new(" username ").unwrap().into_inner(),
"username"
);
§Built-in Sanitizers
Seventy provides built-in sanitizers
for common use cases.
§Custom Sanitizers
Custom sanitizers can be defined with the Sanitizer
trait.
The sanitizer below divides the target by the given value.
use std::ops::DivAssign;
use seventy::{core::Sanitizer, seventy, Newtype};
#[allow(non_snake_case)]
pub struct divide_by<T>(pub T);
impl<T> Sanitizer<T> for divide_by<T>
where
T: DivAssign<T> + Copy,
{
fn sanitize(&self, target: &mut T) {
target.div_assign(self.0);
}
}
#[seventy(sanitize(divide_by(5.0)))]
pub struct DivideBy(f32);
assert_eq!(DivideBy::try_new(10.0).unwrap().into_inner(), 2.0);
§Validating
Validation checks if a target adheres to a set of rules. Validation is run after sanitization.
§Examples
The example below validates the inner string is alphanumeric.
use seventy::{builtins::string::*, seventy, Newtype};
#[seventy(validate(alphanumeric))]
pub struct Username(String);
assert!(Username::try_new("username").is_ok());
assert!(Username::try_new("u$ername").is_err());
§Built-in Validators
Seventy provides built-in validators
for common use cases.
§Custom Validators
Custom validators can be defined with the Validator
trait.
The validator below checks if the target is even.
use seventy::{core::Validator, seventy, Newtype};
#[allow(non_snake_case)]
pub struct even_i64;
impl Validator<i64> for even_i64 {
fn validate(&self, target: &i64) -> bool {
target.abs() % 2 == 0
}
}
#[seventy(validate(even_i64))]
pub struct EvenI64(i64);
assert!(EvenI64::try_new(2).is_ok());
assert!(EvenI64::try_new(3).is_err());
§Errors?
Seventy does not support error handling. A validator only returns a boolean indicating whether the validation result is valid or invalid. If you need to know the specific reason why a newtype couldn’t be created, Seventy is not the crate for you.
§Forwarding
Some sanitizers and validators can be nested inside each other! The outer sanitizer or validator will then forward some value to the inner.
The length
validator below forwards the character length of the string
to the inner gt
validator, which will validate that the length is
greater than 5.
use seventy::{
builtins::{compare::*, string::*},
seventy, Newtype,
};
#[seventy(validate(length::chars(gt(5))))]
pub struct Username(String);
assert!(Username::try_new("username").is_ok());
assert!(Username::try_new("user").is_err());
§Upgrading
Upgrades automatically implement useful functionality. More about upgrades
and the different types of upgrades can be found in the documentation
for the seventy
procedural macro.
§Examples
The example below uses the deref
upgrade, which implements Deref
on
the newtype.
use seventy::{builtins::string::*, seventy, Newtype};
#[seventy(upgrades(deref))]
pub struct Username(String);
let username = Username::try_new("username").unwrap();
assert_eq!(*username, "username");
§Incorporating it all
§Examples
The example below first trims the target and then validates if the trimmed target is alphanumeric.
use seventy::{builtins::string::*, seventy, Newtype};
#[seventy(upgrades(deref), sanitize(trim), validate(alphanumeric))]
pub struct Username(String);
let username = Username::try_new(" username ").unwrap();
assert_eq!(*username, "username");
assert!(Username::try_new(" u$ername ").is_err());
Re-exports§
pub use core::Newtype;
Modules§
Attribute Macros§
- seventy
- Newtype attribute.