use crate::core;
use crate::spf::mechanism::{Kind, Mechanism, MechanismError, Qualifier};
use ipnetwork::IpNetwork;
use std::{convert::TryFrom, str::FromStr};
#[derive(Debug, Clone, PartialEq)]
pub enum ParsedMechanism {
TXT(Mechanism<String>),
IP(Mechanism<IpNetwork>),
}
impl std::fmt::Display for ParsedMechanism {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
ParsedMechanism::TXT(ref m) => write!(f, "{}", m),
ParsedMechanism::IP(ref m) => write!(f, "{}", m),
}
}
}
impl FromStr for ParsedMechanism {
type Err = MechanismError;
fn from_str(s: &str) -> Result<ParsedMechanism, Self::Err> {
if s.contains(core::IP4) || s.contains(core::IP6) {
Ok(ParsedMechanism::IP(Mechanism::<IpNetwork>::from_str(s)?))
} else {
Ok(ParsedMechanism::TXT(Mechanism::<String>::from_str(s)?))
}
}
}
impl TryFrom<&str> for ParsedMechanism {
type Error = MechanismError;
fn try_from(s: &str) -> Result<Self, Self::Error> {
ParsedMechanism::from_str(s)
}
}
impl ParsedMechanism {
pub fn new(s: &str) -> Result<ParsedMechanism, MechanismError> {
ParsedMechanism::try_from(s)
}
pub fn txt(&self) -> Mechanism<String> {
match *self {
ParsedMechanism::TXT(ref m) => m.clone(),
ParsedMechanism::IP(_) => unreachable!(),
}
}
pub fn network(&self) -> Mechanism<IpNetwork> {
match *self {
ParsedMechanism::IP(ref m) => *m,
ParsedMechanism::TXT(_) => unreachable!(),
}
}
#[allow(dead_code)]
fn kind(&self) -> &Kind {
match *self {
ParsedMechanism::TXT(ref m) => m.kind(),
ParsedMechanism::IP(ref m) => m.kind(),
}
}
#[allow(dead_code)]
fn qualifier(&self) -> &Qualifier {
match *self {
ParsedMechanism::TXT(ref m) => m.qualifier(),
ParsedMechanism::IP(ref m) => m.qualifier(),
}
}
#[allow(dead_code)]
fn raw(&self) -> String {
match *self {
ParsedMechanism::TXT(ref m) => m.raw(),
ParsedMechanism::IP(ref m) => m.raw(),
}
}
pub fn is_network(&self) -> bool {
match *self {
ParsedMechanism::TXT(_) => false,
ParsedMechanism::IP(_) => true,
}
}
#[allow(dead_code)]
fn as_network(&self) -> Result<&IpNetwork, MechanismError> {
match *self {
ParsedMechanism::TXT(_) => Err(MechanismError::NotIpNetworkMechanism),
ParsedMechanism::IP(ref m) => Ok(m.as_network()),
}
}
}