1use serde::{Deserialize, Serialize};
6
7use crate::common::{RdapEntity, RdapEvent, RdapLink, RdapRemark, RdapStatus, ResponseMeta};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11#[serde(rename_all = "camelCase")]
12pub struct DomainResponse {
13 pub query: String,
15
16 #[serde(skip_serializing_if = "Option::is_none")]
18 pub ldh_name: Option<String>,
19
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub unicode_name: Option<String>,
23
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub handle: Option<String>,
27
28 #[serde(default, skip_serializing_if = "Vec::is_empty")]
30 pub status: Vec<RdapStatus>,
31
32 #[serde(default, skip_serializing_if = "Vec::is_empty")]
34 pub nameservers: Vec<String>,
35
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub registrar: Option<RegistrarSummary>,
39
40 #[serde(default, skip_serializing_if = "Vec::is_empty")]
42 pub entities: Vec<RdapEntity>,
43
44 #[serde(default, skip_serializing_if = "Vec::is_empty")]
46 pub events: Vec<RdapEvent>,
47
48 #[serde(default, skip_serializing_if = "Vec::is_empty")]
49 pub links: Vec<RdapLink>,
50
51 #[serde(default, skip_serializing_if = "Vec::is_empty")]
52 pub remarks: Vec<RdapRemark>,
53
54 pub meta: ResponseMeta,
56}
57
58impl DomainResponse {
59 pub fn expiration_date(&self) -> Option<&str> {
61 self.events
62 .iter()
63 .find(|e| e.event_action == "expiration")
64 .map(|e| e.event_date.as_str())
65 }
66
67 pub fn registration_date(&self) -> Option<&str> {
69 self.events
70 .iter()
71 .find(|e| e.event_action == "registration")
72 .map(|e| e.event_date.as_str())
73 }
74
75 pub fn is_active(&self) -> bool {
77 self.status.iter().any(|s| matches!(s, RdapStatus::Active))
78 }
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize)]
83pub struct RegistrarSummary {
84 #[serde(skip_serializing_if = "Option::is_none")]
85 pub name: Option<String>,
86 #[serde(skip_serializing_if = "Option::is_none")]
87 pub handle: Option<String>,
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub url: Option<String>,
90 #[serde(skip_serializing_if = "Option::is_none")]
91 pub abuse_email: Option<String>,
92 #[serde(skip_serializing_if = "Option::is_none")]
93 pub abuse_phone: Option<String>,
94}