mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			365 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			365 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package gojsonschema
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"sync"
 | 
						|
	"text/template"
 | 
						|
)
 | 
						|
 | 
						|
var errorTemplates = errorTemplate{template.New("errors-new"), sync.RWMutex{}}
 | 
						|
 | 
						|
// template.Template is not thread-safe for writing, so some locking is done
 | 
						|
// sync.RWMutex is used for efficiently locking when new templates are created
 | 
						|
type errorTemplate struct {
 | 
						|
	*template.Template
 | 
						|
	sync.RWMutex
 | 
						|
}
 | 
						|
 | 
						|
type (
 | 
						|
 | 
						|
	// FalseError. ErrorDetails: -
 | 
						|
	FalseError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// RequiredError indicates that a required field is missing
 | 
						|
	// ErrorDetails: property string
 | 
						|
	RequiredError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// InvalidTypeError indicates that a field has the incorrect type
 | 
						|
	// ErrorDetails: expected, given
 | 
						|
	InvalidTypeError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// NumberAnyOfError is produced in case of a failing "anyOf" validation
 | 
						|
	// ErrorDetails: -
 | 
						|
	NumberAnyOfError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// NumberOneOfError is produced in case of a failing "oneOf" validation
 | 
						|
	// ErrorDetails: -
 | 
						|
	NumberOneOfError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// NumberAllOfError is produced in case of a failing "allOf" validation
 | 
						|
	// ErrorDetails: -
 | 
						|
	NumberAllOfError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// NumberNotError is produced if a "not" validation failed
 | 
						|
	// ErrorDetails: -
 | 
						|
	NumberNotError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// MissingDependencyError is produced in case of a "missing dependency" problem
 | 
						|
	// ErrorDetails: dependency
 | 
						|
	MissingDependencyError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// InternalError indicates an internal error
 | 
						|
	// ErrorDetails: error
 | 
						|
	InternalError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// ConstError indicates a const error
 | 
						|
	// ErrorDetails: allowed
 | 
						|
	ConstError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// EnumError indicates an enum error
 | 
						|
	// ErrorDetails: allowed
 | 
						|
	EnumError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// ArrayNoAdditionalItemsError is produced if additional items were found, but not allowed
 | 
						|
	// ErrorDetails: -
 | 
						|
	ArrayNoAdditionalItemsError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// ArrayMinItemsError is produced if an array contains less items than the allowed minimum
 | 
						|
	// ErrorDetails: min
 | 
						|
	ArrayMinItemsError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// ArrayMaxItemsError is produced if an array contains more items than the allowed maximum
 | 
						|
	// ErrorDetails: max
 | 
						|
	ArrayMaxItemsError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// ItemsMustBeUniqueError is produced if an array requires unique items, but contains non-unique items
 | 
						|
	// ErrorDetails: type, i, j
 | 
						|
	ItemsMustBeUniqueError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// ArrayContainsError is produced if an array contains invalid items
 | 
						|
	// ErrorDetails:
 | 
						|
	ArrayContainsError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// ArrayMinPropertiesError is produced if an object contains less properties than the allowed minimum
 | 
						|
	// ErrorDetails: min
 | 
						|
	ArrayMinPropertiesError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// ArrayMaxPropertiesError is produced if an object contains more properties than the allowed maximum
 | 
						|
	// ErrorDetails: max
 | 
						|
	ArrayMaxPropertiesError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// AdditionalPropertyNotAllowedError is produced if an object has additional properties, but not allowed
 | 
						|
	// ErrorDetails: property
 | 
						|
	AdditionalPropertyNotAllowedError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// InvalidPropertyPatternError is produced if an pattern was found
 | 
						|
	// ErrorDetails: property, pattern
 | 
						|
	InvalidPropertyPatternError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// InvalidPropertyNameError is produced if an invalid-named property was found
 | 
						|
	// ErrorDetails: property
 | 
						|
	InvalidPropertyNameError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// StringLengthGTEError is produced if a string is shorter than the minimum required length
 | 
						|
	// ErrorDetails: min
 | 
						|
	StringLengthGTEError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// StringLengthLTEError is produced if a string is longer than the maximum allowed length
 | 
						|
	// ErrorDetails: max
 | 
						|
	StringLengthLTEError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// DoesNotMatchPatternError is produced if a string does not match the defined pattern
 | 
						|
	// ErrorDetails: pattern
 | 
						|
	DoesNotMatchPatternError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// DoesNotMatchFormatError is produced if a string does not match the defined format
 | 
						|
	// ErrorDetails: format
 | 
						|
	DoesNotMatchFormatError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// MultipleOfError is produced if a number is not a multiple of the defined multipleOf
 | 
						|
	// ErrorDetails: multiple
 | 
						|
	MultipleOfError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// NumberGTEError is produced if a number is lower than the allowed minimum
 | 
						|
	// ErrorDetails: min
 | 
						|
	NumberGTEError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// NumberGTError is produced if a number is lower than, or equal to the specified minimum, and exclusiveMinimum is set
 | 
						|
	// ErrorDetails: min
 | 
						|
	NumberGTError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// NumberLTEError is produced if a number is higher than the allowed maximum
 | 
						|
	// ErrorDetails: max
 | 
						|
	NumberLTEError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// NumberLTError is produced if a number is higher than, or equal to the specified maximum, and exclusiveMaximum is set
 | 
						|
	// ErrorDetails: max
 | 
						|
	NumberLTError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// ConditionThenError is produced if a condition's "then" validation is invalid
 | 
						|
	// ErrorDetails: -
 | 
						|
	ConditionThenError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
 | 
						|
	// ConditionElseError is produced if a condition's "else" condition is invalid
 | 
						|
	// ErrorDetails: -
 | 
						|
	ConditionElseError struct {
 | 
						|
		ResultErrorFields
 | 
						|
	}
 | 
						|
)
 | 
						|
 | 
						|
