use crate::config::ReviewConfig;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TriggerDecision {
ForceLive,
ForceDryRun,
#[default]
None,
}
impl TriggerDecision {
pub fn is_force_live(self) -> bool {
matches!(self, TriggerDecision::ForceLive)
}
pub fn is_force_dry_run(self) -> bool {
matches!(self, TriggerDecision::ForceDryRun)
}
}
pub fn classify_review_request(
config: &ReviewConfig,
requested_login: Option<&str>,
) -> TriggerDecision {
let Some(login) = requested_login.map(str::trim).filter(|s| !s.is_empty()) else {
return TriggerDecision::None;
};
if login.eq_ignore_ascii_case(&config.bot_username) {
return TriggerDecision::ForceLive;
}
let login_lc = login.to_lowercase();
if config.live_review_requesters.iter().any(|r| r == &login_lc) {
return TriggerDecision::ForceLive;
}
TriggerDecision::ForceDryRun
}
pub fn effective_dry_run(config_dry_run: bool, decision: TriggerDecision) -> bool {
(config_dry_run || decision.is_force_dry_run()) && !decision.is_force_live()
}
#[cfg(test)]
mod tests {
use super::*;
fn config_with(bot: &str, requesters: &[&str]) -> ReviewConfig {
let mut c = ReviewConfig::load(None);
c.bot_username = bot.to_string();
c.live_review_requesters = requesters.iter().map(|s| s.to_lowercase()).collect();
c
}
#[test]
fn bot_login_forces_live() {
let config = config_with("trusty-review[bot]", &[]);
let d = classify_review_request(&config, Some("trusty-review[bot]"));
assert_eq!(d, TriggerDecision::ForceLive);
}
#[test]
fn bot_login_case_insensitive() {
let config = config_with("Trusty-Review[bot]", &[]);
let d = classify_review_request(&config, Some("trusty-review[bot]"));
assert_eq!(d, TriggerDecision::ForceLive);
}
#[test]
fn allowlisted_login_forces_live() {
let config = config_with("trusty-review[bot]", &["alice", "bob"]);
let d = classify_review_request(&config, Some("Alice"));
assert_eq!(d, TriggerDecision::ForceLive);
}
#[test]
fn other_reviewer_forces_dry_run() {
let config = config_with("trusty-review[bot]", &["alice"]);
let d = classify_review_request(&config, Some("random-human"));
assert_eq!(d, TriggerDecision::ForceDryRun);
}
#[test]
fn no_reviewer_is_none() {
let config = config_with("trusty-review[bot]", &[]);
assert_eq!(
classify_review_request(&config, None),
TriggerDecision::None
);
assert_eq!(
classify_review_request(&config, Some(" ")),
TriggerDecision::None
);
}
#[test]
fn effective_dry_run_formula() {
assert!(!effective_dry_run(true, TriggerDecision::ForceLive));
assert!(effective_dry_run(false, TriggerDecision::ForceDryRun));
assert!(effective_dry_run(true, TriggerDecision::None));
assert!(!effective_dry_run(false, TriggerDecision::None));
}
}