...

Source file src/github.com/xeipuuv/gojsonschema/result.go

Documentation: github.com/xeipuuv/gojsonschema

     1  // Copyright 2015 xeipuuv ( https://github.com/xeipuuv )
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //   http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // author           xeipuuv
    16  // author-github    https://github.com/xeipuuv
    17  // author-mail      xeipuuv@gmail.com
    18  //
    19  // repository-name  gojsonschema
    20  // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language.
    21  //
    22  // description      Result and ResultError implementations.
    23  //
    24  // created          01-01-2015
    25  
    26  package gojsonschema
    27  
    28  import (
    29  	"fmt"
    30  	"strings"
    31  )
    32  
    33  type (
    34  	// ErrorDetails is a map of details specific to each error.
    35  	// While the values will vary, every error will contain a "field" value
    36  	ErrorDetails map[string]interface{}
    37  
    38  	// ResultError is the interface that library errors must implement
    39  	ResultError interface {
    40  		// Field returns the field name without the root context
    41  		// i.e. firstName or person.firstName instead of (root).firstName or (root).person.firstName
    42  		Field() string
    43  		// SetType sets the error-type
    44  		SetType(string)
    45  		// Type returns the error-type
    46  		Type() string
    47  		// SetContext sets the JSON-context for the error
    48  		SetContext(*JsonContext)
    49  		// Context returns the JSON-context of the error
    50  		Context() *JsonContext
    51  		// SetDescription sets a description for the error
    52  		SetDescription(string)
    53  		// Description returns the description of the error
    54  		Description() string
    55  		// SetDescriptionFormat sets the format for the description in the default text/template format
    56  		SetDescriptionFormat(string)
    57  		// DescriptionFormat returns the format for the description in the default text/template format
    58  		DescriptionFormat() string
    59  		// SetValue sets the value related to the error
    60  		SetValue(interface{})
    61  		// Value returns the value related to the error
    62  		Value() interface{}
    63  		// SetDetails sets the details specific to the error
    64  		SetDetails(ErrorDetails)
    65  		// Details returns details about the error
    66  		Details() ErrorDetails
    67  		// String returns a string representation of the error
    68  		String() string
    69  	}
    70  
    71  	// ResultErrorFields holds the fields for each ResultError implementation.
    72  	// ResultErrorFields implements the ResultError interface, so custom errors
    73  	// can be defined by just embedding this type
    74  	ResultErrorFields struct {
    75  		errorType         string       // A string with the type of error (i.e. invalid_type)
    76  		context           *JsonContext // Tree like notation of the part that failed the validation. ex (root).a.b ...
    77  		description       string       // A human readable error message
    78  		descriptionFormat string       // A format for human readable error message
    79  		value             interface{}  // Value given by the JSON file that is the source of the error
    80  		details           ErrorDetails
    81  	}
    82  
    83  	// Result holds the result of a validation
    84  	Result struct {
    85  		errors []ResultError
    86  		// Scores how well the validation matched. Useful in generating
    87  		// better error messages for anyOf and oneOf.
    88  		score int
    89  	}
    90  )
    91  
    92  // Field returns the field name without the root context
    93  // i.e. firstName or person.firstName instead of (root).firstName or (root).person.firstName
    94  func (v *ResultErrorFields) Field() string {
    95  	return strings.TrimPrefix(v.context.String(), STRING_ROOT_SCHEMA_PROPERTY+".")
    96  }
    97  
    98  // SetType sets the error-type
    99  func (v *ResultErrorFields) SetType(errorType string) {
   100  	v.errorType = errorType
   101  }
   102  
   103  // Type returns the error-type
   104  func (v *ResultErrorFields) Type() string {
   105  	return v.errorType
   106  }
   107  
   108  // SetContext sets the JSON-context for the error
   109  func (v *ResultErrorFields) SetContext(context *JsonContext) {
   110  	v.context = context
   111  }
   112  
   113  // Context returns the JSON-context of the error
   114  func (v *ResultErrorFields) Context() *JsonContext {
   115  	return v.context
   116  }
   117  
   118  // SetDescription sets a description for the error
   119  func (v *ResultErrorFields) SetDescription(description string) {
   120  	v.description = description
   121  }
   122  
   123  // Description returns the description of the error
   124  func (v *ResultErrorFields) Description() string {
   125  	return v.description
   126  }
   127  
   128  // SetDescriptionFormat sets the format for the description in the default text/template format
   129  func (v *ResultErrorFields) SetDescriptionFormat(descriptionFormat string) {
   130  	v.descriptionFormat = descriptionFormat
   131  }
   132  
   133  // DescriptionFormat returns the format for the description in the default text/template format
   134  func (v *ResultErrorFields) DescriptionFormat() string {
   135  	return v.descriptionFormat
   136  }
   137  
   138  // SetValue sets the value related to the error
   139  func (v *ResultErrorFields) SetValue(value interface{}) {
   140  	v.value = value
   141  }
   142  
   143  // Value returns the value related to the error
   144  func (v *ResultErrorFields) Value() interface{} {
   145  	return v.value
   146  }
   147  
   148  // SetDetails sets the details specific to the error
   149  func (v *ResultErrorFields) SetDetails(details ErrorDetails) {
   150  	v.details = details
   151  }
   152  
   153  // Details returns details about the error
   154  func (v *ResultErrorFields) Details() ErrorDetails {
   155  	return v.details
   156  }
   157  
   158  // String returns a string representation of the error
   159  func (v ResultErrorFields) String() string {
   160  	// as a fallback, the value is displayed go style
   161  	valueString := fmt.Sprintf("%v", v.value)
   162  
   163  	// marshal the go value value to json
   164  	if v.value == nil {
   165  		valueString = TYPE_NULL
   166  	} else {
   167  		if vs, err := marshalToJSONString(v.value); err == nil {
   168  			if vs == nil {
   169  				valueString = TYPE_NULL
   170  			} else {
   171  				valueString = *vs
   172  			}
   173  		}
   174  	}
   175  
   176  	return formatErrorDescription(Locale.ErrorFormat(), ErrorDetails{
   177  		"context":     v.context.String(),
   178  		"description": v.description,
   179  		"value":       valueString,
   180  		"field":       v.Field(),
   181  	})
   182  }
   183  
   184  // Valid indicates if no errors were found
   185  func (v *Result) Valid() bool {
   186  	return len(v.errors) == 0
   187  }
   188  
   189  // Errors returns the errors that were found
   190  func (v *Result) Errors() []ResultError {
   191  	return v.errors
   192  }
   193  
   194  // AddError appends a fully filled error to the error set
   195  // SetDescription() will be called with the result of the parsed err.DescriptionFormat()
   196  func (v *Result) AddError(err ResultError, details ErrorDetails) {
   197  	if _, exists := details["context"]; !exists && err.Context() != nil {
   198  		details["context"] = err.Context().String()
   199  	}
   200  
   201  	err.SetDescription(formatErrorDescription(err.DescriptionFormat(), details))
   202  
   203  	v.errors = append(v.errors, err)
   204  }
   205  
   206  func (v *Result) addInternalError(err ResultError, context *JsonContext, value interface{}, details ErrorDetails) {
   207  	newError(err, context, value, Locale, details)
   208  	v.errors = append(v.errors, err)
   209  	v.score -= 2 // results in a net -1 when added to the +1 we get at the end of the validation function
   210  }
   211  
   212  // Used to copy errors from a sub-schema to the main one
   213  func (v *Result) mergeErrors(otherResult *Result) {
   214  	v.errors = append(v.errors, otherResult.Errors()...)
   215  	v.score += otherResult.score
   216  }
   217  
   218  func (v *Result) incrementScore() {
   219  	v.score++
   220  }
   221  

View as plain text