### Setup Development Environment Source: https://github.com/sivchari/govalid/blob/main/CONTRIBUTING.md Commands to clone the repository, install dependencies, and install the govalid binary for local development. ```bash git clone https://github.com/yourusername/govalid.git cd govalid go mod download go install ./cmd/govalid/ ``` -------------------------------- ### Bash Development Setup and Build Source: https://github.com/sivchari/govalid/blob/main/README.md Provides instructions for setting up the govalid project locally and building the command-line interface. It includes cloning the repository, installing left-hook, and building the govalid binary. ```bash git clone https://github.com/sivchari/govalid.git cd govalid make install-lefthook ``` ```bash go install ./cmd/govalid/ ``` -------------------------------- ### Quick Start: Define, Generate, Use Source: https://github.com/sivchari/govalid/blob/main/README.md A step-by-step guide to defining a struct with validation markers, generating validation code, and using the generated validator. ```APIDOC ### 1. Define Your Struct ```go //govalid:required type Person struct { Name string `json:"name"` //govalid:email Email string `json:"email"` } ``` ### 2. Generate Validation Code ```bash govalid ./... ``` ### 3. Use the Validator ```go import "log" func main() { p := &Person{Name: "John", Email: "invalid-email"} if err := p.Validate(); err != nil { log.Printf("Validation failed: %v", err) } } ``` ``` -------------------------------- ### Installation and Verification Source: https://github.com/sivchari/govalid/blob/main/README.md Instructions on how to install the govalid CLI tool and verify its installation. ```APIDOC ## Installation ```bash go install github.com/sivchari/govalid/cmd/govalid@latest ``` ### Verify Installation ```bash govalid -h ``` ``` -------------------------------- ### Run govalid Example Source: https://github.com/sivchari/govalid/blob/main/example/README.md Command to navigate to the example directory and run the basic usage example using 'go run'. ```bash cd example go run ./basic-usage/ ``` -------------------------------- ### Install govalid CLI Source: https://context7.com/sivchari/govalid/llms.txt Installs the govalid command-line interface tool using 'go install'. Includes a command to verify the installation by checking the help message. ```bash go install github.com/sivchari/govalid/cmd/govalid@latest # Verify installation govalid -h ``` -------------------------------- ### Install and Verify govalid CLI Source: https://github.com/sivchari/govalid/blob/main/README.md Commands to install the govalid generator tool and verify the installation. ```bash go install github.com/sivchari/govalid/cmd/govalid@latest govalid -h ``` -------------------------------- ### Install govalid CLI Source: https://github.com/sivchari/govalid/blob/main/example/README.md Command to install the govalid command-line tool using go install. This tool is used for generating validation code. ```bash go install github.com/sivchari/govalid/cmd/govalid@latest ``` -------------------------------- ### Go 1.24+ Benchmark Structure Source: https://github.com/sivchari/govalid/blob/main/CLAUDE.md Demonstrates the recommended structure for writing benchmarks in Go 1.24 and later, emphasizing the use of `b.Loop()` for the main testing loop and `b.ResetTimer()` to exclude setup costs. It also includes result verification. ```go package main import "testing" // Placeholder for setup function func setupData() interface{} { // ... setup logic ... return nil } // Placeholder for function under test func functionUnderTest(instance interface{}) interface{} { // ... function logic ... return nil } // Placeholder for expected result const expected = nil func BenchmarkFunction(b *testing.B) { // Setup (runs once) instance := setupData() b.ResetTimer() // Exclude setup time for b.Loop() { // Go 1.24+ preferred method result := functionUnderTest(instance) if result != expected { b.Fatal("unexpected result") } } b.StopTimer() // Optional, for cleanup exclusion } ``` -------------------------------- ### Run Hugo Development Server Source: https://github.com/sivchari/govalid/blob/main/docs/README.md Commands to navigate into the docs directory and start the Hugo development server. This allows for live previewing of documentation changes at http://localhost:1313. ```bash cd docs hugo server -D ``` -------------------------------- ### Install Hugo on macOS and Linux Source: https://github.com/sivchari/govalid/blob/main/docs/README.md Provides commands to install the Hugo static site generator on macOS using Homebrew and on Linux using a downloaded .deb package. Hugo is required for local development and building the documentation website. ```bash # macOS brew install hugo # Linux wget https://github.com/gohugoio/hugo/releases/download/v0.128.0/hugo_extended_0.128.0_linux-amd64.deb sudo dpkg -i hugo_extended_0.128.0_linux-amd64.deb ``` -------------------------------- ### Go: Running the HTTP Server Source: https://github.com/sivchari/govalid/blob/main/docs/content/examples.md This command compiles and runs the Go application, starting the HTTP server on the default port. Ensure that the go generate command has been executed successfully before running this command. ```bash go run . ``` -------------------------------- ### Define Struct and Generate Validation Source: https://github.com/sivchari/govalid/blob/main/README.md Example of defining a struct with govalid markers and triggering code generation. ```go //govalid:required type Person struct { Name string `json:"name"` //govalid:email Email string `json:"email"` } ``` ```bash govalid ./... ``` -------------------------------- ### Migrate Validation Markers Command with Go Source: https://context7.com/sivchari/govalid/llms.txt Provides examples of using the 'govalid migrate' command to update validation marker syntax from the old '// +govalid:' format to the new '//govalid:' format. It includes options for previewing changes (--dry-run) and migrating files recursively or within specific directories. ```Bash # Preview changes without modifying files govalid migrate --dry-run ./... # Migrate all files in current directory govalid migrate # Migrate files recursively govalid migrate ./... # Migrate specific package govalid migrate ./pkg/models ``` -------------------------------- ### Validation Helper Function Example Source: https://github.com/sivchari/govalid/blob/main/CLAUDE.md Defines a Go function for complex validation logic that is externalized from the main validator implementation. It includes usage examples and best practices for decomposition, allocation minimization, and compiler optimization. ```go // Location: validation/validationhelper/{validator_name}.go package validationhelper func IsValid{ValidationName}(input string) bool { // Complex validation logic return true } ``` ```go // In validator implementation func (v *{validator}Validator) Validate() string { return fmt.Sprintf("!validationhelper.IsValid{ValidationName}(t.%s)", v.FieldName()) } func (v *{validator}Validator) Imports() []string { return []string{"github.com/sivchari/govalid/validation/validationhelper"} } // No need for GeneratorMemory management - external function handles it func (v *{validator}Validator) Err() string { // Only generate error variables, no inline functions } ``` -------------------------------- ### Implement Validator Logic Source: https://github.com/sivchari/govalid/blob/main/CONTRIBUTING.md Example implementation of a custom validator struct in Go, demonstrating the Validator interface, validation expression generation, and error handling. ```go package rules import ( "fmt" "go/ast" "go/types" "strings" "github.com/gostaticanalysis/codegen" "github.com/sivchari/govalid/internal/validator" ) type phonenumberValidator struct { pass *codegen.Pass field *ast.Field structName string pattern string } var _ validator.Validator = (*phonenumberValidator)(nil) func (v *phonenumberValidator) Validate() string { return fmt.Sprintf(`!regexp.MustCompile(%q).MatchString(t.%s)`, v.pattern, v.FieldName()) } func (v *phonenumberValidator) FieldName() string { return v.field.Names[0].Name } func (v *phonenumberValidator) Err() string { const errTemplate = ` // [@ERRVARIABLE] is returned when the [@FIELD] fails phonenumber validation. [@ERRVARIABLE] = govaliderrors.ValidationError{Reason:"field [@PATH] must be a valid phone number",Path:"[@PATH]"} ` replacer := strings.NewReplacer( "[@ERRVARIABLE]", c.ErrVariable(), "[@FIELD]", fieldName, "[@PATH]", fmt.Sprintf("%s.%s", c.structName, fieldName), "[@EXPRESSION]", c.expression, ) return replacer.Replace(errTemplate) } func (v *phonenumberValidator) ErrVariable() string { return strings.ReplaceAll("Err[@PATH]PhonenumberValidation", "[@PATH]", v.structName+v.FieldName()) } func (v *phonenumberValidator) Imports() []string { return []string{"regexp"} } func ValidatePhonenumber(pass *codegen.Pass, field *ast.Field, expressions map[string]string, structName string) validator.Validator { typ := pass.TypesInfo.TypeOf(field.Type) basic, ok := typ.Underlying().(*types.Basic) if !ok || basic.Kind() != types.String { return nil } pattern := `^\+?[1-9]\d{1,14}$` if p, ok := expressions["pattern"]; ok { pattern = p } return &phonenumberValidator{ pass: pass, field: field, structName: structName, pattern: pattern, } } ``` -------------------------------- ### Bash: Testing User Creation API with cURL Source: https://github.com/sivchari/govalid/blob/main/docs/content/examples.md This bash script demonstrates how to test the Go user creation API using cURL. It shows examples of sending both valid and invalid JSON payloads to the /users endpoint and displays the expected responses, including successful creation and validation error messages. ```bash # Test with valid data: curl -X POST http://localhost:8080/users \ -H "Content-Type: application/json" \ -d '{ "name": "John Doe", "email": "john@example.com", "password": "secretpassword123", "age": 25, "role": "user", "tags": ["developer", "golang"] }' # Test with invalid data: curl -X POST http://localhost:8080/users \ -H "Content-Type: application/json" \ -d '{ "name": "A", "email": "invalid-email", "password": "123", "age": 200, "role": "superuser", "tags": [] }' ``` -------------------------------- ### HTTP Middleware Integration Source: https://github.com/sivchari/govalid/blob/main/README.md Example of integrating govalid's request validation middleware into an HTTP server. ```APIDOC ### HTTP Middleware Integration ```go import ( "net/http" "github.com/sivchari/govalid/validation/middleware" ) func handler(w http.ResponseWriter, r *http.Request) { // Your handler logic here } func main() { http.HandleFunc("/person", middleware.ValidateRequest[*Person](handler)) http.ListenAndServe(":8080", nil) } ``` ``` -------------------------------- ### Regenerate Validation Code Source: https://github.com/sivchari/govalid/blob/main/example/README.md Commands to navigate to the basic example directory and regenerate validation code using 'go generate'. This is necessary after modifying Go struct definitions. ```bash cd example/basic go generate ./... ``` -------------------------------- ### Generated Validation Function Example Source: https://github.com/sivchari/govalid/blob/main/docs/content/getting-started.md An example of a validation function automatically generated by govalid based on the struct tags. This function performs checks for required fields, email format, age constraints, and maximum length. ```go // Generated validation function func ValidateUser(t *User) error { if t == nil { return ErrNilUser } if t.Name == "" { return ErrNameRequiredValidation } if !emailRegex.MatchString(t.Email) { return ErrEmailEmailValidation } if !(t.Age >= 0) { return ErrAgeGTEValidation } if !(t.Age <= 120) { return ErrAgeLTEValidation } if utf8.RuneCountInString(t.Bio) > 500 { return ErrBioMaxLengthValidation } return nil } ``` -------------------------------- ### Create REST API with govalid validation Source: https://context7.com/sivchari/govalid/llms.txt This example shows how to define a request struct with govalid tags for validation and implement a handler that validates the request body. It includes custom error handling to map validation failures to a structured API response. ```go package main import ( "encoding/json" "errors" "fmt" "log" "net/http" "time" govaliderrors "github.com/sivchari/govalid/validation/errors" ) //go:generate govalid . type CreateProductRequest struct { //govalid:required //govalid:uuid ID string `json:"id"` //govalid:required //govalid:minlength=3 //govalid:maxlength=200 Name string `json:"name"` //govalid:maxlength=2000 Description string `json:"description,omitempty"` //govalid:required //govalid:gt=0 Price float64 `json:"price"` //govalid:required //govalid:enum=electronics,clothing,books,home,sports Category string `json:"category"` //govalid:required //govalid:minitems=1 //govalid:maxitems=10 Images []string `json:"images"` //govalid:maxitems=20 Tags []string `json:"tags,omitempty"` //govalid:gte=0 Stock int `json:"stock"` //govalid:required //govalid:enum=draft,active,inactive Status string `json:"status"` } func createProductHandler(w http.ResponseWriter, r *http.Request) { var req CreateProductRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { sendError(w, http.StatusBadRequest, "Invalid JSON", nil) return } if err := req.ValidateContext(r.Context()); err != nil { var validationErrors govaliderrors.ValidationErrors if errors.As(err, &validationErrors) { details := make([]ErrorDetail, len(validationErrors)) for i, e := range validationErrors { details[i] = ErrorDetail{Field: e.Path, Type: e.Type, Message: e.Reason} } sendError(w, http.StatusBadRequest, "Validation failed", details) return } sendError(w, http.StatusBadRequest, err.Error(), nil) return } product := map[string]interface{}{ "id": req.ID, "name": req.Name, "price": req.Price, "category": req.Category, "status": req.Status, "created_at": time.Now().Format(time.RFC3339), } sendSuccess(w, product) } ``` -------------------------------- ### Organize Validation Rules in Structs Source: https://github.com/sivchari/govalid/blob/main/docs/content/getting-started.md Provides an example of organizing multiple validation rules within a single struct definition. This demonstrates grouping related rules for fields like 'Name', 'Email', and 'Age' to improve code readability and maintainability. ```go type CreateUserRequest struct { // Basic required fields //govalid:required //govalid:minlength=2 //govalid:maxlength=50 Name string `json:"name"` // Email validation //govalid:required //govalid:email Email string `json:"email"` // Age constraints //govalid:gte=13 //govalid:lte=120 Age int `json:"age"` } ``` -------------------------------- ### Using Context-Aware Validation with Timeouts Source: https://github.com/sivchari/govalid/blob/main/docs/content/context-validation.md This Go example shows how to use `context.WithTimeout` to set a deadline for a validation operation. If the validation takes longer than the specified duration, `context.DeadlineExceeded` will be returned. ```Go ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() err := ValidatePersonRequestContext(ctx, &person) if err == context.DeadlineExceeded { log.Println("Validation timed out") } ``` -------------------------------- ### Generated Validation Logic Source: https://github.com/sivchari/govalid/blob/main/docs/content/_index.md An example of the optimized, zero-allocation validation code generated by govalid. ```go // Code generated by govalid; DO NOT EDIT. var ( ErrNilUser = errors.New("input User is nil") ErrUserNameRequiredValidation = errors.New("field Name is required") ErrUserEmailEmailValidation = errors.New("field Email must be a valid email address") ErrUserAgeGTEValidation = errors.New("field Age must be greater than or equal to 18") ErrUserBioMaxLengthValidation = errors.New("field Bio must have at most 100 characters") ) func ValidateUser(t *User) error { if t == nil { return ErrNilUser } if len(t.Name) == 0 { return ErrUserNameRequiredValidation } if !validationhelper.IsValidEmail(t.Email) { return ErrUserEmailEmailValidation } if !(t.Age >= 18) { return ErrUserAgeGTEValidation } if !(utf8.RuneCountInString(t.Bio) <= 100) { return ErrUserBioMaxLengthValidation } return nil } ``` -------------------------------- ### Define Struct with Validation Markers Source: https://github.com/sivchari/govalid/blob/main/docs/content/_index.md Example of a Go struct using govalid marker comments to define validation rules for fields. ```go package main type User struct { //govalid:required Name string `json:"name"` //govalid:email Email string `json:"email"` //govalid:gte=18 Age int `json:"age"` //govalid:maxlength=100 Bio string `json:"bio"` } ``` -------------------------------- ### Commit Message Pattern Example Source: https://github.com/sivchari/govalid/blob/main/CLAUDE.md Illustrates a structured commit message format for the govalid project. This pattern ensures that each commit clearly communicates the action taken, the specific marker or feature implemented, validation logic, performance notes, testing coverage, and documentation updates. ```markdown {Action} {MarkerName} marker implementation - Add {markername} validator with {specific_features} - Implement {validation_logic} with {performance_notes} - Add comprehensive unit tests with boundary value testing - Add benchmarks showing {performance_improvement} - Update documentation and README ``` -------------------------------- ### Using Context-Aware Validation with Cancellation Source: https://github.com/sivchari/govalid/blob/main/docs/content/context-validation.md This Go example demonstrates how to use `context.WithCancel` to manually cancel a validation operation from another goroutine. The validation function will return `context.Canceled` when the context is cancelled. ```Go ctx, cancel := context.WithCancel(context.Background()) go func() { err := ValidatePersonRequestContext(ctx, &person) if err == context.Canceled { log.Println("Validation cancelled") } }() // Cancel from another goroutine cancel() ``` -------------------------------- ### Numeric Comparison Markers (gt, gte, lt, lte) in Go Source: https://context7.com/sivchari/govalid/llms.txt Shows how to use govalid's numeric comparison markers (gt, gte, lt, lte) to validate integer and float fields against specified thresholds. This includes examples for greater than, greater than or equal to, less than, and less than or equal to constraints. ```go type Profile struct { //govalid:gt=0 Age int `json:"age"` // Must be greater than 0 //govalid:gte=18 MinimumAge int `json:"minimum_age"` // Must be >= 18 //govalid:lt=100 Score int `json:"score"` // Must be less than 100 //govalid:lte=1000000 Salary float64 `json:"salary"` // Must be <= 1000000 //govalid:gte=0 //govalid:lte=100 Percentage float64 `json:"percentage"` // Range: 0-100 } // Generated validation: // if t.Age <= 0 { return ErrProfileAgeGtValidation } // if !(t.MinimumAge >= 18) { return ErrProfileMinimumAgeGTEValidation } // if t.Score >= 100 { return ErrProfileScoreLtValidation } // if !(t.Salary <= 1000000) { return ErrProfileSalaryLTEValidation } ``` -------------------------------- ### Markdown for Documentation Update Source: https://github.com/sivchari/govalid/blob/main/CONTRIBUTING.md This markdown snippet shows how to update the main README.md file to include a new validator marker. It specifies the marker name, its description, type, and usage examples. ```markdown | `phonenumber` | Phone number validation | string | `// govalid:phonenumber` or `// govalid:phonenumber,pattern=^\d{10}$` | ``` -------------------------------- ### Test Execution Workflow Source: https://github.com/sivchari/govalid/blob/main/CLAUDE.md Sequence of commands to build, test, benchmark, and lint the project. ```bash go install ./cmd/govalid/ cd test && go generate cd .. && go test ./internal/analyzers/govalid/ -v cd test && go test ./unit/ -v go test ./benchmark/ -bench=Benchmark.*{MarkerName} -benchmem cd .. && make golangci-lint ``` -------------------------------- ### Execute Generated Validation Source: https://github.com/sivchari/govalid/blob/main/docs/content/_index.md Example usage of the generated ValidateUser function in a Go application. ```go func main() { user := &User{ Name: "Alice", Email: "alice@example.com", Age: 25, Bio: "Software developer", } if err := ValidateUser(user); err != nil { log.Fatal(err) } fmt.Println("User is valid!") } ``` -------------------------------- ### Bash Workflow for Linting and Optimization Source: https://github.com/sivchari/govalid/blob/main/CLAUDE.md Provides a bash script demonstrating the post-implementation workflow in the govalid project. It includes steps for linting, running benchmarks, fixing issues, updating documentation, and verifying tests, ensuring code quality and performance. ```bash # After initial implementation make golangci-lint # If lint issues found: # 1. Fix lint issues (may involve code refactoring) # 2. Re-run benchmarks to check for performance changes go test ./benchmark/ -bench=Benchmark.*{MarkerName} -benchmem # 3. Update benchmark README if numbers changed # 4. Verify tests still pass go test ./unit/ -v # 5. Re-run lint to ensure fixes are correct make golangci-lint ``` -------------------------------- ### Advanced CEL and Collection Validation Source: https://github.com/sivchari/govalid/blob/main/README.md Examples of using CEL expressions for complex logic and validating various collection types. ```go type User struct { //govalid:cel=value >= 18 && value <= 120 Age int //govalid:cel=value >= this.Age RetirementAge int } type UserList struct { //govalid:maxitems=10 Users []User //govalid:minitems=1 UserMap map[string]User //govalid:maxitems=5 UserChan chan User } ``` -------------------------------- ### Generate Validation Code with govalid Source: https://github.com/sivchari/govalid/blob/main/docs/content/getting-started.md Shows how to use the govalid CLI to generate validation code for Go packages. It covers generating for the current directory, recursively for all sub-packages, and for a specific package. ```bash # Generate for current package govalid . # Generate for all packages recursively govalid ./... # Generate for specific package govalid ./internal/models ``` -------------------------------- ### Define Validator Golden Tests Source: https://github.com/sivchari/govalid/blob/main/CONTRIBUTING.md Example of defining a struct with validation tags and the corresponding expected generated output for testing the validator. ```go package phonenumber type User struct { // govalid:phonenumber Phone string `json:"phone"` // govalid:phonenumber,pattern=^\\d{3}-\\d{4}$ ZipCode string `json:"zip_code"` } ``` ```go // Code generated by govalid; DO NOT EDIT. package phonenumber import ( "errors" "regexp" ) var ( ErrNilUser = errors.New("input User is nil") ErrUserPhonePhonenumberValidation = errors.New("field Phone must be a valid phone number") ErrUserZipCodePhonenumberValidation = errors.New("field ZipCode must be a valid phone number") ) func ValidateUser(t *User) error { if t == nil { return ErrNilUser } if !regexp.MustCompile(`^\+?[1-9]\d{1,14}$`).MatchString(t.Phone) { return ErrUserPhonePhonenumberValidation } if !regexp.MustCompile(`^\d{3}-\d{4}$`).MatchString(t.ZipCode) { return ErrUserZipCodePhonenumberValidation } return nil } ``` -------------------------------- ### Benchmark Testing Source: https://github.com/sivchari/govalid/blob/main/CLAUDE.md Performance comparison benchmarks between govalid and go-playground/validator implementations. ```go func BenchmarkGoValid{MarkerName}(b *testing.B) { instance := test.{MarkerName}{Field: "test_value"} b.ResetTimer() for b.Loop() { err := test.Validate{MarkerName}(&instance) if err != nil { b.Fatal("unexpected error:", err) } } b.StopTimer() } func BenchmarkGoPlayground{MarkerName}(b *testing.B) { validate := validator.New() instance := test.{MarkerName}{Field: "test_value"} b.ResetTimer() for b.Loop() { err := validate.Struct(&instance) if err != nil { b.Fatal("unexpected error:", err) } } b.StopTimer() } ``` -------------------------------- ### Run govalid Benchmarks Source: https://github.com/sivchari/govalid/blob/main/test/benchmark/README.md Commands to execute performance benchmarks for the govalid library using the Go testing tool. These commands allow for running all benchmarks or targeting specific validation rules. ```bash make sync-benchmarks cd test go test ./benchmark/ -bench=. -benchmem -benchtime=10s go test ./benchmark/ -bench=BenchmarkGoValid{ValidatorName} -benchmem ``` -------------------------------- ### Combine govalid with Standard Library for User Creation Source: https://github.com/sivchari/govalid/blob/main/docs/content/getting-started.md This Go function demonstrates how to integrate govalid for initial struct validation with subsequent business logic validation using standard Go error handling. It first validates the request struct using govalid, then checks for existing users, and finally proceeds with user creation. ```go func CreateUser(req *CreateUserRequest) error { // First, validate the struct if err := ValidateCreateUserRequest(req); err != nil { return fmt.Errorf("validation failed: %w", err) } // Then, perform business logic validation if userExists(req.Email) { return errors.New("user already exists") } // Create the user return createUser(req) } ``` -------------------------------- ### Build Hugo Site for Production Source: https://github.com/sivchari/govalid/blob/main/docs/README.md Command to build the Hugo documentation site for production deployment. The --minify flag optimizes the output by reducing file sizes, and the generated site is placed in the public/ directory. ```bash cd docs hugo --minify ``` -------------------------------- ### Generated Validation Logic Source: https://github.com/sivchari/govalid/blob/main/docs/content/examples.md An example of the code generated by govalid, which includes specific error definitions and a validation function that checks the struct fields against the defined rules. ```go // Code generated by govalid; DO NOT EDIT. package main import ( "errors" "github.com/sivchari/govalid/validation/validationhelper" ) var ( ErrNilUser = errors.New("input User is nil") ErrUserNameRequiredValidation = errors.New("field Name is required") ErrUserEmailRequiredValidation = errors.New("field Email is required") ErrUserEmailEmailValidation = errors.New("field Email must be a valid email address") ErrUserAgeGTEValidation = errors.New("field Age must be greater than or equal to 0") ErrUserAgeLTEValidation = errors.New("field Age must be less than or equal to 120") ) func ValidateUser(t *User) error { if t == nil { return ErrNilUser } if len(t.Name) == 0 { return ErrUserNameRequiredValidation } if len(t.Email) == 0 { return ErrUserEmailRequiredValidation } if !validationhelper.IsValidEmail(t.Email) { return ErrUserEmailEmailValidation } if !(t.Age >= 0) { return ErrUserAgeGTEValidation } if !(t.Age <= 120) { return ErrUserAgeLTEValidation } return nil } ``` -------------------------------- ### Go Validator Implementation Using Helper Source: https://github.com/sivchari/govalid/blob/main/CONTRIBUTING.md This Go code demonstrates how to integrate a validation helper function into a custom validator within the govalid project. It shows how to define the validation rule and specify necessary imports. ```go func (v *phonenumberValidator) Validate() string { return fmt.Sprintf("!validationhelper.IsValidPhoneNumber(t.%s)", v.FieldName()) } func (v *phonenumberValidator) Imports() []string { return []string{"github.com/sivchari/govalid/validation/validationhelper"} } ``` -------------------------------- ### Basic Struct Validation with govalid Source: https://context7.com/sivchari/govalid/llms.txt Demonstrates how to define a Go struct with validation markers in comments and generate validation code using govalid. It shows both a valid and an invalid user struct to illustrate validation success and failure. ```go package main import ( "fmt" "log" ) //go:generate govalid . type User struct { //govalid:required //govalid:minlength=1 //govalid:maxlength=100 Name string `json:"name"` //govalid:required //govalid:email Email string `json:"email"` //govalid:gte=0 //govalid:lte=150 Age int `json:"age"` } func main() { // Valid user passes validation validUser := &User{ Name: "John Doe", Email: "john@example.com", Age: 30, } if err := ValidateUser(validUser); err != nil { log.Fatal(err) } fmt.Println("Valid user passed validation!") // Invalid user fails validation invalidUser := &User{ Name: "", // required violation Email: "invalid-email", // email format violation Age: 200, // lte=150 violation } if err := ValidateUser(invalidUser); err != nil { fmt.Printf("Validation failed: %v\n", err) } } ``` ```bash govalid . # or go generate ./... ``` -------------------------------- ### POST /products - Create Product API Source: https://context7.com/sivchari/govalid/llms.txt This endpoint handles the creation of new products. It expects a JSON payload containing product details and validates them against predefined rules using GoValidate. ```APIDOC ## POST /products ### Description This endpoint creates a new product. It accepts a JSON payload with product details and performs comprehensive validation using GoValidate. ### Method POST ### Endpoint /products ### Parameters #### Request Body - **id** (string) - Required - Must be a valid UUID. - **name** (string) - Required - Minimum length of 3, maximum length of 200. - **description** (string) - Optional - Maximum length of 2000. - **price** (float64) - Required - Must be greater than 0. - **category** (string) - Required - Must be one of: electronics, clothing, books, home, sports. - **images** (array of strings) - Required - Minimum 1 item, maximum 10 items. - **tags** (array of strings) - Optional - Maximum 20 items. - **stock** (int) - Optional - Must be greater than or equal to 0. - **status** (string) - Required - Must be one of: draft, active, inactive. ### Request Example ```json { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Wireless Headphones", "description": "High-quality Bluetooth headphones", "price": 199.99, "category": "electronics", "images": ["img1.jpg", "img2.jpg"], "tags": ["audio", "wireless"], "stock": 100, "status": "active" } ``` ### Response #### Success Response (200) - **success** (bool) - Indicates if the operation was successful. - **data** (object) - Contains the created product details. - **error** (string) - Error message if the operation failed. - **errors** (array of ErrorDetail) - Detailed validation errors. ```json { "success": true, "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Wireless Headphones", "price": 199.99, "category": "electronics", "status": "active", "created_at": "2023-10-27T10:00:00Z" } } ``` #### Error Response (400) - **success** (bool) - Indicates if the operation was successful. - **data** (object) - Contains the created product details. - **error** (string) - Error message if the operation failed. - **errors** (array of ErrorDetail) - Detailed validation errors. ```json { "success": false, "error": "Validation failed", "errors": [ { "field": "id", "type": "uuid", "message": "invalid uuid format" }, { "field": "name", "type": "minlength", "message": "name must be at least 3 characters long" } ] } ``` ``` -------------------------------- ### Go Context-Aware Validation Source: https://github.com/sivchari/govalid/blob/main/README.md Demonstrates how to perform standard and context-aware validation in Go. It shows how to handle timeouts and cancellations using context.Context, which is crucial for HTTP handlers and high-concurrency scenarios. ```go // Standard validation (no context) if err := p.Validate(); err != nil { log.Printf("Validation failed: %v", err) } // Context-aware validation with timeout ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() if err := p.ValidateContext(ctx); err != nil { switch err { case context.DeadlineExceeded: log.Println("Validation timed out") case context.Canceled: log.Println("Validation cancelled") default: log.Printf("Validation failed: %v", err) } } ``` -------------------------------- ### Executing govalid Generation and Execution Source: https://github.com/sivchari/govalid/blob/main/docs/content/examples.md Commands to trigger the code generation process for validation logic and execute the Go application. ```bash go generate . go run . ``` -------------------------------- ### Go Template Integration for Dynamic Imports Source: https://github.com/sivchari/govalid/blob/main/CLAUDE.md Illustrates a Go template structure for passing data, including package name, type name, metadata, and dynamically collected import packages. The template then iterates over these imports to generate import statements. ```go package main // Template data structure type TemplateData struct { PackageName string TypeName string Metadata []*AnalyzedMetadata // Assuming AnalyzedMetadata is defined elsewhere ImportPackages map[string]struct{} // Dynamic imports } // AnalyzedMetadata placeholder for context type AnalyzedMetadata struct { Validators []Validator // Assuming Validator interface is defined elsewhere } ``` ```go-template {{- range $pkg, $_ := .ImportPackages }} "{{ $pkg }}" {{- end }} ``` -------------------------------- ### Bash Script for Test Execution Source: https://github.com/sivchari/govalid/blob/main/CONTRIBUTING.md This bash script outlines the steps required to execute various tests and checks for the govalid project. It includes building the binary, generating test files, running golden tests, unit tests, benchmarks, and lint checks. ```bash # 1. Build and install updated binary go install ./cmd/govalid/ # 2. Generate test files cd test && go generate # 3. Run golden tests cd .. && go test ./internal/analyzers/govalid/ -v # 4. Run unit tests cd test && go test ./unit/ -v # 5. Run benchmarks go test ./benchmark/ -bench=Benchmark.*Phonenumber -benchmem # 6. Run lint checks make golangci-lint # 7. Update benchmark README with results # Edit test/benchmark/README.md ``` -------------------------------- ### Initialize Feature Branch Source: https://github.com/sivchari/govalid/blob/main/CLAUDE.md Command to create a new feature branch for developing a specific validator marker. ```bash git checkout -b feature/{marker-name}-marker ``` -------------------------------- ### Basic Validation Error Handling in Go Source: https://github.com/sivchari/govalid/blob/main/docs/content/examples.md Demonstrates how to perform basic validation on a struct and handle the resulting error by logging it and returning a user-friendly message. ```go if err := ValidateStruct(data); err != nil { log.Printf("Validation failed: %v", err) return fmt.Errorf("invalid data: %w", err) } ``` -------------------------------- ### Integrate govalid with Go Generate Source: https://github.com/sivchari/govalid/blob/main/docs/content/getting-started.md Explains how to use the `go:generate` directive to automatically run govalid during the Go generation process. This ensures validation code is always up-to-date with struct definitions. ```go //go:generate govalid . package main type User struct { //govalid:required Name string `json:"name"` } ``` -------------------------------- ### Go: User Creation HTTP Handler with govalid Source: https://github.com/sivchari/govalid/blob/main/docs/content/examples.md This Go code defines a CreateUserRequest struct with govalid annotations for validation rules. It includes an HTTP handler that decodes the JSON request, validates it using the generated govalid function, and simulates user creation. The handler returns either a success response with the created user or a 400 Bad Request error if validation fails. ```go package main import ( "encoding/json" "fmt" "log" "net/http" "time" ) //go:generate govalid . type CreateUserRequest struct { //govalid:required //govalid:minlength=2 //govalid:maxlength=50 Name string `json:"name"` //govalid:required //govalid:email Email string `json:"email"` //govalid:required //govalid:minlength=8 //govalid:maxlength=100 Password string `json:"password"` //govalid:gte=13 //govalid:lte=120 Age int `json:"age"` //govalid:enum=admin,user,guest Role string `json:"role"` //govalid:maxitems=10 Tags []string `json:"tags,omitempty"` } type User struct { ID string `json:"id"` Name string `json:"name"` Email string `json:"email"` Age int `json:"age"` Role string `json:"role"` Tags []string `json:"tags,omitempty"` CreatedAt time.Time `json:"created_at"` } func createUserHandler(w http.ResponseWriter, r *http.Request) { var req CreateUserRequest // Parse JSON request if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "Invalid JSON", http.StatusBadRequest) return } // Validate the request using generated function if err := ValidateCreateUserRequest(&req); err != nil { http.Error(w, fmt.Sprintf("Validation failed: %v", err), http.StatusBadRequest) return } // Process the valid request user := createUser(req) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(user) } func createUser(req CreateUserRequest) *User { // Simulate user creation return &User{ ID: "user-123", Name: req.Name, Email: req.Email, Age: req.Age, Role: req.Role, Tags: req.Tags, CreatedAt: time.Now(), } } func main() { http.HandleFunc("/users", createUserHandler) log.Println("Server starting on :8080") log.Fatal(http.ListenAndServe(":8080", nil)) } ``` -------------------------------- ### Execute Validation and Business Logic Source: https://github.com/sivchari/govalid/blob/main/docs/content/examples.md This snippet shows how to invoke the generated validation function and integrate custom business logic validation. It demonstrates checking for field constraints followed by domain-specific rules. ```go func CreateTask(task *Task) error { if err := ValidateTask(task); err != nil { return fmt.Errorf("invalid task: %w", err) } if task.Priority == PriorityHigh && task.AssignedToRole == RoleGuest { return fmt.Errorf("high priority tasks cannot be assigned to guests") } return nil } ``` -------------------------------- ### Handle Validation Errors Source: https://github.com/sivchari/govalid/blob/main/README.md Demonstrates how to check for specific validation errors using errors.Is. ```go if err := p.Validate(); err != nil { if errors.Is(err, ErrPersonEmailEmailValidation) { // Handle email error } if errors.Is(err, ErrPersonNameRequiredValidation) { // Handle required error } } ``` -------------------------------- ### Perform Context-Aware Validation Source: https://context7.com/sivchari/govalid/llms.txt Shows how to generate and utilize context-aware validation methods, allowing for request cancellation and timeout handling during the validation process. ```go ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() if err := person.ValidateContext(ctx); err != nil { if errors.Is(err, context.DeadlineExceeded) { log.Println("Validation timed out") } } ``` -------------------------------- ### String Length Markers (minlength, maxlength, length) in Go Source: https://context7.com/sivchari/govalid/llms.txt Demonstrates the use of govalid's string length validation markers (minlength, maxlength, length) for Go structs. These markers enforce specific character count constraints on string fields, using Unicode-aware counting. ```go type CreateUserRequest struct { //govalid:required //govalid:minlength=2 //govalid:maxlength=50 Name string `json:"name"` // 2-50 characters //govalid:maxlength=500 Bio string `json:"bio"` // Max 500 characters //govalid:length=7 PostalCode string `json:"postal_code"` // Exactly 7 characters //govalid:minlength=8 //govalid:maxlength=100 Password string `json:"password"` // 8-100 characters } // Generated validation: // if utf8.RuneCountInString(t.Name) < 2 { return ErrNameMinLengthValidation } // if utf8.RuneCountInString(t.Name) > 50 { return ErrNameMaxLengthValidation } // if utf8.RuneCountInString(t.PostalCode) != 7 { return ErrPostalCodeLengthValidation } ``` -------------------------------- ### Integrate HTTP Middleware Source: https://github.com/sivchari/govalid/blob/main/README.md Using govalid middleware to automatically validate incoming HTTP requests. ```go import "github.com/sivchari/govalid/validation/middleware" func main() { http.HandleFunc("/person", middleware.ValidateRequest[*Person](handler)) http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Go Interface-Based Import System Source: https://github.com/sivchari/govalid/blob/main/CLAUDE.md Defines a Validator interface for dynamic import declarations and a function to collect unique import packages from analyzed metadata. This system promotes flexible dependency management. ```go package main // Validator interface type Validator interface { Validate() string FieldName() string Err() string ErrVariable() string Imports() []string // Dynamic import declaration } // AnalyzedMetadata placeholder for context type AnalyzedMetadata struct { Validators []Validator } // Collector function func collectImportPackages(metadata []*AnalyzedMetadata) map[string]struct{} { packages := make(map[string]struct{}) for _, meta := range metadata { for _, validator := range meta.Validators { for _, pkg := range validator.Imports() { packages[pkg] = struct{}{} } } } return packages } ``` -------------------------------- ### Generate and Run Validation Commands Source: https://github.com/sivchari/govalid/blob/main/docs/content/examples.md Terminal commands required to trigger the govalid code generation process and execute the resulting Go program. ```bash # Generate the validation code go generate . # Run the program go run . ``` -------------------------------- ### Migrating to Context-Aware Validation Source: https://github.com/sivchari/govalid/blob/main/docs/content/context-validation.md This Go snippet illustrates the migration path from non-context-aware validation to context-aware validation. The primary change involves wrapping the validation call with `context.WithTimeout` and using the context-aware validation function. ```Go // Before err := ValidatePersonRequest(&person) // After (with context) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() err := ValidatePersonRequestContext(ctx, &person) ``` -------------------------------- ### Validator Registry Pattern Source: https://github.com/sivchari/govalid/blob/main/CLAUDE.md Interface and initializer structure for the automated validator discovery system. ```go type Registry interface { Markers() []string Validator(marker string) (ValidatorFactory, error) Init() error } type PhoneNumberInitializer struct{} func (p PhoneNumberInitializer) Marker() string { return markers.GoValidMarkerPhoneNumber } func (p PhoneNumberInitializer) Init() registry.ValidatorFactory { return rules.ValidatePhoneNumber } ``` -------------------------------- ### Advanced Validation with Specific Error Handling Source: https://github.com/sivchari/govalid/blob/main/docs/content/examples.md Shows how to define a struct with govalid tags and use errors.Is to perform granular error handling based on specific validation failures. ```go type User struct { //govalid:required Name string `json:"name"` //govalid:required //govalid:email Email string `json:"email"` //govalid:gte=18 Age int `json:"age"` } func ProcessUser(user *User) error { if err := ValidateUser(user); err != nil { if errors.Is(err, ErrUserNameRequiredValidation) { return fmt.Errorf("user name is mandatory") } // ... additional error checks return fmt.Errorf("validation failed: %w", err) } return nil } ``` -------------------------------- ### Define and Validate Structs with govalid Source: https://github.com/sivchari/govalid/blob/main/docs/layouts/index.html This snippet demonstrates how to define a Go struct with govalid markers and invoke the generated validation function. The markers define constraints such as required fields, minimum lengths, email formats, and numeric ranges. ```go type User struct { // +govalid:required // +govalid:minlength=2 Name string `json:"name"` // +govalid:email Email string `json:"email"` // +govalid:gte=18 Age int `json:"age"` } // Use generated validation user := &User{ Name: "Alice", Email: "alice@example.com", Age: 25, } if err := ValidateUser(user); err != nil { log.Fatal(err) } ``` ```bash govalid . ```