github.com/kaptinlin/jsonschema@v0.4.6/examples/i18n/main.go (about)

     1  package main
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"log"
     7  
     8  	"github.com/kaptinlin/go-i18n"
     9  	"github.com/kaptinlin/jsonschema"
    10  )
    11  
    12  // Static errors for linter compliance
    13  var (
    14  	ErrValidationFailed = errors.New("validation failed")
    15  	ErrUnmarshalFailed  = errors.New("unmarshal failed")
    16  )
    17  
    18  type User struct {
    19  	Name  string `json:"name"`
    20  	Age   int    `json:"age"`
    21  	Email string `json:"email"`
    22  }
    23  
    24  func main() {
    25  	// Compile schema with validation rules
    26  	compiler := jsonschema.NewCompiler()
    27  	schema, err := compiler.Compile([]byte(`{
    28  		"type": "object",
    29  		"properties": {
    30  			"name": {"type": "string", "minLength": 2, "maxLength": 10},
    31  			"age": {"type": "integer", "minimum": 18, "maximum": 99},
    32  			"email": {"type": "string", "format": "email"}
    33  		},
    34  		"required": ["name", "age", "email"]
    35  	}`))
    36  	if err != nil {
    37  		log.Fatal(err)
    38  	}
    39  
    40  	fmt.Println("Internationalization Demo")
    41  	fmt.Println("========================")
    42  
    43  	// Get i18n support
    44  	i18nBundle, err := jsonschema.GetI18n()
    45  	if err != nil {
    46  		log.Fatal("Failed to get i18n:", err)
    47  	}
    48  
    49  	// Create localizers
    50  	chineseLocalizer := i18nBundle.NewLocalizer("zh-Hans")
    51  	englishLocalizer := i18nBundle.NewLocalizer("en")
    52  
    53  	// Test data with various validation errors
    54  	invalidData := map[string]interface{}{
    55  		"name":  "X",             // Too short
    56  		"age":   16,              // Below minimum
    57  		"email": "invalid-email", // Invalid format
    58  	}
    59  
    60  	fmt.Printf("Input: %+v\n\n", invalidData)
    61  
    62  	// Step 1: Validate
    63  	result := schema.Validate(invalidData)
    64  	if result.IsValid() {
    65  		fmt.Println("βœ… Valid - proceeding to unmarshal")
    66  		var user User
    67  		if err := schema.Unmarshal(&user, invalidData); err != nil {
    68  			fmt.Printf("❌ Unmarshal error: %v\n", err)
    69  		} else {
    70  			fmt.Printf("User: %+v\n", user)
    71  		}
    72  	} else {
    73  		fmt.Println("❌ Validation failed")
    74  
    75  		// Show Chinese error messages
    76  		fmt.Println("\nπŸ‡¨πŸ‡³ Chinese errors:")
    77  		chineseErrors := result.ToLocalizeList(chineseLocalizer)
    78  		for field, message := range chineseErrors.Errors {
    79  			fmt.Printf("  %s: %s\n", field, message)
    80  		}
    81  
    82  		// Show English error messages
    83  		fmt.Println("\nπŸ‡ΊπŸ‡Έ English errors:")
    84  		englishErrors := result.ToLocalizeList(englishLocalizer)
    85  		for field, message := range englishErrors.Errors {
    86  			fmt.Printf("  %s: %s\n", field, message)
    87  		}
    88  
    89  		// Unmarshal still works (no validation)
    90  		var user User
    91  		if err := schema.Unmarshal(&user, invalidData); err != nil {
    92  			fmt.Printf("\n❌ Unmarshal error: %v\n", err)
    93  		} else {
    94  			fmt.Printf("\nℹ️  Unmarshal succeeded: %+v\n", user)
    95  		}
    96  	}
    97  
    98  	// Production pattern with i18n
    99  	fmt.Println("\nProduction pattern:")
   100  	fmt.Println("==================")
   101  	validData := map[string]interface{}{
   102  		"name":  "Alice",
   103  		"age":   25,
   104  		"email": "alice@example.com",
   105  	}
   106  
   107  	if err := processUser(schema, validData, chineseLocalizer); err != nil {
   108  		fmt.Printf("❌ Error: %v\n", err)
   109  	} else {
   110  		fmt.Println("βœ… User processed successfully")
   111  	}
   112  }
   113  
   114  // processUser demonstrates production usage with i18n
   115  func processUser(schema *jsonschema.Schema, data interface{}, localizer *i18n.Localizer) error {
   116  	// Step 1: Validate
   117  	result := schema.Validate(data)
   118  	if !result.IsValid() {
   119  		localizedErrors := result.ToLocalizeList(localizer)
   120  		var errMsg string
   121  		for field, message := range localizedErrors.Errors {
   122  			errMsg += fmt.Sprintf("%s: %s; ", field, message)
   123  		}
   124  		return fmt.Errorf("%w: %s", ErrValidationFailed, errMsg)
   125  	}
   126  
   127  	// Step 2: Unmarshal validated data
   128  	var user User
   129  	if err := schema.Unmarshal(&user, data); err != nil {
   130  		return fmt.Errorf("%w: %w", ErrUnmarshalFailed, err)
   131  	}
   132  
   133  	// Step 3: Process user
   134  	fmt.Printf("  Processing: %s (age: %d, email: %s)\n",
   135  		user.Name, user.Age, user.Email)
   136  
   137  	return nil
   138  }