use reqwest::Method;
use serde::Deserialize;
use crate::client::{Client, Request};
use crate::error::Result;
use crate::files::FileDownload;
use crate::models::{Bill, BillDetail, BillRecord, BillsStats, BillsSummary, HeldEmail};
use crate::params::{BillsStatsParams, BillsSummaryParams, ListBillsParams};
#[derive(Debug, Clone, Copy)]
pub struct Bills<'a> {
client: &'a Client,
}
#[derive(Debug, Clone, Copy)]
pub struct HeldEmails<'a> {
client: &'a Client,
}
impl Client {
pub fn bills(&self) -> Bills<'_> {
Bills { client: self }
}
pub fn held_emails(&self) -> HeldEmails<'_> {
HeldEmails { client: self }
}
}
#[derive(Deserialize)]
struct RecordAnswer {
bill: BillRecord,
}
impl Bills<'_> {
pub async fn list(&self, params: ListBillsParams) -> Result<Vec<Bill>> {
#[derive(Deserialize)]
struct Page {
bills: Vec<Bill>,
}
let req = Request::get(&["v1", "bills"])?.query(params.query());
Ok(self.client.json::<Page>(req).await?.bills)
}
pub async fn get(&self, id: &str) -> Result<BillDetail> {
self.client.json(Request::get(&["v1", "bills", id])?).await
}
pub async fn get_file(&self, id: &str) -> Result<FileDownload> {
self.client
.download(Request::get(&["v1", "bills", id, "file"])?)
.await
}
pub async fn summary(&self, params: BillsSummaryParams) -> Result<BillsSummary> {
let req = Request::get(&["v1", "bills", "summary"])?.query(params.query());
self.client.json(req).await
}
pub async fn stats(&self, params: BillsStatsParams) -> Result<BillsStats> {
let req = Request::get(&["v1", "bills", "stats"])?.query(params.query());
self.client.json(req).await
}
pub async fn mark_paid(&self, id: &str) -> Result<BillRecord> {
let req = Request::new(Method::POST, &["v1", "bills", id, "paid"])?;
Ok(self.client.json::<RecordAnswer>(req).await?.bill)
}
pub async fn mark_unpaid(&self, id: &str) -> Result<BillRecord> {
let req = Request::new(Method::DELETE, &["v1", "bills", id, "paid"])?;
Ok(self.client.json::<RecordAnswer>(req).await?.bill)
}
}
impl HeldEmails<'_> {
pub async fn list(&self) -> Result<Vec<HeldEmail>> {
#[derive(Deserialize)]
struct Page {
held_emails: Vec<HeldEmail>,
}
let req = Request::get(&["v1", "held-emails"])?;
Ok(self.client.json::<Page>(req).await?.held_emails)
}
}