use super::classify::Effect;
pub mod answers;
pub mod table;
pub use answers::{Answers, Standing};
pub use table::Table;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Ruling {
Pass,
Hold,
Refuse,
}
impl Ruling {
pub(crate) fn word(self) -> &'static str {
match self {
Ruling::Pass => "pass",
Ruling::Hold => "hold",
Ruling::Refuse => "refuse",
}
}
pub fn of(word: &str) -> Option<Ruling> {
[Ruling::Pass, Ruling::Hold, Ruling::Refuse]
.into_iter()
.find(|r| r.word() == word)
}
pub(crate) fn for_the_operator(self) -> Ruling {
match self {
Ruling::Refuse => Ruling::Hold,
Ruling::Pass | Ruling::Hold => self,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Scope {
Call,
Conversation,
Workspace,
}
impl Scope {
pub(crate) fn word(self) -> &'static str {
match self {
Scope::Call => "call",
Scope::Conversation => "conversation",
Scope::Workspace => "workspace",
}
}
pub fn of(word: &str) -> Option<Scope> {
[Scope::Call, Scope::Conversation, Scope::Workspace]
.into_iter()
.find(|s| s.word() == word)
}
pub fn stands_for(self, tool: &str, effect: Effect) -> String {
match self {
Scope::Call => "this one call".to_owned(),
Scope::Conversation => format!(
"every {tool} call classified {} in this conversation and its descent",
effect.word()
),
Scope::Workspace => format!(
"every {tool} call classified {} in this workspace",
effect.word()
),
}
}
pub fn permits(self, effect: Effect) -> Result<(), String> {
if self == Scope::Call || !matches!(effect, Effect::Destructive | Effect::Secret) {
return Ok(());
}
Err(format!(
"a {class} call takes --scope call only: {class} is what the control refuses \
outright, so it is answered for the call in front of you and never for a class of \
calls to come. To make it standing anyway, state the tool's reach in this \
workspace's capability.yaml `rules:` block, where it is read and deleted.",
class = effect.word(),
))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Answer {
pub ruling: Ruling,
pub scope: Scope,
}
impl Answer {
pub fn once(ruling: Ruling) -> Answer {
Answer {
ruling,
scope: Scope::Call,
}
}
}
pub fn class_key(tool: &str, effect: Effect) -> String {
format!("{tool}@{}", effect.policy_word())
}
#[cfg(test)]
mod tests;