diff --git a/sdk/findings/findings.go b/sdk/findings/findings.go index e9d6f3c2..903eb29c 100644 --- a/sdk/findings/findings.go +++ b/sdk/findings/findings.go @@ -52,3 +52,37 @@ func (s State) Delete(key string) error { func Writer(ctx context.Context, kv func() jetstream.KeyValue) views.FindingWriter { return meshconditionsclient.FindingWriter{State: State{Ctx: ctx, KV: kv}} } + +// Funcs is a findings state held as the two functions a part keeps over it (the assigner's findings, which also say +// its conditions): a value is put as JSON. +type Funcs struct { + PutBytes func(key string, value []byte) error + DeleteKey func(key string) error +} + +var _ meshconditionsclient.FindingState = Funcs{} + +// Put writes one value under its key as JSON; the state not bound (no function) is ErrUnbound. +func (f Funcs) Put(key string, value any) (uint64, error) { + if f.PutBytes == nil { + return 0, ErrUnbound + } + data, err := json.Marshal(value) + if err != nil { + return 0, err + } + return 0, f.PutBytes(key, data) +} + +// Delete clears one key. +func (f Funcs) Delete(key string) error { + if f.DeleteKey == nil { + return ErrUnbound + } + return f.DeleteKey(key) +} + +// WriterOver is the part's views.FindingWriter over its two functions. +func WriterOver(put func(string, []byte) error, del func(string) error) views.FindingWriter { + return meshconditionsclient.FindingWriter{State: Funcs{PutBytes: put, DeleteKey: del}} +} diff --git a/sdk/findings/findings_test.go b/sdk/findings/findings_test.go index 22d9d184..01052ac1 100644 --- a/sdk/findings/findings_test.go +++ b/sdk/findings/findings_test.go @@ -56,4 +56,16 @@ func TestAFindingIsWrittenInTheSeatsLayoutAndClearedAndRefusedUnbound(t *testing if err := w.Delete(f); err != nil || len(kv.held) != 0 { t.Fatalf("the finding is not cleared: %v, %d left", err, len(kv.held)) } + // The same finding over two functions (a part whose findings also say its conditions). + held := map[string][]byte{} + o := WriterOver(func(k string, v []byte) error { held[k] = v; return nil }, func(k string) error { delete(held, k); return nil }) + if err := o.Put(f); err != nil || len(held) != 1 { + t.Fatalf("over functions: %v, %d held", err, len(held)) + } + if err := o.Delete(f); err != nil || len(held) != 0 { + t.Fatalf("over functions not cleared: %v, %d left", err, len(held)) + } + if err := WriterOver(nil, nil).Put(f); !errors.Is(err, ErrUnbound) { + t.Fatalf("no functions took the finding: %v", err) + } }