// newError takes a ResultError type and sets the type, context, description, details, value, and field
 | 
						|
func newError(err ResultError, context *JsonContext, value interface{}, locale locale, details ErrorDetails) {
 | 
						|
	var t string
 | 
						|
	var d string
 | 
						|
	switch err.(type) {
 | 
						|
	case *FalseError:
 | 
						|
		t = "false"
 | 
						|
		d = locale.False()
 | 
						|
	case *RequiredError:
 | 
						|
		t = "required"
 | 
						|
		d = locale.Required()
 | 
						|
	case *InvalidTypeError:
 | 
						|
		t = "invalid_type"
 | 
						|
		d = locale.InvalidType()
 | 
						|
	case *NumberAnyOfError:
 | 
						|
		t = "number_any_of"
 | 
						|
		d = locale.NumberAnyOf()
 | 
						|
	case *NumberOneOfError:
 | 
						|
		t = "number_one_of"
 | 
						|
		d = locale.NumberOneOf()
 | 
						|
	case *NumberAllOfError:
 | 
						|
		t = "number_all_of"
 | 
						|
		d = locale.NumberAllOf()
 | 
						|
	case *NumberNotError:
 | 
						|
		t = "number_not"
 | 
						|
		d = locale.NumberNot()
 | 
						|
	case *MissingDependencyError:
 | 
						|
		t = "missing_dependency"
 | 
						|
		d = locale.MissingDependency()
 | 
						|
	case *InternalError:
 | 
						|
		t = "internal"
 | 
						|
		d = locale.Internal()
 | 
						|
	case *ConstError:
 | 
						|
		t = "const"
 | 
						|
		d = locale.Const()
 | 
						|
	case *EnumError:
 | 
						|
		t = "enum"
 | 
						|
		d = locale.Enum()
 | 
						|
	case *ArrayNoAdditionalItemsError:
 | 
						|
		t = "array_no_additional_items"
 | 
						|
		d = locale.ArrayNoAdditionalItems()
 | 
						|
	case *ArrayMinItemsError:
 | 
						|
		t = "array_min_items"
 | 
						|
		d = locale.ArrayMinItems()
 | 
						|
	case *ArrayMaxItemsError:
 | 
						|
		t = "array_max_items"
 | 
						|
		d = locale.ArrayMaxItems()
 | 
						|
	case *ItemsMustBeUniqueError:
 | 
						|
		t = "unique"
 | 
						|
		d = locale.Unique()
 | 
						|
	case *ArrayContainsError:
 | 
						|
		t = "contains"
 | 
						|
		d = locale.ArrayContains()
 | 
						|
	case *ArrayMinPropertiesError:
 | 
						|
		t = "array_min_properties"
 | 
						|
		d = locale.ArrayMinProperties()
 | 
						|
	case *ArrayMaxPropertiesError:
 | 
						|
		t = "array_max_properties"
 | 
						|
		d = locale.ArrayMaxProperties()
 | 
						|
	case *AdditionalPropertyNotAllowedError:
 | 
						|
		t = "additional_property_not_allowed"
 | 
						|
		d = locale.AdditionalPropertyNotAllowed()
 | 
						|
	case *InvalidPropertyPatternError:
 | 
						|
		t = "invalid_property_pattern"
 | 
						|
		d = locale.InvalidPropertyPattern()
 | 
						|
	case *InvalidPropertyNameError:
 | 
						|
		t = "invalid_property_name"
 | 
						|
		d = locale.InvalidPropertyName()
 | 
						|
	case *StringLengthGTEError:
 | 
						|
		t = "string_gte"
 | 
						|
		d = locale.StringGTE()
 | 
						|
	case *StringLengthLTEError:
 | 
						|
		t = "string_lte"
 | 
						|
		d = locale.StringLTE()
 | 
						|
	case *DoesNotMatchPatternError:
 | 
						|
		t = "pattern"
 | 
						|
		d = locale.DoesNotMatchPattern()
 | 
						|
	case *DoesNotMatchFormatError:
 | 
						|
		t = "format"
 | 
						|
		d = locale.DoesNotMatchFormat()
 | 
						|
	case *MultipleOfError:
 | 
						|
		t = "multiple_of"
 | 
						|
		d = locale.MultipleOf()
 | 
						|
	case *NumberGTEError:
 | 
						|
		t = "number_gte"
 | 
						|
		d = locale.NumberGTE()
 | 
						|
	case *NumberGTError:
 | 
						|
		t = "number_gt"
 | 
						|
		d = locale.NumberGT()
 | 
						|
	case *NumberLTEError:
 | 
						|
		t = "number_lte"
 | 
						|
		d = locale.NumberLTE()
 | 
						|
	case *NumberLTError:
 | 
						|
		t = "number_lt"
 | 
						|
		d = locale.NumberLT()
 | 
						|
	case *ConditionThenError:
 | 
						|
		t = "condition_then"
 | 
						|
		d = locale.ConditionThen()
 | 
						|
	case *ConditionElseError:
 | 
						|
		t = "condition_else"
 | 
						|
		d = locale.ConditionElse()
 | 
						|
	}
 | 
						|
 | 
						|
	err.SetType(t)
 | 
						|
	err.SetContext(context)
 | 
						|
	err.SetValue(value)
 | 
						|
	err.SetDetails(details)
 | 
						|
	err.SetDescriptionFormat(d)
 | 
						|
	details["field"] = err.Field()
 | 
						|
 | 
						|
	if _, exists := details["context"]; !exists && context != nil {
 | 
						|
		details["context"] = context.String()
 | 
						|
	}
 | 
						|
 | 
						|
	err.SetDescription(formatErrorDescription(err.DescriptionFormat(), details))
 | 
						|
}
 | 
						|
 | 
						|
