pidge_client/lib.rs
1//! Microsoft 365 client and OAuth flows for the pidge CLI.
2//!
3//! Provides `AuthClient` (sign-in, refresh, token retrieval) and `GraphClient`
4//! (Microsoft Graph API access). Depends on `pidge-core` for types.
5
6pub mod auth;
7mod error;
8pub mod graph;
9pub mod mcp;
10#[cfg(test)]
11pub(crate) mod test_support;
12pub mod unsubscribe;
13
14pub use auth::AuthClient;
15pub use error::ClientError;
16pub use graph::{GraphClient, MailFolder, Outgoing};
17pub use unsubscribe::{UnsubscribeMethod, mailto_subject, parse_unsubscribe};
18
19pub mod cursor;
20
21pub use cursor::{Cursor, CursorError};
22
23/// Resolve the base directory pidge's config-dir-rooted stores (Microsoft
24/// tokens in `auth::file_store`, MCP tokens in `mcp::store`) live under.
25///
26/// In tests, honors a thread-local override set via
27/// [`test_support::with_base_dir`] so tests never mutate process-wide
28/// `HOME`/`XDG_CONFIG_HOME` env vars: two independent stores' tests
29/// overriding those globally, each behind its own lock, can still race
30/// across threads in the same test binary. A thread-local sidesteps that
31/// entirely: it's invisible to every thread but the one that set it, so
32/// parallel `#[test]` functions never interfere and no lock is needed.
33///
34/// In production this is always `dirs::config_dir()`.
35pub(crate) fn base_config_dir() -> Result<std::path::PathBuf, ClientError> {
36 #[cfg(test)]
37 if let Some(base) = test_support::base_dir_override() {
38 return Ok(base);
39 }
40 dirs::config_dir().ok_or(ClientError::NoConfigDir)
41}