use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecutionSource {
InProcess,
Proxy,
Gateway,
HookClaudeCode,
HookOpenCode,
}
impl ExecutionSource {
pub const ALL: [Self; 5] = [
Self::InProcess,
Self::Proxy,
Self::Gateway,
Self::HookClaudeCode,
Self::HookOpenCode,
];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::InProcess => "in_process",
Self::Proxy => "proxy",
Self::Gateway => "gateway",
Self::HookClaudeCode => "hook_claude_code",
Self::HookOpenCode => "hook_opencode",
}
}
#[must_use]
pub fn parse(value: &str) -> Option<Self> {
Self::ALL.into_iter().find(|s| s.as_str() == value)
}
#[must_use]
pub const fn is_server_observed(self) -> bool {
matches!(self, Self::InProcess | Self::Proxy)
}
#[must_use]
pub const fn from_hook_host(host: &str) -> Self {
if host.eq_ignore_ascii_case("opencode") {
Self::HookOpenCode
} else {
Self::HookClaudeCode
}
}
}
impl std::fmt::Display for ExecutionSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum Correlation {
Exact,
Inferred,
}
impl Correlation {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Exact => "exact",
Self::Inferred => "inferred",
}
}
#[must_use]
pub fn parse(value: &str) -> Option<Self> {
match value {
"exact" => Some(Self::Exact),
"inferred" => Some(Self::Inferred),
_ => None,
}
}
}
impl std::fmt::Display for Correlation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}