Skip to main content

unirate_api/
models.rs

1//! Response models for the UniRate API.
2//!
3//! These are typed deserialization targets for the structured endpoints
4//! ([`get_historical_limits`](crate::Client::get_historical_limits),
5//! [`get_vat_rates`](crate::Client::get_vat_rates),
6//! [`get_vat_rate`](crate::Client::get_vat_rate)).
7
8use serde::Deserialize;
9use std::collections::HashMap;
10use std::fmt;
11
12use crate::endpoints::deserialize_number;
13
14/// Historical-data coverage window for a single currency.
15#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
16pub struct HistoricalLimit {
17    /// Earliest date (`YYYY-MM-DD`) for which data is available.
18    pub earliest_date: String,
19    /// Latest date (`YYYY-MM-DD`) for which data is available.
20    pub latest_date: String,
21}
22
23/// Response for [`Client::get_historical_limits`](crate::Client::get_historical_limits).
24#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
25pub struct HistoricalLimitsResponse {
26    /// Total number of currencies with historical coverage.
27    pub total_currencies: u32,
28    /// Per-currency coverage details, keyed by ISO-4217 code.
29    pub currencies: HashMap<String, HistoricalLimit>,
30}
31
32/// VAT rate data for a single country.
33#[derive(Debug, Clone, PartialEq, Deserialize)]
34pub struct VatRate {
35    /// ISO-3166 alpha-2 country code (may be omitted in nested responses).
36    #[serde(default)]
37    pub country_code: Option<String>,
38    /// Human-readable country name.
39    #[serde(default)]
40    pub country_name: Option<String>,
41    /// VAT rate as a percentage (e.g. `19.0` for 19%). Accepts numbers or numeric strings.
42    #[serde(deserialize_with = "deserialize_number")]
43    pub vat_rate: f64,
44}
45
46/// Response for [`Client::get_vat_rate`](crate::Client::get_vat_rate).
47#[derive(Debug, Clone, PartialEq, Deserialize)]
48pub struct VatRateResponse {
49    /// ISO-3166 alpha-2 country code echoed back by the API.
50    #[serde(default)]
51    pub country: Option<String>,
52    /// Nested VAT rate detail.
53    pub vat_data: VatRate,
54}
55
56/// Response for [`Client::get_vat_rates`](crate::Client::get_vat_rates).
57#[derive(Debug, Clone, PartialEq, Deserialize)]
58pub struct VatRatesResponse {
59    /// Snapshot date (`YYYY-MM-DD`), when provided by the API.
60    #[serde(default)]
61    pub date: Option<String>,
62    /// Total number of countries in the response.
63    pub total_countries: u32,
64    /// Per-country VAT rates, keyed by ISO-3166 alpha-2 code.
65    pub vat_rates: HashMap<String, VatRate>,
66}
67
68impl fmt::Display for VatRate {
69    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70        let code = self.country_code.as_deref().unwrap_or("??");
71        write!(f, "{}: {}%", code, self.vat_rate)
72    }
73}