use std::error::Error;
use std::fmt;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ADRuleKind {
Jvp,
Transpose,
}
impl ADRuleKind {
pub const fn as_str(self) -> &'static str {
match self {
Self::Jvp => "jvp",
Self::Transpose => "transpose",
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ADRuleError {
Unsupported {
op: String,
rule: ADRuleKind,
},
InvalidInput {
op: String,
rule: ADRuleKind,
message: String,
},
}
impl ADRuleError {
pub fn unsupported(op: impl Into<String>, rule: ADRuleKind) -> Self {
Self::Unsupported {
op: op.into(),
rule,
}
}
pub fn invalid_input(
op: impl Into<String>,
rule: ADRuleKind,
message: impl Into<String>,
) -> Self {
Self::InvalidInput {
op: op.into(),
rule,
message: message.into(),
}
}
#[cfg_attr(coverage, inline(never))]
pub const fn rule(&self) -> ADRuleKind {
match self {
Self::Unsupported { rule, .. } => *rule,
Self::InvalidInput { rule, .. } => *rule,
}
}
}
impl fmt::Display for ADRuleError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Unsupported { op, rule } => {
write!(f, "unsupported {} AD rule for {op}", rule.as_str())
}
Self::InvalidInput { op, rule, message } => {
write!(f, "invalid {} AD input for {op}: {message}", rule.as_str())
}
}
}
}
impl Error for ADRuleError {}
pub type ADRuleResult<T> = Result<T, ADRuleError>;