forked from yvv/decision
v3 : relecture de cd7e683 — coquilles, objections et retraits
- Le revirement de l'auteur sur une coquille (reprendre une correction appliquée, valider une correction refusée) ne s'écrit que sur une version encore ouverte : Settle porte while_open ; et la garde de statut de write_text marche enfin (?9 restait NULL, le statut est le 8e paramètre). - 0008 lève les signalements debout dont un côté est déjà retiré. - Une seule objection debout par personne et par paire (index unique partiel) ; envoyée plusieurs fois à la fois, les autres reçoivent objection_exists. - Un retrait relance l'adoption : la version que l'objection retenait entre aussitôt. Tests vus rouges d'abord. Boucle : 230 tests Rust, svelte-check 0, 55 vitest, e2e 35 / 35. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -88,6 +88,9 @@ pub enum TextChange {
|
||||
pub struct Settle {
|
||||
pub status: TypoStatus,
|
||||
pub text: TextChange,
|
||||
/// Holds only while the version is not in force: the author's change of mind,
|
||||
/// decided on a version read open, must not land on one that entered meanwhile.
|
||||
pub while_open: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
@@ -98,21 +101,24 @@ pub enum TypoRefusal {
|
||||
|
||||
/// An answer of the one who answers for the version. `in_force`: the version is in force now.
|
||||
pub fn answer(status: TypoStatus, answer: Answer, in_force: bool) -> Result<Settle, TypoRefusal> {
|
||||
let to = |status, text| Ok(Settle { status, text });
|
||||
let to = |status, text, while_open| Ok(Settle { status, text, while_open });
|
||||
match (status, answer) {
|
||||
(TypoStatus::Pending, Answer::Validate) => to(TypoStatus::Applied, TextChange::Write),
|
||||
(TypoStatus::Pending, Answer::Refuse) => to(TypoStatus::Refused, TextChange::Keep),
|
||||
(TypoStatus::Pending, Answer::Validate) => to(TypoStatus::Applied, TextChange::Write, false),
|
||||
(TypoStatus::Pending, Answer::Refuse) => to(TypoStatus::Refused, TextChange::Keep, false),
|
||||
// The author keeps the hand while the version is not in force.
|
||||
(TypoStatus::Applied, Answer::Refuse) if !in_force => to(TypoStatus::Refused, TextChange::Restore),
|
||||
(TypoStatus::Refused, Answer::Validate) if !in_force => to(TypoStatus::Applied, TextChange::Write),
|
||||
(TypoStatus::Applied, Answer::Refuse) if !in_force => to(TypoStatus::Refused, TextChange::Restore, true),
|
||||
(TypoStatus::Refused, Answer::Validate) if !in_force => to(TypoStatus::Applied, TextChange::Write, true),
|
||||
_ => Err(TypoRefusal::Settled),
|
||||
}
|
||||
}
|
||||
|
||||
/// The clock (sortable stamps): a pending fix applies by itself at its deadline.
|
||||
pub fn tick(status: TypoStatus, due: &str, now: &str) -> Option<Settle> {
|
||||
(status == TypoStatus::Pending && due <= now)
|
||||
.then_some(Settle { status: TypoStatus::Applied, text: TextChange::Write })
|
||||
(status == TypoStatus::Pending && due <= now).then_some(Settle {
|
||||
status: TypoStatus::Applied,
|
||||
text: TextChange::Write,
|
||||
while_open: false,
|
||||
})
|
||||
}
|
||||
|
||||
/// A text as a fix sees it: the revision it belongs to, its title and body.
|
||||
@@ -145,11 +151,11 @@ mod tests {
|
||||
for in_force in [false, true] {
|
||||
assert_eq!(
|
||||
answer(TypoStatus::Pending, Answer::Validate, in_force),
|
||||
Ok(Settle { status: TypoStatus::Applied, text: TextChange::Write })
|
||||
Ok(Settle { status: TypoStatus::Applied, text: TextChange::Write, while_open: false })
|
||||
);
|
||||
assert_eq!(
|
||||
answer(TypoStatus::Pending, Answer::Refuse, in_force),
|
||||
Ok(Settle { status: TypoStatus::Refused, text: TextChange::Keep })
|
||||
Ok(Settle { status: TypoStatus::Refused, text: TextChange::Keep, while_open: false })
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -159,11 +165,11 @@ mod tests {
|
||||
// A proposal: an applied fix may be taken back, a refused one validated after all.
|
||||
assert_eq!(
|
||||
answer(TypoStatus::Applied, Answer::Refuse, false),
|
||||
Ok(Settle { status: TypoStatus::Refused, text: TextChange::Restore })
|
||||
Ok(Settle { status: TypoStatus::Refused, text: TextChange::Restore, while_open: true })
|
||||
);
|
||||
assert_eq!(
|
||||
answer(TypoStatus::Refused, Answer::Validate, false),
|
||||
Ok(Settle { status: TypoStatus::Applied, text: TextChange::Write })
|
||||
Ok(Settle { status: TypoStatus::Applied, text: TextChange::Write, while_open: true })
|
||||
);
|
||||
// In force: an answer is final.
|
||||
assert_eq!(answer(TypoStatus::Applied, Answer::Refuse, true), Err(TypoRefusal::Settled));
|
||||
@@ -182,7 +188,7 @@ mod tests {
|
||||
assert_eq!(tick(TypoStatus::Pending, due, "2026-11-03T08:59:59Z"), None);
|
||||
assert_eq!(
|
||||
tick(TypoStatus::Pending, due, due),
|
||||
Some(Settle { status: TypoStatus::Applied, text: TextChange::Write })
|
||||
Some(Settle { status: TypoStatus::Applied, text: TextChange::Write, while_open: false })
|
||||
);
|
||||
// A deadline passed while the server was stopped is taken at the next tick.
|
||||
assert!(tick(TypoStatus::Pending, due, "2027-02-01T00:00:00Z").is_some());
|
||||
|
||||
Reference in New Issue
Block a user