Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cayo-rodrigues/safe
Simple validation library
https://github.com/cayo-rodrigues/safe
library tests validation
Last synced: about 1 month ago
JSON representation
Simple validation library
- Host: GitHub
- URL: https://github.com/cayo-rodrigues/safe
- Owner: cayo-rodrigues
- License: mit
- Created: 2024-07-31T20:44:38.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2024-09-17T20:30:46.000Z (4 months ago)
- Last Synced: 2024-09-18T01:26:08.024Z (4 months ago)
- Topics: library, tests, validation
- Language: Go
- Homepage:
- Size: 251 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Safe
> A simple Go validation library
User input is unpredictable. Never trust it. Use this library to validate anything you want, and you know you're safe!
## Installation
```bash
go get -u github.com/cayo-rodrigues/safe
```## Usage
```go
u := &User{...}oneYear := (time.Hour * 24) * 365
minorBirthDate := time.Now().Add(-oneYear * 18)
unavailableRoles := [2]string{"software developer", "pepsimaaaaan"}
pineappleRegex := regexp.MustCompile("^pine.*apple$")fields := safe.Fields{
{
Name: "username",
Value: u.Username,
Rules: safe.Rules{safe.Required(), safe.Min(3), safe.Max(128)},
},
{
Name: "email",
Value: u.Email,
Rules: safe.Rules{safe.Required(), safe.Email(), safe.Max(128).WithMessage("Is your email really that long?")},
},
{
Name: "cpf/cnpj",
Value: u.CpfCnpj,
Rules: safe.Rules{
safe.RequiredUnless(safe.All(u.Email, u.Username)), // cpf/cnpj is required, unless both u.Email and u.Username have a value
safe.CpfCnpj(),
safe.Max(128),
},
},
{
Name: "password",
Value: u.Password,
Rules: safe.Rules{safe.Required(), safe.StrongPassword()},
},
{
Name: "roles",
Value: u.Roles,
Rules: safe.Rules{
safe.UniqueList[string](), // must provide the type of the elements in the list
safe.NotOneOf(unavailableRoles[:]), // the input must be a slice, but unavailableRoles is an array with a fixed size, that's why we need [:] here
},
},
{
Name: "birth",
Value: u.BirthDate,
Rules: safe.Rules{
safe.RequiredUnless(u.CpfCnpj, u.Pineapple), // required, unless u.CpfCnpj OR u.Pineapple have a value
safe.NotBefore(minorBirthDate)},
},
{
Name: "company_id",
Value: u.CompanyID,
Rules: safe.Rules{
safe.RequiredUnless(safe.CnpjRegex.MatchString(u.CpfCnpj)).WithMessage("Must provide a valid cnpj or company_id"), // got it?
safe.UUIDstr(),
},
},
{
Name: "pineapple",
Value: u.Pineapple,
Rules: safe.Rules{safe.Match(pineappleRegex)},
},
}errors, isValid := safe.Validate(fields)
```That's it!
In the example above, `errors` is a `map[string]string` with error messages for each field. The default error message can be overwritten with the `WithMessage` func, as demonstrated in the example, for the email field.
When a field fails to pass a given rule, no more subsequent rules are applied. For instance, if password is not provided, it will fail the `safe.Required` rule, hence the `safe.StrongPassword` rule will not run its validation func, and the resulting error message will be regarding the absence of a value, instead of the fact that it does not conform to a strong password standard.
You can refer to the source code or the individual documentation of each function for further instructions. They are all very intuitive.
## Creating your own rules
You can also create your own rules. For instance:
```go
MyCustomRule := &safe.RuleSet{
RuleName: "my own rule!", // this is used only for pretty printing, like fmt.Println("%s", rs)
MessageFunc: func(rs *safe.RuleSet) string {
// here, you can return a message for when the input is not valid
return fmt.Sprintf("why did you input %v? please colaborate", rs.FieldValue)
},
ValidateFunc: func(rs *safe.RuleSet) bool {
// in this function, you may perform any validation you want!
userInput, ok := rs.FieldValue.(string)
if !ok {
return false
}if userInput == "" {
return true // in case you return false, the field will be required
}isValid := false
// perform checks...
return isValid
},
}someVal := "someVal"
fields := safe.Fields{
// ...
{
Name: "my custom rule",
Value: someVal,
Rules: safe.Rules{MyCustomRule, safe.Max(256)},
}
}
```## Helper functions
Safe exposes some helper functions that you can use, whether in the context of validation rules or not. They are:
- `safe.All`
- `safe.HasValue`
- `safe.AllUnique`
- `safe.IsStrongPassword`
- `safe.DaysDifference`Please refer to their individual documentations.
## Regexes
Safe also exposes some regexes for convenience. They are:
- `safe.WhateverRegex` (accepts literally anything)
- `safe.EmailRegex`
- `safe.PhoneRegex`
- `safe.CpfRegex`
- `safe.CnpjRegex`
- `safe.CepRegex`
- `safe.AddressNumberRegex`
- `safe.UUIDRegex`Please refer to their individual documentations.
Regarding regexes, here is a useful repo: https://github.com/osintbrazuca/osint-brazuca-regex.