use std::{error::Error, net::IpAddr, time::Duration};
use viaspf::{
lookup::Name,
record::{
Exists, ExplainString, Explanation, Include, Ip4, Ip6, Mx, Ptr, Redirect, SpfRecord, A,
},
EvalError, ExplanationString, SpfResult,
};
pub struct TimedLookup {
pub lookup: LookupTarget,
pub duration: Duration,
}
pub enum LookupTarget {
A(Name),
Aaaa(Name),
Mx(Name),
Txt(Name),
Ptr(IpAddr),
}
pub struct TimedEvaluatedQuery {
pub query: EvaluatedQuery,
pub duration: Duration,
pub lookup_times: Vec<TimedLookup>,
}
pub struct EvaluatedQuery {
pub domain: Name,
pub result: EvaluatedQueryResult,
pub query_result: SpfResult,
}
pub enum EvaluatedQueryResult {
NoRecord,
Error(String),
Record(EvaluatedRecord),
}
pub struct EvaluatedRecord {
pub spf_record: SpfRecord,
pub terms: Vec<EvaluatedTerm>,
}
pub enum EvaluatedTerm {
All(AllDirective),
Ip4(Ip4Directive),
Ip6(Ip6Directive),
A(ADirective),
Mx(MxDirective),
Ptr(PtrDirective),
Exists(ExistsDirective),
Include(IncludeDirective),
Redirect(RedirectModifier),
Exp(ExpModifier),
NeutralDefault,
}
pub struct AllDirective {
pub result: DirectiveResult,
}
pub struct Ip4Directive {
pub mechanism: Ip4,
pub result: DirectiveResult,
}
pub struct Ip6Directive {
pub mechanism: Ip6,
pub result: DirectiveResult,
}
pub struct ADirective {
pub mechanism: A,
pub lookup_counts: LookupCounts,
pub target_domain: Option<Name>,
pub ips: Vec<IpAddr>,
pub result: DirectiveResult,
}
pub struct MxDirective {
pub mechanism: Mx,
pub lookup_counts: LookupCounts,
pub target_domain: Option<Name>,
pub mxs: Vec<MxName>,
pub result: DirectiveResult,
}
pub struct MxName {
pub target_domain: Name,
pub ips: Vec<IpAddr>,
}
pub struct PtrDirective {
pub mechanism: Ptr,
pub lookup_counts: LookupCounts,
pub target_domain: Option<Name>,
pub ip: Option<IpAddr>,
pub lookup_error: Option<EvalError>,
pub ptrs: Vec<PtrName>,
pub result: DirectiveResult,
}
pub struct PtrName {
pub target_domain: Name,
pub error: Option<Box<dyn Error>>,
pub ips: Vec<IpAddr>,
pub validated: bool,
}
pub struct ExistsDirective {
pub mechanism: Exists,
pub lookup_counts: LookupCounts,
pub target_domain: Option<Name>,
pub result: DirectiveResult,
}
pub struct IncludeDirective {
pub mechanism: Include,
pub lookup_counts: LookupCounts,
pub target_domain: Option<Name>,
pub query: Option<EvaluatedQuery>,
pub result: DirectiveResult,
}
pub struct RedirectModifier {
pub modifier: Redirect,
pub lookup_counts: LookupCounts,
pub error: Option<Box<dyn Error>>,
pub target_domain: Option<Name>,
pub query: Option<EvaluatedQuery>,
pub result: SpfResult,
}
pub struct ExpModifier {
pub modifier: Explanation,
pub target_domain: Option<Name>,
pub error: Option<Box<dyn Error>>,
pub explain_string: Option<ExplainString>,
pub explanation: ExplanationString,
}
#[derive(Default)]
pub struct LookupCounts {
pub lookups: usize,
pub nested: usize,
pub void: usize,
}
pub enum DirectiveResult {
Match(SpfResult),
NotMatch,
Error(EvalError, SpfResult),
}