An open API service indexing awesome lists of open source software.

https://github.com/twharmon/govalid

Struct validation using tags
https://github.com/twharmon/govalid

go validation

Last synced: 5 months ago
JSON representation

Struct validation using tags

Awesome Lists containing this project

README

          

# Govalid

[![](https://goreportcard.com/badge/github.com/twharmon/govalid)](https://goreportcard.com/report/github.com/twharmon/govalid)

Use Govalid to validate structs.

## Basic Example
```go
package main

import (
"errors"
"fmt"
"log"
"strings"
"unicode/utf8"

"github.com/twharmon/govalid"
)

type Post struct {
// ID has no constraints
ID int

// Title is required, must be at least 3 characters long, and
// cannot be more than 20 characters long
Title string `valid:"req|min:3|max:20"`

// Body is not required, cannot be more than 10000 charachers,
// and must be "fun" (a custom rule defined below).
Body string `valid:"max:10000|fun"`
}

func main() {
// Add custom string rule "fun" that can be used on any string field
// in any struct.
govalid.Rule("fun", func(v any) error {
switch tv := v.(type) {
case string:
if float64(strings.Count(tv, "!"))/float64(utf8.RuneCountInString(tv)) > 0.001 {
return nil
}
// return a validation error with govalid.Error
return govalid.NewValidationError("must contain more exclamation marks")
default:
// return a non validation (internal) error
return errors.New("fun constraint must be applied to string only")
}
})
fmt.Println(govalid.Validate(&Post{
ID: 5,
Title: "Hi",
Body: "Hello world!",
}))
}
```

## Error Values
When you call `govalid.Validate` to validate a struct, it returns an error if the validation rules are not met. This error may either be a validation-specific error (an implementation of `govalid.ValidationError`) or a different error indicating a problem in processing the validation. This allows you to distinguish between errors caused by invalid data and those caused by issues in your validation logic, such as setting the `valid` tag to `max:not-a-number`.

```go
if err := govalid.Validate(value); err != nil {
if verr, ok := err.(govalid.ValidationError); ok {
fmt.Println("validation error", verr)
} else {
fmt.Println("some other error", err)
}
}
```

## Dive Usage
The `dive` rule is used to apply validation rules to elements within pointers, slices, arrays, and structs. When the `dive` rule is encountered, it instructs the validator to "dive" into the elements of the collection or the value pointed to by a pointer and apply the remaining rules to each element or the dereferenced value.

### Notes
- **Pointers**: The `dive` rule will dereference the pointer and apply the remaining rules to the value it points to.
- **Slices/Arrays**: The `dive` rule will iterate over each element in the slice or array and apply the remaining rules to each element.
- **Structs**: The `dive` rule will validate the struct according to its own field tags. The remaining rules after `dive` have no meaning for structs.

### Examples

#### Pointers

```go
type Example struct {
Field *string `valid:"req|dive|min:3"`
}
```
In this example, the Field must be a non-nil pointer to a string, and the string must be at least 3 characters long.

#### Slices/Arrays
```go
type Example struct {
Field []string `valid:"req|dive|min:3"`
}
```
In this example, the Field must be a non-nil slice of strings, and each string in the slice must be at least 3 characters long.

#### Structs
```go
type Inner struct {
Name string `valid:"req"`
}

type Outer struct {
InnerStruct Inner `valid:"dive"`
}
```
In this example, the InnerStruct field will be validated according to the validation tags defined in the Inner struct.

## Contribute

Make a pull request.