Skip to content

Commit cdae976

Browse files
authored
Merge pull request #21 from foomo/feature/generics
Use generics
2 parents ca0ae8a + b47f5d2 commit cdae976

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+1518
-1715
lines changed

.github/workflows/pull-requests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ jobs:
2222
name: lint
2323
runs-on: ubuntu-latest
2424
steps:
25-
- uses: actions/checkout@v3.1.0
26-
- uses: actions/setup-go@v3
25+
- uses: actions/checkout@v3
26+
- uses: actions/setup-go@v4
2727
with:
2828
cache: true
2929
check-latest: true

.github/workflows/releases.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
release:
1919
runs-on: ubuntu-latest
2020
steps:
21-
- uses: actions/checkout@v3.1.0
21+
- uses: actions/checkout@v3
2222
with:
2323
fetch-depth: 0
2424
- run: git fetch --force --tags

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ check: test lint
2121
test:
2222
gotestsum --format dots-v2 ./...
2323

24+
.PHONY: bench
25+
## Run benchmarks
26+
bench:
27+
go test -run ^$$ -bench . | prettybench
28+
2429
.PHONY: lint
2530
## Run linter
2631
lint:

README.md

Lines changed: 99 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -2,150 +2,130 @@
22

33
> a piece of rope or a tyre that protects the side of a boat from knocks
44
5-
Fender provides a unified way to validate data and make the errors passable to the frontend e.g. through gotsrpc.
5+
Fender provides a unified way to validate data and on the backend & frontend side.
66

77
## Usage
88

9-
Fender provides different ways to validate your data.
10-
11-
### struct validation using go-playground validator
9+
### All
1210

1311
```go
14-
package main
15-
16-
import (
17-
"fmt"
18-
19-
"github.com/foomo/fender"
20-
)
21-
22-
type Test struct {
23-
Int int `validate:"min=1"`
24-
Int8 int8 `validate:"min=1"`
25-
Int32 int32 `validate:"min=1"`
26-
Int64 int64 `validate:"min=1"`
27-
UInt uint `validate:"min=1"`
28-
UInt8 uint8 `validate:"min=1"`
29-
UInt32 uint32 `validate:"min=1"`
30-
UInt64 uint64 `validate:"min=1"`
31-
Float32 float32 `validate:"min=1.5"`
32-
Float64 float64 `validate:"min=1.5"`
33-
Bool bool `validate:"required"`
34-
String string `validate:"required"`
35-
}
36-
37-
func main() {
38-
u := Test{}
39-
fendErr, err := fender.Struct(u)
40-
if err != nil {
41-
panic("internal error: " + err.Error())
12+
func ExampleAll() {
13+
err := fender.All(
14+
context.Background(),
15+
fend.Field("one", "", rule.RequiredString, rule.MinString(10)),
16+
fend.Field("two", "", rule.RequiredString, rule.MinString(10)),
17+
)
18+
// check for fender error
19+
if fendErr := fender.AsError(err); fendErr != nil {
20+
fmt.Println(err)
21+
} else if err != nil {
22+
panic(err)
4223
}
43-
fmt.Println(fendErr) // bool:required;string:required;uInt:min=1;uInt8:min=1;uInt32:min=1;uInt64:min=1;float32:min=1.5;int:min=1;int8:min=1;int32:min=1;int64:min=1;float64:min=1.5
24+
// Output: one:required:min=10;two:required:min=10
4425
}
4526
```
4627

47-
### validate by code
28+
### AllFirst
4829

4930
```go
50-
package main
51-
52-
import (
53-
"fmt"
54-
55-
"github.com/foomo/fender"
56-
"github.com/foomo/fender/fend"
57-
"github.com/foomo/fender/rule"
58-
)
59-
60-
type Test struct {
61-
Int int
62-
Int8 int8
63-
Int32 int32
64-
Int64 int64
65-
UInt uint
66-
UInt8 uint8
67-
UInt32 uint32
68-
UInt64 uint64
69-
Float32 float32
70-
Float64 float64
71-
Bool bool
72-
String string
73-
}
74-
75-
func main() {
76-
u := Test{}
77-
fendErr, err := fender.All(
78-
fender.Field("int", fend.Int(u.Int, rule.MinInt(1))),
79-
fender.Field("int8", fend.Int8(u.Int8, rule.MinInt8(1))),
80-
fender.Field("int32", fend.Int32(u.Int32, rule.MinInt32(1))),
81-
fender.Field("int64", fend.Int64(u.Int64, rule.MinInt64(1))),
82-
fender.Field("uint", fend.UInt(u.UInt, rule.MinUInt(1))),
83-
fender.Field("uint8", fend.UInt8(u.UInt8, rule.MinUInt8(1))),
84-
fender.Field("uint32", fend.UInt32(u.UInt32, rule.MinUInt32(1))),
85-
fender.Field("uint64", fend.UInt64(u.UInt64, rule.MinUInt64(1))),
86-
fender.Field("float32", fend.Float32(u.Float32, rule.MinFloat32(1.5))),
87-
fender.Field("float64", fend.Float64(u.Float64, rule.MinFloat64(1.5))),
88-
fender.Field("bool", fend.Bool(u.Bool, rule.Bool(true))),
89-
fender.Field("string", fend.String(u.String, rule.RequiredString)),
31+
func ExampleAllFirst() {
32+
err := fender.AllFirst(
33+
context.Background(),
34+
fend.Field("one", "", rule.RequiredString, rule.MinString(10)),
35+
fend.Field("two", "", rule.RequiredString, rule.MinString(10)),
9036
)
91-
if err != nil {
92-
panic("internal error: " + err.Error())
37+
38+
// check for fender error
39+
if fendErr := fender.AsError(err); fendErr != nil {
40+
fmt.Println(err)
41+
} else if err != nil {
42+
panic(err)
9343
}
94-
fmt.Println(fendErr) // uint:min=1;uint64:min=1;float32:min=1.5;int:min=1;int8:min=1;uint8:min=1;uint32:min=1;float64:min=1.5;bool:bool=true;string:required;int32:min=1;int64:min=1
44+
// Output: one:required:min=10
9545
}
9646
```
9747

