package resolution import ( "fmt" "sort" mcat "git.novox.be/novox/mesh-sdk/go/catalogue" ) // wantsHard is whether this module wants the name as a hard requirement: required without // `optional`, or contributed to. func manifestWantsHard(m mcat.Manifest, name string) bool { for _, w := range m.Wants() { if w == name { return !m.IsOptional(name) } } return false } // AbsentFor is the optional requirements of one module this resolution leaves unbound. func AbsentFor(r mcat.Resolution, module string) map[string]bool { out := map[string]bool{} for _, a := range r.Absent { if a.Consumer == module { out[a.Requirement] = true } } return out } // absentOf is, for each requirement left absent, every module of the set that requires it // optionally, sorted by consumer then requirement. func absentOf(names map[string]bool, order []string, catalogue map[string]mcat.Manifest) []mcat.Absent { var out []mcat.Absent for _, module := range order { m := catalogue[module] for _, r := range m.Requires { if names[r] && m.IsOptional(r) { out = append(out, mcat.Absent{Consumer: module, Requirement: r}) } } } sort.Slice(out, func(i, j int) bool { if out[i].Consumer != out[j].Consumer { return out[i].Consumer < out[j].Consumer } return out[i].Requirement < out[j].Requirement }) return out } // withoutAbsent drops the resources delivered only while a requirement is bound whose requirement is // absent here (ADR 0330 ยง5), and the field itself from every resource that keeps it. func withoutAbsent(resources []map[string]any, absent map[string]bool) []map[string]any { out := make([]map[string]any, 0, len(resources)) for _, r := range resources { when, has := r[mcat.OnlyWhenBound] if !has { out = append(out, r) continue } if absent[fmt.Sprint(when)] { continue } kept := make(map[string]any, len(r)) for k, v := range r { if k != mcat.OnlyWhenBound { kept[k] = v } } out = append(out, kept) } return out }