package parse import ( "fmt" "github.com/aziis98/cabret" "github.com/aziis98/cabret/config" "github.com/aziis98/cabret/operation" ) // switchMapHasKey returns a function that returns true if the map "m" contains the given key and binds the corresponding value to the provided "target" pointer, useful for writing map key checks using a switch instead of an if chain func switchMapHasKey(m map[string]any, target *any) func(k string) bool { return func(k string) bool { val, ok := m[k] if ok { *target = val } return ok } } func ParsePipeline(p config.Pipeline) ([]cabret.Operation, error) { ops := []cabret.Operation{} for _, operationConfig := range p.Pipeline { var rawValue any hasKey := switchMapHasKey(operationConfig, &rawValue) switch { case hasKey("source"): value, ok := rawValue.(string) if !ok { return nil, fmt.Errorf(`expected string but got "%v" of type %T`, rawValue, rawValue) } operationConfig[operation.ShortFormValueKey] = value op, err := ParseOperation("source", operationConfig) if err != nil { return nil, err } ops = append(ops, op) case hasKey("target"): value, ok := rawValue.(string) if !ok { return nil, fmt.Errorf(`expected string but got "%v" of type %T`, rawValue, rawValue) } operationConfig[operation.ShortFormValueKey] = value op, err := ParseOperation("target", operationConfig) if err != nil { return nil, err } ops = append(ops, op) case hasKey("use"): name, ok := rawValue.(string) if !ok { return nil, fmt.Errorf(`expected string but got "%v" of type %T`, rawValue, rawValue) } op, err := ParseOperation(name, operationConfig) if err != nil { return nil, err } ops = append(ops, op) default: return nil, fmt.Errorf(`pipeline entry is missing one of "use", "source" or "target", got %#v`, operationConfig) } } return ops, nil } func ParseOperation(name string, options map[string]any) (cabret.Operation, error) { op, err := operation.NewWithName(name) if err != nil { return nil, err } if err := op.Configure(options); err != nil { return nil, err } return op, nil }