github.com/kaptinlin/jsonschema@v0.4.6/result.go (about) 1 package jsonschema 2 3 import "github.com/kaptinlin/go-i18n" 4 5 type EvaluationError struct { 6 Keyword string `json:"keyword"` 7 Code string `json:"code"` 8 Message string `json:"message"` 9 Params map[string]interface{} `json:"params"` 10 } 11 12 func NewEvaluationError(keyword string, code string, message string, params ...map[string]interface{}) *EvaluationError { 13 if len(params) > 0 { 14 return &EvaluationError{ 15 Keyword: keyword, 16 Code: code, 17 Message: message, 18 Params: params[0], 19 } 20 } else { 21 return &EvaluationError{ 22 Keyword: keyword, 23 Code: code, 24 Message: message, 25 } 26 } 27 } 28 29 func (e *EvaluationError) Error() string { 30 return replace(e.Message, e.Params) 31 } 32 33 func (e *EvaluationError) Localize(localizer *i18n.Localizer) string { 34 if localizer != nil { 35 return localizer.Get(e.Code, i18n.Vars(e.Params)) 36 } else { 37 return e.Error() 38 } 39 } 40 41 type Flag struct { 42 Valid bool `json:"valid"` 43 } 44 45 type List struct { 46 Valid bool `json:"valid"` 47 EvaluationPath string `json:"evaluationPath"` 48 SchemaLocation string `json:"schemaLocation"` 49 InstanceLocation string `json:"instanceLocation"` 50 Annotations map[string]interface{} `json:"annotations,omitempty"` 51 Errors map[string]string `json:"errors,omitempty"` 52 Details []List `json:"details,omitempty"` 53 } 54 55 type EvaluationResult struct { 56 schema *Schema `json:"-"` 57 Valid bool `json:"valid"` 58 EvaluationPath string `json:"evaluationPath"` 59 SchemaLocation string `json:"schemaLocation"` 60 InstanceLocation string `json:"instanceLocation"` 61 Annotations map[string]interface{} `json:"annotations,omitempty"` 62 Errors map[string]*EvaluationError `json:"errors,omitempty"` // Store error messages here 63 Details []*EvaluationResult `json:"details,omitempty"` 64 } 65 66 func NewEvaluationResult(schema *Schema) *EvaluationResult { 67 e := &EvaluationResult{ 68 schema: schema, 69 Valid: true, 70 } 71 //nolint:errcheck 72 e.CollectAnnotations() 73 74 return e 75 } 76 77 func (e *EvaluationResult) SetEvaluationPath(evaluationPath string) *EvaluationResult { 78 e.EvaluationPath = evaluationPath 79 80 return e 81 } 82 83 func (e *EvaluationResult) Error() string { 84 return "evaluation failed" 85 } 86 87 func (e *EvaluationResult) SetSchemaLocation(location string) *EvaluationResult { 88 e.SchemaLocation = location 89 90 return e 91 } 92 93 func (e *EvaluationResult) SetInstanceLocation(instanceLocation string) *EvaluationResult { 94 e.InstanceLocation = instanceLocation 95 96 return e 97 } 98 99 func (e *EvaluationResult) SetInvalid() *EvaluationResult { 100 e.Valid = false 101 102 return e 103 } 104 105 func (e *EvaluationResult) IsValid() bool { 106 return e.Valid 107 } 108 109 func (e *EvaluationResult) AddError(err *EvaluationError) *EvaluationResult { 110 if e.Errors == nil { 111 e.Errors = make(map[string]*EvaluationError) 112 } 113 114 if e.Valid { 115 e.Valid = false 116 } 117 118 e.Errors[err.Keyword] = err 119 return e 120 } 121 122 func (e *EvaluationResult) AddDetail(detail *EvaluationResult) *EvaluationResult { 123 if e.Details == nil { 124 e.Details = make([]*EvaluationResult, 0) 125 } 126 127 e.Details = append(e.Details, detail) 128 return e 129 } 130 131 func (e *EvaluationResult) AddAnnotation(keyword string, annotation interface{}) *EvaluationResult { 132 if e.Annotations == nil { 133 e.Annotations = make(map[string]interface{}) 134 } 135 136 e.Annotations[keyword] = annotation 137 return e 138 } 139 140 func (e *EvaluationResult) CollectAnnotations() *EvaluationResult { 141 if e.Annotations == nil { 142 e.Annotations = make(map[string]interface{}) 143 } 144 145 if e.schema.Title != nil { 146 e.Annotations["title"] = e.schema.Title 147 } 148 if e.schema.Description != nil { 149 e.Annotations["description"] = e.schema.Description 150 } 151 if e.schema.Default != nil { 152 e.Annotations["default"] = e.schema.Default 153 } 154 if e.schema.Deprecated != nil { 155 e.Annotations["deprecated"] = e.schema.Deprecated 156 } 157 if e.schema.ReadOnly != nil { 158 e.Annotations["readOnly"] = e.schema.ReadOnly 159 } 160 if e.schema.WriteOnly != nil { 161 e.Annotations["writeOnly"] = e.schema.WriteOnly 162 } 163 if e.schema.Examples != nil { 164 e.Annotations["examples"] = e.schema.Examples 165 } 166 167 return e 168 } 169 170 // Converts EvaluationResult to a simple Flag struct 171 func (e *EvaluationResult) ToFlag() *Flag { 172 return &Flag{ 173 Valid: e.Valid, 174 } 175 } 176 177 // ToList converts the evaluation results into a list format with optional hierarchy 178 // includeHierarchy is variadic; if not provided, it defaults to true 179 func (e *EvaluationResult) ToList(includeHierarchy ...bool) *List { 180 // Set default value for includeHierarchy to true 181 hierarchyIncluded := true 182 if len(includeHierarchy) > 0 { 183 hierarchyIncluded = includeHierarchy[0] 184 } 185 186 return e.ToLocalizeList(nil, hierarchyIncluded) 187 } 188 189 // ToLocalizeList converts the evaluation results into a list format with optional hierarchy with localization 190 // includeHierarchy is variadic; if not provided, it defaults to true 191 func (e *EvaluationResult) ToLocalizeList(localizer *i18n.Localizer, includeHierarchy ...bool) *List { 192 // Set default value for includeHierarchy to true 193 hierarchyIncluded := true 194 if len(includeHierarchy) > 0 { 195 hierarchyIncluded = includeHierarchy[0] 196 } 197 198 list := &List{ 199 Valid: e.Valid, 200 EvaluationPath: e.EvaluationPath, 201 SchemaLocation: e.SchemaLocation, 202 InstanceLocation: e.InstanceLocation, 203 Annotations: e.Annotations, 204 Errors: e.convertErrors(localizer), 205 Details: make([]List, 0), 206 } 207 208 if hierarchyIncluded { 209 for _, detail := range e.Details { 210 childList := detail.ToLocalizeList(localizer, true) // recursively include hierarchy 211 list.Details = append(list.Details, *childList) 212 } 213 } else { 214 e.flattenDetailsToList(localizer, list, e.Details) // flat structure 215 } 216 217 return list 218 } 219 220 func (e *EvaluationResult) flattenDetailsToList(localizer *i18n.Localizer, list *List, details []*EvaluationResult) { 221 for _, detail := range details { 222 flatDetail := List{ 223 Valid: detail.Valid, 224 EvaluationPath: detail.EvaluationPath, 225 SchemaLocation: detail.SchemaLocation, 226 InstanceLocation: detail.InstanceLocation, 227 Annotations: detail.Annotations, 228 Errors: detail.convertErrors(localizer), 229 } 230 list.Details = append(list.Details, flatDetail) 231 232 if len(detail.Details) > 0 { 233 e.flattenDetailsToList(localizer, list, detail.Details) 234 } 235 } 236 } 237 238 func (e *EvaluationResult) convertErrors(localizer *i18n.Localizer) map[string]string { 239 errors := make(map[string]string) 240 for key, err := range e.Errors { 241 if localizer != nil { 242 errors[key] = err.Localize(localizer) 243 } else { 244 errors[key] = err.Error() 245 } 246 } 247 return errors 248 }