package registry import ( "fmt" "git.maximhutz.com/max/lambda/pkg/engine" ) // An Engine is a type-erased evaluation engine that can load an expression // into a runnable Process. type Engine interface { // Load prepares an expression for evaluation, returning a Process. Returns // an error if the expression's data does not match the engine's expected // representation type. Load(Expr) (Process, error) // Name returns the name of this engine. Name() string // InType returns the name of the representation this engine operates on. InType() string } // A registeredEngine adapts a typed engine.Engine[T] into the type-erased // Engine interface. It extracts the underlying T from an Expr before passing it // to the engine. type registeredEngine[T any] struct { engine engine.Engine[T] name string inType string } func (e registeredEngine[T]) InType() string { return e.inType } func (e registeredEngine[T]) Name() string { return e.name } func (e registeredEngine[T]) Load(expr Expr) (Process, error) { t, ok := expr.Data().(T) if !ok { return nil, fmt.Errorf("incorrect format '%s' for engine '%s'", expr.Repr(), e.inType) } process, err := e.engine(t) if err != nil { return nil, err } return registeredProcess[T]{process, e.inType}, nil } // RegisterEngine registers a typed engine under the given name. Returns an // error if an engine with that name is already registered. func RegisterEngine[T any](registry *Registry, e engine.Engine[T], name, inType string) error { if _, ok := registry.engines[name]; ok { return fmt.Errorf("engine '%s' already registered", name) } registry.engines[name] = ®isteredEngine[T]{e, name, inType} return nil }