Skip to content

Commit 7c89dd6

Browse files
authored
Merge pull request #4 from Bas-Man/dev
Bring 0.3.0 code into master branch.
2 parents afc6ad1 + 60a7d41 commit 7c89dd6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+4061
-2868
lines changed

CHANGELOG.md

+47-14
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,54 @@
1+
0.3.0 2024-12-03
2+
================
3+
4+
- Breaking Changes
5+
- `Spf` struct renamed to `SpfBuilder` and placed behind a `builder` flag.
6+
- New simplified `Spf<T>` struct defined.
7+
- New Spf<String> Implementation.
8+
9+
___
10+
11+
- Add
12+
13+
- `iter()` functionality for `Spf` & `SpfBuilder`
14+
- `From` implementations
15+
- From `Mechanism<IpNetwork>` for `Mechanism<String>`
16+
- From `Mechanism<All>` for `Mechanism<String>`
17+
- From `Spf<String>` for `SpfBuilder`
18+
- `trait Appendable`
19+
- This provides a dynamically dispatched `append()` function that accepts
20+
either a `Mechanism<String>` or `Mechanism<IpNetwork>`
21+
- `validate()` for `Spf<String>`
22+
- This function returns either `()` or a `SpfErrors`
23+
24+
- Fix
25+
26+
- `Mechanism<IpNetwork>`
27+
- This Mechanism now correctly returns IP Addresses and Networks.
28+
Previously `ip4:192.168.1.10` would later be returned as `ip4:192.168.1.10/32`.
29+
This has now been corrected for both ip4 and ip6.
30+
31+
___
32+
133
0.2.6 2023-12-18
234
================
335

436
- Add Serialize and Deserialize Support
5-
- Requires the serde feature to be enabled.
37+
- Requires the serde feature to be enabled.
638

739
0.2.5 2023-11-04
840
================
941

