rusty_ts/error.rs
1//! Library error type for `rusty-ts`.
2//!
3//! Per AD-009: library errors are typed via `thiserror`; the binary boundary
4//! (`src/main.rs`) wraps these in `anyhow` for human-readable diagnostics.
5//!
6//! All public variants carry actionable context (offending input, source
7//! error) rather than opaque strings. The enum is `#[non_exhaustive]` so new
8//! variants can be added in minor versions without breaking semver per the
9//! pre-1.0 evolution rules documented in `plan.md` §API Surface Summary.
10
11use std::io;
12
13/// Errors raised by the `rusty-ts` library API.
14///
15/// Marked `#[non_exhaustive]` to allow new variants in minor releases.
16///
17/// # Example
18///
19/// ```
20/// use rusty_ts::{Error, TimestamperBuilder};
21///
22/// // Pattern-match on specific variants for actionable handling.
23/// let result = TimestamperBuilder::new()
24/// .utc(true)
25/// .tz_name("Asia/Tokyo")
26/// .build();
27///
28/// match result {
29/// Err(Error::InvalidUtcWithNamedTz { tz }) => {
30/// eprintln!("cannot combine -u with --tz={tz}");
31/// }
32/// Err(Error::InvalidIanaName(name)) => {
33/// eprintln!("unknown IANA timezone: {name}");
34/// }
35/// Err(other) => eprintln!("error: {other}"),
36/// Ok(_) => unreachable!("we configured a conflict"),
37/// }
38/// ```
39#[non_exhaustive]
40#[derive(Debug, thiserror::Error)]
41pub enum Error {
42 /// `-u` (UTC) and `--tz=<name>` were both specified, which is invalid.
43 /// Mirrors the CLI-layer `FR-020` mutual-exclusion check at the library
44 /// layer so library consumers do not depend on the CLI to catch it.
45 #[error("--utc and --tz=<name> are mutually exclusive; got --tz={tz}")]
46 InvalidUtcWithNamedTz {
47 /// The IANA name the caller supplied.
48 tz: String,
49 },
50
51 /// The named IANA timezone could not be resolved (e.g., typo, removed
52 /// zone). Carries the offending input.
53 #[error("unknown IANA timezone: {0}")]
54 InvalidIanaName(String),
55
56 /// The strftime format string is malformed or unsupported. Carries the
57 /// offending format string.
58 #[error("invalid strftime format: {0}")]
59 InvalidFormat(String),
60
61 /// Underlying IO error, surfaced from `BufRead`/`Write` operations.
62 #[error("io error: {0}")]
63 Io(#[from] io::Error),
64}