David K. Bainbridge | 528b318 | 2017-01-23 08:51:59 -0800 | [diff] [blame] | 1 | // Copyright 2015 Canonical Ltd. |
| 2 | // Licensed under the LGPLv3, see LICENCE file for details. |
| 3 | |
| 4 | package schema |
| 5 | |
| 6 | import ( |
| 7 | "fmt" |
| 8 | "reflect" |
| 9 | ) |
| 10 | |
| 11 | // Const returns a Checker that only succeeds if the input matches |
| 12 | // value exactly. The value is compared with reflect.DeepEqual. |
| 13 | func Const(value interface{}) Checker { |
| 14 | return constC{value} |
| 15 | } |
| 16 | |
| 17 | type constC struct { |
| 18 | value interface{} |
| 19 | } |
| 20 | |
| 21 | func (c constC) Coerce(v interface{}, path []string) (interface{}, error) { |
| 22 | if reflect.DeepEqual(v, c.value) { |
| 23 | return v, nil |
| 24 | } |
| 25 | return nil, error_{fmt.Sprintf("%#v", c.value), v, path} |
| 26 | } |
| 27 | |
| 28 | // Nil returns a Checker that only succeeds if the input is nil. To tweak the |
| 29 | // error message, valueLabel can contain a label of the value being checked to |
| 30 | // be empty, e.g. "my special name". If valueLabel is "", "value" will be used |
| 31 | // as a label instead. |
| 32 | // |
| 33 | // Example 1: |
| 34 | // schema.Nil("widget").Coerce(42, nil) will return an error message |
| 35 | // like `expected empty widget, got int(42)`. |
| 36 | // |
| 37 | // Example 2: |
| 38 | // schema.Nil("").Coerce("", nil) will return an error message like |
| 39 | // `expected empty value, got string("")`. |
| 40 | func Nil(valueLabel string) Checker { |
| 41 | if valueLabel == "" { |
| 42 | valueLabel = "value" |
| 43 | } |
| 44 | return nilC{valueLabel} |
| 45 | } |
| 46 | |
| 47 | type nilC struct { |
| 48 | valueLabel string |
| 49 | } |
| 50 | |
| 51 | func (c nilC) Coerce(v interface{}, path []string) (interface{}, error) { |
| 52 | if reflect.DeepEqual(v, nil) { |
| 53 | return v, nil |
| 54 | } |
| 55 | label := fmt.Sprintf("empty %s", c.valueLabel) |
| 56 | return nil, error_{label, v, path} |
| 57 | } |