invoist/lib.rs
1//! The official Rust client for the [Invoist API](https://invoi.st/docs):
2//! turn invoices into structured data, read a household's bills, and verify
3//! the webhooks Invoist sends.
4//!
5//! # A business workspace
6//!
7//! ```no_run
8//! # async fn run() -> Result<(), invoist::Error> {
9//! use invoist::{Client, UploadFile, WaitOptions};
10//!
11//! let client = Client::from_env()?; // INVOIST_API_KEY
12//! let file = UploadFile::from_path_async("invoice.pdf").await.expect("readable file");
13//! let done = client.extract_and_wait(file, WaitOptions::default()).await?;
14//! println!("{:?} owes {:?} cents", done.extraction.vendor_name, done.extraction.total_cents);
15//! # Ok(())
16//! # }
17//! ```
18//!
19//! # A household
20//!
21//! ```no_run
22//! # async fn run() -> Result<(), invoist::Error> {
23//! use invoist::{Client, ListBillsParams};
24//!
25//! let client = Client::from_env()?;
26//! let unpaid = client
27//! .bills()
28//! .list(ListBillsParams { paid: Some(false), ..Default::default() })
29//! .await?;
30//! for bill in unpaid {
31//! println!("{:?}: {:?} due {:?}", bill.vendor_name, bill.total_cents, bill.due_date);
32//! }
33//! # Ok(())
34//! # }
35//! ```
36//!
37//! # Errors, retries, cancellation
38//!
39//! Every failure is an [`Error`] with an HTTP [`status`](Error::status) (0 when
40//! no response arrived), a stable [`code`](Error::code), and the response's
41//! [`request_id`](Error::request_id). Failures worth retrying (no response,
42//! 429, 5xx) are retried up to twice, honouring `Retry-After` (a wait above
43//! 60 seconds fails at once instead), otherwise
44//! backing off from 500ms with jitter. Dropping a call's future cancels it.
45//!
46//! # Features
47//!
48//! * `rustls-tls` (default): TLS through rustls. No OpenSSL.
49//! * `native-tls`: TLS through the platform's library instead.
50//! * `http2`: HTTP/2 when the server offers it.
51//! * `blocking`: [`blocking::Client`], for code without an async runtime.
52//!
53//! Money is always an `i64` in minor units (cents), never a float.
54
55#![cfg_attr(docsrs, feature(doc_cfg))]
56
57mod macros;
58pub(crate) use macros::string_enum;
59
60mod bills;
61mod client;
62pub mod error;
63mod files;
64pub mod models;
65mod month;
66mod params;
67mod retry;
68pub mod webhooks;
69
70#[cfg(feature = "blocking")]
71#[cfg_attr(docsrs, doc(cfg(feature = "blocking")))]
72pub mod blocking;
73
74pub use bills::{Bills, HeldEmails};
75pub use client::{
76 Client, ClientBuilder, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT,
77 ExtractedDocument,
78};
79pub use error::{Error, Result};
80pub use files::{FileDownload, UploadFile};
81pub use month::Month;
82pub use params::{
83 BillsStatsParams, BillsSummaryParams, CreateWebhookEndpoint, ExtractOptions, ListBillsParams,
84 ListDocumentsParams, ListReviewQueueParams, ReviewResolution, WaitOptions,
85};
86
87/// The `bytes` crate, whose `Bytes` holds uploads and downloads.
88pub use bytes;
89/// The `reqwest` crate this client is built on, to build a custom
90/// [`reqwest::Client`] for [`ClientBuilder::http_client`] with the same
91/// version.
92pub use reqwest;
93
94/// The `User-Agent` every request sends.
95pub const USER_AGENT: &str = client::USER_AGENT;
96
97#[cfg(doctest)]
98#[doc = include_str!("../README.md")]
99struct ReadmeDoctests;