Skip to content

Commit

Permalink
Bump version in semantic versioning of go mod
Browse files Browse the repository at this point in the history
  • Loading branch information
guiferpa committed Apr 14, 2020
1 parent 4940e41 commit 771eb76
Show file tree
Hide file tree
Showing 28 changed files with 1,601 additions and 0 deletions.
61 changes: 61 additions & 0 deletions v2/examples/custom_rule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package main

import (
"fmt"
"log"

gody "github.com/guiferpa/gody/v2"
"github.com/guiferpa/gody/v2/rule"
)

// ErrInvalidPalindrome is a custom error to a specific rule implementation
type ErrInvalidPalindrome struct {
Value string
}

func (e *ErrInvalidPalindrome) Error() string {
return fmt.Sprintf("invalid palindrome: %s", e.Value)
}

// PalindromeRule is a struct that implements the Rule interface
type PalindromeRule struct{}

// Name is a func from the Rule contract
func (r *PalindromeRule) Name() string {
return "palindrome"
}

// Validate is a func from the Rule contract
func (r *PalindromeRule) Validate(f, v, p string) (bool, error) {
// TODO: The algorithm for palindrome validation
return true, &ErrInvalidPalindrome{Value: v}
}

func CustomRuleValidation() {
b := struct {
Text string `json:"text" validate:"min_bound=5"`
Palindrome string `json:"palindrome" validate:"palindrome"`
}{
Text: "test-text",
Palindrome: "test-palindrome",
}

customRules := []gody.Rule{
&PalindromeRule{},
}

valid, err := gody.DefaultValidate(b, customRules)
if err != nil {
if !valid {
log.Println("body do not validated", err)
}

switch err.(type) {
case *rule.ErrRequired:
log.Println("required error:", err)

case *ErrInvalidPalindrome:
log.Println("palindrome error:", err)
}
}
}
107 changes: 107 additions & 0 deletions v2/examples/http_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package main

import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"

gody "github.com/guiferpa/gody/v2"
)

type ErrIsAdult struct{}

func (err *ErrIsAdult) Error() string {
return "The client isn't a adult then it isn't allowed buy"
}

type IsAdultRule struct {
adultAge int
}

func (r *IsAdultRule) Name() string {
return "is_adult"
}

func (r *IsAdultRule) Validate(_, value, _ string) (bool, error) {
if value == "" {
return true, &ErrIsAdult{}
}

clientAge, err := strconv.Atoi(value)
if err != nil {
return false, err
}

if clientAge < r.adultAge {
return true, &ErrIsAdult{}
}

return true, nil
}

type User struct {
Name string `validate:"min_bound=5"`
Age int16 `validate:"min=10 is_adult"`
}

type Product struct {
Name string `validate:"not_empty"`
Description string `validate:"not_empty"`
Price int
}

type Cart struct {
Owner User
Products []Product
}

func HTTPServerAPI() {
validator := gody.NewValidator()

if err := validator.AddRules(&IsAdultRule{adultAge: 21}); err != nil {
log.Fatalln(err)
}

port := ":8092"
log.Printf("Example for REST API is running on port %v, now send a POST to /carts and set the claimed Cart struct as request body", port)
http.ListenAndServe(port, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/carts" || r.Method != http.MethodPost {
w.WriteHeader(http.StatusNotFound)
fmt.Fprintf(w, "Path or method is wrong: path: %v, method: %v\n", r.URL.Path, r.Method)
return
}

var body Cart
err := json.NewDecoder(r.Body).Decode(&body)
defer r.Body.Close()
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintln(w, err)
return
}

if validated, err := validator.Validate(body); err != nil {
if !validated {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "Validation for body wasn't processed because of error: %v\n", err)
return
}

w.WriteHeader(http.StatusUnprocessableEntity)

if _, ok := err.(*ErrIsAdult); ok {
fmt.Fprintf(w, "The client called %v isn't a adult\n", body.Owner.Name)
return
}

fmt.Fprintln(w, err)
return
}

w.WriteHeader(http.StatusCreated)
fmt.Fprintf(w, "The client %v created your cart!\n", body.Owner.Name)
return
}))
}
75 changes: 75 additions & 0 deletions v2/examples/simple.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package main

import (
"log"

gody "github.com/guiferpa/gody/v2"
"github.com/guiferpa/gody/v2/rule"
)

