100 lines
2.1 KiB
Go
100 lines
2.1 KiB
Go
package pipeline
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
type ModuleStage string
|
|
|
|
const (
|
|
StageInput ModuleStage = "input"
|
|
StageChunk ModuleStage = "chunk"
|
|
StageExtract ModuleStage = "extract"
|
|
StageMerge ModuleStage = "merge"
|
|
StageNormalize ModuleStage = "normalize"
|
|
StageValidate ModuleStage = "validate"
|
|
StageOutput ModuleStage = "output"
|
|
)
|
|
|
|
type ModuleSpec struct {
|
|
Key string
|
|
Stage ModuleStage
|
|
Provides []string
|
|
Requires []string
|
|
}
|
|
|
|
func defaultModuleSpec(key string, stage ModuleStage) ModuleSpec {
|
|
return ModuleSpec{
|
|
Key: key,
|
|
Stage: stage,
|
|
}
|
|
}
|
|
|
|
func normalizeModuleSpec(spec ModuleSpec) ModuleSpec {
|
|
return ModuleSpec{
|
|
Key: strings.TrimSpace(spec.Key),
|
|
Stage: spec.Stage,
|
|
Provides: normalizeCapabilities(spec.Provides),
|
|
Requires: normalizeCapabilities(spec.Requires),
|
|
}
|
|
}
|
|
|
|
func normalizeCapabilities(values []string) []string {
|
|
if len(values) == 0 {
|
|
return nil
|
|
}
|
|
|
|
seen := make(map[string]struct{}, len(values))
|
|
for _, value := range values {
|
|
normalized := strings.TrimSpace(value)
|
|
if normalized == "" {
|
|
continue
|
|
}
|
|
seen[normalized] = struct{}{}
|
|
}
|
|
if len(seen) == 0 {
|
|
return nil
|
|
}
|
|
|
|
capabilities := make([]string, 0, len(seen))
|
|
for value := range seen {
|
|
capabilities = append(capabilities, value)
|
|
}
|
|
sort.Strings(capabilities)
|
|
return capabilities
|
|
}
|
|
|
|
func cloneModuleSpec(spec ModuleSpec) ModuleSpec {
|
|
return ModuleSpec{
|
|
Key: spec.Key,
|
|
Stage: spec.Stage,
|
|
Provides: append([]string(nil), spec.Provides...),
|
|
Requires: append([]string(nil), spec.Requires...),
|
|
}
|
|
}
|
|
|
|
func validateModuleSpec(kind string, expectedStage ModuleStage, spec ModuleSpec) error {
|
|
if spec.Key == "" {
|
|
return fmt.Errorf("%s key must not be empty", kind)
|
|
}
|
|
if spec.Stage != expectedStage {
|
|
return fmt.Errorf("%s %q must use %q stage, got %q", kind, spec.Key, expectedStage, spec.Stage)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func sortedRegistryKeys[C any](constructors map[string]C) []string {
|
|
if len(constructors) == 0 {
|
|
return nil
|
|
}
|
|
|
|
keys := make([]string, 0, len(constructors))
|
|
for key := range constructors {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
return keys
|
|
}
|