1use std::net::{Ipv4Addr, Ipv6Addr};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum SpfResult {
6 Pass,
8 Fail { explanation: Option<String> },
10 SoftFail,
12 Neutral,
14 None,
16 TempError,
18 PermError,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub enum Qualifier {
25 Pass, Fail, SoftFail, Neutral, }
30
31impl Qualifier {
32 pub fn from_char(c: char) -> Option<Self> {
33 match c {
34 '+' => Some(Qualifier::Pass),
35 '-' => Some(Qualifier::Fail),
36 '~' => Some(Qualifier::SoftFail),
37 '?' => Some(Qualifier::Neutral),
38 _ => None,
39 }
40 }
41}
42
43#[derive(Debug, Clone, PartialEq, Eq)]
45pub struct Directive {
46 pub qualifier: Qualifier,
47 pub mechanism: Mechanism,
48}
49
50#[derive(Debug, Clone, PartialEq, Eq)]
52pub enum Mechanism {
53 All,
54 Include { domain: String },
55 A { domain: Option<String>, cidr4: Option<u8>, cidr6: Option<u8> },
56 Mx { domain: Option<String>, cidr4: Option<u8>, cidr6: Option<u8> },
57 Ptr { domain: Option<String> },
58 Ip4 { addr: Ipv4Addr, prefix: Option<u8> },
59 Ip6 { addr: Ipv6Addr, prefix: Option<u8> },
60 Exists { domain: String },
61}
62
63#[derive(Debug, Clone, PartialEq, Eq)]
65pub struct SpfRecord {
66 pub directives: Vec<Directive>,
67 pub redirect: Option<String>,
68 pub explanation: Option<String>,
69}
70
71impl SpfRecord {
72 pub fn parse(record: &str) -> Result<Self, String> {
75 super::parser::parse_record(record)
76 }
77}