whois_rust/
who_is_server_value.rs1use std::borrow::Cow;
2
3use serde_json::Value;
4use validators::prelude::*;
5
6use crate::{WhoIsError, WhoIsHost};
7
8const DEFAULT_PUNYCODE: bool = true;
9
10#[derive(Debug, Clone)]
12pub struct WhoIsServerValue {
13 pub host: WhoIsHost,
15 pub query: Option<String>,
17 pub punycode: bool,
19}
20
21impl WhoIsServerValue {
22 pub fn from_value(value: &Value) -> Result<WhoIsServerValue, WhoIsError> {
24 match value {
25 Value::Object(map) => match map.get("host") {
26 Some(Value::String(host)) => {
27 let host = match WhoIsHost::parse_str(host) {
28 Ok(host) => host,
29 Err(_) => {
30 return Err(WhoIsError::MapError(
31 "The server value is an object, but it has not a correct host \
32 string.",
33 ));
34 },
35 };
36
37 let query = match map.get("query") {
38 Some(query) => {
39 if let Value::String(query) = query {
40 Some(String::from(query))
41 } else {
42 return Err(WhoIsError::MapError(
43 "The server value is an object, but it has an incorrect query \
44 string.",
45 ));
46 }
47 },
48 None => None,
49 };
50
51 let punycode = match map.get("punycode") {
52 Some(punycode) => {
53 if let Value::Bool(punycode) = punycode {
54 *punycode
55 } else {
56 return Err(WhoIsError::MapError(
57 "The server value is an object, but it has an incorrect \
58 punycode boolean value.",
59 ));
60 }
61 },
62 None => DEFAULT_PUNYCODE,
63 };
64
65 Ok(WhoIsServerValue {
66 host,
67 query,
68 punycode,
69 })
70 },
71 _ => Err(WhoIsError::MapError(
72 "The server value is an object, but it has not a host string.",
73 )),
74 },
75 Value::String(host) => Self::from_string(host),
76 _ => Err(WhoIsError::MapError("The server value is not an object or a host string.")),
77 }
78 }
79
80 #[inline]
82 pub fn from_string<S: AsRef<str>>(string: S) -> Result<WhoIsServerValue, WhoIsError> {
83 let host = string.as_ref();
84
85 let host = match WhoIsHost::parse_str(host) {
86 Ok(host) => host,
87 Err(_) => {
88 return Err(WhoIsError::MapError("The server value is not a correct host string."));
89 },
90 };
91
92 Ok(WhoIsServerValue {
93 host,
94 query: None,
95 punycode: DEFAULT_PUNYCODE,
96 })
97 }
98
99 pub(crate) fn encode_domain<'a>(&self, domain: &'a str) -> Cow<'a, str> {
101 if self.punycode {
102 Cow::Borrowed(domain)
103 } else {
104 Cow::Owned(validators::idna::domain_to_unicode(domain).0)
105 }
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn encode_domain_honors_punycode_flag() {
115 let mut server = WhoIsServerValue::from_string("whois.denic.de").unwrap();
116
117 assert_eq!("xn--mller-kva.de", server.encode_domain("xn--mller-kva.de").as_ref());
119
120 server.punycode = false;
122 assert_eq!("müller.de", server.encode_domain("xn--mller-kva.de").as_ref());
123 }
124}