1// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
78use std::net::IpAddr;
910use crate::rr::{Name, RData};
1112/// 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
15fn try_parse_ip(&self) -> Option<RData>;
16}
1718impl TryParseIp for str {
19fn try_parse_ip(&self) -> Option<RData> {
20match self.parse::<IpAddr>() {
21Ok(IpAddr::V4(ip4)) => Ok(RData::A(ip4)),
22Ok(IpAddr::V6(ip6)) => Ok(RData::AAAA(ip6)),
23Err(err) => Err(err),
24 }
25 .ok()
26 }
27}
2829impl TryParseIp for String {
30fn try_parse_ip(&self) -> Option<RData> {
31 (self[..]).try_parse_ip()
32 }
33}
3435impl TryParseIp for Name {
36/// Always returns none for Name, it assumes something that is already a name, wants to be a name
37fn try_parse_ip(&self) -> Option<RData> {
38None
39}
40}
4142impl<'a, T> TryParseIp for &'a T
43where
44T: TryParseIp + ?Sized,
45{
46fn try_parse_ip(&self) -> Option<RData> {
47 TryParseIp::try_parse_ip(*self)
48 }
49}
5051#[test]
52fn test_try_parse_ip() {
53use std::net::{Ipv4Addr, Ipv6Addr};
5455assert_eq!(
56"127.0.0.1".try_parse_ip().expect("failed"),
57 RData::A(Ipv4Addr::new(127, 0, 0, 1))
58 );
5960assert_eq!(
61"::1".try_parse_ip().expect("failed"),
62 RData::AAAA(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))
63 );
6465assert!("example.com".try_parse_ip().is_none());
66}