github.com/kaptinlin/jsonschema@v0.4.6/examples/multiple-input-types/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/kaptinlin/jsonschema" 8 ) 9 10 // User struct for demonstrations 11 type User struct { 12 Name string `json:"name"` 13 Age int `json:"age"` 14 Email string `json:"email,omitempty"` 15 Country string `json:"country,omitempty"` 16 Active bool `json:"active,omitempty"` 17 } 18 19 func main() { 20 // Setup schema with defaults 21 schema := setupSchema() 22 23 fmt.Println("Multiple Input Types Demo") 24 fmt.Println("========================") 25 26 // Demonstrate different input types 27 fmt.Println("\n1. Input Type Validation:") 28 demonstrateInputTypes(schema) 29 30 // Demonstrate unmarshal with defaults 31 fmt.Println("\n2. Unmarshal with Defaults:") 32 demonstrateUnmarshal(schema) 33 34 // Show best practices 35 fmt.Println("\n3. Best Practices:") 36 demonstrateBestPractices(schema) 37 } 38 39 func setupSchema() *jsonschema.Schema { 40 schemaJSON := `{ 41 "type": "object", 42 "properties": { 43 "name": {"type": "string", "minLength": 1}, 44 "age": {"type": "integer", "minimum": 0, "maximum": 150}, 45 "email": {"type": "string", "format": "email"}, 46 "country": {"type": "string", "default": "US"}, 47 "active": {"type": "boolean", "default": true} 48 }, 49 "required": ["name", "age"] 50 }` 51 52 compiler := jsonschema.NewCompiler() 53 schema, err := compiler.Compile([]byte(schemaJSON)) 54 if err != nil { 55 log.Fatal("Failed to compile schema:", err) 56 } 57 return schema 58 } 59 60 func demonstrateInputTypes(schema *jsonschema.Schema) { 61 examples := []struct { 62 name string 63 data interface{} 64 emoji string 65 }{ 66 { 67 name: "JSON Bytes", 68 data: []byte(`{"name": "Alice", "age": 28, "email": "alice@example.com"}`), 69 emoji: "π", 70 }, 71 { 72 name: "Go Struct", 73 data: User{Name: "Bob", Age: 35, Email: "bob@example.com"}, 74 emoji: "ποΈ", 75 }, 76 { 77 name: "Map Data", 78 data: map[string]interface{}{ 79 "name": "Charlie", 80 "age": 42, 81 "email": "charlie@example.com", 82 }, 83 emoji: "πΊοΈ", 84 }, 85 { 86 name: "JSON String (as []byte)", 87 data: []byte(`{"name": "Diana", "age": 30}`), 88 emoji: "π€", 89 }, 90 } 91 92 for _, example := range examples { 93 result := schema.Validate(example.data) 94 status := getStatusIcon(result.IsValid()) 95 fmt.Printf(" %s %s %s: %s\n", example.emoji, example.name, status, getStatusText(result.IsValid())) 96 } 97 } 98 99 func demonstrateUnmarshal(schema *jsonschema.Schema) { 100 // Example 1: JSON bytes with defaults 101 fmt.Println(" π From JSON bytes:") 102 var user1 User 103 err := schema.Unmarshal(&user1, []byte(`{"name": "Eve", "age": 25}`)) 104 if err != nil { 105 fmt.Printf(" β Error: %v\n", err) 106 } else { 107 fmt.Printf(" β Success: %s, age %d, country: %s (default), active: %t (default)\n", 108 user1.Name, user1.Age, user1.Country, user1.Active) 109 } 110 111 // Example 2: Map with defaults 112 fmt.Println(" πΊοΈ From map data:") 113 var user2 User 114 mapData := map[string]interface{}{ 115 "name": "Frank", 116 "age": 40, 117 "country": "Canada", 118 } 119 err = schema.Unmarshal(&user2, mapData) 120 if err != nil { 121 fmt.Printf(" β Error: %v\n", err) 122 } else { 123 fmt.Printf(" β Success: %s, age %d, country: %s, active: %t (default)\n", 124 user2.Name, user2.Age, user2.Country, user2.Active) 125 } 126 127 // Example 3: Struct to struct 128 fmt.Println(" ποΈ From struct:") 129 var user3 User 130 sourceUser := User{Name: "Grace", Age: 33, Email: "grace@example.com"} 131 err = schema.Unmarshal(&user3, sourceUser) 132 if err != nil { 133 fmt.Printf(" β Error: %v\n", err) 134 } else { 135 fmt.Printf(" β Success: %s, age %d, country: %s (default), active: %t (default)\n", 136 user3.Name, user3.Age, user3.Country, user3.Active) 137 } 138 } 139 140 func demonstrateBestPractices(schema *jsonschema.Schema) { 141 fmt.Println(" π Recommended approaches:") 142 143 // Best practice 1: JSON strings 144 fmt.Println(" β’ For JSON strings, convert to []byte:") 145 jsonString := `{"name": "Henry", "age": 45}` 146 fmt.Printf(" jsonString := %s\n", jsonString) 147 fmt.Printf(" schema.Validate([]byte(jsonString)) // β Recommended\n") 148 149 // Best practice 2: Error handling 150 fmt.Println(" β’ Always check validation before unmarshal:") 151 fmt.Println(" result := schema.Validate(data)") 152 fmt.Println(" if result.IsValid() {") 153 fmt.Println(" schema.Unmarshal(&target, data)") 154 fmt.Println(" }") 155 156 // Best practice 3: Defaults 157 fmt.Println(" β’ Use schema defaults for cleaner data:") 158 fmt.Println(" Define defaults in schema, not in Go structs") 159 160 // Demonstrate validation failure 161 fmt.Println("\n β οΈ Validation failure example:") 162 invalidData := []byte(`{"name": "", "age": -5}`) // Invalid data 163 result := schema.Validate(invalidData) 164 if !result.IsValid() { 165 fmt.Println(" Validation errors:") 166 for field, err := range result.Errors { 167 fmt.Printf(" - %s: %s\n", field, err.Message) 168 } 169 } 170 } 171 172 func getStatusIcon(isValid bool) string { 173 if isValid { 174 return "β " 175 } 176 return "β" 177 } 178 179 func getStatusText(isValid bool) string { 180 if isValid { 181 return "Valid" 182 } 183 return "Invalid" 184 }