use crate::trit::Trit;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum Badge {
White,
Brown,
Purple,
Red,
Yellow,
GreenFresh,
BlueSettled,
Orange,
Closed,
CycleEvent,
}
#[derive(Debug, Clone, Copy, Default)]
pub struct BadgeContext {
pub in_progress: bool,
pub deliberating: bool,
pub flagged_by_calibration: bool,
pub closed: bool,
pub reconfirm_count: u32,
pub is_cycle_event: bool,
}
pub fn derive(trit: Trit, ctx: BadgeContext) -> Badge {
if ctx.is_cycle_event {
return Badge::CycleEvent;
}
if ctx.closed {
return Badge::Closed;
}
if ctx.flagged_by_calibration {
return Badge::Orange;
}
if ctx.deliberating {
return Badge::Purple;
}
if ctx.in_progress {
return Badge::Brown;
}
match trit {
Trit::Reject => Badge::Red,
Trit::Tend => Badge::Yellow,
Trit::Affirm => {
if ctx.reconfirm_count > 1 {
Badge::BlueSettled
} else {
Badge::GreenFresh
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cycle_event_overrides_everything() {
let ctx = BadgeContext { closed: true, is_cycle_event: true, ..Default::default() };
assert_eq!(derive(Trit::Affirm, ctx), Badge::CycleEvent);
}
#[test]
fn settled_vs_fresh_affirm() {
let fresh = BadgeContext::default();
let settled = BadgeContext { reconfirm_count: 3, ..Default::default() };
assert_eq!(derive(Trit::Affirm, fresh), Badge::GreenFresh);
assert_eq!(derive(Trit::Affirm, settled), Badge::BlueSettled);
}
}