addr/
lib.rs

1/*!
2  Robust domain name parsing using the Public Suffix List
3
4  This library allows you to easily and accurately parse any given domain name.
5
6  ## Examples
7
8  ```rust
9  # fn main() -> Result<(), Box<dyn std::error::Error>> {
10  # #[cfg(feature = "psl")]
11  # {
12  use addr::{parse_domain_name, parse_dns_name};
13
14  // You can find out the root domain
15  // or extension of any given domain name
16  let domain = parse_domain_name("www.example.com")?;
17  assert_eq!(domain.root(), Some("example.com"));
18  assert_eq!(domain.suffix(), "com");
19
20  let domain = parse_domain_name("www.食狮.中国")?;
21  assert_eq!(domain.root(), Some("食狮.中国"));
22  assert_eq!(domain.suffix(), "中国");
23
24  let domain = parse_domain_name("www.xn--85x722f.xn--55qx5d.cn")?;
25  assert_eq!(domain.root(), Some("xn--85x722f.xn--55qx5d.cn"));
26  assert_eq!(domain.suffix(), "xn--55qx5d.cn");
27
28  let domain = parse_domain_name("a.b.example.uk.com")?;
29  assert_eq!(domain.root(), Some("example.uk.com"));
30  assert_eq!(domain.suffix(), "uk.com");
31
32  let name = parse_dns_name("_tcp.example.com.")?;
33  assert_eq!(name.suffix(), Some("com."));
34
35  // In any case if the domain's suffix is in the list
36  // then this is definately a registrable domain name
37  assert!(domain.has_known_suffix());
38  # }
39  # Ok(())
40  # }
41  ```
42!*/
43
44#![cfg_attr(not(feature = "std"), no_std)]
45#![forbid(unsafe_code)]
46
47pub mod dns;
48pub mod domain;
49pub mod email;
50pub mod error;
51mod matcher;
52#[cfg(feature = "net")]
53pub mod net;
54pub mod parser;
55#[cfg(feature = "serde")]
56mod serde;
57
58#[cfg(not(any(feature = "psl", feature = "publicsuffix")))]
59pub use crate::empty_psl::{parse_dns_name, parse_domain_name, parse_email_address};
60#[cfg(feature = "psl")]
61pub use crate::psl::{parse_dns_name, parse_domain_name, parse_email_address};
62
63/// The static implementation of the public suffix list
64#[cfg(feature = "psl")]
65pub mod psl {
66    use crate::parser::{DnsName, DomainName, EmailAddress};
67    use crate::{dns, domain, email, Result};
68
69    pub use psl::List;
70
71    pub fn parse_domain_name(input: &str) -> Result<domain::Name> {
72        List.parse_domain_name(input)
73    }
74
75    pub fn parse_dns_name(input: &str) -> Result<dns::Name> {
76        List.parse_dns_name(input)
77    }
78
79    pub fn parse_email_address(input: &str) -> Result<email::Address> {
80        List.parse_email_address(input)
81    }
82}
83
84#[cfg(not(any(feature = "psl", feature = "publicsuffix")))]
85mod empty_psl {
86    use crate::parser::{DnsName, DomainName, EmailAddress};
87    use crate::{dns, domain, email, Result};
88    use psl_types::Info;
89
90    pub struct List;
91
92    impl psl_types::List for List {
93        fn find<'a, T>(&self, mut labels: T) -> Info
94        where
95            T: Iterator<Item = &'a [u8]>,
96        {
97            match labels.next() {
98                Some(label) => Info {
99                    len: label.len(),
100                    typ: None,
101                },
102                None => Info { len: 0, typ: None },
103            }
104        }
105    }
106
107    pub fn parse_domain_name(input: &str) -> Result<domain::Name> {
108        List.parse_domain_name(input)
109    }
110
111    pub fn parse_dns_name(input: &str) -> Result<dns::Name> {
112        List.parse_dns_name(input)
113    }
114
115    pub fn parse_email_address(input: &str) -> Result<email::Address> {
116        List.parse_email_address(input)
117    }
118}
119
120/// The dynamic implementation of the public suffix list
121#[cfg(feature = "publicsuffix")]
122pub mod publicsuffix {
123    pub use publicsuffix::{IcannList, List, PrivateList};
124}
125
126/// Custom result type
127pub type Result<'a, T> = core::result::Result<T, error::Error<'a>>;