1use serde_json::{Value, json};
2use std::collections::HashMap;
3
4use crate::client::DnaClient;
5use crate::error::DnaResult;
6use crate::models::contact::{ContactInput, ContactPayload};
7use crate::models::domain::DomainInfo;
8use crate::models::domain::DomainInfoResponse;
9use crate::models::transfer::{
10 DomainActionPayload, TransferCheckResponse, TransferCheckResult, TransferPayload,
11 TransferStatusResponse,
12};
13use crate::ops::util::{build_contact_payload, parse_domain_info};
14
15impl DnaClient {
16 pub async fn transfer(
18 &self,
19 domain_name: &str,
20 epp_code: &str,
21 period: u32,
22 contacts: Option<HashMap<&str, ContactInput>>,
23 ) -> DnaResult<DomainInfo> {
24 let payload_contacts: Vec<ContactPayload> = contacts
25 .unwrap_or_default()
26 .iter()
27 .map(|(t, c)| build_contact_payload(c, t))
28 .collect();
29
30 let payload = TransferPayload {
31 domain_name: domain_name.into(),
32 auth_code: epp_code.into(),
33 period,
34 contacts: payload_contacts,
35 };
36
37 let raw: DomainInfoResponse = self.http.post("domains/transfer", &payload).await?;
38 parse_domain_info(raw)
39 }
40
41 pub async fn check_transfer(
43 &self,
44 domain_name: &str,
45 auth_code: &str,
46 ) -> DnaResult<TransferCheckResult> {
47 let payload = json!({ "domainName": domain_name, "authCode": auth_code });
48 let resp: TransferCheckResponse =
49 self.http.post("domains/transfers/check", &payload).await?;
50
51 let available = resp
52 .transfer_availability_status
53 .as_ref()
54 .map(|v| !v.is_null() && v != &Value::Bool(false) && v != &json!(0) && v != &json!(""))
55 .unwrap_or(false);
56
57 Ok(TransferCheckResult {
58 transfer_available: available,
59 auth_code_is_required: resp.auth_code_is_required.unwrap_or(false),
60 auth_code_is_valid: resp.auth_code_is_valid.unwrap_or(false),
61 user_transfer_required: resp.user_transfer_required.unwrap_or(false),
62 transfer_lock: resp.transfer_lock.unwrap_or(false),
63 message: resp.message.unwrap_or_default(),
64 message_key: resp.message_key.unwrap_or_default(),
65 })
66 }
67
68 pub async fn cancel_transfer(&self, domain_name: &str) -> DnaResult<String> {
70 let payload = DomainActionPayload {
71 domain_name: domain_name.into(),
72 };
73 let resp: TransferStatusResponse =
74 self.http.post("domains/transfers/cancel", &payload).await?;
75 Ok(resp.status.unwrap_or_else(|| "Cancelled".into()))
76 }
77
78 pub async fn approve_transfer(&self, domain_name: &str) -> DnaResult<String> {
80 let payload = DomainActionPayload {
81 domain_name: domain_name.into(),
82 };
83 let resp: TransferStatusResponse = self
84 .http
85 .post("domains/transfers/approve", &payload)
86 .await?;
87 Ok(resp.status.unwrap_or_else(|| "Approved".into()))
88 }
89
90 pub async fn reject_transfer(&self, domain_name: &str) -> DnaResult<String> {
92 let payload = DomainActionPayload {
93 domain_name: domain_name.into(),
94 };
95 let resp: TransferStatusResponse =
96 self.http.post("domains/transfers/reject", &payload).await?;
97 Ok(resp.status.unwrap_or_else(|| "Rejected".into()))
98 }
99}