...
1
16
17 package typed
18
19 import (
20 "fmt"
21
22 yaml "gopkg.in/yaml.v2"
23 "sigs.k8s.io/structured-merge-diff/v4/schema"
24 "sigs.k8s.io/structured-merge-diff/v4/value"
25 )
26
27
28 type YAMLObject string
29
30
31 type Parser struct {
32 Schema schema.Schema
33 }
34
35
36 func create(s YAMLObject) (*Parser, error) {
37 p := Parser{}
38 err := yaml.Unmarshal([]byte(s), &p.Schema)
39 return &p, err
40 }
41
42 func createOrDie(schema YAMLObject) *Parser {
43 p, err := create(schema)
44 if err != nil {
45 panic(fmt.Errorf("failed to create parser: %v", err))
46 }
47 return p
48 }
49
50 var ssParser = createOrDie(YAMLObject(schema.SchemaSchemaYAML))
51
52
53 func NewParser(schema YAMLObject) (*Parser, error) {
54 _, err := ssParser.Type("schema").FromYAML(schema)
55 if err != nil {
56 return nil, fmt.Errorf("unable to validate schema: %v", err)
57 }
58 p, err := create(schema)
59 if err != nil {
60 return nil, err
61 }
62 return p, nil
63 }
64
65
66 func (p *Parser) TypeNames() (names []string) {
67 for _, td := range p.Schema.Types {
68 names = append(names, td.Name)
69 }
70 return names
71 }
72
73
74
75 func (p *Parser) Type(name string) ParseableType {
76 return ParseableType{
77 Schema: &p.Schema,
78 TypeRef: schema.TypeRef{NamedType: &name},
79 }
80 }
81
82
83 type ParseableType struct {
84 TypeRef schema.TypeRef
85 Schema *schema.Schema
86 }
87
88
89 func (p ParseableType) IsValid() bool {
90 _, ok := p.Schema.Resolve(p.TypeRef)
91 return ok
92 }
93
94
95
96 func (p ParseableType) FromYAML(object YAMLObject, opts ...ValidationOptions) (*TypedValue, error) {
97 var v interface{}
98 err := yaml.Unmarshal([]byte(object), &v)
99 if err != nil {
100 return nil, err
101 }
102 return AsTyped(value.NewValueInterface(v), p.Schema, p.TypeRef, opts...)
103 }
104
105
106
107
108
109
110
111 func (p ParseableType) FromUnstructured(in interface{}, opts ...ValidationOptions) (*TypedValue, error) {
112 return AsTyped(value.NewValueInterface(in), p.Schema, p.TypeRef, opts...)
113 }
114
115
116
117
118
119
120 func (p ParseableType) FromStructured(in interface{}, opts ...ValidationOptions) (*TypedValue, error) {
121 v, err := value.NewValueReflect(in)
122 if err != nil {
123 return nil, fmt.Errorf("error creating struct value reflector: %v", err)
124 }
125 return AsTyped(v, p.Schema, p.TypeRef, opts...)
126 }
127
128
129
130 var DeducedParseableType ParseableType = createOrDie(YAMLObject(`types:
131 - name: __untyped_atomic_
132 scalar: untyped
133 list:
134 elementType:
135 namedType: __untyped_atomic_
136 elementRelationship: atomic
137 map:
138 elementType:
139 namedType: __untyped_atomic_
140 elementRelationship: atomic
141 - name: __untyped_deduced_
142 scalar: untyped
143 list:
144 elementType:
145 namedType: __untyped_atomic_
146 elementRelationship: atomic
147 map:
148 elementType:
149 namedType: __untyped_deduced_
150 elementRelationship: separable
151 `)).Type("__untyped_deduced_")
152
View as plain text