-
Notifications
You must be signed in to change notification settings - Fork 4
/
property.go
executable file
·138 lines (119 loc) · 3.79 KB
/
property.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
package property
import (
"errors"
"fmt"
)
var (
//ErrWrongPropertyType is cast when the Property is of another type
ErrWrongPropertyType = errors.New("the property is not of this data type")
//ErrNoSuchProperty is when trying to assign value to Property that does not exist
ErrNoSuchProperty = errors.New("the property ur trying to set the value for does not exist")
)
// Property is a value holder used by Actions to handle Configs
type Property struct {
Name string `json:"name" yaml:"name"`
Value interface{} `json:"value" yaml:"value"`
Description string `json:"description" yaml:"description"`
Required bool `json:"required" yaml:"required"`
Valid bool `json:"valid" yaml:"valid"`
}
// IsValid is used to control if Required is true, then Value cannot be nil, if it is it will return False
func (p *Property) IsValid() bool {
if p.Required && p.Value == nil {
p.Valid = false
return false
}
p.Valid = true
return true
}
// String Will return the Value as string
func (p *Property) String() string {
return fmt.Sprintf("%v", p.Value)
}
// Int will reutnr the value as int
func (p *Property) Int() (int, error) {
var value int
var ok bool
if value, ok = p.Value.(int); !ok {
return -1, ErrWrongPropertyType
}
return value, nil
}
// Int64 resemblance of the property is returned
func (p *Property) Int64() (int64, error) {
var value int
var ok bool
if value, ok = p.Value.(int); !ok {
return -1, ErrWrongPropertyType
}
return int64(value), nil
}
// Bool is used to return the value as a boolean
func (p *Property) Bool() (bool, error) {
var value bool
var ok bool
if value, ok = p.Value.(bool); !ok {
return false, ErrWrongPropertyType
}
return value, nil
}
// StringSplice is used to get the value as a stringslice
func (p *Property) StringSplice() ([]string, error) {
var value []interface{}
var ok bool
// THis is the same as with the MAP case, we cannot type assert into slice of strings.
// GOland doest know that the content is strings and wont work.
if value, ok = p.Value.([]interface{}); !ok {
// Also try with regular slice instead of interface
if valueSplice, ok2 := p.Value.([]string); ok2 {
return valueSplice, nil
}
return nil, fmt.Errorf("%s: %w", p.Name, ErrWrongPropertyType)
}
valueStr := make([]string, len(value))
for _, val := range value {
valueStr = append(valueStr, val.(string))
}
return valueStr, nil
}
// StringMap is used to return the value as a map[string]string
func (p *Property) StringMap() (map[string]string, error) {
// The reason for this is because golang cannot type asset to
// a map string string, only map string interface
// So we need to first type convert to map string interface and then convert each value
var value map[string]interface{}
valueStr := make(map[string]string, 0)
var ok bool
if value, ok = p.Value.(map[string]interface{}); !ok {
// Also try mstrmap
if valueStr, ok2 := p.Value.(map[string]string); ok2 {
return valueStr, nil
}
return nil, fmt.Errorf("%s: %w", p.Name, ErrWrongPropertyType)
}
for key, val := range value {
valueStr[key] = val.(string)
}
return valueStr, nil
}
// MapWithSlice will return a Map that holds a slice of strings
func (p *Property) MapWithSlice() (map[string][]string, error) {
value := make(map[string][]string, 0)
value, ok := p.Value.(map[string][]string)
if !ok {
value := make(map[string][]string, 0)
// Now try interface conversion instead -- this is a use case needed when handeling YAML marshall
intvalue, ok2 := p.Value.(map[string]interface{})
if ok2 {
for group, mapvalue := range intvalue {
slice := mapvalue.([]interface{})
for _, str := range slice {
value[group] = append(value[group], str.(string))
}
}
return value, nil
}
return nil, ErrWrongPropertyType
}
return value, nil
}