pub fn resolve_claim<F>(
claim_flag: bool,
yes: bool,
identity: Option<&str>,
prompt: &str,
confirm: F,
) -> Result<Option<String>, String>
where
F: FnOnce(&str) -> Result<bool, String>,
{
let identity = match identity {
Some(i) if !i.is_empty() => i,
_ => return Ok(None),
};
let want = if claim_flag {
true
} else if yes {
false
} else {
confirm(prompt)?
};
Ok(want.then(|| identity.to_string()))
}
#[cfg(test)]
mod tests {
use super::*;
fn no_prompt(_: &str) -> Result<bool, String> {
panic!("confirm must not be called");
}
#[test]
fn the_flag_claims_without_asking() {
let got = resolve_claim(true, false, Some("me"), "?", no_prompt).unwrap();
assert_eq!(got.as_deref(), Some("me"));
}
#[test]
fn yes_alone_does_not_claim() {
let got = resolve_claim(false, true, Some("me"), "?", no_prompt).unwrap();
assert_eq!(got, None);
}
#[test]
fn no_identity_skips_silently() {
let got = resolve_claim(false, false, None, "?", no_prompt).unwrap();
assert_eq!(got, None);
let empty = resolve_claim(true, false, Some(""), "?", no_prompt).unwrap();
assert_eq!(empty, None, "an empty identity is no identity");
}
#[test]
fn otherwise_the_user_is_asked() {
let yes = resolve_claim(false, false, Some("me"), "claim?", |p| {
assert_eq!(p, "claim?");
Ok(true)
})
.unwrap();
assert_eq!(yes.as_deref(), Some("me"));
let no = resolve_claim(false, false, Some("me"), "claim?", |_| Ok(false)).unwrap();
assert_eq!(no, None);
}
}