### Quick Start: Poxxy Schema Definition and Validation in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates the basic usage of Poxxy for defining a schema with default values, transformers, and validators, and applying it to a data map. It shows how to initialize a schema, apply it to data, and handle validation errors. Dependencies include the 'github.com/arkan/poxxy' package and standard Go libraries. ```go package main import ( "fmt" "time" "github.com/arkan/poxxy" ) func main() { var name string var email string var age int var createdAt time.Time schema := poxxy.NewSchema( poxxy.Value("name", &name, poxxy.WithDefault("Anonymous"), poxxy.WithTransformers( poxxy.TrimSpace(), poxxy.Capitalize(), ), poxxy.WithValidators(poxxy.Required()), ), poxxy.Value("email", &email, poxxy.WithTransformers(poxxy.SanitizeEmail()), poxxy.WithValidators(poxxy.Required(), poxxy.Email()), ), poxxy.Value("age", &age, poxxy.WithDefault(25), poxxy.WithValidators(poxxy.Min(18), poxxy.Max(120)), ), poxxy.Convert("created_at", &createdAt, func(dateStr string) (time.Time, error) { return time.Parse("2006-01-02", dateStr) }, poxxy.WithDefault(time.Now())), ) data := map[string]interface{}{ "name": " john doe ", "email": " JOHN.DOE@EXAMPLE.COM ", "created_at": "2024-01-15", // age will use default value } if err := schema.Apply(data); err != nil { fmt.Printf("Validation failed: %v\n", err) return } fmt.Printf("Name: '%s'\n", name) // Output: Name: 'John doe' fmt.Printf("Email: '%s'\n", email) // Output: Email: 'john.doe@example.com' fmt.Printf("Age: %d\n", age) // Output: Age: 25 fmt.Printf("Created At: %v\n", createdAt) // Output: Created At: 2024-01-15 00:00:00 +0000 UTC } ``` -------------------------------- ### Field Consistency Validation Example Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates how to define a schema for an Order struct with nested OrderItem structs, enforcing various validations like required fields, positive values, subtotal correctness, unique product IDs, currency restrictions, discount limits, and final total consistency. ```APIDOC ## Complex Cross-Field Validations ### Field Consistency Validation This section illustrates how to perform complex validations on nested structures like `Order` and `OrderItem` using `poxxy.NewSchema`. #### Order Schema Definition - **Items** (`[]OrderItem`) - Required. Each item must have a non-empty `ProductID`, positive `Quantity` and `Price`. The `Subtotal` must match `Quantity * Price`. - **Total** (`float64`) - Must be non-negative. - **Currency** (`string`) - Must be one of "USD", "EUR", or "GBP". - **Discount** (`float64`) - Must be between 0 and 100 (inclusive). - **FinalTotal** (`float64`) - Must be consistent with `Total * (1 - Discount/100)`. ```go type Order struct { Items []OrderItem `json:"items"` Total float64 `json:"total"` Currency string `json:"currency"` Discount float64 `json:"discount"` FinalTotal float64 `json:"final_total"` } type OrderItem struct { ProductID string `json:"product_id"` Quantity int `json:"quantity"` Price float64 `json:"price"` Subtotal float64 `json:"subtotal"` } var order Order schema := poxxy.NewSchema( poxxy.Struct("order", &order, poxxy.WithSubSchema(func(s *poxxy.Schema, o *Order) { poxxy.WithSchema(s, poxxy.Slice("items", &o.Items, poxxy.WithValidators( poxxy.Required(), poxxy.Each( poxxy.ValidatorFunc(func(item OrderItem, fieldName string) error { if item.ProductID == "" { return fmt.Errorf("product ID is required") } if item.Quantity <= 0 { return fmt.Errorf("quantity must be positive") } if item.Price <= 0 { return fmt.Errorf("price must be positive") } // Check that the subtotal is correct expectedSubtotal := float64(item.Quantity) * item.Price if item.Subtotal != expectedSubtotal { return fmt.Errorf("subtotal mismatch: expected %.2f, got %.2f", expectedSubtotal, item.Subtotal) } return nil }), ), poxxy.UniqueBy(func(item interface{}) interface{} { return item.(OrderItem).ProductID }), ), )) poxxy.WithSchema(s, poxxy.Value("total", &o.Total, poxxy.WithValidators(poxxy.Min(0)), )) poxxy.WithSchema(s, poxxy.Value("currency", &o.Currency, poxxy.WithValidators(poxxy.In("USD", "EUR", "GBP")), )) poxxy.WithSchema(s, poxxy.Value("discount", &o.Discount, poxxy.WithValidators(poxxy.Min(0), poxxy.Max(100)), )) poxxy.WithSchema(s, poxxy.Value("final_total", &o.FinalTotal, poxxy.WithValidators( poxxy.ValidatorFunc(func(finalTotal float64, fieldName string) error { // Check that the final total is consistent expectedTotal := o.Total * (1 - o.Discount/100) if finalTotal != expectedTotal { return fmt.Errorf("final total mismatch: expected %.2f, got %.2f", expectedTotal, finalTotal) } return nil }), ), )) })), ) ``` ``` -------------------------------- ### Go: Validate HTTP Request with poxxy ApplyHTTPRequest Source: https://github.com/arkan/poxxy/blob/main/README.md Provides a Go example of validating an incoming HTTP request using `schema.ApplyHTTPRequest(r)`. This method automatically detects the content type (JSON, form data, query parameters) and applies the defined schema validation. Errors are returned as `http.StatusBadRequest`. ```go func handleRequest(w http.ResponseWriter, r *http.Request) { var user User schema := poxxy.NewSchema( poxxy.Value("name", &user.Name, poxxy.WithValidators(poxxy.Required())), poxxy.Value("email", &user.Email, poxxy.WithValidators(poxxy.Required(), poxxy.Email())), ) if err := schema.ApplyHTTPRequest(r); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // Process validated user data } ``` -------------------------------- ### Set Default Boolean Value with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Example of setting a default boolean value using Poxxy. If the boolean field is not provided in the input data, it will default to true. ```go poxxy.WithDefault(true) ``` -------------------------------- ### Validate Permissions with Custom Logic in Go Source: https://github.com/arkan/poxxy/blob/main/README.md This Go example shows how to validate permissions using Poxxy with custom validator functions. It defines a schema for a nested map 'permissions', ensuring keys are valid permission names ('read', 'write', 'delete', 'admin'). The poxxy.ValidatorFunc is used to implement this custom validation. ```go var permissions map[string]bool schema := poxxy.NewSchema( poxxy.NestedMap("permissions", &permissions, func(s *poxxy.Schema, key string, value *bool) { // Key validation (must be a valid permission name) poxxy.WithSchema(s, poxxy.ValueWithoutAssign("key", poxxy.WithValidators( poxxy.Required(), poxxy.ValidatorFunc(func(key string, fieldName string) error { validPermissions := []string{"read", "write", "delete", "admin"} for _, perm := range validPermissions { if key == perm { return nil } } return fmt.Errorf("invalid permission: %s", key) }), ), )) }), ) ``` -------------------------------- ### Set Default Integer Value with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Example of setting a default integer value using Poxxy. If the integer field is not provided in the input data, it will default to 25. ```go poxxy.WithDefault(25) ``` -------------------------------- ### Set Default String Value with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Example of setting a default string value using Poxxy. If the 'Anonymous' field is not provided in the input data, it will default to 'Anonymous'. ```go poxxy.WithDefault("Anonymous") ``` -------------------------------- ### Go: Create Custom String Validator with poxxy Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates creating a custom validator function using `poxxy.ValidatorFunc` in Go. This example creates a validator that checks if a string value contains the '@' symbol, returning an error if it's missing. Custom validators allow for flexible and specific data validation rules. ```go poxxy.ValidatorFunc(func(value string, fieldName string) error { if !strings.Contains(value, "@") { return fmt.Errorf("must contain @ symbol") } return nil }) ``` -------------------------------- ### Set Default Map Value with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Example of setting a default map value using Poxxy. If the map field is not provided, it will default to a map containing {'theme': 'dark'}. ```go poxxy.WithDefault(map[string]string{"theme": "dark"}) ``` -------------------------------- ### Poxxy: HTTPMap Field for Form Data with Schema in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates the use of `HTTPMap` fields in Poxxy for handling complex HTTP form data, converting it into typed structures with nested validation. This example defines an `Attachment` struct and uses `poxxy.HTTPMap` to validate a map of attachments, including default values and specific field validators. ```go type Attachment struct { URL string `json:"url"` Filename string `json:"filename"` Size int `json:"size"` } var attachments map[string]Attachment defaultAttachments := map[string]Attachment{ "default": { URL: "https://example.com/default.pdf", Filename: "default.pdf", Size: 1024, }, } schema := poxxy.NewSchema( poxxy.HTTPMap("attachments", &attachments, func(s *poxxy.Schema, a *Attachment) { poxxy.WithSchema(s, poxxy.Value("url", &a.URL, poxxy.WithValidators(poxxy.Required(), poxxy.URL()), poxxy.WithDescription("Attachment URL"), )) poxxy.WithSchema(s, poxxy.Value("filename", &a.Filename, poxxy.WithValidators(poxxy.Required(), poxxy.MinLength(1)), poxxy.WithTransformers(poxxy.TrimSpace()), )) poxxy.WithSchema(s, poxxy.Value("size", &a.Size, poxxy.WithDefault(0), poxxy.WithValidators(poxxy.Min(0)), )) }, poxxy.WithDefault(defaultAttachments)), ) ``` -------------------------------- ### Schema Options Source: https://github.com/arkan/poxxy/blob/main/README.md Covers schema options, including how to skip the validation phase for specific use cases like data transformation. ```APIDOC ## Schema Options ### Skip Validators Skip the validation phase, which can be useful for data transformation tasks where validation is not immediately required. - **poxxy.WithSkipValidators(true)**: Option to pass during schema application. #### Usage: ```go schema.Apply(data, poxxy.WithSkipValidators(true)) ``` ``` -------------------------------- ### Apply String Transformer: Capitalize with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates using the Capitalize() transformer with Poxxy to capitalize the first letter of a string (e.g., 'hello world' becomes 'Hello world') before validation and assignment. ```go poxxy.WithTransformers(poxxy.Capitalize()) ``` -------------------------------- ### Apply String Transformer: TitleCase with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates using the TitleCase() transformer with Poxxy to convert string values to title case (e.g., 'hello world' becomes 'Hello World') before validation and assignment. ```go poxxy.WithTransformers(poxxy.TitleCase()) ``` -------------------------------- ### Apply String Transformer: ToLower with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates using the ToLower() transformer with Poxxy to convert string values to lowercase before they are validated and assigned. ```go poxxy.WithTransformers(poxxy.ToLower()) ``` -------------------------------- ### Apply String Transformer: ToUpper with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates using the ToUpper() transformer with Poxxy to convert string values to uppercase before they are validated and assigned. ```go poxxy.WithTransformers(poxxy.ToUpper()) ``` -------------------------------- ### Apply String Transformer: TrimSpace with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates using the TrimSpace() transformer with Poxxy to remove leading and trailing whitespace from string values before validation and assignment. ```go poxxy.WithTransformers(poxxy.TrimSpace()) ``` -------------------------------- ### Validate Configuration Parameters with Poxxy Go Source: https://github.com/arkan/poxxy/blob/main/README.md This Go snippet demonstrates how to validate configuration parameters using Poxxy's schema validation. It defines a schema for a nested map named 'config', specifying required keys and minimum length for values. Dependencies include the poxxy library. ```go var config map[string]string schema := poxxy.NewSchema( poxxy.NestedMap("config", &config, func(s *poxxy.Schema, key string, value *string) { // Key validation poxxy.WithSchema(s, poxxy.ValueWithoutAssign("key", poxxy.WithValidators( poxxy.Required(), poxxy.In("theme", "language", "timezone", "currency"), ), )) // Value validation poxxy.WithSchema(s, poxxy.ValueWithoutAssign("value", poxxy.WithValidators(poxxy.Required(), poxxy.MinLength(1)), )) }), ) ``` -------------------------------- ### Poxxy: Defining Basic Value Fields in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Illustrates how to define a basic value field in Poxxy for simple data types like strings and integers. This involves using the `poxxy.Value` function with a field name, a pointer to the variable, and optional configuration options. ```go var name string poxxy.Value("name", &name, opts...) ``` -------------------------------- ### Convert String to *time.Time with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates using Poxxy's ConvertPointer function to parse a date-time string into a pointer to a time.Time object. It includes error handling for parsing failures. ```go var updatedAt *time.Time poxxy.ConvertPointer("updated_at", &updatedAt, func(dateStr string) (*time.Time, error) { t, err := time.Parse("2006-01-02T15:04:05Z", dateStr) if err != nil { return nil, err } return &t, nil }, opts...) ``` -------------------------------- ### Manage User Data with Validation and Transformations in Go Source: https://github.com/arkan/poxxy/blob/main/README.md This Go code snippet defines a `User` struct and demonstrates how to create a Poxxy schema for validating and transforming user data, specifically for use with HTTP requests. It includes validators for required fields, minimum length, email format, and age ranges, along with transformers for trimming whitespace, capitalizing names, and sanitizing emails. This schema is intended to be applied to an incoming HTTP request for user data management. ```go type User struct { Name string `json:"name"` Email string `json:"email"` Age int `json:"age"` } var users map[int]User schema := poxxy.NewSchema( poxxy.HTTPMap("users", &users, func(s *poxxy.Schema, u *User) { poxxy.WithSchema(s, poxxy.Value("name", &u.Name, poxxy.WithValidators(poxxy.Required(), poxxy.MinLength(2)), poxxy.WithTransformers(poxxy.TrimSpace(), poxxy.Capitalize()), )) poxxy.WithSchema(s, poxxy.Value("email", &u.Email, poxxy.WithValidators(poxxy.Required(), poxxy.Email()), poxxy.WithTransformers(poxxy.SanitizeEmail()), )) poxxy.WithSchema(s, poxxy.Value("age", &u.Age, poxxy.WithValidators(poxxy.Min(18), poxxy.Max(120)), )) }), ) ``` -------------------------------- ### HTTP Integration Source: https://github.com/arkan/poxxy/blob/main/README.md Explains how to integrate Poxxy validation with HTTP requests, including automatic content-type detection and direct JSON validation. ```APIDOC ## HTTP Integration Integrate Poxxy validation seamlessly with HTTP request handling. ### ApplyHTTPRequest Validates HTTP requests, automatically detecting the content type and parsing the request body or query parameters. - **Supported Content Types**: `application/json`, `application/x-www-form-urlencoded`, and query parameters (no content type specified). #### Example: ```go func handleRequest(w http.ResponseWriter, r *http.Request) { var user User schema := poxxy.NewSchema( poxxy.Value("name", &user.Name, poxxy.WithValidators(poxxy.Required())), poxxy.Value("email", &user.Email, poxxy.WithValidators(poxxy.Required(), poxxy.Email())), ) if err := schema.ApplyHTTPRequest(r); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // Process validated user data } ``` ### ApplyJSON Validates raw JSON data directly. #### Example: ```go jsonData := `{"name": "John", "email": "john@example.com"}` if err := schema.ApplyJSON([]byte(jsonData)); err != nil { // Handle validation error } ``` ``` -------------------------------- ### Create URL Normalization Transformer in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Develops a custom transformer to normalize URLs by trimming whitespace, adding a default 'https://' protocol if missing, and converting the URL to lowercase. This ensures consistency for URL fields within a Poxxy schema, combined with required and URL format validation. ```go // URL normalization transformer urlNormalizer := poxxy.CustomTransformer(func(url string) (string, error) { url = strings.TrimSpace(url) // Add protocol if missing if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { url = "https://" + url } // Normalize to lowercase url = strings.ToLower(url) return url, nil }) var normalizedURL string schema := poxxy.NewSchema( poxxy.Value("url", &normalizedURL, poxxy.WithTransformers(urlNormalizer), poxxy.WithValidators(poxxy.Required(), poxxy.URL()), ), ) ``` -------------------------------- ### Apply Multiple Validators in Poxxy Schema in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates how to apply a combination of built-in validators such as `Required`, `Email`, `Min`, `Max`, `MinLength`, and `MaxLength` to fields within a Poxxy schema. This allows for comprehensive data integrity checks. ```go poxxy.WithValidators( poxxy.Required(), poxxy.Email(), poxxy.Min(18), poxxy.Max(120), poxxy.MinLength(3), poxxy.MaxLength(50), ) ``` -------------------------------- ### Poxxy: Defining Array Fields in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Illustrates the definition of fixed-size array fields using Poxxy. The `poxxy.Array` function is employed, requiring the field name, a pointer to the array variable, and any applicable options. ```go var coords [2]float64 poxxy.Array("coords", &coords, opts...) ``` -------------------------------- ### Implement Date and Type Conversion in Go with Poxxy Source: https://github.com/arkan/poxxy/blob/main/README.md This Go code demonstrates Poxxy's ability to convert string representations of dates into time.Time objects and handle Unix timestamps. It shows custom conversion functions for different date formats and includes validators and transformers for robust data handling. ```go var createdAt time.Time var updatedAt *time.Time var unixTimestamp int64 schema := poxxy.NewSchema( poxxy.Convert("created_at", &createdAt, func(dateStr string) (*time.Time, error) { t, err := time.Parse("2006-01-02", dateStr) if err != nil { return nil, err } return &t, nil }, poxxy.WithValidators(poxxy.Required())), poxxy.ConvertPointer("updated_at", &updatedAt, func(dateStr string) (*time.Time, error) { t, err := time.Parse("2006-01-02T15:04:05Z", dateStr) if err != nil { return nil, err } return &t, nil }), poxxy.Convert("timestamp", &unixTimestamp, func(unixTime int64) (*int64, error) { return &unixTime, nil }, poxxy.WithTransformers(poxxy.CustomTransformer(func(timestamp int64) (int64, error) { // Ensure timestamp is not in the future if timestamp > time.Now().Unix() { return 0, fmt.Errorf("timestamp cannot be in the future") } return timestamp, nil }))), ) ``` -------------------------------- ### Apply String Transformer: SanitizeEmail with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates using the SanitizeEmail() transformer with Poxxy to normalize email addresses (e.g., convert to lowercase, trim whitespace) before validation and assignment. ```go poxxy.WithTransformers(poxxy.SanitizeEmail()) ``` -------------------------------- ### Add Field Description in Poxxy Schema in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Shows how to use `WithDescription` to add a human-readable description to a field in a Poxxy schema. This is useful for generating better error messages and enhancing documentation. ```go poxxy.WithDescription("User's full name") ``` -------------------------------- ### Handle File Uploads with HTTP Validation in Go Source: https://github.com/arkan/poxxy/blob/main/README.md This Go function demonstrates how to handle file uploads by validating form data using Poxxy schemas. It defines a schema for attachments, applying validators for required fields, URL format, size constraints, and transformers for trimming whitespace. The schema is applied to an incoming HTTP request, and errors are returned if validation fails. Processed attachments are then printed. ```go func handleFileUpload(w http.ResponseWriter, r *http.Request) { var attachments map[string]Attachment schema := poxxy.NewSchema( poxxy.HTTPMap("attachments", &attachments, func(s *poxxy.Schema, a *Attachment) { poxxy.WithSchema(s, poxxy.Value("url", &a.URL, poxxy.WithValidators(poxxy.Required(), poxxy.URL()), )) poxxy.WithSchema(s, poxxy.Value("filename", &a.Filename, poxxy.WithValidators(poxxy.Required()), poxxy.WithTransformers(poxxy.TrimSpace()), )) poxxy.WithSchema(s, poxxy.Value("size", &a.Size, poxxy.WithValidators(poxxy.Min(1), poxxy.Max(10*1024*1024)), // Max 10MB )) }), ) if err := schema.ApplyHTTPRequest(r); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // Process validated attachments for key, attachment := range attachments { fmt.Printf("Attachment %s: %s (%d bytes)\n", key, attachment.Filename, attachment.Size) } } ``` -------------------------------- ### Convert String to Time.Time with Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Shows how to use Poxxy's Convert function to parse a date string into a time.Time object. It defines a custom parsing function for the 'created_at' field. ```go var createdAt time.Time poxxy.Convert("created_at", &createdAt, func(dateStr string) (time.Time, error) { return time.Parse("2006-01-02", dateStr) }, opts...) ``` -------------------------------- ### Poxxy: Defining Map Fields with Default Values in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Shows how to define map fields in Poxxy, including the ability to set default values. The `poxxy.Map` function is used, and the `poxxy.WithDefault` option can be provided with a map literal. ```go var settings map[string]string poxxy.Map("settings", &settings, opts...) // With default values defaultSettings := map[string]string{ "theme": "dark", "lang": "en", } poxxy.Map("settings", &settings, poxxy.WithDefault(defaultSettings), opts...) ``` -------------------------------- ### Go: Handle poxxy Validation Errors and Field Information Source: https://github.com/arkan/poxxy/blob/main/README.md Shows how to catch and iterate through validation errors generated by `schema.Apply(data)` in Go. It demonstrates type assertion to `poxxy.Errors` and then loops through individual `FieldError` details, printing the field name and its specific error message. ```go if err := schema.Apply(data); err != nil { if errors, ok := err.(poxxy.Errors); ok { for _, fieldError := range errors { fmt.Printf("Field '%s': %v\n", fieldError.Field, fieldError.Error) } } } ``` -------------------------------- ### Error Handling Source: https://github.com/arkan/poxxy/blob/main/README.md Details the types of errors returned by Poxxy and how to access detailed information about validation failures. ```APIDOC ## Error Handling Understand and handle validation errors effectively. ### Error Types - **FieldError**: Represents an error for a specific field. - **Errors**: A collection of `FieldError` instances. ### Error Information Each error provides: - **Field**: The name of the field that failed validation. - **Error**: A description of the validation failure. - **Field Description**: (Optional) A description of the field if provided during schema definition. #### Example: ```go if err := schema.Apply(data); err != nil { if errors, ok := err.(poxxy.Errors); ok { for _, fieldError := range errors { fmt.Printf("Field '%s': %v\n", fieldError.Field, fieldError.Error) } } } ``` ``` -------------------------------- ### Custom Validators Source: https://github.com/arkan/poxxy/blob/main/README.md Explains how to create custom validation logic using `poxxy.ValidatorFunc` for specific field requirements not covered by built-in validators. ```APIDOC ### Custom Validators Create custom validation functions to enforce specific business rules. - **ValidatorFunc**: A function that takes the field's value and its name, returning an `error` if validation fails. #### Example: Email format validation ```go poxxy.ValidatorFunc(func(value string, fieldName string) error { if !strings.Contains(value, "@") { return fmt.Errorf("must contain @ symbol") } return nil }) ``` ``` -------------------------------- ### Migrate Email Transformation in Go with Poxxy Source: https://github.com/arkan/poxxy/blob/main/README.md This Go code illustrates the migration from the deprecated Poxxy 'Transform' field to the integrated 'WithTransformers' approach. It shows how to sanitize email addresses by converting them to lowercase and trimming whitespace using a custom transformer. ```go // Old way (removed) // poxxy.Transform[string, string]("email", &email, func(email string) (string, error) { // return strings.ToLower(strings.TrimSpace(email)), nil // }) // New way // poxxy.Value("email", &email, // poxxy.WithTransformers( // poxxy.SanitizeEmail(), // ), // ) ``` -------------------------------- ### Poxxy: Defining Pointer Fields in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Shows how to define a pointer field in Poxxy, suitable for optional values or complex struct pointers. The `poxxy.Pointer` function is used, accepting the field name, a pointer to the pointer variable, and configuration options. ```go var user *User poxxy.Pointer("user", &user, opts...) ``` -------------------------------- ### Go: Validate JSON Data Directly with poxxy ApplyJSON Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates validating raw JSON data as a byte slice using `schema.ApplyJSON([]byte(jsonData))` in Go. This function parses the JSON and applies the schema validation rules. Errors during parsing or validation are handled accordingly. ```go jsonData := `{"name": "John", "email": "john@example.com"}` if err := schema.ApplyJSON([]byte(jsonData)); err != nil { // Handle validation error } ``` -------------------------------- ### Create Currency Formatting Transformer in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Develops a custom transformer to format a float64 amount into a currency string (e.g., "$123.45"), ensuring the amount is not negative. This transformer is then used within a Poxxy schema to convert and format a given numeric value. ```go // Currency formatting transformer currencyTransformer := poxxy.CustomTransformer(func(amount float64) (string, error) { if amount < 0 { return "", fmt.Errorf("amount cannot be negative") } return fmt.Sprintf("$%.2f", amount), nil }) var formattedAmount string schema := poxxy.NewSchema( poxxy.Convert("amount", &formattedAmount, func(amount float64) (*string, error) { formatted, err := currencyTransformer.Transform(amount) if err != nil { return nil, err } return &formatted, nil }), ) ``` -------------------------------- ### Validate Metadata with Custom Validators in Go Source: https://github.com/arkan/poxxy/blob/main/README.md This Go code illustrates validating metadata using Poxxy, including custom validator functions. It defines a schema for a nested map 'metadata', enforcing lowercase keys and ensuring values are strings, integers, or float64. It utilizes poxxy.ValidatorFunc for custom logic. ```go var metadata map[string]interface{} schema := poxxy.NewSchema( poxxy.NestedMap("metadata", &metadata, func(s *poxxy.Schema, key string, value *interface{}) { // Key validation (must be lowercase) poxxy.WithSchema(s, poxxy.ValueWithoutAssign("key", poxxy.WithValidators( poxxy.Required(), poxxy.ValidatorFunc(func(key string, fieldName string) error { if key != strings.ToLower(key) { return fmt.Errorf("key must be lowercase") } return nil }), ), )) // Value validation (must be string or number) poxxy.WithSchema(s, poxxy.ValueWithoutAssign("value", poxxy.WithValidators( poxxy.Required(), poxxy.ValidatorFunc(func(value interface{}, fieldName string) error { switch v := value.(type) { case string, int, float64: return nil default: return fmt.Errorf("value must be string, int, or float, got %T", v) } }), ), )) }), ) ``` -------------------------------- ### Validate Product Slice with Each() Custom Validator and UniqueBy() in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Validates a slice of Product structs. Each product must have a non-empty ID and Name, and a positive Price. The slice is validated to ensure all products have unique IDs. ```go type Product struct { ID string `json:"id"` Name string `json:"name"` Price float64 `json:"price"` } var products []Product schema := poxxy.NewSchema( poxxy.Slice("products", &products, poxxy.WithValidators( poxxy.Required(), poxxy.Each( poxxy.ValidatorFunc(func(product Product, fieldName string) error { if product.ID == "" { return fmt.Errorf("product ID is required") } if product.Name == "" { return fmt.Errorf("product name is required") } if product.Price <= 0 { return fmt.Errorf("product price must be positive") } return nil }), ), // Check uniqueness by ID poxxy.UniqueBy(func(product interface{}) interface{} { return product.(Product).ID }), ), ), ) ``` -------------------------------- ### Validate Email List with Each(), MinLength(), and Unique() in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Validates a slice of email strings. Each email must be a valid email format and have a minimum length of 5. The entire list of emails must also contain unique entries. It includes a transformer to normalize emails to lowercase and trim whitespace. ```go var emails []string schema := poxxy.NewSchema( poxxy.Slice("emails", &emails, poxxy.WithValidators( poxxy.Required(), poxxy.Each(poxxy.Email(), poxxy.MinLength(5)), poxxy.Unique(), ), poxxy.WithTransformers( poxxy.CustomTransformer(func(emails []string) ([]string, error) { // Normalize all emails for i, email := range emails { emails[i] = strings.ToLower(strings.TrimSpace(email)) } return emails, nil }), ), ), ) ``` -------------------------------- ### Configure Sub-schema for Map Values in Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates how to use `WithSubSchemaMap` to configure validation and transformation rules for the values within a map (key-value pairs) in a Poxxy schema. This is useful for validating map entries dynamically. ```go poxxy.WithSubSchemaMap(func(s *poxxy.Schema, key string, value *string) { // Configure map value validation }) ``` -------------------------------- ### Polymorphic Documents with Poxxy Schema in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Defines a polymorphic Document structure (Text, Image, Video) using Go interfaces and concrete types. It then utilizes the poxxy.Union schema to handle these different document types, including validation and transformation rules for each. This pattern is useful for flexible data ingestion and processing. ```go type Document interface { GetType() string } type TextDocument struct { Content string `json:"content"` WordCount int `json:"word_count"` Language string `json:"language"` } type ImageDocument struct { URL string `json:"url"` Width int `json:"width"` Height int `json:"height"` Format string `json:"format"` } type VideoDocument struct { URL string `json:"url"` Duration int `json:"duration"` Quality string `json:"quality"` Subtitles bool `json:"subtitles"` } // GetType method implementations func (t TextDocument) GetType() string { return "text" } func (i ImageDocument) GetType() string { return "image" } func (v VideoDocument) GetType() string { return "video" } var document Document schema := poxxy.NewSchema( poxxy.Union("document", &document, func(data map[string]interface{}) (interface{}, error) { docType, ok := data["type"].(string) if !ok { return nil, fmt.Errorf("missing or invalid document type") } switch docType { case "text": var doc TextDocument subSchema := poxxy.NewSchema( poxxy.Value("content", &doc.Content, poxxy.WithValidators(poxxy.Required(), poxxy.MinLength(10)), poxxy.WithTransformers(poxxy.TrimSpace()), ), poxxy.Value("word_count", &doc.WordCount, poxxy.WithValidators(poxxy.Min(0)), ), poxxy.Value("language", &doc.Language, poxxy.WithDefault("en"), poxxy.WithValidators(poxxy.In("en", "fr", "es", "de")), ), ) if err := subSchema.Apply(data); err != nil { return nil, err } return doc, nil case "image": var doc ImageDocument subSchema := poxxy.NewSchema( poxxy.Value("url", &doc.URL, poxxy.WithValidators(poxxy.Required(), poxxy.URL()), ), poxxy.Value("width", &doc.Width, poxxy.WithValidators(poxxy.Min(1), poxxy.Max(10000)), ), poxxy.Value("height", &doc.Height, poxxy.WithValidators(poxxy.Min(1), poxxy.Max(10000)), ), poxxy.Value("format", &doc.Format, poxxy.WithDefault("jpeg"), poxxy.WithValidators(poxxy.In("jpeg", "png", "gif", "webp")), ), ) if err := subSchema.Apply(data); err != nil { return nil, err } return doc, nil case "video": var doc VideoDocument subSchema := poxxy.NewSchema( poxxy.Value("url", &doc.URL, poxxy.WithValidators(poxxy.Required(), poxxy.URL()), ), poxxy.Value("duration", &doc.Duration, poxxy.WithValidators(poxxy.Min(1)), ), poxxy.Value("quality", &doc.Quality, poxxy.WithDefault("720p"), poxxy.WithValidators(poxxy.In("480p", "720p", "1080p", "4k")), ), poxxy.Value("subtitles", &doc.Subtitles, poxxy.WithDefault(false), ), ) if err := subSchema.Apply(data); err != nil { return nil, err } return doc, nil default: return nil, fmt.Errorf("unknown document type: %s", docType) } }), ) ``` -------------------------------- ### Go: Customize poxxy Validator Error Messages Source: https://github.com/arkan/poxxy/blob/main/README.md Shows how to customize the default error messages for poxxy validators in Go. By chaining `.WithMessage()` to a validator instance, you can provide user-friendly or context-specific error strings. This improves the clarity of validation feedback. ```go poxxy.Required().WithMessage("This field is mandatory") poxxy.Min(18).WithMessage("Must be at least 18 years old") ``` -------------------------------- ### Poxxy: Defining Slice Fields in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates the definition of slice fields in Poxxy, which are used for arrays of values or structs. The `poxxy.Slice` function takes the field name, a pointer to the slice variable, and optional configuration. ```go var tags []string poxxy.Slice("tags", &tags, opts...) ``` -------------------------------- ### Validate Settings Map with Unique() Values and Required Keys in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Validates a map of string keys to string values. It ensures the map is not empty and that all values within the map are unique. Additionally, it enforces that specific keys ('theme', 'language', 'timezone') must be present in the map. ```go var settings map[string]string schema := poxxy.NewSchema( poxxy.Map("settings", &settings, poxxy.WithValidators( poxxy.Required(), poxxy.Unique(), // Check uniqueness of values poxxy.WithMapKeys("theme", "language", "timezone"), // Required keys ), ), ) ``` -------------------------------- ### Configure Sub-schema for Nested Structures in Poxxy in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Illustrates the usage of `WithSubSchema` for defining validation and transformation rules for nested object structures within a Poxxy schema. It shows a callback function to configure the sub-schema fields. ```go poxxy.WithSubSchema(func(s *poxxy.Schema, user *User) { // Configure sub-schema fields }) ``` -------------------------------- ### Validate Tag Slice with Each(), Min/MaxLength(), and Unique() in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Validates a slice of tag strings. Each tag must have a minimum length of 2 and a maximum length of 20 characters. All tags in the slice must be unique. A transformer normalizes tags to lowercase and replaces spaces with hyphens. ```go var tags []string schema := poxxy.NewSchema( poxxy.Slice("tags", &tags, poxxy.WithValidators( poxxy.Required(), poxxy.Each(poxxy.MinLength(2), poxxy.MaxLength(20)), poxxy.Unique(), ), poxxy.WithTransformers( poxxy.CustomTransformer(func(tags []string) ([]string, error) { // Normalize tags (lowercase, no spaces) for i, tag := range tags { tags[i] = strings.ToLower(strings.ReplaceAll(tag, " ", "-")) } return tags, nil }), ), ), ) ``` -------------------------------- ### Validate Nested Map Fields with Key-Value Validation in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Demonstrates how to define validation rules for nested map fields using Poxxy. It specifies that both keys and values within the 'settings' map must be present and non-empty. ```go var userSettings map[string]string poxxy.NestedMap("settings", &userSettings, func(s *poxxy.Schema, key string, value *string) { // Validate each key-value pair poxxy.WithSchema(s, poxxy.ValueWithoutAssign("key", poxxy.WithValidators(poxxy.Required()))) poxxy.WithSchema(s, poxxy.ValueWithoutAssign("value", poxxy.WithValidators(poxxy.Required()))) }, opts...) ``` -------------------------------- ### Polymorphic Notifications with Poxxy Schema in Go Source: https://github.com/arkan/poxxy/blob/main/README.md Illustrates the implementation of polymorphic Notification types (Email, SMS, Push) using Go interfaces and concrete structs. The code employs poxxy.Union to create a schema that can dynamically parse and validate different notification channels, specifying validation and default values for each. ```go type Notification interface { GetChannel() string } type EmailNotification struct { To string `json:"to"` Subject string `json:"subject"` Body string `json:"body"` } type SMSNotification struct { Phone string `json:"phone"` Message string `json:"message"` } type PushNotification struct { Token string `json:"token"` Title string `json:"title"` Body string `json:"body"` Data map[string]string `json:"data"` } func (e EmailNotification) GetChannel() string { return "email" } func (s SMSNotification) GetChannel() string { return "sms" } func (p PushNotification) GetChannel() string { return "push" } var notification Notification schema := poxxy.NewSchema( poxxy.Union("notification", ¬ification, func(data map[string]interface{}) (interface{}, error) { channel, ok := data["channel"].(string) if !ok { return nil, fmt.Errorf("missing or invalid notification channel") } switch channel { case "email": var notif EmailNotification subSchema := poxxy.NewSchema( poxxy.Value("to", ¬if.To, ``` -------------------------------- ### Go: Skip Validators During poxxy Schema Application Source: https://github.com/arkan/poxxy/blob/main/README.md Illustrates how to bypass the validation phase when applying a poxxy schema in Go using `poxxy.WithSkipValidators(true)`. This option is useful for scenarios where only data transformation or parsing is needed, without enforcing validation rules at that stage. ```go schema.Apply(data, poxxy.WithSkipValidators(true)) ```