Fix 10: the catalogue reads a seat's views and stream-ridden accepts, and a consumed view of a seat
Builds: design 47 G §616, §699, A-102, A-131 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -27,6 +27,14 @@ func SeatFromDefinition(d seatdef.Definition) Seat {
|
||||
}
|
||||
for _, st := range d.States {
|
||||
s.States = append(s.States, st.Name)
|
||||
if st.View {
|
||||
s.Views = append(s.Views, st.Name)
|
||||
}
|
||||
}
|
||||
for _, a := range d.Accepts {
|
||||
if a.Stream != "" {
|
||||
s.AcceptedOn = append(s.AcceptedOn, a.Stream+"."+a.Name)
|
||||
}
|
||||
}
|
||||
for _, r := range d.Receives {
|
||||
rv := Receivable{Kind: r.Kind, Comment: r.Comment, Dirs: r.Dirs, Offered: r.Offered}
|
||||
|
||||
@@ -49,6 +49,12 @@ type Seat struct {
|
||||
// States are the names of the state the seat's holder keeps, which a module reads by `seat:<seat>.<state>` (design 47 G
|
||||
// A-116, A-128). Compiled from the definition's states.
|
||||
States []string
|
||||
// Views are the names of those states the seat offers as views, which a module follows by `consumes`
|
||||
// `seat:<seat>.views.<state>` (design 47 G §616, §699, A-131). Compiled from the definition's states marked `view`.
|
||||
Views []string
|
||||
// AcceptedOn are the accepted kinds that ride a stream, each as `<stream>.<kind>`, which a part names in `invokes` as
|
||||
// `seat:<seat>.<stream>.<kind>` (design 47 G A-102, §415). Compiled from the definition's accepts.
|
||||
AcceptedOn []string
|
||||
// Receives is what other modules may contribute to the seat's holder, by kind (novox/hq ADR
|
||||
// 0212): each kind is text in the tool's own grammar, placed by the holder with
|
||||
// ${contribution:<seat>:<kind>}. Compiled, never stored: like the protocol, it is the mesh's
|
||||
|
||||
@@ -97,6 +97,21 @@ func SeatRead(read string) (seat, local string, ok bool, err error) {
|
||||
return rest[:at], rest[at+1:], true, nil
|
||||
}
|
||||
|
||||
// SeatViewConsume splits a consumed view of a seat, `seat:<seat>.views.<state>`, into the seat and the state; ok is false for a
|
||||
// consumed entry that is not of this kind (an event, `<emitter>.<event>`), and err says why a `seat:` entry is malformed. The
|
||||
// holder is not in it: the grants part resolves it from the catalog half (design 47 G §616, A-131).
|
||||
func SeatViewConsume(consume string) (seat, state string, ok bool, err error) {
|
||||
rest, isSeat := strings.CutPrefix(consume, SeatReadPrefix)
|
||||
if !isSeat {
|
||||
return "", "", false, nil
|
||||
}
|
||||
seat, view, named := strings.Cut(rest, ".views.")
|
||||
if !named || !stateName.MatchString(seat) || !stateName.MatchString(view) {
|
||||
return "", "", true, fmt.Errorf("%q does not name a seat and its view: a consumed view of a seat is seat:<seat>.views.<state>", consume)
|
||||
}
|
||||
return seat, view, true, nil
|
||||
}
|
||||
|
||||
// ReadState splits a read into the owning module and the local name, or says why it is not one.
|
||||
func ReadState(read string) (module, local string, err error) {
|
||||
at := strings.LastIndex(read, ".")
|
||||
|
||||
@@ -88,8 +88,25 @@ func TestSeatRead(t *testing.T) {
|
||||
t.Errorf("SeatRead(%q) = %q, %q, %v, %v", row.read, seat, local, ok, err)
|
||||
}
|
||||
}
|
||||
s := SeatFromDefinition(seatdef.Definition{Seat: "mesh-provisioner", Scope: "mesh", States: []seatdef.State{{Name: "plans"}, {Name: "provisions"}}})
|
||||
if len(s.States) != 2 || s.States[0] != "plans" || s.States[1] != "provisions" {
|
||||
t.Errorf("the seat's states = %v", s.States)
|
||||
for _, row := range []struct {
|
||||
consume, seat, state string
|
||||
ok, bad bool
|
||||
}{
|
||||
{"seat:mesh-provisioner.views.plans", "mesh-provisioner", "plans", true, false},
|
||||
{"mesh-provisioner.views.plans", "", "", false, false},
|
||||
{"seat:mesh-provisioner.plans", "", "", true, true},
|
||||
{"seat:.views.plans", "", "", true, true},
|
||||
} {
|
||||
seat, state, ok, err := SeatViewConsume(row.consume)
|
||||
if seat != row.seat || state != row.state || ok != row.ok || (err != nil) != row.bad {
|
||||
t.Errorf("SeatViewConsume(%q) = %q, %q, %v, %v", row.consume, seat, state, ok, err)
|
||||
}
|
||||
}
|
||||
s := SeatFromDefinition(seatdef.Definition{Seat: "mesh-provisioner", Scope: "mesh",
|
||||
States: []seatdef.State{{Name: "plans", View: true}, {Name: "provisions"}},
|
||||
Accepts: []seatdef.Message{{Name: "step", Stream: "check"}, {Name: "step"}}})
|
||||
if len(s.States) != 2 || s.States[0] != "plans" || s.States[1] != "provisions" || len(s.Views) != 1 || s.Views[0] != "plans" ||
|
||||
len(s.AcceptedOn) != 1 || s.AcceptedOn[0] != "check.step" {
|
||||
t.Errorf("the seat's states = %v, views = %v, accepted on = %v", s.States, s.Views, s.AcceptedOn)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user