1use crate::v1::{Client, error, BASE_URL, standard};
2
3use serde::Deserialize;
4
5#[derive(Deserialize, Debug)]
8pub struct ListAccountsResponse {
9 pub data : Vec<AccountResource>,
11 pub links : ResponseLinks,
12}
13
14#[derive(Deserialize, Debug)]
15pub struct GetAccountResponse {
16 pub data : AccountResource,
18}
19
20#[derive(Deserialize, Debug)]
21pub struct AccountResource {
22 pub r#type : String,
24 pub id : String,
26 pub attributes : Attributes,
27 pub relationships : Relationships,
28 pub links : Option<AccountResourceLinks>,
29}
30
31#[derive(Deserialize, Debug)]
32pub struct AccountResourceLinks {
33 #[serde(rename = "self")]
35 pub this : Option<String>,
36}
37
38#[derive(Deserialize, Debug)]
39pub struct ResponseLinks {
40 pub prev : Option<String>,
42 pub next : Option<String>,
44}
45
46#[derive(Deserialize, Debug)]
47pub struct Relationships {
48 pub transactions : Transactions,
49}
50
51#[derive(Deserialize, Debug)]
52pub struct Transactions {
53 pub links : Option<TransactionLinks>,
54}
55
56#[derive(Deserialize, Debug)]
57pub struct TransactionLinks {
58 pub related : String,
60}
61
62#[derive(Deserialize, Debug)]
63#[serde(rename_all = "camelCase")]
64pub struct Attributes {
65 pub display_name : String,
67 pub account_type : String,
69 pub ownership_type : String,
71 pub balance : standard::MoneyObject,
73 pub created_at : String,
75}
76
77#[derive(Default)]
80pub struct ListAccountsOptions {
81 page_size : Option<u8>,
83 filter_account_type : Option<String>,
85 filter_ownership_type : Option<String>,
87}
88
89impl ListAccountsOptions {
90 pub fn page_size(&mut self, value : u8) {
92 self.page_size = Some(value);
93 }
94
95 pub fn filter_account_type(&mut self, value : String) {
97 self.filter_account_type = Some(value);
98 }
99
100 pub fn filter_ownership_type(&mut self, value : String) {
102 self.filter_ownership_type = Some(value);
103 }
104
105 fn add_params(&self, url : &mut reqwest::Url) {
106 let mut query = String::new();
107
108 if let Some(value) = &self.page_size {
109 if !query.is_empty() {
110 query.push('&');
111 }
112 query.push_str(&format!("page[size]={}", value));
113 }
114
115 if let Some(value) = &self.filter_account_type {
116 if !query.is_empty() {
117 query.push('&');
118 }
119 query.push_str(&format!("filter[accountType]={}", urlencoding::encode(value)));
120 }
121
122 if let Some(value) = &self.filter_ownership_type {
123 if !query.is_empty() {
124 query.push('&');
125 }
126 query.push_str(&format!("filter[ownershipType]={}", urlencoding::encode(value)));
127 }
128
129 if !query.is_empty() {
130 url.set_query(Some(&query));
131 }
132 }
133}
134
135impl Client {
136 pub async fn list_accounts(&self, options : &ListAccountsOptions) -> Result<ListAccountsResponse, error::Error> {
138 let mut url = reqwest::Url::parse(&format!("{}/accounts", BASE_URL)).map_err(error::Error::UrlParse)?;
139 options.add_params(&mut url);
140
141 let res = reqwest::Client::new()
142 .get(url)
143 .header("Authorization", self.auth_header())
144 .send()
145 .await
146 .map_err(error::Error::Request)?;
147
148 match res.status() {
149 reqwest::StatusCode::OK => {
150 let body = res.text().await.map_err(error::Error::BodyRead)?;
151 let account_response : ListAccountsResponse = serde_json::from_str(&body).map_err(error::Error::Json)?;
152
153 Ok(account_response)
154 },
155 _ => {
156 let body = res.text().await.map_err(error::Error::BodyRead)?;
157 let error : error::ErrorResponse = serde_json::from_str(&body).map_err(error::Error::Json)?;
158
159 Err(error::Error::Api(error))
160 }
161 }
162 }
163
164 pub async fn get_account(&self, id : &str) -> Result<GetAccountResponse, error::Error> {
166 if id.is_empty() {
169 panic!("The provided account ID must not be empty.");
170 }
171
172 let url = reqwest::Url::parse(&format!("{}/accounts/{}", BASE_URL, id)).map_err(error::Error::UrlParse)?;
173
174 let res = reqwest::Client::new()
175 .get(url)
176 .header("Authorization", self.auth_header())
177 .send()
178 .await
179 .map_err(error::Error::Request)?;
180
181 match res.status() {
182 reqwest::StatusCode::OK => {
183 let body = res.text().await.map_err(error::Error::BodyRead)?;
184 let account_response : GetAccountResponse = serde_json::from_str(&body).map_err(error::Error::Json)?;
185
186 Ok(account_response)
187 },
188 _ => {
189 let body = res.text().await.map_err(error::Error::BodyRead)?;
190 let error : error::ErrorResponse = serde_json::from_str(&body).map_err(error::Error::Json)?;
191
192 Err(error::Error::Api(error))
193 }
194 }
195 }
196}
197
198implement_pagination_v1!(ListAccountsResponse);