1#![cfg_attr(not(feature = "std"), no_std)]
9
10extern crate alloc;
11#[cfg(feature = "client")]
12use alloc::string::String;
13
14pub mod antifraud;
15#[cfg(feature = "client")]
16pub mod ebs;
17#[cfg(feature = "client")]
18pub mod tspi;
19
20#[cfg(feature = "client")]
21use reqwest::Client as HttpClient;
22#[cfg(feature = "client")]
23use std::time::Duration;
24
25#[derive(Debug, thiserror::Error)]
26pub enum CbrApiError {
27 #[cfg(feature = "client")]
28 #[error("HTTP Error: {0}")]
29 Http(#[from] reqwest::Error),
30 #[error("Rate Limit Exceeded (429)")]
31 RateLimited,
32 #[error("Service Unavailable (503)")]
33 Unavailable,
34 #[error("API JSON Parse Error: {0}")]
35 Json(#[from] serde_json::Error),
36 #[error("Authentication Error: {0}")]
37 Auth(alloc::string::String),
38}
39
40#[cfg(feature = "client")]
41pub struct CbrApiClient {
42 http: HttpClient,
43 base_url: String,
44 api_key: String,
45}
46
47#[cfg(feature = "client")]
48impl CbrApiClient {
49 pub fn builder() -> CbrApiBuilder {
50 CbrApiBuilder::default()
51 }
52
53 pub fn antifraud(&self) -> antifraud::AntiFraudClient<'_> {
54 antifraud::AntiFraudClient::new(self)
55 }
56
57 pub fn tspi(&self) -> tspi::TspiClient<'_> {
58 tspi::TspiClient::new(self)
59 }
60
61 pub fn ebs(&self) -> ebs::EbsClient<'_> {
62 ebs::EbsClient::new(self)
63 }
64}
65
66#[cfg(feature = "client")]
67#[derive(Default)]
68pub struct CbrApiBuilder {
69 base_url: Option<String>,
70 api_key: Option<String>,
71}
72
73#[cfg(feature = "client")]
74impl CbrApiBuilder {
75 pub fn base_url(mut self, url: impl Into<String>) -> Self {
76 self.base_url = Some(url.into());
77 self
78 }
79
80 pub fn api_key(mut self, key: impl Into<String>) -> Self {
81 self.api_key = Some(key.into());
82 self
83 }
84
85 pub fn build(self) -> Result<CbrApiClient, CbrApiError> {
86 let base_url = self
87 .base_url
88 .unwrap_or_else(|| "https://finapi.cbr.ru".to_string());
89 let api_key = self
90 .api_key
91 .ok_or_else(|| CbrApiError::Auth("Missing API Key".into()))?;
92
93 let http = HttpClient::builder()
94 .timeout(Duration::from_secs(10))
95 .build()?;
96
97 Ok(CbrApiClient {
98 http,
99 base_url,
100 api_key,
101 })
102 }
103}