-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathresource.go
175 lines (149 loc) · 4.58 KB
/
resource.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package stretchr
import (
"fmt"
"github.com/stretchr/objx"
"github.com/stretchr/sdk-go/api"
"github.com/stretchr/sdk-go/common"
stewstrings "github.com/stretchr/stew/strings"
"strings"
"time"
)
const (
// NoID represents the string indicating the resource has no ID.
NoID string = ""
)
// Resource represents a resource in Stretchr.
type Resource struct {
// Path is the path of this resource.
path string
// Data holds the data for the resource.
data objx.Map
}
// MakeResourceAt makes a new Resource with the specified path.
func MakeResourceAt(path string) *Resource {
resource := new(Resource)
resource.path = path
resource.data = make(map[string]interface{})
// do we need to set the ID in the data?
pathSegments := strings.Split(path, common.PathSeparator)
if len(pathSegments)%2 == 0 {
// yes -
resource.data[common.DataFieldID] = pathSegments[len(pathSegments)-1]
}
return resource
}
// ResourcePath gets the path for this Resource.
func (r *Resource) ResourcePath() string {
// TODO: have this cache
// break the path apart
pathSegments := strings.Split(r.path, common.PathSeparator)
// do we have an ID in the data?
if id, hasId := r.data[common.DataFieldID]; hasId {
// do we have an ID in the path?
if len(pathSegments)%2 == 0 {
// update the ID
pathSegments[len(pathSegments)-1] = id.(string)
} else {
// add the ID
pathSegments = append(pathSegments, id.(string))
}
}
return stewstrings.JoinStrings(common.PathSeparator, pathSegments...)
}
// ResourceData gets the data for this Resource.
func (r *Resource) ResourceData() objx.Map {
return r.data
}
// MergeData merges the passed data with the internal map
func (r *Resource) MergeData(data objx.Map) {
r.data.MergeHere(data)
}
// Get gets a value from the resource.
//
// Keypaths are supported with the dot syntax, for more information see
// http://godoc.org/github.com/stretchr/objx#Map.Get
func (r *Resource) Get(keypath string) interface{} {
return r.data.Get(keypath).Data()
}
// GetString gets a strongly typed value from the data of this Resource
// or panics if that is impossible.
func (r *Resource) GetString(keypath string) string {
if val, ok := r.Get(keypath).(string); ok {
return val
}
panic(fmt.Sprintf("stretchr: Cannot GetString on %s.", r.Get(keypath)))
}
// GetNumber gets a strongly typed value from the data of this Resource
// or panics if that is impossible.
func (r *Resource) GetNumber(keypath string) float64 {
if val, ok := r.Get(keypath).(float64); ok {
return val
}
panic(fmt.Sprintf("stretchr: Cannot GetNumber on %s.", r.Get(keypath)))
}
// GetBool gets a strongly typed value from the data of this Resource
// or panics if that is impossible.
func (r *Resource) GetBool(keypath string) bool {
if val, ok := r.Get(keypath).(bool); ok {
return val
}
panic(fmt.Sprintf("stretchr: Cannot GetBool on %s.", r.Get(keypath)))
}
// GetTime gets a strongly typed value from the data of this Resource
// or panics if that is impossible.
func (r *Resource) GetTime(keypath string) time.Time {
if floatTime, floatTimeOk := r.Get(keypath).(float64); floatTimeOk {
return time.Unix(int64(floatTime), 0)
}
panic(fmt.Sprintf("stretchr: Cannot GetTime on %s.", r.Get(keypath)))
}
// ID gets the ID string for this resource.
//
// If this resource doesn't have an ID (which can happen if it has not yet
// been persisted) then `NoID` will be returned.
func (r *Resource) ID() string {
if id, ok := r.data[common.DataFieldID]; ok {
if idString, typeOk := id.(string); typeOk {
return idString
}
}
// no ID
return NoID
}
// Set sets a value to the specified key and returns the Resource for chaining.
//
// Keypaths are supported with the dot syntax, for more information see
// http://godoc.org/github.com/stretchr/objx#Map.Set
func (r *Resource) Set(keypath string, value interface{}) *Resource {
toStore := value
switch value.(type) {
case int:
toStore = float64(value.(int))
case int8:
toStore = float64(value.(int8))
case int16:
toStore = float64(value.(int16))
case int32:
toStore = float64(value.(int32))
case int64:
toStore = float64(value.(int64))
case uint:
toStore = float64(value.(uint))
case uint8:
toStore = float64(value.(uint8))
case uint16:
toStore = float64(value.(uint16))
case uint32:
toStore = float64(value.(uint32))
case uint64:
toStore = float64(value.(uint64))
case float32:
toStore = float64(value.(float32))
}
r.data.Set(keypath, toStore)
return r
}
// SetID sets the ID value to the specified string and returns the Resource for chaining.
func (r *Resource) SetID(ID string) api.Resource {
return r.Set(common.DataFieldID, ID)
}