pub mod compile;
pub mod diff;
pub mod error;
pub mod format;
pub mod ir;
pub mod manifest_edit;
pub mod match_tree;
pub mod path;
pub mod sandbox_edit;
pub mod sandbox_types;
pub mod test_eval;
#[cfg(test)]
mod proptests;
pub use compile::compile_multi_level_to_tree;
pub use error::{CompileError, PolicyError, PolicyParseError};
pub use ir::{DecisionTrace, PolicyDecision, RuleMatch, RuleSkip};
pub use match_tree::{CompiledPolicy, IncludeEntry, PolicyManifest};
use std::fmt;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub enum PolicyLevel {
User = 0,
Project = 1,
Session = 2,
}
impl PolicyLevel {
pub fn all_by_precedence() -> &'static [PolicyLevel] {
&[PolicyLevel::Project, PolicyLevel::User]
}
pub fn name(&self) -> &'static str {
match self {
PolicyLevel::User => "user",
PolicyLevel::Project => "project",
PolicyLevel::Session => "session",
}
}
}
impl fmt::Display for PolicyLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name())
}
}
impl std::str::FromStr for PolicyLevel {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"user" => Ok(PolicyLevel::User),
"project" => Ok(PolicyLevel::Project),
"session" => Ok(PolicyLevel::Session),
_ => anyhow::bail!(
"unknown policy level: {s} (expected 'user', 'project', or 'session')"
),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Effect {
Allow,
Deny,
Ask,
}
impl fmt::Display for Effect {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Effect::Allow => write!(f, "allow"),
Effect::Deny => write!(f, "deny"),
Effect::Ask => write!(f, "ask"),
}
}
}
impl std::str::FromStr for Effect {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"allow" => Ok(Effect::Allow),
"deny" => Ok(Effect::Deny),
"ask" => Ok(Effect::Ask),
_ => Err(format!("unknown effect: {s:?}")),
}
}
}