-
Notifications
You must be signed in to change notification settings - Fork 23
/
space.go
152 lines (130 loc) · 3.84 KB
/
space.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Copyright 2016 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.
package description
import (
"github.com/juju/errors"
"github.com/juju/schema"
)
type spaces struct {
Version int `yaml:"version"`
Spaces_ []*space `yaml:"spaces"`
}
type space struct {
Id_ string `yaml:"id"`
Name_ string `yaml:"name"`
Public_ bool `yaml:"public"`
ProviderID_ string `yaml:"provider-id,omitempty"`
}
// SpaceArgs is an argument struct used to create a new internal space
// type that supports the Space interface.
type SpaceArgs struct {
Id string
Name string
Public bool
ProviderID string
}
func newSpace(args SpaceArgs) *space {
return &space{
Id_: args.Id,
Name_: args.Name,
Public_: args.Public,
ProviderID_: args.ProviderID,
}
}
// Id implements Space.
func (s *space) Id() string {
return s.Id_
}
// Name implements Space.
func (s *space) Name() string {
return s.Name_
}
// Public implements Space.
func (s *space) Public() bool {
return s.Public_
}
// ProviderID implements Space.
func (s *space) ProviderID() string {
return s.ProviderID_
}
func importSpaces(source map[string]interface{}) ([]*space, error) {
checker := versionedChecker("spaces")
coerced, err := checker.Coerce(source, nil)
if err != nil {
return nil, errors.Annotatef(err, "spaces version schema check failed")
}
valid := coerced.(map[string]interface{})
version := int(valid["version"].(int64))
importFunc, ok := spaceDeserializationFuncs[version]
if !ok {
return nil, errors.NotValidf("version %d", version)
}
sourceList := valid["spaces"].([]interface{})
return importSpaceList(sourceList, importFunc)
}
func importSpaceList(sourceList []interface{}, importFunc spaceDeserializationFunc) ([]*space, error) {
result := make([]*space, 0, len(sourceList))
for i, value := range sourceList {
source, ok := value.(map[string]interface{})
if !ok {
return nil, errors.Errorf("unexpected value for space %d, %T", i, value)
}
space, err := importFunc(source)
if err != nil {
return nil, errors.Annotatef(err, "space %d", i)
}
result = append(result, space)
}
return result, nil
}
type spaceDeserializationFunc func(map[string]interface{}) (*space, error)
var spaceDeserializationFuncs = map[int]spaceDeserializationFunc{
1: importSpaceV1,
2: importSpaceV2,
}
func importSpaceV1(source map[string]interface{}) (*space, error) {
fields, defaults := spaceV1Fields()
checker := schema.FieldMap(fields, defaults)
coerced, err := checker.Coerce(source, nil)
if err != nil {
return nil, errors.Annotatef(err, "space v1 schema check failed")
}
valid := coerced.(map[string]interface{})
// From here we know that the map returned from the schema coercion
// contains fields of the right type.
return &space{
Name_: valid["name"].(string),
Public_: valid["public"].(bool),
ProviderID_: valid["provider-id"].(string),
}, nil
}
func importSpaceV2(source map[string]interface{}) (*space, error) {
fields, defaults := spaceV1Fields()
fields["id"] = schema.String()
checker := schema.FieldMap(fields, defaults)
coerced, err := checker.Coerce(source, nil)
if err != nil {
return nil, errors.Annotatef(err, "space v2 schema check failed")
}
valid := coerced.(map[string]interface{})
// From here we know that the map returned from the schema coercion
// contains fields of the right type.
return &space{
Id_: valid["id"].(string),
Name_: valid["name"].(string),
Public_: valid["public"].(bool),
ProviderID_: valid["provider-id"].(string),
}, nil
}
func spaceV1Fields() (schema.Fields, schema.Defaults) {
fields := schema.Fields{
"name": schema.String(),
"public": schema.Bool(),
"provider-id": schema.String(),
}
// Some values don't have to be there.
defaults := schema.Defaults{
"provider-id": "",
}
return fields, defaults
}