ascii_domain

Domains whose labels are only ASCII.
git clone https://git.philomathiclife.com/repos/ascii_domain
Log | Files | Refs | README

commit 6942af70d23a30fdd1af795343e5a4416481a2b5
parent c5a121a1c7171f3264c7abb44024822f814b03df
Author: Zack Newman <zack@philomathiclife.com>
Date:   Fri, 21 Nov 2025 19:39:05 -0700

update deps. fix clippy on tests

Diffstat:
MCargo.toml | 21+++++++++++++++++----
MREADME.md | 10+++++++---
Msrc/char_set.rs | 46+++++++++++++++++++++++++++++-----------------
Msrc/dom.rs | 237+++++++++++++++++++++++++++++++++++--------------------------------------------
Msrc/serde.rs | 28+++++++++++++---------------
5 files changed, 171 insertions(+), 171 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml @@ -10,7 +10,7 @@ name = "ascii_domain" readme = "README.md" repository = "https://git.philomathiclife.com/repos/ascii_domain/" rust-version = "1.86.0" -version = "0.6.6" +version = "0.6.7" [lints.rust] ambiguous_negative_literals = { level = "deny", priority = -1 } @@ -82,16 +82,29 @@ missing_trait_methods = "allow" question_mark_used = "allow" return_and_then = "allow" single_char_lifetime_names = "allow" +unseparated_literal_suffix = "allow" [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] +default-target = "x86_64-unknown-linux-gnu" +targets = [ + "aarch64-apple-darwin", + "aarch64-pc-windows-msvc", + "aarch64-unknown-linux-gnu", + "i686-pc-windows-msvc", + "i686-unknown-linux-gnu", + "x86_64-pc-windows-gnu", + "x86_64-pc-windows-msvc", + "x86_64-unknown-freebsd", + "x86_64-unknown-linux-musl", + "x86_64-unknown-netbsd" +] [dependencies] -serde = { version = "1.0.219", default-features = false, features = ["alloc"], optional = true } +serde = { version = "1.0.228", default-features = false, features = ["alloc"], optional = true } [dev-dependencies] -serde_json = { version = "1.0.143", default-features = false, features = ["alloc"] } +serde_json = { version = "1.0.145", default-features = false, features = ["alloc"] } ### FEATURES ################################################################# diff --git a/README.md b/README.md @@ -44,9 +44,13 @@ at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. -Before any PR is sent, `cargo clippy` and `cargo t` should be run for both `--no-default-features` and -`--all-features`. Additionally `RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features` should be run to -ensure documentation can be built. +Before any PR is sent, `cargo clippy --all-targets`, `cargo test --all-targets`, and `cargo test --doc` should be +run _for each possible combination of "features"_ using the stable and MSRV toolchains. One easy way to achieve this +is by invoking [`ci-cargo`](https://crates.io/crates/ci-cargo) as `ci-cargo clippy --all-targets test --all-targets` +in the `ascii_domain` directory. + +Last, `RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features` should be run to ensure documentation can be +built on non-OpenBSD platforms; otherwise `cargo doc --all-features` should be run. ### Status diff --git a/src/char_set.rs b/src/char_set.rs @@ -49,6 +49,7 @@ impl Error for AsciiErr {} /// /// It is _highly_ unlikely that non-printable ASCII nor `b'\\'` should be used since such ASCII would almost /// certainly require being escaped. +#[cfg_attr(test, derive(Eq, PartialEq))] #[derive(Debug)] pub struct AllowedAscii<T> { /// The allowed ASCII `u8`s. @@ -342,37 +343,43 @@ mod tests { ASCII_HYPHEN_DIGITS_UPPERCASE, ASCII_LETTERS, ASCII_LOWERCASE, ASCII_UPPERCASE, AllowedAscii, AsciiErr, PRINTABLE_ASCII, RFC5322_ATEXT, WHATWG_VALID_DOMAIN_CODE_POINTS, }; - use alloc::{borrow::ToOwned, vec::Vec}; + use alloc::{borrow::ToOwned as _, vec::Vec}; #[test] fn try_from() { // Empty is allowed. - assert!(AllowedAscii::try_from_unique_ascii([]).is_ok()); + assert_eq!( + AllowedAscii::try_from_unique_ascii([]), + Ok(AllowedAscii { allowed: [] }) + ); // Duplicates are not allowed. - assert!( - AllowedAscii::try_from_unique_ascii(b"aba".to_owned()) - .map_or_else(|e| e == AsciiErr::Duplicate(b'a'), |_| false) + assert_eq!( + AllowedAscii::try_from_unique_ascii(b"aba".to_owned()), + Err(AsciiErr::Duplicate(b'a')) ); // `b'.'` is not allowed. - assert!( - AllowedAscii::try_from_unique_ascii(b"a.c".to_owned()) - .map_or_else(|e| e == AsciiErr::Contains46, |_| false) + assert_eq!( + AllowedAscii::try_from_unique_ascii(b"a.c".to_owned()), + Err(AsciiErr::Contains46) ); // At most 127 bytes are allowed. - assert!( - AllowedAscii::try_from_unique_ascii([0; 128]) - .map_or_else(|e| e == AsciiErr::CountTooLarge(128), |_| false) + assert_eq!( + AllowedAscii::try_from_unique_ascii([0; 128]), + Err(AsciiErr::CountTooLarge(128)) ); let mut all_ascii = (0..b'.').collect::<Vec<u8>>(); let next = b'.' + 1; all_ascii.extend(next..=127); - assert!(AllowedAscii::try_from_unique_ascii(all_ascii).is_ok()); + assert_eq!( + AllowedAscii::try_from_unique_ascii(all_ascii.clone()), + Ok(AllowedAscii { allowed: all_ascii }) + ); // Only ASCII is allowed. - assert!( - AllowedAscii::try_from_unique_ascii([255]) - .map_or_else(|e| e == AsciiErr::InvalidByte(255), |_| false) + assert_eq!( + AllowedAscii::try_from_unique_ascii([255]), + Err(AsciiErr::InvalidByte(255)) ); assert!( - AllowedAscii::try_from_unique_ascii(b"abcdef".to_owned()).map_or(false, |bytes| bytes + AllowedAscii::try_from_unique_ascii(b"abcdef".to_owned()).is_ok_and(|bytes| bytes .contains(b'a') && bytes.contains(b'b') && bytes.contains(b'c') @@ -381,8 +388,13 @@ mod tests { && bytes.contains(b'f')) ); } + #[expect( + clippy::cognitive_complexity, + clippy::too_many_lines, + reason = "want to test a lot of things" + )] #[test] - fn test_consts() { + fn consts() { let letters = ASCII_LETTERS; assert!(letters.len() == 52); for i in b'A'..=b'Z' { diff --git a/src/dom.rs b/src/dom.rs @@ -1510,11 +1510,11 @@ mod tests { extern crate alloc; use super::{Domain, DomainErr, Rfc1123Domain, Rfc1123Err}; use crate::char_set::{ASCII_FIREFOX, ASCII_HYPHEN_DIGITS_LETTERS, AllowedAscii}; - use alloc::borrow::ToOwned; + use alloc::borrow::ToOwned as _; use core::cmp::Ordering; use serde_json as _; #[test] - fn test_dom_parse() { + fn dom_parse() { let allowed_ascii = ASCII_FIREFOX; // Test empty is error. assert!( @@ -1552,37 +1552,35 @@ mod tests { "www.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", &allowed_ascii ) - .map_or(false, |d| d.len().get() == 71) + .is_ok_and(|d| d.len().get() == 71) ); // Test domain too long. - assert!(Domain::try_from_bytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", &allowed_ascii).map_or_else(|e| e == DomainErr::LenExceeds253(254), |_| false)); - assert!(Domain::try_from_bytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", &allowed_ascii).map_or(false, |d| d.len().get() == 253 )); + assert!(Domain::try_from_bytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", &allowed_ascii).is_err_and(|e| e == DomainErr::LenExceeds253(254))); + assert!(Domain::try_from_bytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", &allowed_ascii).is_ok_and(|d| d.len().get() == 253 )); // Test max labels. - assert!(Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a", &allowed_ascii).map_or_else(|e| e == DomainErr::LenExceeds253(255), |_| false)); - assert!(Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a", &allowed_ascii).map_or(false, |d| d.iter().count() == 127 && d.len().get() == 253)); - assert!(Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.", &allowed_ascii).map_or(false, |d| d.iter().count() == 127 && d.len().get() == 253)); + assert!(Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a", &allowed_ascii).is_err_and(|e| e == DomainErr::LenExceeds253(255))); + assert!(Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a", &allowed_ascii).is_ok_and(|d| d.iter().count() == 127 && d.len().get() == 253)); + assert!(Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.", &allowed_ascii).is_ok_and(|d| d.iter().count() == 127 && d.len().get() == 253)); // Test removal of trailing '.'. - assert!( - Domain::try_from_bytes("com.", &allowed_ascii).map_or(false, |d| d.as_str() == "com") - ); + assert!(Domain::try_from_bytes("com.", &allowed_ascii).is_ok_and(|d| d.as_str() == "com")); // Test single label. - assert!(Domain::try_from_bytes("c", &allowed_ascii).map_or(false, |d| d.as_str() == "c")); + assert!(Domain::try_from_bytes("c", &allowed_ascii).is_ok_and(|d| d.as_str() == "c")); // Test case-insensitivity. assert!( - Domain::try_from_bytes("wwW.ExAMple.COm", &allowed_ascii).map_or(false, |d| { + Domain::try_from_bytes("wwW.ExAMple.COm", &allowed_ascii).is_ok_and(|d| { Domain::try_from_bytes("www.example.com", &allowed_ascii) - .map_or(false, |d2| d == d2 && d.cmp(&d2) == Ordering::Equal) + .is_ok_and(|d2| d == d2 && d.cmp(&d2) == Ordering::Equal) }) ); assert!( - Domain::try_from_bytes("ww_W.com", &allowed_ascii).map_or(false, |d| { + Domain::try_from_bytes("ww_W.com", &allowed_ascii).is_ok_and(|d| { Domain::try_from_bytes("Ww_w.com", &allowed_ascii) - .map_or(false, |d2| d == d2 && d.cmp(&d2) == Ordering::Equal) + .is_ok_and(|d2| d == d2 && d.cmp(&d2) == Ordering::Equal) }) ); // Test valid bytes let mut input; - let mut counter = 0; + let mut counter = 0u8; for i in 0..=127 { input = [i]; match i { @@ -1598,36 +1596,30 @@ mod tests { | b'}'..=b'~' => { counter += 1; assert!( - Domain::try_from_bytes(input, &allowed_ascii).map_or(false, |d| d - .value - .len() - == 1 - && d.value == input) - ) + Domain::try_from_bytes(input, &allowed_ascii) + .is_ok_and(|d| d.value.len() == 1 && d.value == input) + ); } b'.' => { let input2 = b"a."; assert!( - Domain::try_from_bytes(input2, &allowed_ascii).map_or(false, |d| d - .len() - .get() - == 1 - && d.value == input2) - ) + Domain::try_from_bytes(input2, &allowed_ascii) + .is_ok_and(|d| d.len().get() == 1 && d.value == input2) + ); } _ => assert!( Domain::try_from_bytes(input, &allowed_ascii) - .map_or_else(|e| e == DomainErr::InvalidByte(i), |_| false) + .is_err_and(|e| e == DomainErr::InvalidByte(i)) ), } } assert!(counter == 78); } #[test] - fn test_dom_iter() { + fn dom_iter() { let allowed_ascii = ASCII_FIREFOX; assert!( - Domain::try_from_bytes("www.example.com", &allowed_ascii).map_or(false, |d| { + Domain::try_from_bytes("www.example.com", &allowed_ascii).is_ok_and(|d| { let mut iter = d.iter(); let Some(l) = iter.next() else { return false; @@ -1635,21 +1627,21 @@ mod tests { if l.value != "com" { return false; } - let Some(l) = iter.next() else { return false }; - if l.value != "example" { + let Some(l2) = iter.next() else { return false }; + if l2.value != "example" { return false; } - let Some(l) = iter.next() else { + let Some(l3) = iter.next() else { return false; }; - if l.value != "www" { + if l3.value != "www" { return false; } iter.next().is_none() }) ); assert!( - Domain::try_from_bytes("www.example.com", &allowed_ascii).map_or(false, |d| { + Domain::try_from_bytes("www.example.com", &allowed_ascii).is_ok_and(|d| { let mut iter = d.iter(); let Some(l) = iter.next_back() else { return false; @@ -1657,23 +1649,23 @@ mod tests { if l.value != "www" { return false; } - let Some(l) = iter.next_back() else { + let Some(l2) = iter.next_back() else { return false; }; - if l.value != "example" { + if l2.value != "example" { return false; } - let Some(l) = iter.next_back() else { + let Some(l3) = iter.next_back() else { return false; }; - if l.value != "com" { + if l3.value != "com" { return false; } iter.next_back().is_none() }) ); assert!( - Domain::try_from_bytes("www.example.com", &allowed_ascii).map_or(false, |d| { + Domain::try_from_bytes("www.example.com", &allowed_ascii).is_ok_and(|d| { let mut iter = d.iter(); let Some(l) = iter.next_back() else { return false; @@ -1681,14 +1673,14 @@ mod tests { if l.value != "www" { return false; } - let Some(l) = iter.next() else { return false }; - if l.value != "com" { + let Some(l2) = iter.next() else { return false }; + if l2.value != "com" { return false; } - let Some(l) = iter.next_back() else { + let Some(l3) = iter.next_back() else { return false; }; - if l.value != "example" { + if l3.value != "example" { return false; } iter.next().is_none() && iter.next_back().is_none() @@ -1698,129 +1690,112 @@ mod tests { #[test] fn rfc1123() { assert!( - Domain::try_from_bytes("example.com", &ASCII_HYPHEN_DIGITS_LETTERS).map_or( - false, - |dom| Rfc1123Domain::try_from(dom) - .map_or(false, |dom| dom.as_str() == "example.com") - ) + Domain::try_from_bytes("example.com", &ASCII_HYPHEN_DIGITS_LETTERS) + .is_ok_and(|dom| Rfc1123Domain::try_from(dom) + .is_ok_and(|rfc_dom| rfc_dom.as_str() == "example.com")) ); assert!( - AllowedAscii::try_from_unique_ascii(b"exampl!co".to_owned()).map_or(false, |ascii| { - Domain::try_from_bytes("exampl!e.com", &ascii).map_or(false, |dom| { - Rfc1123Domain::try_from(dom).map_or_else( - |e| e == Rfc1123Err::DomainErr(DomainErr::InvalidByte(b'!')), - |_| false, - ) + AllowedAscii::try_from_unique_ascii(b"exampl!co".to_owned()).is_ok_and(|ascii| { + Domain::try_from_bytes("exampl!e.com", &ascii).is_ok_and(|dom| { + Rfc1123Domain::try_from(dom) + .is_err_and(|e| e == Rfc1123Err::DomainErr(DomainErr::InvalidByte(b'!'))) }) }) ); assert!( - Domain::try_from_bytes("example-.com", &ASCII_HYPHEN_DIGITS_LETTERS).map_or( - false, - |dom| Rfc1123Domain::try_from(dom) - .map_or_else(|e| e == Rfc1123Err::LabelEndsWithAHyphen, |_| false) - ) + Domain::try_from_bytes("example-.com", &ASCII_HYPHEN_DIGITS_LETTERS) + .is_ok_and(|dom| Rfc1123Domain::try_from(dom) + .is_err_and(|e| e == Rfc1123Err::LabelEndsWithAHyphen)) ); assert!( - Domain::try_from_bytes("-example.com", &ASCII_HYPHEN_DIGITS_LETTERS).map_or( - false, - |dom| Rfc1123Domain::try_from(dom) - .map_or_else(|e| e == Rfc1123Err::LabelStartsWithAHyphen, |_| false) - ) + Domain::try_from_bytes("-example.com", &ASCII_HYPHEN_DIGITS_LETTERS) + .is_ok_and(|dom| Rfc1123Domain::try_from(dom) + .is_err_and(|e| e == Rfc1123Err::LabelStartsWithAHyphen)) ); assert!( - Domain::try_from_bytes("example.c1m", &ASCII_HYPHEN_DIGITS_LETTERS).map_or( - false, - |dom| Rfc1123Domain::try_from(dom) - .map_or_else(|e| e == Rfc1123Err::InvalidTld, |_| false) - ) + Domain::try_from_bytes("example.c1m", &ASCII_HYPHEN_DIGITS_LETTERS).is_ok_and(|dom| { + Rfc1123Domain::try_from(dom).is_err_and(|e| e == Rfc1123Err::InvalidTld) + }) ); assert!( - Domain::try_from_bytes("example.commm", &ASCII_HYPHEN_DIGITS_LETTERS).map_or( - false, - |dom| Rfc1123Domain::try_from(dom) - .map_or(false, |rfc| rfc.is_literal_interpretation()) - ) + Domain::try_from_bytes("example.commm", &ASCII_HYPHEN_DIGITS_LETTERS) + .is_ok_and(|dom| Rfc1123Domain::try_from(dom) + .is_ok_and(|rfc| rfc.is_literal_interpretation())) ); assert!( - Domain::try_from_bytes("example.xn--abc", &ASCII_HYPHEN_DIGITS_LETTERS).map_or( - false, - |dom| Rfc1123Domain::try_from(dom) - .map_or(false, |rfc| !rfc.is_literal_interpretation()) - ) + Domain::try_from_bytes("example.xn--abc", &ASCII_HYPHEN_DIGITS_LETTERS) + .is_ok_and(|dom| Rfc1123Domain::try_from(dom) + .is_ok_and(|rfc| !rfc.is_literal_interpretation())) ); assert!( - Domain::try_from_bytes("example.com", &ASCII_HYPHEN_DIGITS_LETTERS).map_or( - false, - |dom| Rfc1123Domain::try_from(dom) - .map_or(false, |rfc| rfc.is_strict_interpretation()) - ) + Domain::try_from_bytes("example.com", &ASCII_HYPHEN_DIGITS_LETTERS) + .is_ok_and(|dom| Rfc1123Domain::try_from(dom) + .is_ok_and(|rfc| rfc.is_strict_interpretation())) ); assert!( - Domain::try_from_bytes("example.comm", &ASCII_HYPHEN_DIGITS_LETTERS).map_or( - false, - |dom| Rfc1123Domain::try_from(dom) - .map_or(false, |rfc| !rfc.is_strict_interpretation()) - ) + Domain::try_from_bytes("example.comm", &ASCII_HYPHEN_DIGITS_LETTERS) + .is_ok_and(|dom| Rfc1123Domain::try_from(dom) + .is_ok_and(|rfc| !rfc.is_strict_interpretation())) ); } #[test] - fn test_tld() { + fn tld() { assert!( Domain::try_from_bytes("example.com", &ASCII_HYPHEN_DIGITS_LETTERS) - .map_or(false, |dom| dom.tld().as_str() == "com",) + .is_ok_and(|dom| dom.tld().as_str() == "com",) ); } + #[expect(clippy::cognitive_complexity, reason = "want to test many things")] #[test] - fn test_rfc1123_parse() { + fn rfc1123_parse() { // Test empty is error. assert!( Rfc1123Domain::try_from_bytes("") - .map_or_else(|e| e == Rfc1123Err::DomainErr(DomainErr::Empty), |_| false) + .is_err_and(|e| e == Rfc1123Err::DomainErr(DomainErr::Empty)) ); // Test root domain. - assert!(Rfc1123Domain::try_from_bytes(".").map_or_else( - |e| e == Rfc1123Err::DomainErr(DomainErr::RootDomain), - |_| false - )); + assert!( + Rfc1123Domain::try_from_bytes(".") + .is_err_and(|e| e == Rfc1123Err::DomainErr(DomainErr::RootDomain)) + ); // Test empty label is error. - assert!(Rfc1123Domain::try_from_bytes("a..com").map_or_else( - |e| e == Rfc1123Err::DomainErr(DomainErr::EmptyLabel), - |_| false - )); - assert!(Rfc1123Domain::try_from_bytes("a..").map_or_else( - |e| e == Rfc1123Err::DomainErr(DomainErr::EmptyLabel), - |_| false - )); - assert!(Rfc1123Domain::try_from_bytes("..").map_or_else( - |e| e == Rfc1123Err::DomainErr(DomainErr::EmptyLabel), - |_| false - )); + assert!( + Rfc1123Domain::try_from_bytes("a..com") + .is_err_and(|e| e == Rfc1123Err::DomainErr(DomainErr::EmptyLabel)) + ); + assert!( + Rfc1123Domain::try_from_bytes("a..") + .is_err_and(|e| e == Rfc1123Err::DomainErr(DomainErr::EmptyLabel)) + ); + assert!( + Rfc1123Domain::try_from_bytes("..") + .is_err_and(|e| e == Rfc1123Err::DomainErr(DomainErr::EmptyLabel)) + ); // Test label too long. let val = "www.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com"; // 4 + 64 + 4 assert!(val.len() == 72); - assert!(Rfc1123Domain::try_from_bytes(val).map_or_else( - |e| e == Rfc1123Err::DomainErr(DomainErr::LabelLenExceeds63), - |_| false - )); + assert!( + Rfc1123Domain::try_from_bytes(val) + .is_err_and(|e| e == Rfc1123Err::DomainErr(DomainErr::LabelLenExceeds63),) + ); assert!( Rfc1123Domain::try_from_bytes( "www.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", ) - .map_or(false, |d| d.len().get() == 71) + .is_ok_and(|d| d.len().get() == 71) ); // Test domain too long. - assert!(Rfc1123Domain::try_from_bytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").map_or_else(|e| e == Rfc1123Err::DomainErr(DomainErr::LenExceeds253(254)), |_| false)); - assert!(Rfc1123Domain::try_from_bytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").map_or(false, |d| d.len().get() == 253 )); + assert!(Rfc1123Domain::try_from_bytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").is_err_and(|e| e == Rfc1123Err::DomainErr(DomainErr::LenExceeds253(254)))); + assert!(Rfc1123Domain::try_from_bytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").is_ok_and(|d| d.len().get() == 253 )); // Test max labels. - assert!(Rfc1123Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a").map_or_else(|e| e == Rfc1123Err::DomainErr(DomainErr::LenExceeds253(255)), |_| false)); - assert!(Rfc1123Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a").map_or(false, |d| d.iter().count() == 127 && d.len().get() == 253)); - assert!(Rfc1123Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.").map_or(false, |d| d.iter().count() == 127 && d.len().get() == 253)); + assert!(Rfc1123Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a").is_err_and(|e| e == Rfc1123Err::DomainErr(DomainErr::LenExceeds253(255)))); + assert!(Rfc1123Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a").is_ok_and(|d| d.iter().count() == 127 && d.len().get() == 253)); + assert!(Rfc1123Domain::try_from_bytes("a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.").is_ok_and(|d| d.iter().count() == 127 && d.len().get() == 253)); // Test removal of trailing '.'. - assert!(Rfc1123Domain::try_from_bytes("com.").map_or(false, |d| d.as_str() == "com")); + assert!(Rfc1123Domain::try_from_bytes("com.").is_ok_and(|d| d.as_str() == "com")); // Test single label. - assert!(Rfc1123Domain::try_from_bytes("c").map_or(false, |d| d.as_str() == "c")); + assert!(Rfc1123Domain::try_from_bytes("c").is_ok_and(|d| d.as_str() == "c")); // Test ends with hyphen. assert!( Rfc1123Domain::try_from_bytes("-") @@ -1853,17 +1828,15 @@ mod tests { ); // Test case-insensitivity. assert!( - Rfc1123Domain::try_from_bytes("wwW.ExAMple.COm").map_or(false, |d| { + Rfc1123Domain::try_from_bytes("wwW.ExAMple.COm").is_ok_and(|d| { Rfc1123Domain::try_from_bytes("www.example.com") - .map_or(false, |d2| d == d2 && d.cmp(&d2) == Ordering::Equal) - }) - ); - assert!( - Rfc1123Domain::try_from_bytes("ww-W.com").map_or(false, |d| { - Rfc1123Domain::try_from_bytes("Ww-w.com") - .map_or(false, |d2| d == d2 && d.cmp(&d2) == Ordering::Equal) + .is_ok_and(|d2| d == d2 && d.cmp(&d2) == Ordering::Equal) }) ); + assert!(Rfc1123Domain::try_from_bytes("ww-W.com").is_ok_and(|d| { + Rfc1123Domain::try_from_bytes("Ww-w.com") + .is_ok_and(|d2| d == d2 && d.cmp(&d2) == Ordering::Equal) + })); assert!( Rfc1123Domain::try_from_bytes("1.1.1.1") .map_or_else(|err| err == Rfc1123Err::InvalidTld, |_| false) diff --git a/src/serde.rs b/src/serde.rs @@ -242,44 +242,42 @@ mod tests { }; use alloc::string::String; #[test] - fn test_serde() { + fn serde() { assert!( serde_json::from_str::<Domain<&str>>(r#""example.com""#) - .map_or(false, |dom| dom.into_iter().count() == 2) + .is_ok_and(|dom| dom.into_iter().count() == 2) ); assert!( serde_json::from_str::<Domain<String>>(r#""c\"om""#) - .map_or(false, |dom| dom.into_iter().count() == 1) + .is_ok_and(|dom| dom.into_iter().count() == 1) ); // Can't borrow since input needs to be de-escaped. assert!( serde_json::from_str::<Domain<&str>>(r#""c\"om""#) - .map_or_else(|err| err.is_data() && err.column() == 7, |_| false) + .is_err_and(|err| err.is_data() && err.column() == 7) ); assert!( - serde_json::to_string( - &Domain::try_from_bytes("example.com", &ASCII_HYPHEN_DIGITS_LETTERS).unwrap() - ) - .map_or(false, |output| output == r#""example.com""#) + Domain::try_from_bytes("example.com", &ASCII_HYPHEN_DIGITS_LETTERS) + .is_ok_and(|dom| serde_json::to_string(&dom) + .is_ok_and(|output| output == r#""example.com""#)) ); assert!( - serde_json::to_string( - &Domain::try_from_bytes(b"example.com", &ASCII_HYPHEN_DIGITS_LETTERS).unwrap() - ) - .map_or(false, |output| output == r#""example.com""#) + Domain::try_from_bytes(b"example.com", &ASCII_HYPHEN_DIGITS_LETTERS) + .is_ok_and(|dom| serde_json::to_string(&dom) + .is_ok_and(|output| output == r#""example.com""#)) ); assert!( serde_json::from_str::<Rfc1123Domain<&str>>(r#""example.com""#) - .map_or(false, |dom| dom.into_iter().count() == 2) + .is_ok_and(|dom| dom.into_iter().count() == 2) ); assert!( serde_json::from_str::<Rfc1123Domain<String>>(r#""c\u006fm""#) - .map_or(false, |dom| dom.tld().as_str() == "com") + .is_ok_and(|dom| dom.tld().as_str() == "com") ); // Can't borrow since input needs to be de-escaped. assert!( serde_json::from_str::<Rfc1123Domain<&str>>(r#""c\u006fm""#) - .map_or_else(|err| err.is_data() && err.column() == 10, |_| false) + .is_err_and(|err| err.is_data() && err.column() == 10) ); } }