package catalogue // TakesSettingsField is the key a mergeable file carries to name the top-level setting keys it takes. const TakesSettingsField = "takes-settings" // Fields of a renamed takes-config entry. const ( takenKeyField = "key" takenAsField = "as" ) // takenEntry is one value a mergeable file takes: its key and the name the file has for it. type takenEntry struct { key, as string renamed bool } // takenEntries is the entries of a takes-settings list in their order, a usable entry only: a string is a key // under its own name, an object with exactly key and as a key under another (TakenSettingsProblems says the rest). func takenEntries(raw any) []takenEntry { list, _ := raw.([]any) var out []takenEntry for _, item := range list { if e, ok := asTakenEntry(item); ok { out = append(out, e) } } return out } // asTakenEntry reads one item of a takes-settings list, and whether it is shaped as an entry at all. func asTakenEntry(item any) (takenEntry, bool) { switch v := item.(type) { case string: return takenEntry{key: v, as: v}, true case map[string]any: key, keyOK := v[takenKeyField].(string) as, asOK := v[takenAsField].(string) if !keyOK || !asOK || len(v) != 2 { return takenEntry{}, false } return takenEntry{key: key, as: as, renamed: true}, true } return takenEntry{}, false } // takenKeys is the keys a resource names in takes-settings, each with the name the file has for it, and whether // it names any list at all. An empty list is a list: that file takes no setting. func takenKeys(resource map[string]any) (map[string]string, bool) { raw, said := resource[TakesSettingsField] if !said { return nil, false } keys := map[string]string{} for _, e := range takenEntries(raw) { keys[e.key] = e.as } return keys, true } // takenNames is every key a layer may say for the values a resource takes: each config key and, for a renamed // one, the file's own spelling a layer said before its module moved (onlyTaken). func takenNames(resource map[string]any) []string { var names []string for _, e := range takenEntries(resource[TakesSettingsField]) { names = append(names, e.key) if e.renamed { names = append(names, e.as) } } return names }