forked from yvv/decision
Fusion du lot G : sur une version retenue par une objection, « contre » et retrait oui, « pour » non (Yvv, 01/11)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,10 @@
|
||||
//! is changed by a proposal. The target is fixed when the objection is raised;
|
||||
//! - the votes already cast on it stay, but it cannot enter into force
|
||||
//! (`votable` and the adoption: a non-votable version is blocked);
|
||||
//! - while it is held, one may still **vote against it or take one's vote
|
||||
//! back**, never add a *for* (`may_cast`, Yvv 2026-11-01: « Retirer ou
|
||||
//! "contre" »): it can only lose votes, and once lifted it enters with the
|
||||
//! votes still there;
|
||||
//! - its author **answers**: a substantive revision of it, or a proposal linked
|
||||
//! to the objection (on the article it repeats, for a « redit »; a reworded
|
||||
//! version, for a version without author). A substantive revision of **the
|
||||
@@ -31,6 +35,7 @@
|
||||
//! lift too (never reiterate: the objection is not theirs); withdrawing either
|
||||
//! version ends it.
|
||||
|
||||
use crate::ballot::Choice;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
@@ -296,6 +301,16 @@ pub fn votable(id: &str, in_force: bool, held: &[&str]) -> bool {
|
||||
in_force || !held.contains(&id)
|
||||
}
|
||||
|
||||
/// May this choice be cast on a version? `held` = a standing objection holds it
|
||||
/// back now (never a version in force, `votable`). Yvv, 2026-11-01, to « pendant
|
||||
/// qu'une objection retient une version, que permet-on ? »: « Retirer ou
|
||||
/// "contre" ». On a held version one may take one's vote back or vote against,
|
||||
/// never add a *for*: it can only lose votes while it is held, and once lifted it
|
||||
/// enters with the votes still there. A version not held takes any choice.
|
||||
pub fn may_cast(held: bool, choice: Choice) -> bool {
|
||||
!held || choice != Choice::For
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -357,6 +372,17 @@ mod tests {
|
||||
assert!(votable("x", true, &["x"]), "a version in force is never made non-votable");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_held_version_takes_against_and_withdrawal_never_for() {
|
||||
// Yvv, 2026-11-01: « Retirer ou "contre" » — it can only lose votes while held.
|
||||
assert!(!may_cast(true, Choice::For), "never a new *for* while held");
|
||||
assert!(may_cast(true, Choice::Against), "against, yes");
|
||||
assert!(may_cast(true, Choice::None), "taking one's vote back, yes");
|
||||
for c in [Choice::For, Choice::Against, Choice::None] {
|
||||
assert!(may_cast(false, c), "a version not held takes any choice: {c:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_full_cycle_answer_reiterate_answer_lift() {
|
||||
let start = Phase::Author { cycle: 1 };
|
||||
|
||||
Reference in New Issue
Block a user