Code Monkey home page Code Monkey logo

accord's Introduction

Accord

Build Status Current Crates.io Version API Documentation codecov

Accord is a library for validating data according to rules like length, contains, range and either.

Accord is two fold, the first part being a set of validator-functions that for example tests that a String has a minimum of 5 characters or that an i32 is either 10 or 20, and the second part being the rules! macro which allows you to run a set of validators on a single piece of data, or a whole collection of data and get back a set of errors which explains exactly what is wrong. The errors can easily be serialized using Serde and then be used in for example a REST API to report to the user which of the data the user posted contains illegal values.

See the Rocket example for how to use Accord with Rocket to validate JSON input and return explanations for any occuring error as JSON which then can be parsed by the requesting application and shown to the user to guide them in how to fix their input values according to the applications rules.

Error messages uses numbered placeholders meaning that an error message could be "Must not be less than %1." with an accompanien list [5], which makes it easy to translate "Must not be less than %1." without having to deal with the variable value 5.

Usage tl;dr:

#[macro_use]
extern crate accord;
extern crate serde;
extern crate serde_json;

use accord::{Accord, Result as AccordResult, Error, MultipleError, MultipleInvalid};
use accord::validators::{length, contains, range};

struct Account {
    pub name: String,
    pub email: String,
    pub age: i8,
}

impl Accord for Account {
    fn validate(&self) -> AccordResult {
        rules!{
            "name" => self.name => [length(1, 64)],
            "email" => self.email => [length(5, 64), contains("@"), contains(".")],
            "age" => self.age => [range(12, 127)]
        }
    }
}

fn main() {
    let account = Account {
        name: "".to_string(),
        email: "test".to_string(),
        age: 11,
    };

    // You can use the `rules!` macro on any value.
    // This way of using the the `rules!` macro returns a
    // `Result<(), Error>`.
    let _ = rules!(account.name, [length(1, 64)]);
    let _ = rules!(account.email, [length(5, 64), contains("@"), contains(".")]);
    let _ = rules!(account.age, [range(12, 127)]);

    // You can also use the collection form of the `rules!` macro
    // again using any value you'd like.
    // This way of using the `rules!` macro returns a
    // `Result<(), MultipleError>`. Notice the string slices that has
    // been appended to the lines from last example. These string slices
    // are called tags and are used to distingues between the sets of errors
    // that are returned.
    let _ = rules!{
        "name" => account.name => [length(1, 64)],
        "email" => account.email => [length(5, 64), contains("@"), contains(".")],
        "age" => account.age => [range(12, 127)]
    };

    // And finally, since our `Account` has implemented the
    // `Accord` trait, we can simply do the following, which once
    // again returns `Result<(), MultipleError>`, which we then
    // serialize to JSON using Serde and print:
    if let Err(multiple_error) = account.validate() {
        println!("Errors as json: {}",
                 serde_json::to_string(&multiple_error).unwrap());
    } else {
        println!("No errors occured");
    }
}

Documentation

  • Examples: Usage examples are available in the examples/ directory
  • API Documentation: Documentation generated from the source code, comments and examples

Building locally

Stable

Building: cargo build

Testing: cargo test

Nightly + unstable features

Make sure you have an up-to-date version of rust nightly installed.

Building: cargo build

Testing: cargo test

You can add --features FEATURES TO ENABLE to both cargo build and cargo test to build or test unstable features. The unstable features currently supported are:

  • inclusive_range RFC#1192 which enables one to use the length and range validators with inclusive ranges instead of a, b-variables, as in the example above. An example crate using inclusive ranges can be found here.

Make

You can also use make for doing more stuff in a simpler way. The Makefile requires that you are using Rust via rustup.

  • make will build and test Accord and all examples on both stable and nightly, on nightly both with and without unstable features
  • make build will build everything on both stable and nightly
  • make build-stable will build everything on stable
  • make build-unstable will build everything on nightly with and without unstable features
  • make build-examples will build examples on both stable and nightly
  • make build-stable-examples
  • make build-unstable-examples
  • make build-stable-example-<NAME-OF-STABLE-EXAMPLE>
  • make build-unstable-example-<NAME-OF-UNSTABLE-EXAMPLE>
  • make test will test everything on both stable and nightly, on nightly with and without unstable features
  • make test-stable will test everything on stable
  • make test-unstable will test everything on nightly with and without unstable features
  • make test-examples will test examples on both stable and nightly
  • make test-stable-examples
  • make test-unstable-examples
  • make test-stable-example-<NAME-OF-STABLE-EXAMPLE>
  • make test-unstable-example-<NAME-OF-UNSTABLE-EXAMPLE>

Contributing

Contributions are absolutely, positively welcome and encouraged! Contributions come in many forms. You could:

  1. Submit a feature request or bug report as an issue.
  2. Ask for improved documentation as an issue.
  3. Contribute code via pull requests.

To keep a high standard of quality, contributed code must be:

  • Commented: Public items must be commented.
  • Documented: Exposed items must have rustdoc comments with examples, if applicable.
  • Styled: Your code should be rustfmt'd when possible.
  • Simple: Your code should accomplish its task as simply and idiomatically as possible.
  • Tested: You must add (and pass) convincing tests for any functionality you add.
  • Focused: Your code should do what it's supposed to do and nothing more.

All pull requests are code reviewed and tested by the CI. Note that unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Accord by you shall be MIT License without any additional terms or conditions.

Thanks to Rocket for showing how to form a great contributing-section.

License

Accord is Copyright (c) 2017 Christoffer Buchholz. It is free software, and may be redistributed under the terms specified in the LICENSE file.

accord's People

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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

accord's Issues

Provide an API for stable rust

Currently there's no timeline for stabilization of impl trait. What do you think about moving the current validators behind a nightly feature gate, and returning boxed closures when that feature is not enabled?

Makefile for testing accord + example crates

Right now, the only way to test both accord and its examples is to run cargo test in both the accord crate and the bundled example crates. Introducing a Makefile to handle testing could reduce this to a single stop of make test.

More complete examples

The only real examples right now focuses of use in a REST API setting. There should be examples showcasing other scenarios.

Auto-rules for structs?

If you're looking for an idea for something to do, I think it would be pretty cool if I could:

#[derive(AccordValidate)]
struct Account {
    #[accord_rule(length(1..64))]
    name: String,
    #[accord_rule(length(5..64), contains("@"), contains("."))]
    email: String,
    #[accord_rule(range(12..127))]
    age: i8,
}

And get an auto-impld Account::validate function. A similar thing like derive(AccordNew) or AccordBuilder seem like something that would also be nice so that it's impossible to even build invalid objects in the common case.

Email validator

I'm really not sure about this, since it's easy to make an email validator too restrictive so as to hit false on obscure but valid urls.

URL validator

I'm really not sure about this, since it's easy to make an URL validator too restrictive so as to hit false on obscure but valid urls.

Range is supposed to be half-open

Range is defined in Rust as half-open: so 12..127 means “at least 12, and less than 127”. In your validators you’ve implemented it with incorrect semantics, treating it as an inclusive range, which is instead 12...127 (and experimental).

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.