Giter Club home page Giter Club logo

nim-validation's Introduction

Nim Validation

Description

Nim validation is a simple to use validation library that performs validations against nim objects using their field pragmas. This approach is inspired by libraries like Hibernate validators and Rust's validation library.

The aim of this library is to provide a simple, flexible mechanism for adding validations to your object fields - it does this without using RTTI and is type safe. It is easy to create custom validations, and currently has a small number of validations to demonstrate that it works. Nim Validation also works recursively with nested objects and supports cross field references in validations.

This library is still quite young so breaking changes may come in and there could be bugs. Licensed under GPLv3. Currently it will build under Nim 0.18.0.

Examples

Basic example

There are some examples in the tests directory. Here's one for a quick viewing. It shows a couple of the validators being used - lessThan which just determines if the field being validated is less than the value given, and matchesPattern which determines if the field matches a regex.

In the test given here, you can see there is a single validation error where 100 is not less than 50.

type TestObject = object
    something {.lessThan(50).}: int # Here we use a field pragma to assert that this field should be less than 50
    stringyfield {.matchesPattern("hello|bye").}: string


# To generate the validation methods, you must call generateValidators on your type:
generateValidators(TestObject) 

# Then to validate the object you simply call validate() on it
let validation = TestObject(something: 100, stringyfield: "hello").validate()

# errorCount and hasErrors give you some information about the objects
doAssert(validation.errorCount == 1)
doAssert(validation.hasErrors == true)

# But you can also get a seq of the errors which you can use to extract messages to do with the errors
for error in validation.validationErrors:
    echo error.message

Example validator

This is the less than validator included in this library. There are many others in validatordefs/validatordefs.nim - validators always need to have a pragma defined to keep the compiler happy - it should take the number of arguments in the field pragma expression. Then the proc definition should always take the field as the first parameter, followed by the parameters passed in in the pragma expression. E.g. the fields x in the template and the proc map to eachother.

template lessThan*(x: untyped) {.pragma.}

# Note here that we have one more parameter than in the pragma template.
# the first parameter is always the field that is being validated.
proc lessThan* [T](field: T, x: T): Option[ValidationError] = 
    if not (field < x):
        return someValidationError("$1 was not less than $2".format($field, $x))
    else: return none(ValidationError)

Cross field validation

With nim-validation, you can validate a field against any of the other fields in the object - even those which are nested within the object. Using the this keyword to reference the current object, you can reference any of the fields on that object. In the below example, we access the 'something' field of a child object in the equals validation. This could be, for instance, a reference to a parent object.

There is an example in the tests for this, it is the below:

type
    WrapperObject = ref object of RootObj
        child* {.valid().}: TestObject
        b* {.matchesPattern("hello|bye").}: string
        a* {.lessThan(50), equals(this.child.something).}: int 

generateValidators(WrapperObject)

let validationNestedNegative = WrapperObject(a: 75, b: "slkjdf", child: TestObject(something: 70, stringyfield: "bye", shouldMatch: "hu")).validate()

echo "ValidatinNested: ", validationNestedNegative.errorCount, "msgs: ", validationNestedNegative
doAssert(validationNestedNegative.errorCount == 4)
doAssert(validationNestedNegative.hasErrors == true)

nim-validation's People

Contributors

captainbland avatar

Stargazers

Comamoca avatar Gál Tamás avatar Emre Şafak avatar Arham Jain avatar Zaidin Amiot avatar Scott Wadden avatar Nebojša Koturović avatar  avatar Mike avatar  avatar Steve Howe avatar Cristian M. Pinheiro avatar oskca avatar R3D9477 avatar Andrei Subbota avatar Li Jie avatar Huy Doan avatar DJ avatar Mamy Ratsimbazafy avatar Abhishek avatar Pablo Cabezas avatar Akira Komamura avatar OldhamMade avatar Andrea Ferretti avatar Alexander Ivanov avatar Constantine Molchanov avatar

Watchers

Huy Doan avatar James Cloos avatar  avatar

nim-validation's Issues

Field cross referencing

Considering something like for syntax.

type MyType = object
  myfield: int {.greaterThan(self.otherField).}
  otherfield: int

More validator types

At the moment there are not very many default validators. Good examples would be some default regex validators for, for instance, emails and password validation, date validation (before, after, during), etc. Please open a PR with any you want to contribute.

If you're a newcomer wanting to make a contribution to this library, the validations are all currently defined in src/validator_defs.nim and one of these is explained in the README.md - follow the pattern you see in there for each validation type. If you have a question, please do not hesitate to ask below, I don't bite (although might sometimes take a little while to reply).

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.