ADR 0593 §7: the composer with its refusals leaves mesh-sdk, so mesh-sdk carries no composition rule. The catalogue functions only the node-engine's composition reaches (Resolve, Resolution's Compose, Declaration, DataItems, LeftOut, Rules and the rest, the settings, placeholder and template refusals, the rendering helpers) are copied with their tests into internal/compose/resolution; a method of a mesh-sdk shape becomes a function taking it first. The composition calls its own copies, and the captured catalogue its tests read lives here now, shared by mesh-compose's tests. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
87 lines
2.3 KiB
Go
87 lines
2.3 KiB
Go
package resolution
|
|
|
|
import (
|
|
"sort"
|
|
|
|
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
)
|
|
|
|
// matches is whether this provider is the one chosen.
|
|
func chosenMatches(c mcat.Chosen, p mcat.Provider) bool {
|
|
return p.Node == c.Node && (c.Module == "" || p.Module == c.Module)
|
|
}
|
|
|
|
// among is every offered provider the choice names — one, when the choice is whole.
|
|
func chosenAmong(c mcat.Chosen, where []mcat.Provider) []mcat.Provider {
|
|
var out []mcat.Provider
|
|
for _, p := range where {
|
|
if chosenMatches(c, p) {
|
|
out = append(out, p)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// nameOf is how a refusal names a provider: the node and the module on it.
|
|
func nameOf(p mcat.Provider) string {
|
|
return mcat.Chosen{Node: p.Node, Module: p.Module}.String()
|
|
}
|
|
|
|
// providerNames is every provider named, sorted, for a refusal to list.
|
|
func providerNames(where []mcat.Provider) []string {
|
|
out := make([]string, 0, len(where))
|
|
for _, p := range where {
|
|
out = append(out, nameOf(p))
|
|
}
|
|
sort.Strings(out)
|
|
return out
|
|
}
|
|
|
|
// providersHere is which modules in this node's own set offer a provision, sorted.
|
|
func providersHere(catalogue map[string]mcat.Manifest, here func(string) bool, want string) []string {
|
|
var out []string
|
|
for name, m := range catalogue {
|
|
if !here(name) {
|
|
continue
|
|
}
|
|
for _, o := range m.Offers() {
|
|
if o == want {
|
|
out = append(out, name)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
sort.Strings(out)
|
|
return out
|
|
}
|
|
|
|
// servedByOne is what one provider beside the consumer says a consumer needs to know, or nothing.
|
|
//
|
|
// Serving is *whether* a need is created at all when the provider is on this same machine (novox/hq
|
|
// 04-ISSUES/038's sibling): a need never created is a binding the consumer never gets. The manifest
|
|
// alone answers that; the values are settled later, with the node's settings.
|
|
func servedByOne(m mcat.Manifest, want string) map[string]any {
|
|
if _, ok := m.Serves[want]; ok {
|
|
return ServedOn(m, want, nil)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// sharedByOne is the own secret that provider names as its credential (ADR 0158), or "" when it
|
|
// gives each consumer its own.
|
|
func sharedByOne(m mcat.Manifest, want string) string {
|
|
if own, shared := m.SharedCredentialOf(want); shared {
|
|
return own
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func oneOf(list []string, s string) bool {
|
|
for _, x := range list {
|
|
if x == s {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|