pub fn vote(
layout: &Layout,
id: &str,
choice: Option<&str>,
identity: &str,
) -> Result<String>Expand description
Cast or change one agent’s vote, or read the tally when choice is None.
Consensus among several agents is not the same question as what one agent concluded, and the tracker had no way to hold the difference: an agent could append prose saying what it thought, and a reader had to read every append and count by hand.
One ballot per identity, and casting again replaces it. That is last write wins per agent, which is the right rule here and is not the bug the id reservation had: an agent changing its mind should not leave two ballots, and two different agents must never overwrite each other. The first is why a recast replaces, the second is why the whole read-modify-write runs under the file lock.
Stored as a :VOTES: drawer on the heading rather than in the event log,
because a tally a person can read in the file is worth more than one that
needs a scan, and drawers already survive a rewrite untouched.
§Errors
Returns an error if id is not in the corpus, choice is blank, or the file
cannot be rewritten.