1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
#![forbid(unsafe_code)]
#![warn(missing_docs)]
//! This crate is responsible for providing tools to access and modify information about spf records.
//! Provides methods for building spf records programmatically.
//!
//!
//! For a list of supported *Modifiers* and *Mechanism*. See [`Kind`](mechanism::Kind)
//!
//! This crate is able to decontruct `v=spf1` and `spf2.0` records.
//!
//! # Features:
//! - Check and Set Spf record version: [`Spf Versions`](spf::Spf::set_v1)
//! - Check and Create Spf Mechanism/Modifiers:
//! - [`Mechanism`](mechanism::Mechanism)
//! - [`Check Qualifier Type`](mechanism::Mechanism::is_pass)
//! - [`Check Mechanism Type`](mechanism::Mechanism::kind)
//!
//! # Example Code
//! Deconstructing an existing spf record into its corresponding components.
//! ========================================================================
//!```rust
//! use decon_spf::Spf;
//! let test_str = "v=spf1 a mx ~all";
//! // Parse test_str and populate Spf Struct.
//! // Parse returns a Result<Spf, SpfError> allowing for some error checking.
//! let spf: Spf = test_str.parse().unwrap();
//! // spf should be of v_1 form
//! assert_eq!(spf.is_v1(), true);
//! // There should be no ip4 or ip6 data
//! assert_eq!(spf.ip4().is_none(), true);
//! assert_eq!(spf.ip6().is_none(), true);
//! // Check that 'A' and 'MX' both have records.
//! assert_eq!(spf.a().is_some(), true);
//! assert_eq!(spf.mx().is_some(), true);
//! assert_eq!(spf.all().is_some(), true);
//! // Check that 'All' is a soft fail denoted by the use of '~'
//! assert_eq!(spf.all().unwrap().qualifier().is_softfail(), true);
//! // Generate the spf record based on the content of the Spf struct.
//! // Does not use the original source string.
//! // # Note: `Display` has been implemented for Spf so we could usually make the call
//! // as follows.
//! println!("{}", spf);
//! assert_eq!(spf.to_string(), "v=spf1 a mx ~all");
//!```
//!
//! Build an Spf Struct programmatically.
//! =====================================
//!
//!```rust
//! use decon_spf::Spf;
//! use decon_spf::mechanism::{Qualifier, Kind, Mechanism};
//! let mut spf1 = Spf::new();
//! spf1.set_v1();
//! spf1.append_ip_mechanism(Mechanism::new_ip(Qualifier::Pass,
//! "203.32.160.0/32".parse().unwrap()));
//!
//! assert_eq!(spf1.to_string(), "v=spf1 ip4:203.32.160.0/32");
//! println!("New spf 1: >{}<", spf1);
//!
//! let mut spf2 = Spf::new();
//! spf2.set_v1();
//! let ip = "203.32.166.0/24".parse().unwrap();
//! spf2.append_ip_mechanism(Mechanism::new_ip(Qualifier::Pass, ip));
//!
//! println!("\nNew spf 2: >{}<", spf2);
//! assert_eq!(spf2.to_string(), "v=spf1 ip4:203.32.166.0/24");
//! println!("Add mx to spf2");
//! spf2.append_mechanism(Mechanism::new_mx_without_mechanism(Qualifier::Pass));
//!
//! assert_eq!(spf2.to_string(), "v=spf1 mx ip4:203.32.166.0/24");
//! println!("Altered spf 2: >{}<", spf2);
//! println!("Clear mx from spf2");
//! spf2.clear_mechanism(Kind::MX);
//! assert_eq!(spf2.to_string(), "v=spf1 ip4:203.32.166.0/24");
//! println!("Altered spf 2: >{}<", spf2);
//!
//! let mut spf3 = Spf::new();
//! spf3.set_v2_pra();
//! spf3.append_mechanism(Mechanism::new_a_without_mechanism(Qualifier::Pass));
//! spf3.append_mechanism(Mechanism::new_all(Qualifier::Neutral));
//!
//! assert_eq!(spf3.to_string(), "spf2.0/pra a ?all");
//! println!("\nNew spf 3: >{}<", spf3);
//! println!("Change spf3 all to Fail");
//! spf3.append_mechanism(Mechanism::new_all(Qualifier::Fail));
//! assert_eq!(spf3.to_string(), "spf2.0/pra a -all");
//! println!("Altered spf 3: >{}<", spf3);
//!```
//!
mod helpers;
pub mod mechanism;
mod spf;
//use crate::mechanism::Mechanism;
pub use crate::spf::Spf;
pub use crate::spf::SpfError;