blob: 8682136f51eea83936c81fdd8d17f25752753e4b [file] [log] [blame]
David K. Bainbridge528b3182017-01-23 08:51:59 -08001// Copyright 2015 Canonical Ltd.
2// Licensed under the LGPLv3, see LICENCE file for details.
3
4package schema
5
6import (
7 "strings"
8)
9
10// The Coerce method of the Checker interface is called recursively when
11// v is being validated. If err is nil, newv is used as the new value
12// at the recursion point. If err is non-nil, v is taken as invalid and
13// may be either ignored or error out depending on where in the schema
14// checking process the error happened. Checkers like OneOf may continue
15// with an alternative, for instance.
16type Checker interface {
17 Coerce(v interface{}, path []string) (newv interface{}, err error)
18}
19
20// Any returns a Checker that succeeds with any input value and
21// results in the value itself unprocessed.
22func Any() Checker {
23 return anyC{}
24}
25
26type anyC struct{}
27
28func (c anyC) Coerce(v interface{}, path []string) (interface{}, error) {
29 return v, nil
30}
31
32// OneOf returns a Checker that attempts to Coerce the value with each
33// of the provided checkers. The value returned by the first checker
34// that succeeds will be returned by the OneOf checker itself. If no
35// checker succeeds, OneOf will return an error on coercion.
36func OneOf(options ...Checker) Checker {
37 return oneOfC{options}
38}
39
40type oneOfC struct {
41 options []Checker
42}
43
44func (c oneOfC) Coerce(v interface{}, path []string) (interface{}, error) {
45 for _, o := range c.options {
46 newv, err := o.Coerce(v, path)
47 if err == nil {
48 return newv, nil
49 }
50 }
51 return nil, error_{"", v, path}
52}
53
54// pathAsPrefix returns a string consisting of the path elements
55// suitable for using as the prefix of an error message. If path
56// starts with a ".", the dot is omitted.
57func pathAsPrefix(path []string) string {
58 if len(path) == 0 {
59 return ""
60 }
61 var s string
62 if path[0] == "." {
63 s = strings.Join(path[1:], "")
64 } else {
65 s = strings.Join(path, "")
66 }
67 if s == "" {
68 return ""
69 }
70 return s + ": "
71}