hickory_proto/rr/domain/
try_parse_ip.rs

1// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// https://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use std::net::IpAddr;
9
10use crate::rr::{Name, RData};
11
12/// Types of this trait will can be attempted for conversion to an IP address
13pub trait TryParseIp {
14    /// Attempts to parse self into an RData::A or RData::AAAA, None is returned if not possible
15    fn try_parse_ip(&self) -> Option<RData>;
16}
17
18impl TryParseIp for str {
19    fn try_parse_ip(&self) -> Option<RData> {
20        match self.parse::<IpAddr>() {
21            Ok(IpAddr::V4(ip4)) => Ok(RData::A(ip4.into())),
22            Ok(IpAddr::V6(ip6)) => Ok(RData::AAAA(ip6.into())),
23            Err(err) => Err(err),
24        }
25        .ok()
26    }
27}
28
29impl TryParseIp for String {
30    fn try_parse_ip(&self) -> Option<RData> {
31        (self[..]).try_parse_ip()
32    }
33}
34
35impl TryParseIp for Name {
36    /// Always returns none for Name, it assumes something that is already a name, wants to be a name
37    fn try_parse_ip(&self) -> Option<RData> {
38        None
39    }
40}
41
42impl<T> TryParseIp for &T
43where
44    T: TryParseIp + ?Sized,
45{
46    fn try_parse_ip(&self) -> Option<RData> {
47        TryParseIp::try_parse_ip(*self)
48    }
49}
50
51#[test]
52fn test_try_parse_ip() {
53    use std::net::{Ipv4Addr, Ipv6Addr};
54
55    assert_eq!(
56        "127.0.0.1".try_parse_ip().expect("failed"),
57        RData::A(Ipv4Addr::new(127, 0, 0, 1).into())
58    );
59
60    assert_eq!(
61        "::1".try_parse_ip().expect("failed"),
62        RData::AAAA(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).into())
63    );
64
65    assert!("example.com".try_parse_ip().is_none());
66}