use serde::{Deserialize, Serialize};
use std::fmt::Display;
pub mod output;
pub mod parse;
pub mod verify;
pub use output::{DmarcOutput, DmarcResult};
#[derive(Debug, Hash, Clone, PartialEq, Eq)]
pub struct DmarcRecord {
pub adkim: Alignment,
pub aspf: Alignment,
pub fo: FailureOptions,
pub np: Policy,
pub p: Policy,
pub psd: Psd,
pub rua: Vec<Uri>,
pub ruf: Vec<Uri>,
pub sp: Policy,
pub t: bool,
}
#[derive(Debug, Hash, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Uri {
pub uri: String,
pub max_size: usize,
}
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum Alignment {
Relaxed,
Strict,
}
#[derive(Debug, Hash, Clone, PartialEq, Eq)]
pub enum Psd {
Yes,
No,
Default,
}
#[derive(Debug, Hash, Clone, PartialEq, Eq)]
pub enum FailureOptions {
All,
Any,
Dkim,
Spf,
DkimSpf,
}
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum Policy {
None,
Quarantine,
Reject,
#[default]
Unspecified,
}
impl Uri {
#[cfg(test)]
pub fn new(uri: impl Into<String>, max_size: usize) -> Self {
Uri {
uri: uri.into(),
max_size,
}
}
pub fn uri(&self) -> &str {
&self.uri
}
pub fn max_size(&self) -> usize {
self.max_size
}
}
impl DmarcRecord {
pub fn ruf(&self) -> &[Uri] {
&self.ruf
}
pub fn rua(&self) -> &[Uri] {
&self.rua
}
}
impl Display for Alignment {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Alignment::Relaxed => "r",
Alignment::Strict => "s",
})
}
}
impl Display for Policy {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Policy::Quarantine => "quarantine",
Policy::Reject => "reject",
Policy::None | Policy::Unspecified => "none",
})
}
}
impl AsRef<str> for Uri {
fn as_ref(&self) -> &str {
&self.uri
}
}