Skip to main content

monzo/endpoints/transactions/
list.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4use super::{Pagination, Since, Transaction};
5use crate::{client, endpoints::Endpoint, Result};
6
7/// A request to retrieve a list of transactions from the Monzo API
8///
9/// Use the builder-style methods to set optional fields on the request
10#[derive(Debug)]
11#[must_use]
12pub struct Request<'a, C>
13where
14    C: client::Inner,
15{
16    client: &'a C,
17    query: Query<'a>,
18}
19
20impl<C> Endpoint for Request<'_, C>
21where
22    C: client::Inner,
23{
24    const METHOD: reqwest::Method = reqwest::Method::GET;
25
26    fn endpoint(&self) -> &'static str {
27        "/transactions"
28    }
29
30    fn query(&self) -> Option<&dyn erased_serde::Serialize> {
31        Some(&self.query)
32    }
33}
34
35impl<'a, C> Request<'a, C>
36where
37    C: client::Inner,
38{
39    pub(crate) fn new(client: &'a C, account_id: &'a str) -> Self {
40        let query = Query {
41            account_id,
42            pagination: Pagination::default(),
43            expand_merchant: None,
44        };
45
46        Self { client, query }
47    }
48
49    /// Only return transactions which occurred after the given `DateTime`
50    pub fn since(mut self, datetime: DateTime<Utc>) -> Self {
51        self.query.pagination.since = Some(Since::Timestamp(datetime));
52        self
53    }
54
55    /// Only return transactions which occurred after the given transaction.
56    ///
57    /// This can be used for paginating.
58    pub fn since_transaction(mut self, transaction_id: String) -> Self {
59        self.query.pagination.since = Some(Since::ObjectId(transaction_id));
60        self
61    }
62
63    /// Only return transactions which occurred before a given `DateTime`
64    pub const fn before(mut self, datetime: DateTime<Utc>) -> Self {
65        self.query.pagination.before = Some(datetime);
66        self
67    }
68
69    /// Set the maximum number of transactions to be returned
70    pub const fn limit(mut self, limit: u16) -> Self {
71        self.query.pagination.limit = Some(limit);
72        self
73    }
74
75    /// Optionally expand the merchant field from an id string into a struct
76    /// container merchant details
77    pub const fn expand_merchant(mut self) -> Self {
78        self.query.expand_merchant = Some("merchant");
79        self
80    }
81
82    /// Consume the request and return the list of [`Transaction`]s
83    pub async fn send(self) -> Result<Vec<Transaction>> {
84        #[derive(Deserialize)]
85        struct Response {
86            transactions: Vec<Transaction>,
87        }
88
89        let response: Response = self.client.handle_request(&self).await?;
90
91        Ok(response.transactions)
92    }
93}
94
95#[derive(Serialize, Debug)]
96struct Query<'a> {
97    account_id: &'a str,
98
99    #[serde(flatten)]
100    pagination: Pagination,
101
102    #[serde(skip_serializing_if = "Option::is_none")]
103    #[serde(rename = "expand[]")]
104    expand_merchant: Option<&'a str>,
105}
106
107#[derive(Deserialize, Debug)]
108pub struct Response {
109    transactions: Vec<Transaction>,
110}
111
112impl From<Response> for Vec<Transaction> {
113    fn from(response: Response) -> Self {
114        response.transactions
115    }
116}