use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use super::{Pagination, Since, Transaction};
use crate::{client, endpoints::Endpoint, Result};
#[derive(Debug)]
#[must_use]
pub struct Request<'a, C>
where
C: client::Inner,
{
client: &'a C,
query: Query<'a>,
}
impl<C> Endpoint for Request<'_, C>
where
C: client::Inner,
{
const METHOD: reqwest::Method = reqwest::Method::GET;
fn endpoint(&self) -> &'static str {
"/transactions"
}
fn query(&self) -> Option<&dyn erased_serde::Serialize> {
Some(&self.query)
}
}
impl<'a, C> Request<'a, C>
where
C: client::Inner,
{
pub(crate) fn new(client: &'a C, account_id: &'a str) -> Self {
let query = Query {
account_id,
pagination: Pagination::default(),
expand_merchant: None,
};
Self { client, query }
}
pub fn since(mut self, datetime: DateTime<Utc>) -> Self {
self.query.pagination.since = Some(Since::Timestamp(datetime));
self
}
pub fn since_transaction(mut self, transaction_id: String) -> Self {
self.query.pagination.since = Some(Since::ObjectId(transaction_id));
self
}
pub const fn before(mut self, datetime: DateTime<Utc>) -> Self {
self.query.pagination.before = Some(datetime);
self
}
pub const fn limit(mut self, limit: u16) -> Self {
self.query.pagination.limit = Some(limit);
self
}
pub const fn expand_merchant(mut self) -> Self {
self.query.expand_merchant = Some("merchant");
self
}
pub async fn send(self) -> Result<Vec<Transaction>> {
#[derive(Deserialize)]
struct Response {
transactions: Vec<Transaction>,
}
let response: Response = self.client.handle_request(&self).await?;
Ok(response.transactions)
}
}
#[derive(Serialize, Debug)]
struct Query<'a> {
account_id: &'a str,
#[serde(flatten)]
pagination: Pagination,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "expand[]")]
expand_merchant: Option<&'a str>,
}
#[derive(Deserialize, Debug)]
pub struct Response {
transactions: Vec<Transaction>,
}
impl From<Response> for Vec<Transaction> {
fn from(response: Response) -> Self {
response.transactions
}
}