Skip to content

Commit

Permalink
structs sub-package enhanced
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonWaldherr committed Jun 19, 2024
1 parent a1397b8 commit 3da0bf1
Show file tree
Hide file tree
Showing 8 changed files with 677 additions and 9 deletions.
15 changes: 8 additions & 7 deletions specialdays/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,25 @@ package specialdays_test
import (
"fmt"
"sort"

"simonwaldherr.de/go/golibs/specialdays"
)

func ExampleGetSpecialDays() {
days := specialdays.GetSpecialDays(2019)

keys := make([]string, 0, len(days))
for k := range days{
keys = append(keys, k)
}

for k := range days {
keys = append(keys, k)
}
sort.Strings(keys)

for _, k := range keys {
fmt.Printf("%s: %s\n", k, days[k].Format("2006-01-02"))
}

// Output:
// Output:
// 1. Weihnachtstag: 2019-12-25
// 2. Weihnachtstag: 2019-12-26
// Allerheiligen: 2019-11-01
Expand Down
2 changes: 1 addition & 1 deletion specialdays/specialdays.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func CalculateBussUndBettag(year int) time.Time {
// Der Buß- und Bettag ist der Mittwoch vor dem ersten Advent.
firstAdvent := CalculateFirstAdvent(year)
bussUndBettag := firstAdvent.AddDate(0, 0, -11)

return bussUndBettag
}

Expand Down
253 changes: 252 additions & 1 deletion structs/example_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package structs_test

import (
"encoding/json"
"errors"
"fmt"
"log"
"reflect"
"simonwaldherr.de/go/golibs/structs"
"sort"
"testing"
"unicode"

"simonwaldherr.de/go/golibs/structs"
)

type LIPS struct {
Expand Down Expand Up @@ -68,3 +74,248 @@ func ExampleReflectHelper() {
// VRKME - string - - 0
// VKBUR - string - - 0
}

type ExampleUser struct {
Name string `json:"name" modify:"upper" validate:"required"`
Age int `json:"age" modify:"abs" validate:"gte=0,lte=130"`
Email string `json:"email" modify:"lower" modify:"trim" validate:"required,email"`
Password string `json:"password" modify:"trim" validate:"minlen=8"`
Status string `json:"status" validate:"oneof=active inactive"`
Zip string `modify:"pattern=\d+"`
}

func ExampleValidateAndModify() {
user := &ExampleUser{
Name: "john",
Age: -25,
Email: "[email protected] ",
Password: " password123 ",
Status: "active",
Zip: "94522 Wallersdorf",
}

if err := structs.ValidateAndModify(user); err != nil {
fmt.Println("Validation error:", err)
} else {
fmt.Println("Validation and modification passed!")
fmt.Printf("%+v\n", user)
}

// Output:
// Validation and modification passed!
// &{Name:JOHN Age:25 Email:[email protected] Password:password123 Status:active Zip:94522}
}

func TestExampleUserValidation(t *testing.T) {
validUser := &ExampleUser{
Name: "Alice",
Age: 28,
Email: "[email protected]",
Password: "securepassword",
Status: "active",
}

if err := structs.ValidateAndModify(validUser); err != nil {
t.Errorf("Expected valid user to pass validation, but got error: %v", err)
}

invalidUser := &ExampleUser{
Name: "",
Age: 150,
Email: "invalid-email",
Password: "short",
Status: "unknown",
}

if err := structs.ValidateAndModify(invalidUser); err == nil {
t.Errorf("Expected invalid user to fail validation, but got no error")
}
}

func ExampleJSON() {
jsonString := `{
"name": "john",
"age": -25,
"email": "[email protected] ",
"password": " password123 ",
"status": "active"
}`

var user ExampleUser

// Decode JSON string
if err := json.Unmarshal([]byte(jsonString), &user); err != nil {
log.Fatalf("Error decoding JSON: %v", err)
}

// Validate and modify struct fields
if err := structs.ValidateAndModify(&user); err != nil {
log.Fatalf("Validation/Modification error: %v", err)
}

// Encode struct back to JSON
modifiedJSON, err := json.MarshalIndent(user, "", " ")
if err != nil {
log.Fatalf("Error encoding JSON: %v", err)
}

fmt.Println("Modified JSON:")
fmt.Println(string(modifiedJSON))

// Output:
// Modified JSON:
//{
// "name": "JOHN",
// "age": 25,
// "email": "[email protected]",
// "password": "password123",
// "status": "active",
// "Zip": ""
//}
}

// Example of using the validator with a struct that has nested fields
func ExampleNestedStruct() {
type Address struct {
Street string `validate:"required"`
City string `validate:"required"`
ZipCode string `validate:"required"`
}

type User struct {
Name string `validate:"required"`
Age int `validate:"gte=0,lte=130"`
Email string `validate:"required,email"`
Address Address `validate:"required"`
}

user := &User{
Name: "J. Doe",
Age: 28,
Email: "[email protected]",
Address: Address{
Street: "123 Main St",
City: "Springfield",
ZipCode: "12345",
},
}

if err := structs.ValidateAndModify(user); err != nil {
fmt.Println("Validation error:", err)
} else {
fmt.Println("Validation and modification passed!")
fmt.Printf("%+v\n", user)
}

// Output:
// Validation and modification passed!
// &{Name:J. Doe Age:28 Email:[email protected] Address:{Street:123 Main St City:Springfield ZipCode:12345}}
}

// Example of using the validator with a struct that has nested fields
func ExampleBase64() {
type User struct {
Name string `validate:"required"`
Data string `modify:"base64_decode" validate:"required"`
}

user := &User{
Name: "Simon",
Data: "SGVsbG8gV29ybGQ=",
}

if err := structs.ValidateAndModify(user); err != nil {
fmt.Println("Validation error:", err)
} else {
fmt.Println("Validation and modification passed!")
fmt.Printf("%+v\n", user)
}

// Output:
// Validation and modification passed!
// &{Name:Simon Data:Hello World}
}

// Example of using the hashing feature of the validator
func ExampleHash() {
type User struct {
Name string `validate:"required"`
Data string `modify:"hash=md5"`
}

user := &User{
Name: "Simon",
Data: "Hello World",
}

if err := structs.ValidateAndModify(user); err != nil {
fmt.Println("Validation error:", err)
} else {
fmt.Println("Validation and modification passed!")
fmt.Printf("%+v\n", user)
}

// Output:
// Validation and modification passed!
// &{Name:Simon Data:b10a8db164e0754105b7a99be72e3fe5}
}

// Example of using the URL encoding feature of the validator
func ExampleURLEncode() {
type Req struct {
Data string `modify:"url_encode"`
}

req := &Req{
Data: "Hello World",
}

if err := structs.ValidateAndModify(req); err != nil {
fmt.Println("Validation error:", err)
} else {
fmt.Println("Validation and modification passed!")
fmt.Printf("%+v\n", req)
}

// Output:
// Validation and modification passed!
// &{Data:Hello+World}
}

// CustomValidatorFunc ist eine benutzerdefinierte Validierungsfunktion, die überprüft, ob ein String nur Buchstaben enthält.
func CustomValidatorFuncOnlyLetters(field reflect.Value) error {
if field.Kind() == reflect.String {
str := field.String()
for _, char := range str {
if !unicode.IsLetter(char) {
return errors.New("field contains non-letter characters")
}
}
}
return nil
}

// Example with a custom validation function
func ExampleCustomValidation() {
type User struct {
Name string `validate:"required,onlyletters"`
}

// Register custom validation function
structs.RegisterCustomValidator("onlyletters", CustomValidatorFuncOnlyLetters)

user := &User{
Name: "Abc",
}

if err := structs.ValidateAndModify(user); err != nil {
fmt.Println("Validation error:", err)
} else {
fmt.Println("Validation and modification passed!")
fmt.Printf("%+v\n", user)
}

// Output:
// Validation and modification passed!
// &{Name:Abc}
}
Loading

0 comments on commit 3da0bf1

Please sign in to comment.