func SimpleDefaultValidation() {
b := struct {
Text string `json:"text" validate:"not_empty"`
}{}

valid, err := gody.DefaultValidate(b, nil)
if err != nil {
if !valid {
log.Println("body do not validated:", err)
}

switch err.(type) {
case *rule.ErrNotEmpty:
log.Println("not empty error:", err)

}
}
}

func SimplePureValidation() {
b := struct {
Text string `json:"text" validate:"not_empty"`
}{}

rules := []gody.Rule{
rule.NotEmpty,
}
valid, err := gody.Validate(b, rules)
if err != nil {
if !valid {
log.Println("body do not validated:", err)
}

switch err.(type) {
case *rule.ErrNotEmpty:
log.Println("not empty error:", err)

}
}
}

func SimpleValidationFromValidator() {
b := struct {
Text string `json:"text" validate:"not_empty"`
}{}

validator := gody.NewValidator()

if err := validator.AddRules(rule.NotEmpty); err != nil {
log.Println(err)
return
}

valid, err := validator.Validate(b)
if err != nil {
if !valid {
log.Println("body do not validated:", err)
}

switch err.(type) {
case *rule.ErrNotEmpty:
log.Println("not empty error:", err)

}
}
}
3 changes: 3 additions & 0 deletions v2/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/guiferpa/gody/v2

go 1.13
7 changes: 7 additions & 0 deletions v2/rule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package gody

// Rule is a interface with the contract to implement a any rule
type Rule interface {
Name() string
Validate(name, value, param string) (bool, error)
}
36 changes: 36 additions & 0 deletions v2/rule/enum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package rule

import (
"fmt"
"strings"
)

type enum struct{}

func (r *enum) Name() string {
return "enum"
}

// ErrEnum is the representation about any error happened inside of the rule Enum
type ErrEnum struct {
Field string
Value string
Enum []string
}

func (err *ErrEnum) Error() string {
return fmt.Sprintf("the value %v in field %v not contains in %v", err.Value, err.Field, err.Enum)
}

func (r *enum) Validate(f, v, p string) (bool, error) {
if v == "" {
return true, nil
}
es := strings.Split(p, ",")
for _, e := range es {
if v == e {
return true, nil
}
}
return true, &ErrEnum{f, v, es}
}
53 changes: 53 additions & 0 deletions v2/rule/enum_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package rule

import (
"testing"
)

func TestEnumName(t *testing.T) {
r := Enum
if r.Name() != "enum" {
t.Errorf("unexpected result, result: %v, expected: %v", r.Name(), "enum")
}
}

func TestEnum(t *testing.T) {
r := Enum
cases := []struct {
value, param string
}{
{"a", "a,b,c,d"},
{"b", "a,b,c,d"},
{"c", "a,b,c,d"},
{"d", "a,b,c,d"},
{"", "a,b,c,d"},
}
for _, test := range cases {
ok, err := r.Validate("", test.value, test.param)
if err != nil {
t.Error(err)
}
if !ok {
t.Errorf("unexpected result, result: %v, expected: %v", ok, true)
}
}
}

func TestEnumWithInvalidParams(t *testing.T) {
r := Enum
cases := []struct {
value, param string
}{
{"d", "a,b,c"},
{"1", "a,b,c"},
}
for _, test := range cases {
ok, err := r.Validate("", test.value, test.param)
if _, ok := err.(*ErrEnum); !ok {
t.Error(err)
}
if !ok {
t.Errorf("unexpected result, result: %v, expected: %v", ok, true)
}
}
}
39 changes: 39 additions & 0 deletions v2/rule/max.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package rule

import (
"fmt"
"strconv"
"strings"
)

type max struct{}

func (r *max) Name() string {
return "max"
}

// ErrMax is the representation about any error happened inside of the rule Max
type ErrMax struct {
Field string
Value int
Max int
}

func (err *ErrMax) Error() string {
return fmt.Sprintf("the value %v in field %v is grater than %v", err.Value, err.Field, err.Max)
}

func (r *max) Validate(f, v, p string) (bool, error) {
n, err := strconv.Atoi(p)
if err != nil {
return false, err
}
vn, err := strconv.Atoi(v)
if err != nil {
return false, err
}
if vn > n {
return true, &ErrMax{strings.ToLower(f), vn, n}
}
return true, nil
}
Loading

0 comments on commit 771eb76

Please sign in to comment.