org_gdocs/error.rs
1//! Typed error surface for the `org-gdocs` library.
2//!
3//! Every distinct failure a caller might branch on is its own variant. `anyhow`
4//! is confined to the binary edge and never appears here.
5
6use std::path::PathBuf;
7
8/// Errors raised by `org-gdocs` library code.
9#[derive(Debug, thiserror::Error)]
10pub enum Error {
11 /// A filesystem operation failed for the given path.
12 #[error("I/O error at {path}: {source}")]
13 Io {
14 /// Path the failing operation targeted.
15 path: PathBuf,
16 /// Underlying I/O error.
17 source: std::io::Error,
18 },
19
20 /// The configuration file could not be parsed as TOML.
21 #[error("invalid TOML configuration: {0}")]
22 ConfigToml(#[from] toml::de::Error),
23
24 /// The configuration could not be serialized to TOML.
25 #[error("could not serialize TOML configuration: {0}")]
26 ConfigTomlSerialize(#[from] toml::ser::Error),
27
28 /// A JSON value could not be (de)serialized.
29 ///
30 /// JSON is confined to the forced external boundaries (the Google API wire
31 /// format and OAuth credential/token files, OVR-1/A5); surfaces this crate
32 /// owns use s-expressions and surface [`Error::Sexp`] instead.
33 #[error("JSON error: {0}")]
34 Json(#[from] serde_json::Error),
35
36 /// An s-expression (the `** Sync State` block or the CLI↔Emacs envelope, A5)
37 /// could not be parsed or did not match the expected shape.
38 #[error("s-expression error: {0}")]
39 Sexp(#[from] crate::sexp::SexpError),
40
41 /// A Google Docs or Drive API call failed — transport, protocol, or a
42 /// non-success API response.
43 ///
44 /// The generated client's error type is mapped to its display string at the
45 /// single seam in [`crate::google::client`] (F6) so it never leaks into this
46 /// crate's public surface (EI-1).
47 #[error("Google API error: {0}")]
48 Google(String),
49
50 /// The target document exposes more than one tab, which is unsupported.
51 ///
52 /// We operate only on the first/legacy tab (DI-6); a multi-tab document is
53 /// reported rather than silently mis-indexed.
54 #[error("document has multiple tabs, which is unsupported (operate on a single-tab document)")]
55 MultipleTabs,
56
57 /// The org body could not be parsed by `tftio-kb`.
58 #[error("could not parse org body: {0}")]
59 OrgParse(String),
60
61 /// The org file has no linked Google Doc (`#+GDOC_ID:`).
62 ///
63 /// `pull`, `clean`, and `open` all require a document to have been created by
64 /// a prior `push`; this is the branchable failure they surface when it has not.
65 #[error("org file has no linked Google Doc (#+GDOC_ID:); run `push` first")]
66 NotLinked,
67
68 /// A required path could not be resolved (e.g. no home/config directory).
69 #[error("could not resolve {0}")]
70 PathResolution(String),
71
72 /// OAuth authentication, token acquisition, or TLS setup failed.
73 #[error("authentication error: {0}")]
74 Auth(String),
75}
76
77/// Convenience result alias for fallible `org-gdocs` library functions.
78pub type Result<T> = std::result::Result<T, Error>;