github.com/aaronlehmann/figtree@v1.0.1/rawoption.go (about) 1 //go:generate genny -in=$GOFILE -out=gen-$GOFILE gen "RawType=BUILTINS" 2 3 package figtree 4 5 import ( 6 "encoding/json" 7 "fmt" 8 9 "github.com/cheekybits/genny/generic" 10 ) 11 12 type RawType generic.Type 13 14 type RawTypeOption struct { 15 Source string 16 Defined bool 17 Value RawType 18 } 19 20 func NewRawTypeOption(dflt RawType) RawTypeOption { 21 return RawTypeOption{ 22 Source: "default", 23 Defined: true, 24 Value: dflt, 25 } 26 } 27 28 func (o RawTypeOption) IsDefined() bool { 29 return o.Defined 30 } 31 32 func (o *RawTypeOption) SetSource(source string) { 33 o.Source = source 34 } 35 36 func (o *RawTypeOption) GetSource() string { 37 return o.Source 38 } 39 40 func (o RawTypeOption) GetValue() interface{} { 41 return o.Value 42 } 43 44 // This is useful with kingpin option parser 45 func (o *RawTypeOption) Set(s string) error { 46 err := convertString(s, &o.Value) 47 if err != nil { 48 return err 49 } 50 o.Source = "override" 51 o.Defined = true 52 return nil 53 } 54 55 // This is useful with survey prompting library 56 func (o *RawTypeOption) WriteAnswer(name string, value interface{}) error { 57 if v, ok := value.(RawType); ok { 58 o.Value = v 59 o.Defined = true 60 o.Source = "prompt" 61 return nil 62 } 63 return fmt.Errorf("Got %T expected %T type: %v", value, o.Value, value) 64 } 65 66 func (o *RawTypeOption) SetValue(v interface{}) error { 67 if val, ok := v.(RawType); ok { 68 o.Value = val 69 o.Defined = true 70 return nil 71 } 72 return fmt.Errorf("Got %T expected %T type: %v", v, o.Value, v) 73 } 74 75 func (o *RawTypeOption) UnmarshalYAML(unmarshal func(interface{}) error) error { 76 if err := unmarshal(&o.Value); err != nil { 77 return err 78 } 79 o.Source = "yaml" 80 o.Defined = true 81 return nil 82 } 83 84 func (o *RawTypeOption) UnmarshalJSON(b []byte) error { 85 if err := json.Unmarshal(b, &o.Value); err != nil { 86 return err 87 } 88 o.Source = "json" 89 o.Defined = true 90 return nil 91 } 92 93 func (o RawTypeOption) MarshalYAML() (interface{}, error) { 94 if StringifyValue { 95 return o.Value, nil 96 } 97 // need a copy of this struct without the MarshalYAML interface attached 98 return struct { 99 Value RawType 100 Source string 101 Defined bool 102 }{ 103 Value: o.Value, 104 Source: o.Source, 105 Defined: o.Defined, 106 }, nil 107 } 108 109 func (o RawTypeOption) MarshalJSON() ([]byte, error) { 110 if StringifyValue { 111 return json.Marshal(o.Value) 112 } 113 // need a copy of this struct without the MarshalJSON interface attached 114 return json.Marshal(struct { 115 Value RawType 116 Source string 117 Defined bool 118 }{ 119 Value: o.Value, 120 Source: o.Source, 121 Defined: o.Defined, 122 }) 123 } 124 125 // String is required for kingpin to generate usage with this datatype 126 func (o RawTypeOption) String() string { 127 if StringifyValue { 128 return fmt.Sprintf("%v", o.Value) 129 } 130 return fmt.Sprintf("{Source:%s Defined:%t Value:%v}", o.Source, o.Defined, o.Value) 131 } 132 133 type MapRawTypeOption map[string]RawTypeOption 134 135 // Set is required for kingpin interfaces to allow command line params 136 // to be set to our map datatype 137 func (o *MapRawTypeOption) Set(value string) error { 138 parts := stringMapRegex.Split(value, 2) 139 if len(parts) != 2 { 140 return fmt.Errorf("expected KEY=VALUE got '%s'", value) 141 } 142 val := RawTypeOption{} 143 val.Set(parts[1]) 144 (*o)[parts[0]] = val 145 return nil 146 } 147 148 // IsCumulative is required for kingpin interfaces to allow multiple values 149 // to be set on the data structure. 150 func (o MapRawTypeOption) IsCumulative() bool { 151 return true 152 } 153 154 // String is required for kingpin to generate usage with this datatype 155 func (o MapRawTypeOption) String() string { 156 return fmt.Sprintf("%v", map[string]RawTypeOption(o)) 157 } 158 159 func (o MapRawTypeOption) Map() map[string]RawType { 160 tmp := map[string]RawType{} 161 for k, v := range o { 162 tmp[k] = v.Value 163 } 164 return tmp 165 } 166 167 // This is useful with survey prompting library 168 func (o *MapRawTypeOption) WriteAnswer(name string, value interface{}) error { 169 tmp := RawTypeOption{} 170 if v, ok := value.(RawType); ok { 171 tmp.Value = v 172 tmp.Defined = true 173 tmp.Source = "prompt" 174 (*o)[name] = tmp 175 return nil 176 } 177 return fmt.Errorf("Got %T expected %T type: %v", value, tmp.Value, value) 178 } 179 180 func (o MapRawTypeOption) IsDefined() bool { 181 // true if the map has any keys 182 if len(o) > 0 { 183 return true 184 } 185 return false 186 } 187 188 type ListRawTypeOption []RawTypeOption 189 190 // Set is required for kingpin interfaces to allow command line params 191 // to be set to our map datatype 192 func (o *ListRawTypeOption) Set(value string) error { 193 val := RawTypeOption{} 194 val.Set(value) 195 *o = append(*o, val) 196 return nil 197 } 198 199 // This is useful with survey prompting library 200 func (o *ListRawTypeOption) WriteAnswer(name string, value interface{}) error { 201 tmp := RawTypeOption{} 202 if v, ok := value.(RawType); ok { 203 tmp.Value = v 204 tmp.Defined = true 205 tmp.Source = "prompt" 206 *o = append(*o, tmp) 207 return nil 208 } 209 return fmt.Errorf("Got %T expected %T type: %v", value, tmp.Value, value) 210 } 211 212 // IsCumulative is required for kingpin interfaces to allow multiple values 213 // to be set on the data structure. 214 func (o ListRawTypeOption) IsCumulative() bool { 215 return true 216 } 217 218 // String is required for kingpin to generate usage with this datatype 219 func (o ListRawTypeOption) String() string { 220 return fmt.Sprintf("%v", []RawTypeOption(o)) 221 } 222 223 func (o ListRawTypeOption) Append(values ...RawType) ListRawTypeOption { 224 results := o 225 for _, val := range values { 226 results = append(results, NewRawTypeOption(val)) 227 } 228 return results 229 } 230 231 func (o ListRawTypeOption) Slice() []RawType { 232 tmp := []RawType{} 233 for _, elem := range o { 234 tmp = append(tmp, elem.Value) 235 } 236 return tmp 237 } 238 239 func (o ListRawTypeOption) IsDefined() bool { 240 // true if the list is not empty 241 if len(o) > 0 { 242 return true 243 } 244 return false 245 }