use chrono::{DateTime, Utc};
use serde::Deserialize;
#[derive(Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
#[non_exhaustive]
pub struct Account {
pub id: String,
#[serde(flatten)]
pub account_type: Type,
pub closed: bool,
pub created: DateTime<Utc>,
pub description: String,
pub currency: String,
pub country_code: String,
pub owners: Vec<Owner>,
pub business_id: Option<String>,
}
#[derive(Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub struct Owner {
pub user_id: String,
pub preferred_name: String,
pub preferred_first_name: String,
}
#[derive(Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
#[serde(tag = "type", rename_all = "snake_case")]
#[non_exhaustive]
pub enum Type {
UkRetail(AccountDetails),
UkRetailJoint(AccountDetails),
UkBusiness(AccountDetails),
UkRewards,
UkMonzoFlex,
UkLoan,
}
#[derive(Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub struct AccountDetails {
pub account_number: String,
pub sort_code: String,
}
pub(crate) use list::Request as List;
mod list {
use crate::endpoints::Endpoint;
pub struct Request;
impl Endpoint for Request {
const METHOD: reqwest::Method = reqwest::Method::GET;
fn endpoint(&self) -> &'static str {
"/accounts"
}
}
}
#[cfg(test)]
mod tests {
use test_case::test_case;
use super::Account;
#[test_case(
r#"
{
"id": "acc_00009",
"closed": false,
"created": "2021-06-12T00:00:00.000Z",
"description": "user_00009",
"type": "uk_retail",
"owner_type": "personal",
"is_flex": false,
"product_type": "standard",
"closed_account_app_access": false,
"currency": "GBP",
"legal_entity": "monzo_uk",
"country_code": "GB",
"country_code_alpha3": "GBR",
"owners": [
{
"user_id": "user_0000",
"preferred_name": "First Last",
"preferred_first_name": "First"
}
],
"account_number": "12345678",
"sort_code": "040004",
"payment_details": {
"locale_uk": {
"account_number": "12345678",
"sort_code": "040004"
},
"iban": {
"unformatted": "GB90MONZXXXXXXXXXXX",
"formatted": "GB90MONZXXXXXXXXXXXXX",
"bic": "MONZGB2L",
"usage_description": "Receive international payments in over 40 currencies. We charge a currency conversion fee. [Learn more...](monzo://backend_screen?id=international-payment-views:bank-transfer-info&instance_params_id=acc_00009jmHyLkxAPVUSe8H45)",
"usage_description_web": "Receive international payments in over 40 currencies. We charge a currency conversion fee."
}
},
"monzo_branch_address_formatted": "Monzo Bank, Broadwalk House, 5 Appold St, London EC2A 2AG, United Kingdom",
"assets": {
"image_url": "https://public-images.monzo.com/card_styles/account_icon/personal@3x.png"
}
}
"#
; "uk_retail"
)]
#[test_case(
r#"{
"id": "acc_ID",
"closed": false,
"created": "2024-01-20T00:00:00.000Z",
"description": "rewardsoptin_0000",
"type": "uk_rewards",
"owner_type": "personal",
"is_flex": false,
"product_type": "rewards",
"closed_account_app_access": false,
"currency": "GBP",
"legal_entity": "monzo_uk",
"country_code": "GB",
"country_code_alpha3": "GBR",
"owners": [
{
"user_id": "user_0000",
"preferred_name": "First Last",
"preferred_first_name": "First"
}
]
}"#
; "uk_rewards"
)]
#[test_case(
r#"{
"id": "acc_0000",
"closed": false,
"created": "2024-01-01T00:00:00.000Z",
"description": "monzoflex_0000",
"type": "uk_monzo_flex",
"owner_type": "personal",
"is_flex": true,
"product_type": "flex",
"closed_account_app_access": false,
"currency": "GBP",
"legal_entity": "monzo_uk",
"country_code": "GB",
"country_code_alpha3": "GBR",
"owners": [
{
"user_id": "user_0000",
"preferred_name": "First Last",
"preferred_first_name": "First"
}
],
"assets": {
"image_url": "https://public-images.monzo.com/card_styles/account_icon/flex@3x.png"
}
}"#
; "uk_monzo_flex"
)]
#[test_case(
r#"{
"id": "acc_0000",
"closed": false,
"created": "2024-01-01T00:00:00.000Z",
"description": "loan_0000",
"type": "uk_loan",
"owner_type": "unknown",
"is_flex": false,
"product_type": "loan",
"closed_account_app_access": false,
"currency": "GBP",
"legal_entity": "monzo_uk",
"country_code": "GB",
"country_code_alpha3": "GBR",
"owners": [
{
"user_id": "user_0000",
"preferred_name": "First Last",
"preferred_first_name": "First"
}
]
}"#
; "uk_loan"
)]
fn parse_account(json_data: &str) {
let _account: Account = serde_json::from_str(json_data).unwrap();
}
}