98-
### validate by code and stop on first error
48+
### First
9949

10050
```go
101-
package main
102-
103-
import (
104-
"fmt"
105-
106-
"github.com/foomo/fender"
107-
"github.com/foomo/fender/fend"
108-
"github.com/foomo/fender/rule"
109-
)
110-
111-
type Test struct {
112-
Int int
113-
Int8 int8
114-
Int32 int32
115-
Int64 int64
116-
UInt uint
117-
UInt8 uint8
118-
UInt32 uint32
119-
UInt64 uint64
120-
Float32 float32
121-
Float64 float64
122-
Bool bool
123-
String string
51+
func ExampleFirst() {
52+
err := fender.First(
53+
context.Background(),
54+
fend.Field("one", "", rule.RequiredString, rule.MinString(10)),
55+
fend.Field("two", "", rule.RequiredString, rule.MinString(10)),
56+
)
57+
58+
// check for fender error
59+
if fendErr := fender.AsError(err); fendErr != nil {
60+
fmt.Println(err)
61+
} else if err != nil {
62+
panic(err)
63+
}
64+
// Output: one:required
12465
}
66+
```
67+
68+
### Handle errors
12569

126-
func main() {
127-
u := Test{}
128-
fendErr, err := fender.First(
129-
fender.Field("int", fend.Int(u.Int, rule.MinInt(1))),
130-
fender.Field("int8", fend.Int8(u.Int8, rule.MinInt8(1))),
131-
fender.Field("int32", fend.Int32(u.Int32, rule.MinInt32(1))),
132-
fender.Field("int64", fend.Int64(u.Int64, rule.MinInt64(1))),
133-
fender.Field("uint", fend.UInt(u.UInt, rule.MinUInt(1))),
134-
fender.Field("uint8", fend.UInt8(u.UInt8, rule.MinUInt8(1))),
135-
fender.Field("uint32", fend.UInt32(u.UInt32, rule.MinUInt32(1))),
136-
fender.Field("uint64", fend.UInt64(u.UInt64, rule.MinUInt64(1))),
137-
fender.Field("float32", fend.Float32(u.Float32, rule.MinFloat32(1.5))),
138-
fender.Field("float64", fend.Float64(u.Float64, rule.MinFloat64(1.5))),
139-
fender.Field("bool", fend.Bool(u.Bool, rule.Bool(true))),
140-
fender.Field("string", fend.String(u.String, rule.RequiredString)),
70+
```go
71+
func ExampleErrors() {
72+
err := fender.All(
73+
context.Background(),
74+
fend.Field("one", "", rule.RequiredString, rule.MinString(10)),
75+
fend.Field("two", "", rule.RequiredString, rule.MinString(10)),
14176
)
142-
if err != nil {
143-
panic("internal error: " + err.Error())
77+
78+
// cast fender error
79+
if fenderErr := fender.AsError(err); fenderErr != nil {
80+
81+
// iterate fend errors
82+
for _, err := range fenderErr.Errors() {
83+
84+
// cast fend error
85+
if fendErr := fend.AsError(err); fendErr != nil {
86+
87+
fmt.Println(fendErr.Name())
88+
89+
// iterate rule errors
90+
for _, err := range fendErr.Errors() {
91+
92+
// cast rule error
93+
if ruleErr := rule.AsError(err); ruleErr != nil {
94+
fmt.Println(ruleErr.Error())
95+
}
96+
}
97+
}
98+
}
99+
} else if err != nil {
100+
panic(err)
144101
}
145-
fmt.Println(fendErr) // int:min=1
102+
// Output:
103+
// one
104+
// required
105+
// min=10
106+
// two
107+
// required
108+
// min=10
146109
}
147110
```
148111

112+
## Benchmarks
113+
114+
```text
115+
go test -bench=. | prettybench
116+
goos: darwin
117+
goarch: arm64
118+
pkg: github.com/foomo/fender
119+
PASS
120+
benchmark iter time/iter
121+
--------- ---- ---------
122+
BenchmarkAll/invalid_reused/fender-10 282154 3771.00 ns/op
123+
BenchmarkAll/invalid_reused/playground-10 678679 1741.00 ns/op
124+
BenchmarkAll/success_new/fender-10 1000000 1026.00 ns/op
125+
BenchmarkAll/success_new/playground-10 1308327 937.60 ns/op
126+
ok github.com/foomo/fender 5.619s
127+
```
128+
149129
## References & alternatives
150130

151131
- [go-playground/validator](https://github.com/go-playground/validator)
@@ -158,7 +138,3 @@ Make a pull request...
158138
## License
159139

160140
Distributed under MIT License, please see license file within the code for more details.
161-
162-
## Notes
163-
164-
We'll take another refactoring round as soon as go supports generics

all.go

Lines changed: 0 additions & 22 deletions
This file was deleted.

all_test.go

Lines changed: 0 additions & 71 deletions
This file was deleted.

0 commit comments

Comments
 (0)