49 lines
2.1 KiB
Go
49 lines
2.1 KiB
Go
package viewstate
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient"
|
|
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks"
|
|
)
|
|
|
|
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
|
|
}
|