// formatErrorDescription takes a string in the default text/template
 | 
						|
// format and converts it to a string with replacements. The fields come
 | 
						|
// from the ErrorDetails struct and vary for each type of error.
 | 
						|
func formatErrorDescription(s string, details ErrorDetails) string {
 | 
						|
 | 
						|
	var tpl *template.Template
 | 
						|
	var descrAsBuffer bytes.Buffer
 | 
						|
	var err error
 | 
						|
 | 
						|
	errorTemplates.RLock()
 | 
						|
	tpl = errorTemplates.Lookup(s)
 | 
						|
	errorTemplates.RUnlock()
 | 
						|
 | 
						|
	if tpl == nil {
 | 
						|
		errorTemplates.Lock()
 | 
						|
		tpl = errorTemplates.New(s)
 | 
						|
 | 
						|
		if ErrorTemplateFuncs != nil {
 | 
						|
			tpl.Funcs(ErrorTemplateFuncs)
 | 
						|
		}
 | 
						|
 | 
						|
		tpl, err = tpl.Parse(s)
 | 
						|
		errorTemplates.Unlock()
 | 
						|
 | 
						|
		if err != nil {
 | 
						|
			return err.Error()
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	err = tpl.Execute(&descrAsBuffer, details)
 | 
						|
	if err != nil {
 | 
						|
		return err.Error()
 | 
						|
	}
 | 
						|
 | 
						|
	return descrAsBuffer.String()
 | 
						|
}
 |