1use std::collections::HashSet;
4use std::hash::Hash;
5use std::net::IpAddr;
6use std::ops::RangeInclusive;
7
8use ipnet::IpNet;
9
10pub mod authority;
11pub(crate) mod ip;
12pub mod url;
13
14pub(crate) fn has_unique_elements<T>(iter: T) -> bool
16where
17 T: IntoIterator,
18 T::Item: Eq + Hash,
19{
20 let mut uniq = HashSet::new();
21 iter.into_iter().all(move |x| uniq.insert(x))
22}
23
24pub trait IntoIpRange {
26 fn into_range(self) -> Option<RangeInclusive<IpAddr>>;
28
29 fn validate(ip_range: RangeInclusive<IpAddr>) -> Option<RangeInclusive<IpAddr>> {
31 if ip_range.start() <= ip_range.end() {
32 Some(ip_range)
33 } else {
34 None
35 }
36 }
37}
38
39impl IntoIpRange for IpNet {
40 fn into_range(self) -> Option<RangeInclusive<IpAddr>> {
41 let start = self.network();
42 let end = self.broadcast();
43 Some(start..=end)
44 }
45}
46
47impl IntoIpRange for RangeInclusive<IpAddr> {
48 fn into_range(self) -> Option<RangeInclusive<IpAddr>> {
49 Self::validate(self)
50 }
51}
52
53impl IntoIpRange for (IpAddr, IpAddr) {
54 fn into_range(self) -> Option<RangeInclusive<IpAddr>> {
55 Self::validate(self.0..=self.1)
56 }
57}