1042
- Add support to Mechanism `exist` for Macro Expansion. Strings starting with `%` will now be matched.
11-
Support contributed by [22ca54d00f05391d6ffee4bc23a5ba60](phttps://github.com/22ca54d00f05391d6ffeoe4bc23a5ba60)
12-
43+
Support contributed by [22ca54d00f05391d6ffee4bc23a5ba60](phttps://github.com/22ca54d00f05391d6ffeoe4bc23a5ba60)
44+
1345
0.2.4 2022-01-19
1446
================
1547

1648
- Remove code which has been deprecated since 0.2.0
1749
- Implement `strict-dns` feature
18-
- Use crate `addr` to validate *domain* information for `a`, `mx`, `ptr`, `include`, and `exists`
19-
- See: `examples/build-spf-strict.rs`
50+
- Use crate `addr` to validate *domain* information for `a`, `mx`, `ptr`, `include`, and `exists`
51+
- See: `examples/build-spf-strict.rs`
2052
- Deprecate `Mechanism::new_` functions.
2153
- Breaking Change: Rename some `MechanismError::` messages.
2254

@@ -29,15 +61,15 @@
2961
================
3062

3163
- Add Feature (warn-dns)
32-
With this feature enabled any malformed DNS records will cause `has_warnings()` to be set to `true`. Their values can then be accessed using `warnings()`. Even though they are invalid. No error will be generated.
33-
64+
With this feature enabled any malformed DNS records will cause `has_warnings()` to be set to `true`. Their values can
65+
then be accessed using `warnings()`. Even though they are invalid. No error will be generated.
66+
3467
0.2.1 2021-11-03
3568
================
3669

3770
- Documentation Update
3871

39-
40-
0.2.0 2021-11-02
72+
0.2.0 2021-11-02
4173
================
4274

4375
Breaking Changes.
@@ -52,13 +84,14 @@ Changes
5284
- Bump Version to 0.2.0
5385
- Add this CHANGELOG.md file.
5486
- Complete re-orginisation of the crate's module layout.
55-
- Note that spf::{qualifier::Qualifier, kinds::MechanismKind, mechanism::Mechanism} no longer exist. These can now be accessed more simply as:
56-
- mechanism::{Qualifer, Kind, Mechanism}
87+
- Note that spf::{qualifier::Qualifier, kinds::MechanismKind, mechanism::Mechanism} no longer exist. These can now
88+
be accessed more simply as:
89+
- mechanism::{Qualifer, Kind, Mechanism}
5790
- Correct license reference to correctly show as MIT license
58-
- Introduced ability to build SPF records programmatically.
59-
- See examples/build-new-spf.rs
91+
- Introduced ability to build SPF records programmatically.
92+
- See examples/build-new-spf.rs
6093
- Implemented **Display** trait for structs *Spf* and *Mechanism*
61-
- This also depreciates the previously implemented *as_spf()* and *string()* methods.
94+
- This also depreciates the previously implemented *as_spf()* and *string()* methods.
6295
- implemented **FromStr** trait for Struct *Spf*
6396
- Implemented Errors for `Mechanism`
6497
- Improved regular expressions to handle more strings when parsing.

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Contributing
1+
Contributing
22
--------------
33

44
- All commits must be digitally signed

Cargo.toml

+21-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "decon-spf"
3-
version = "0.2.6"
3+
version = "0.3.0"
44
authors = ["Adam.S <[email protected]>"]
55
edition = "2018"
66

@@ -28,39 +28,47 @@ name = "decon_spf"
2828
path = "src/lib.rs"
2929

3030
[[example]]
31-
name = "trust-dns-demo"
32-
path = "examples/trust-dns-demo.rs"
31+
name = "trust-dns-builder"
32+
path = "examples/trust-dns-demo-builder.rs"
33+
required-features = ["builder"]
34+
35+
[[example]]
36+
name = "trust-dns-spf"
37+
path = "examples/trust-dns-demo-spf.rs"
3338

3439
[[example]]
3540
name = "build-spf"
3641
path = "examples/build-spf.rs"
42+
required-features = ["builder", "spf2"]
3743

3844
[[example]]
3945
name = "build-spf-strict"
4046
path = "examples/build-spf-strict.rs"
41-
required-features = ["strict-dns"]
47+
required-features = ["builder", "strict-dns", "spf2"]
4248

4349
[[example]]
4450
name = "serde-demo"
4551
path = "examples/serde-demo.rs"
46-
required-features = ["serde"]
52+
required-features = ["serde", "spf2"]
4753

4854
[dependencies]
4955
ipnetwork = "0.20.0"
50-
regex = "1.10.2"
51-
lazy_static = "1.4.0"
52-
addr = { version = "0.15.0", optional = true }
53-
serde = { version = "1.0.193", features = ["derive"], optional = true }
54-
#serde_json = { version = "1.0.108", optional = true }
56+
regex = "1.11.1"
57+
lazy_static = "1.5.0"
58+
addr = { version = "0.15.6", optional = true }
59+
serde = { version = "1.0.215", features = ["derive"], optional = true }
5560

5661
[dev-dependencies]
5762
trust-dns-resolver = "0.23.2"
58-
serde_json = { version = "1.0.108" }
63+
serde_json = { version = "1.0.133" }
5964

6065
[features]
61-
warn-dns = ["addr"]
62-
strict-dns = ["addr"]
66+
default = ["ptr"]
67+
builder = []
68+
strict-dns = ["dep:addr"]
6369
serde = ["dep:serde"]
70+
spf2 = ["builder"]
71+
ptr = []
6472

6573
[package.metadata.docs.rs]
6674
all-features = true

README.md

+10-6
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22

33
# Overview
44

5-
This crate allows you to deconstruct an existing SPF record that might be retrieved with a dns query of type TXT.
5+
This crate allows you to deconstruct an existing SPF record that might be retrieved with a dns query of type TXT.
66

7-
With 0.2.0. You now have the ability to create SPF records programmatically.
7+
With 0.2.0. You now have the ability to create SPF records programmatically.
88
Check the **Examples** directory for sample code.
99

1010
### See Example Code
1111

1212
Lookup and deconstruct Spf record.
1313

14-
- [trust-dns-resolver](https://github.com/Bas-Man/rust-decon-spf/blob/master/examples/trust-dns-demo.rs)
14+
- [trust-dns-resolver-builder](https://github.com/Bas-Man/rust-decon-spf/blob/master/examples/trust-dns-demo-builder.rs)
15+
- [trust-dns-resolver-spf](https://github.com/Bas-Man/rust-decon-spf/blob/master/examples/trust-dns-demo-spf.rs)
1516
- [build-spf](https://github.com/Bas-Man/rust-decon-spf/blob/master/examples/build-spf.rs)
17+
- [build-spf-strict](https://github.com/Bas-Man/rust-decon-spf/blob/master/examples/build-spf-strict.rs)
1618
- [serde-demo](https://github.com/Bas-Man/rust-decon-spf/blob/master/examples/serde-demo.rs)
1719

1820
### Run example
@@ -24,16 +26,18 @@ $ cargo run --example
2426
```
2527

2628
```bash
27-
$ cargo run --example trust-dns-demo
29+
$ cargo run --example trust-dns-builder
30+
$ cargo run --example trust-dns-spf
2831
$ cargo run --example build-spf
2932
$ cargo run -F strict-dns --example build-spf-strict
3033
$ cargo run -F serde --example serde-demo
3134
```
3235

3336
## Syntax Validation
3437

35-
This crate is not intended to provide syntax validation.
36-
If you are looking to validate your SPF record. I would suggest you use one of
38+
Whilst this crate is not intended to provide syntax validation, some validation has been added as
39+
of Version **0.3.0**.
40+
If you are looking to validate your SPF record. I would suggest you use one of
3741
the following:
3842

3943
1. [VamSoft.com](https://vamsoft.com/support/tools/spf-syntax-validator)

examples/build-spf-strict.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
use decon_spf::mechanism::{Kind, Mechanism, ParsedMechanism, Qualifier};
2-
use decon_spf::Spf;
2+
use decon_spf::SpfBuilder;
33

44
fn main() {
5-
let mut spf1 = Spf::new();
5+
let mut spf1 = SpfBuilder::new();
66
spf1.set_v1();
77
let ip_m_1 = ParsedMechanism::new("+ip4:203.32.160.0/24");
88
let ip_m_2 = ParsedMechanism::new("+ip4:203.32.166.0/24");
99
if let Ok(ip1) = ip_m_1 {
10-
spf1.append_ip_mechanism(ip1.network());
10+
spf1.append_mechanism(ip1.network());
1111
}
1212
if let Ok(ip2) = ip_m_2 {
13-
spf1.append_ip_mechanism(ip2.network());
13+
spf1.append_mechanism(ip2.network());
1414
}
1515

1616
if let Ok(mx) = ParsedMechanism::new("mx") {
1717
spf1.append_mechanism(mx.txt());
1818
}
1919

2020
// example.xx is not a valid domain. There is no TLD of xx
21-
if let Ok(m) = "a:test.xx".parse() {
21+
if let Ok(m) = "a:test.xx".parse::<Mechanism<String>>() {
2222
// Append does not occur
2323
spf1.append_mechanism(m);
2424
}
@@ -29,10 +29,10 @@ fn main() {
2929
"v=spf1 mx ip4:203.32.160.0/24 ip4:203.32.166.0/24"
3030
);
3131

32-
let mut spf2 = Spf::new();
32+
let mut spf2 = SpfBuilder::new();
3333
spf2.set_v1();
3434
let ip = "203.32.166.0/24".parse().unwrap();
35-
spf2.append_ip_mechanism(Mechanism::ip(Qualifier::Pass, ip));
35+
spf2.append_mechanism(Mechanism::ip(Qualifier::Pass, ip));
3636

3737
println!("\nNew spf 2: >{}<", spf2);
3838
println!("Attempt to create invalid mx to spf2");
@@ -51,13 +51,13 @@ fn main() {
5151
spf2.clear_mechanism(Kind::MX);
5252
println!("Altered spf 2: >{}<", spf2);
5353

54-
let mut spf3 = Spf::new();
54+
let mut spf3 = SpfBuilder::new();
5555
spf3.set_v2_pra();
5656
spf3.append_mechanism(Mechanism::a(Qualifier::Pass));
57-
spf3.append_mechanism(Mechanism::all(Qualifier::Neutral));
57+
spf3.append_mechanism(Mechanism::all_with_qualifier(Qualifier::Neutral));
5858

5959
println!("\nNew spf 3: >{}<", spf3);
6060
println!("Change spf3 all to Fail");
61-
spf3.append_mechanism(Mechanism::all(Qualifier::Fail));
61+
spf3.append_mechanism(Mechanism::all_default());
6262
println!("Altered spf 3: >{}<", spf3);
6363
}

examples/build-spf.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
11
use decon_spf::mechanism::{Kind, Mechanism, ParsedMechanism, Qualifier};
2-
use decon_spf::Spf;
2+
use decon_spf::SpfBuilder;
33

44
fn main() {
5-
let mut spf1 = Spf::new();
5+
let mut spf1 = SpfBuilder::new();
66
spf1.set_v1();
77
let ip_m_1 = ParsedMechanism::new("ip4:203.32.160.0/24");
88
let ip_m_2 = ParsedMechanism::new("+ip4:203.32.166.0/24");
99
let mx = ParsedMechanism::new("mx").unwrap();
1010
if let Ok(ip1) = ip_m_1 {
11-
spf1.append_ip_mechanism(ip1.network());
11+
spf1.append_mechanism(ip1.network());
1212
}
1313
if let Ok(ip2) = ip_m_2 {
14-
spf1.append_ip_mechanism(ip2.network());
14+
spf1.append_mechanism(ip2.network());
1515
}
1616
spf1.append_mechanism(mx.txt());
1717

18-
spf1.append_mechanism("a:test.com".parse().unwrap());
18+
spf1.append_mechanism("a:test.com".parse::<Mechanism<String>>().unwrap());
1919

2020
println!("New spf 1: >{}<", spf1);
2121
assert_eq!(
2222
spf1.to_string(),
2323
"v=spf1 a:test.com mx ip4:203.32.160.0/24 ip4:203.32.166.0/24"
2424
);
2525

26-
let mut spf2 = Spf::new();
26+
let mut spf2 = SpfBuilder::new();
2727
spf2.set_v1();
2828
let ip = "203.32.166.0/24".parse().unwrap();
2929
let m = Mechanism::ip(Qualifier::Pass, ip);
30-
spf2.append_ip_mechanism(m);
30+
spf2.append_mechanism(m);
3131

3232
println!("\nNew spf 2: >{}<", spf2);
3333
println!("Add mx to spf2");
@@ -37,13 +37,13 @@ fn main() {
3737
spf2.clear_mechanism(Kind::MX);
3838
println!("Altered spf 2: >{}<", spf2);
3939

40-
let mut spf3 = Spf::new();
40+
let mut spf3 = SpfBuilder::new();
4141
spf3.set_v2_pra();
4242
spf3.append_mechanism(Mechanism::a(Qualifier::Pass));
43-
spf3.append_mechanism(Mechanism::all(Qualifier::Neutral));
43+
spf3.append_mechanism(Mechanism::all_with_qualifier(Qualifier::Neutral));
4444

4545
println!("\nNew spf 3: >{}<", spf3);
4646
println!("Change spf3 all to Fail");
47-
spf3.append_mechanism(Mechanism::all(Qualifier::Fail));
47+
spf3.append_mechanism(Mechanism::all_default());
4848
println!("Altered spf 3: >{}<", spf3);
4949
}

examples/serde-demo.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
use decon_spf::mechanism::{Mechanism, ParsedMechanism, Qualifier};
2-
use decon_spf::Spf;
2+
use decon_spf::SpfBuilder;
33
use serde_json;
44

55
fn main() {
6-
let mut spf1 = Spf::new();
6+
let mut spf1 = SpfBuilder::new();
77
spf1.set_v1();
88
let ip_m_1 = ParsedMechanism::new("ip4:203.32.160.0/24");
99
let ip_m_2 = ParsedMechanism::new("+ip4:203.32.166.0/24");
1010
let mx = ParsedMechanism::new("mx").unwrap();
1111
if let Ok(ip1) = ip_m_1 {
12-
spf1.append_ip_mechanism(ip1.network());
12+
spf1.append_mechanism(ip1.network());
1313
}
1414
if let Ok(ip2) = ip_m_2 {
15-
spf1.append_ip_mechanism(ip2.network());
15+
spf1.append_mechanism(ip2.network());
1616
}
1717
spf1.append_mechanism(mx.txt());
1818

19-
spf1.append_mechanism("a:test.com".parse().unwrap());
19+
spf1.append_mechanism("a:test.com".parse::<Mechanism<String>>().unwrap());
2020

2121
println!("New spf 1: >{}<", spf1);
2222
assert_eq!(
@@ -27,13 +27,12 @@ fn main() {
2727
let spf_as_json = serde_json::to_string_pretty(&spf1).unwrap();
2828
println!("JSON:\n{}", spf_as_json);
2929

30-
let mut spf2 = Spf::new();
30+
let mut spf2 = SpfBuilder::new();
3131
spf2.set_v2_pra();
3232
spf2.append_mechanism(Mechanism::a(Qualifier::Pass));
33-
spf2.append_mechanism(Mechanism::all(Qualifier::Neutral));
33+
spf2.append_mechanism(Mechanism::all_with_qualifier(Qualifier::Neutral));
3434

3535
println!("\nNew spf 2: >{}<", spf2);
3636
let spf_as_json = serde_json::to_string_pretty(&spf2).unwrap();
3737
println!("JSON:\n{}", spf_as_json);
38-
3938
}

0 commit comments

Comments
 (0)