Files
mesh-delivery/modules/mesh-delivery-view/viewstate/answerkey.go
T
jschoubben 71a35a6376 MV1: move contracts and sdk under modules/, importers follow
The delivery repository's contracts and SDK live under modules/ as
mesh-delivery-contracts and mesh-delivery-sdk, their Go module paths
renamed to match the folders (the TypeScript names already did), and
every importer in mesh-delivery, mesh-catalog, mesh-host, mesh-tools
and mesh-sdk follows in the same group: a design as it should be, one
path per module, checked by the group's check building every importer.

Builds: design 47 G §427, §88

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:09:56 +01:00

49 lines
2.1 KiB
Go

package viewstate
import (
"fmt"
"strings"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/clients/meshdeliveryclient"
)
const viewWord = "view"
// ViewAnswerKey is the key, in the state answers, of the view's answer to the ask at askKey: `<ask key>.view`. An ask that needs
// proof of who answered is refused with its reason: it is answered on the phone (issue 953).
func ViewAnswerKey(askKey string) (string, error) {
ask, err := asks.ParseAnyAskKey(askKey)
if err != nil {
return "", err
}
if proof, _ := asks.AskNeedsProof(ask.Kind); proof {
return "", fmt.Errorf("viewstate: the ask %s needs proof of who answered: answer it on the phone (issue 953)", askKey)
}
return askKey + "." + viewWord, nil
}
// ParseViewAnswerKey is the inverse of ViewAnswerKey: the ask's key. It refuses a key without `.view`, an ask key of a kind that
// needs proof, and a key of another state, naming it.
func ParseViewAnswerKey(key string) (askKey string, err error) {
askKey, ok := strings.CutSuffix(key, "."+viewWord)
if !ok {
return "", fmt.Errorf("viewstate: %q is not a view answer key, <ask key>.view", key)
}
if _, err := ViewAnswerKey(askKey); err != nil {
return "", fmt.Errorf("viewstate: %q is not a view answer key: %w", key, err)
}
return askKey, nil
}
// ViewAnswerFits says whether the view's answer a answers the ask at key as it stands now: it refuses an answer to another
// asking of the ask (a stale answer to an earlier writing of the same key), naming both. Whether the ask offers the option
// chosen, and at the level acknowledge only (an option that authorises is answered on a channel that proves who answered,
// never in the view, which proves nobody), the teller reads from the ask through operator-channel's client.
func ViewAnswerFits(a ViewAnswer, key string, ask asks.Ask) error {
if want := meshdeliveryclient.AskingID(key, ask.Asking); a.Asking != want {
return fmt.Errorf("viewstate: the view's answer is to the asking %s, and the ask stands at the asking %s", a.Asking, want)
}
return nil
}