StructRegister takes an CLI args struct with optional struct tags, and generates simple functions from the contained fields in the specified namespace. If no struct field named `func` is included, then a default function name which is the lower case representation of the field name will be used, oth
(moduleName string, args interface{})
| 251 | // TODO: An alternative version of this might choose to return all of the values |
| 252 | // as a single giant struct. |
| 253 | func StructRegister(moduleName string, args interface{}) error { |
| 254 | if args == nil { |
| 255 | // programming error |
| 256 | return fmt.Errorf("could not convert/access our struct") |
| 257 | } |
| 258 | //fmt.Printf("A: %+v\n", args) |
| 259 | |
| 260 | val := reflect.ValueOf(args) |
| 261 | if val.Kind() == reflect.Pointer { // max one de-referencing |
| 262 | val = val.Elem() |
| 263 | } |
| 264 | typ := val.Type() |
| 265 | |
| 266 | for i := 0; i < typ.NumField(); i++ { |
| 267 | v := val.Field(i) // value of the field |
| 268 | t := typ.Field(i) // struct type, get real type with .Type |
| 269 | |
| 270 | name := strings.ToLower(t.Name) // default |
| 271 | if alias, ok := t.Tag.Lookup("func"); ok { |
| 272 | if alias == "-" { // skip |
| 273 | continue |
| 274 | } |
| 275 | name = alias |
| 276 | } |
| 277 | //fmt.Printf("N: %+v\n", name) // debug |
| 278 | if len(strings.Trim(name, "abcdefghijklmnopqrstuvwxyz_")) > 0 { |
| 279 | return fmt.Errorf("struct field index(%d) has invalid char(s) in function name", i) |
| 280 | } |
| 281 | |
| 282 | typed, err := types.TypeOf(t.Type) // reflect.Type -> (*types.Type, error) |
| 283 | if err != nil { |
| 284 | return err |
| 285 | } |
| 286 | //fmt.Printf("T: %+v\n", typed.String()) // debug |
| 287 | |
| 288 | ModuleRegister(moduleName, name, &Scaffold{ |
| 289 | T: types.NewType(fmt.Sprintf("func() %s", typed.String())), |
| 290 | F: func(ctx context.Context, input []types.Value) (types.Value, error) { |
| 291 | //if args == nil { |
| 292 | // // programming error |
| 293 | // return nil, fmt.Errorf("could not convert/access our struct") |
| 294 | //} |
| 295 | |
| 296 | value, err := types.ValueOf(v) // reflect.Value -> (types.Value, error) |
| 297 | if err != nil { |
| 298 | return nil, errwrap.Wrapf(err, "func `%s.%s()` has nil value", moduleName, name) |
| 299 | } |
| 300 | //fmt.Printf("V: %+v\n", value) // debug |
| 301 | return value, nil |
| 302 | }, |
| 303 | }) |
| 304 | } |
| 305 | |
| 306 | return nil |
| 307 | } |