use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
mod list;
pub use list::Request as List;
mod get;
pub use get::Request as Get;
#[derive(Deserialize, Debug)]
pub struct Transaction {
account_balance: i64,
account_id: String,
amount: i64,
amount_is_pending: bool,
can_add_to_tab: bool,
can_be_excluded_from_breakdown: bool,
can_be_made_subscription: bool,
can_split_the_bill: bool,
category: Category,
created: DateTime<Utc>,
currency: String,
description: String,
id: String,
include_in_spending: bool,
merchant: Option<MerchantInfo>,
metadata: HashMap<String, String>,
notes: String,
decline_reason: Option<DeclineReason>,
is_load: bool,
#[serde(deserialize_with = "empty_string_as_none")]
settled: Option<DateTime<Utc>>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum DeclineReason {
InsufficientFunds,
CardInactive,
CardBlocked,
InvalidCvc,
Other,
}
#[derive(Deserialize, Debug)]
#[non_exhaustive]
#[serde(rename_all = "snake_case")]
pub enum Category {
General,
EatingOut,
Expenses,
Transport,
Cash,
Bills,
Entertainment,
Shopping,
Holidays,
Groceries,
}
#[derive(Deserialize, Debug)]
#[serde(untagged)]
pub enum MerchantInfo {
Id(String),
Details(Box<Merchant>),
}
#[derive(Deserialize, Debug)]
pub struct Merchant {
address: Address,
created: DateTime<Utc>,
group_id: String,
id: String,
logo: String,
emoji: String,
name: String,
category: Category,
}
#[derive(Deserialize, Debug)]
pub struct Address {
address: String,
city: String,
country: String,
latitude: f32,
longitude: f32,
postcode: String,
region: String,
}
use serde::de::IntoDeserializer;
fn empty_string_as_none<'de, D, T>(de: D) -> Result<Option<T>, D::Error>
where
D: serde::Deserializer<'de>,
T: serde::Deserialize<'de>,
{
let opt = Option::<String>::deserialize(de)?;
let opt = opt.as_deref();
match opt {
None | Some("") => Ok(None),
Some(s) => T::deserialize(s.into_deserializer()).map(Some),
}
}
#[derive(Serialize, Default)]
struct Pagination {
#[serde(skip_serializing_if = "Option::is_none")]
limit: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
since: Option<Since>,
#[serde(skip_serializing_if = "Option::is_none")]
before: Option<DateTime<Utc>>,
}
#[derive(Serialize)]
#[serde(untagged)]
pub enum Since {
Timestamp(DateTime<Utc>),
ObjectId(String),
}