Example #1
0
func equal(a json.Value, b json.Value) bool {
	switch x := a.(type) {
	case *json.Array:
		b, ok := b.(*json.Array)
		if !ok {
			return false
		}
		if len(x.Value) != len(b.Value) {
			return false
		}
		for i, item := range x.Value {
			if !equal(item, b.Value[i]) {
				return false
			}
		}
		return true
	case *json.Bool:
		b, ok := b.(*json.Bool)
		if !ok {
			return false
		}
		return x.Value == b.Value
	case *json.Number:
		switch b := b.(type) {
		case *json.Number:
			return x.Value == b.Value // XXX: comparing floating point numbers.
		case *json.Integer:
			return x.Value == float64(b.Value) // XXX: comparing floating point numbers.
		default:
			return false
		}
	case *json.Integer:
		switch b := b.(type) {
		case *json.Number:
			return float64(x.Value) == b.Value // XXX: comparing floating point numbers.
		case *json.Integer:
			return x.Value == b.Value
		default:
			return false
		}
	case *json.Null:
		_, ok := b.(*json.Null)
		if !ok {
			return false
		}
		return true
	case *json.Object:
		b, ok := b.(*json.Object)
		if !ok {
			return false
		}
		if len(x.Value) != len(b.Value) {
			return false
		}
		for i, item := range x.Value {
			if !equal(item, b.Find(i.Value)) {
				return false
			}
		}
		return true
	case *json.String:
		b, ok := b.(*json.String)
		if !ok {
			return false
		}
		return x.Value == b.Value
	default:
		return false
	}
}
Example #2
0
func validateDraft04Schema(path string, v json.Value) error {
	switch v := v.(type) {
	case *json.Object:
		s, found := v.Lookup("$ref")
		if found {
			return validateURI(path+"/$ref", s)
		}
		validators := map[string]func(string, json.Value) error{
			"type":                 validateType,
			"id":                   validateURI,
			"$schema":              validateURI,
			"title":                validateString,
			"description":          validateString,
			"multipleOf":           validateMultipleOf,
			"maximum":              validateNumber,
			"minimum":              validateNumber,
			"exclusiveMaximum":     validateBoolean,
			"exclusiveMinimum":     validateBoolean,
			"minLength":            validatePositiveInteger,
			"maxLength":            validatePositiveInteger,
			"pattern":              validatePattern,
			"additionalItems":      validateBoolOrSchema,
			"items":                validateItems,
			"maxItems":             validatePositiveInteger,
			"minItems":             validatePositiveInteger,
			"uniqueItems":          validateBoolean,
			"maxProperties":        validatePositiveInteger,
			"minProperties":        validatePositiveInteger,
			"required":             validateStringArray,
			"additionalProperties": validateBoolOrSchema,
			"definitions":          validateSchemaCollection,
			"properties":           validateSchemaCollection,
			"patternProperties":    validateSchemaCollection,
			"dependencies":         validateDependencies,
			"enum":                 validateEnum,
			"allOf":                validateSchemaArray,
			"anyOf":                validateSchemaArray,
			"oneOf":                validateSchemaArray,
			"not":                  validateDraft04Schema,
		}
		for prop, validate := range validators {
			val, found := v.Lookup(prop)
			if !found {
				continue
			}
			err := validate(path+"/"+prop, val)
			if err != nil {
				return err
			}
		}
		_, a := v.Lookup("exclusiveMaximum")
		_, b := v.Lookup("maximum")
		if a && !b {
			return fmt.Errorf("%q: \"exclusiveMaximum\" requires \"maximum\" to be present")
		}
		_, a = v.Lookup("exclusiveMinimum")
		_, b = v.Lookup("minimum")
		if a && !b {
			return fmt.Errorf("%q: \"exclusiveMinimum\" requires \"minimum\" to be present")
		}
		return nil
	default:
		return fmt.Errorf("%q has invalid type, it needs to be an object", path)
	}
}