package state import ( "fmt" "time" ) type OutputProjection struct { Path string Kind string SourcePath string Transform string URL string SHA256 string Size int64 } func FindOutputByPath(outputs []OutputFile, path string) (OutputFile, bool) { for _, output := range outputs { if output.Path == path { return output, true } } return OutputFile{}, false } func MergeOutputFiles(retained, planned []OutputFile) ([]OutputFile, error) { outputs := make([]OutputFile, 0, len(retained)+len(planned)) indexByPath := make(map[string]int, len(retained)+len(planned)) for _, output := range retained { if _, exists := indexByPath[output.Path]; exists { return nil, fmt.Errorf("state output path %q is duplicated", output.Path) } indexByPath[output.Path] = len(outputs) outputs = append(outputs, output) } seenPlanned := make(map[string]struct{}, len(planned)) for _, output := range planned { if _, exists := seenPlanned[output.Path]; exists { return nil, fmt.Errorf("state output path %q is duplicated", output.Path) } seenPlanned[output.Path] = struct{}{} if index, exists := indexByPath[output.Path]; exists { outputs[index] = output continue } indexByPath[output.Path] = len(outputs) outputs = append(outputs, output) } return outputs, nil } func ManagedOutputPaths(s DistributorState) []string { paths := make([]string, 0, len(s.Outputs)) for _, output := range s.Outputs { paths = append(paths, output.Path) } return paths } func ProjectOutputs(outputs []OutputProjection, existing []OutputFile, now time.Time) []OutputFile { now = now.UTC() files := make([]OutputFile, 0, len(outputs)) for _, output := range outputs { createdAt := now if existingOutput, ok := FindOutputByPath(existing, output.Path); ok { createdAt = existingOutput.CreatedAt } files = append(files, OutputFile{ Path: output.Path, Kind: output.Kind, SourcePath: output.SourcePath, Transform: output.Transform, URL: output.URL, SHA256: output.SHA256, Size: output.Size, CreatedAt: createdAt, UpdatedAt: now, }) } return files }