aboutsummaryrefslogtreecommitdiff
path: root/src/response/nameserver.rs
blob: 6ac330bff67a753e6d64a8070d1af2f41f4bd330 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use super::Response;
use crate::common::nameserver::{DomainType, RecordType, SlaveDns, UrlRdrType};
use crate::common::*;
use crate::{Error, Result};

use iso8601::DateTime;

/// A nameserver record. Contains DNS information as well as INWX metadata.
#[derive(Clone, Debug)]
pub struct Record {
    pub id: i32,
    pub name: String,
    pub record_type: RecordType,
    pub content: String,
    pub ttl: i32,
    pub priority: i32,
    pub url_rdr_type: Option<UrlRdrType>,
    pub url_rdr_title: Option<String>,
    pub url_rdr_desc: Option<String>,
    pub url_rdr_keywords: Option<String>,
    pub url_rdr_favicon: Option<String>,
    pub url_append: Option<bool>,
}

impl TryFrom<xmlrpc::Value> for Record {
    type Error = Error;
    fn try_from(v: xmlrpc::Value) -> Result<Self> {
        if let xmlrpc::Value::Struct(map) = v {
            let record = Self {
                id: get_i32(&map, "id".into())?,
                name: get_str(&map, "name".into())?,
                record_type: get_str(&map, "type".into())?.try_into()?,
                content: get_str(&map, "content".into())?,
                ttl: get_i32(&map, "ttl".into())?,
                priority: get_i32(&map, "prio".into())?,
                url_rdr_type: match get_str(&map, "urlRedirectType".into()).ok() {
                    Some(url_rdr_type) => url_rdr_type.try_into().ok(),
                    None => None,
                },
                url_rdr_title: get_str(&map, "urlRedirectTitle".into()).ok(),
                url_rdr_desc: get_str(&map, "urlRedirectDescription".into()).ok(),
                url_rdr_keywords: get_str(&map, "urlRedirectKeywords".into()).ok(),
                url_rdr_favicon: get_str(&map, "urlRedirectFavIcon".into()).ok(),
                url_append: get_bool(&map, "urlAppend".into()).ok(),
            };

            Ok(record)
        } else {
            Err(Error::Type("record".into(), "Struct".into(), v))
        }
    }
}

/// The records that match a search.
#[derive(Clone, Debug)]
pub struct RecordInfo {
    pub domain_id: Option<i32>,
    pub domain_name: Option<String>,
    pub domain_type: Option<DomainType>,
    pub master_address: Option<String>,
    pub last_zone_check: Option<DateTime>,
    pub slave_dns: Option<SlaveDns>,
    pub soa_serial: Option<String>,
    pub records: Option<Vec<Record>>,
}

impl TryFrom<Response> for RecordInfo {
    type Error = Error;
    fn try_from(resp: Response) -> Result<Self> {
        let info = Self {
            domain_id: get_i32(&resp.data, "roId".into()).ok(),
            domain_name: get_str(&resp.data, "domain".into()).ok(),
            domain_type: match get_str(&resp.data, "type".into()).ok() {
                Some(domain_type) => domain_type.try_into().ok(),
                None => None,
            },
            master_address: get_str(&resp.data, "masterIp".into()).ok(),
            last_zone_check: { get_datetime(&resp.data, "lastZoneCheck".into()).ok() },
            slave_dns: match get_map(&resp.data, "slaveDns".into()).ok() {
                Some(slave_dns) => slave_dns.try_into().ok(),
                None => None,
            },
            soa_serial: get_str(&resp.data, "SOAserial".into()).ok(),
            records: match get_array(&resp.data, "record".into()).ok() {
                Some(records) => Some(
                    records
                        .iter()
                        .map(|v| v.to_owned().try_into())
                        .collect::<Result<Vec<Record>>>()?,
                ),
                None => None,
            },
        };

        Ok(info)
    }
}