use serde::Deserialize;
use crate::client::Client;
use crate::error::Result;
#[derive(Debug, Clone, Copy)]
pub struct Users<'a> {
client: &'a Client,
}
impl<'a> Users<'a> {
pub(crate) fn new(client: &'a Client) -> Self {
Self { client }
}
pub async fn get_balances(&self) -> Result<Balances> {
let payload: BalancesPayload = self
.client
.send("namecheap.users.getBalances", Vec::new())
.await?;
Ok(payload.result)
}
}
#[derive(Debug, Deserialize)]
struct BalancesPayload {
#[serde(rename = "UserGetBalancesResult")]
result: Balances,
}
#[derive(Debug, Clone, Deserialize)]
#[non_exhaustive]
pub struct Balances {
#[serde(rename = "@Currency")]
pub currency: String,
#[serde(rename = "@AvailableBalance")]
pub available_balance: f64,
#[serde(rename = "@AccountBalance")]
pub account_balance: f64,
#[serde(rename = "@EarnedAmount")]
pub earned_amount: f64,
#[serde(rename = "@WithdrawableAmount")]
pub withdrawable_amount: f64,
#[serde(rename = "@FundsRequiredForAutoRenew")]
pub funds_required_for_auto_renew: f64,
}
#[cfg(test)]
mod tests {
use super::*;
use reqwest::StatusCode;
#[test]
fn parses_balances_response() {
let body = r#"<?xml version="1.0" encoding="utf-8"?>
<ApiResponse Status="OK" xmlns="http://api.namecheap.com/xml.response">
<Errors />
<CommandResponse Type="namecheap.users.getBalances">
<UserGetBalancesResult Currency="USD" AvailableBalance="4932.96" AccountBalance="4932.96" EarnedAmount="381.30" WithdrawableAmount="1500.00" FundsRequiredForAutoRenew="0.00" />
</CommandResponse>
</ApiResponse>"#;
let payload: BalancesPayload = crate::response::parse(StatusCode::OK, body).unwrap();
let balances = payload.result;
assert_eq!(balances.currency, "USD");
assert_eq!(balances.available_balance, 4932.96);
assert_eq!(balances.earned_amount, 381.30);
assert_eq!(balances.funds_required_for_auto_renew, 0.0);
}
}