cistern
v.0
Cistern
Law
law owner: (request.kind == 0) or (request.subject == "did:plc:6amo7col5h4ciq2gpm5eur7b")
Source varat-vusit
44 lines of Objective Bend
edition ObjectiveBend 1
import ./Abi.obend as Abi
import ./List.obend as Lists
import ./Document.obend as Document
import ./Plan.obend as Plans
import ./World.obend as World
import ./Card.obend as Card
import ./Relation.obend as Relations
import ./Text.obend as Text
# A retained receipt, keyed {at, slot}: `at` is the receipt's height, so key order is the order
# of the turns, and past 256 the host drops the oldest.
record Kept:
at: Nat
slot: Plans.Slot
outcome: Plans.Outcome
record State:
entries: Relations.Relation<Kept>
def initial() -> State:
{entries: Relations.empty()}
def relations() -> Relations.Decls:
Lists.append(Relations.Decls.nil(), {field: "entries", key: Text.words("at slot"), limit: 256n})
# Retains a refusal (or any) receipt; the answer is how many it keeps.
def retain(state: State, input: {receipt: Plans.Receipt}, context: Abi.Context) -> Activity<Nat>:
let written(_) = write {entries: insert {at: input.receipt.height, slot: input.receipt.slot, outcome: input.receipt.outcome}}
Relations.count(Relations.insert(state.entries, {at: input.receipt.height, slot: input.receipt.slot, outcome: input.receipt.outcome}, keptKey))
def keptKey(kept: Kept) -> {at: Nat, slot: Plans.Slot}:
{at: kept.at, slot: kept.slot}
# A receipt is structured data, not a spell: the card offers no form.
def methods() -> Lists.List<String>:
Text.words("retain")
def forms() -> Card.Forms:
Card.Forms.nil()
def blurb() -> Card.Door:
{word: "cistern", blurb: "Keeps the receipts it is given, newest first."}
def receive(state: State, input: Card.Reply, context: Abi.Context) -> Activity<Card.Replied>:
Card.answer(input, context, forms(), render(state, context))
def outcomeName(outcome: Plans.Outcome) -> String:
match outcome:
case admitted(_): "admitted"
case refused(r): "refused {r.class}"
def line(kept: Kept) -> Document.Document:
Document.text("#{natText(kept.at)} {Card.handle(kept.slot.principal)}: {outcomeName(kept.outcome)}\n")
def render(state: State, context: Abi.Context) -> Document.Document:
Document.Document.sequence({items: Document.Documents.cons({head: Document.text("Cistern\n"), tail: Card.clipped(Lists.map(Lists.reverse(Relations.rows(state.entries)), line), 8n)})})
Ledger
- ◦ createdht.13homik-kakafgenesis-cistern · did:plc:6amo7col5h4ciq2gpm5eur7b