Giter Club home page Giter Club logo

valitron's Introduction

Valitron is an ergonomic, functional and configurable validator

In the future, modularization will be supported

Inspired by axum

Features

  • Ergonomics validation
  • Build-in rule, e.g. Required, StartWith ...
  • Closure validate
  • Related validate, e.g. password confirm
  • Custom rule with other parameter
  • Check / modify input data
  • Custom error message type
  • Support different error types convert, it can use both build-in rules and custom error type simultaneously
  • Collect validate error messages
  • Support all types data on #[derive(Serialize, Deserialize)] ( visit serde for more info)

Example 1

fn main() {
    let validator = Validator::new()
        .rule("name", Required.and(StartWith("hello")))
        .rule("age", custom(age_limit))
        .message([
            ("name.required", "name is required"),
            ("name.start_with", "name should be starts with `hello`"),
        ]);

    let person = Person {
        name: "li",
        age: 18,
    };

    let res = validator.validate(person);
    // or using trait
    let res = person.validate(validator);
}

fn age_limit(n: &mut u8) -> Result<(), Message> {
    if *n >= 25 && *n <= 45 {
        return Ok(());
    }
    Err("age should be between 25 and 45".into())
}

Example 2

use valitron::register::string::Validator;
impl Input {
    fn new(mut input: Input) -> Result<Self, Validator<Message>> {
        let valid = Validator::new()
            .insert("name", &mut input.name, Trim.and(Required))
            .insert("email", &mut input.email, Trim.and(Required).and(Email))
            .insert("gender", &mut input.gender, custom(validate_gender))
            .insert(
                "password",
                &mut input.password,
                Trim.custom(validate_password),
            )
            .insert_fn("age", || {
                if input.age < 10 {
                    input.age = 10;
                }
                if input.age > 18 {
                    Err(Message::fallback("age is out of range"))
                } else {
                    Ok(())
                }
            });

        valid.validate(input)
    }
}
fn validate_password(pass: &mut String) -> Result<(), Message> {
    todo!()
}

fn validate_gender(gender: &mut String) -> Result<(), Message> {
    Ok(())
}

Document

Rules Usage

Usage Description
Required one rule
Required.and(StartsWith("foo")) multi rules
Required.and(StartsWith('a')).bail() multi rules and bail
custom(my_handler) custom handler rule
Required.custom(my_handler) rule and handler rule
Not(StartsWith("foo")) negative rule
Required.and(Not(StartsWith("foo"))) negative rule

Bench

second scheme validator(other library)
192.55 ns 680.43 ns

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

valitron's People

Contributors

asuper0 avatar tu6ge avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

asuper0

valitron's Issues

Expect multi call message method, and merge messages

pub fn message<const N: usize, Msg>(mut self, list: [(&'v str, Msg); N]) -> Self
where
Msg: Into<M>,
{
self.message = HashMap::from_iter(list.map(|(key_str, v)| {
let msg_key = panic_on_err!(field_name::parse_message(key_str));
panic_on_err!(self.exit_message(&msg_key));
(msg_key, v.into())
}));
self
}

expect generate two messages:

let validator = Validator::new()
    .message(["name.required", "name is required"])
    .message(["second.required", "second is required"]);

achieve BNF

/// # Register rules
///
/// **Feild support multiple formats:**
/// - `field1` used to matching struct field
/// - `0`,`1`.. used to matching tuple item or tuple struct field
/// - `[0]`,`[1]` used to matching array item
/// - `[foo]` used to matching struct variant, e.g. `enum Foo{ Color { r: u8, g: u8, b: u8 } }`
///
/// The above can also be combined:
/// - `field1.0`
/// - `0.color`
/// - `[12].1`
/// - `foo.1[color]`
/// - more combine
///
/// TODO add BNF

Call method inner first iterator and outside second iterator, can we merge?

let rule_resp = rules.call(value_map);
names = value_map.take_index();
let field_msg = rule_resp
.into_iter()
.map(
|(rule, msg)| match message.remove(&MessageKey::new(names.clone(), rule)) {
Some(s) => s,
None => msg,
},
)
.collect();

valitron/src/rule/mod.rs

Lines 195 to 207 in 997b381

pub(crate) fn call(self, data: &mut ValueMap) -> Vec<(&'static str, M)> {
let RuleList { mut list, .. } = self;
let mut msg = Vec::new();
for endpoint in list.iter_mut() {
let _ = endpoint
.call(data)
.map_err(|e| msg.push((endpoint.name(), e)));
if self.is_bail && !msg.is_empty() {
return msg;
}
}
msg
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.