adrs_core/error.rs
1//! Error types for adrs-core.
2
3use std::path::PathBuf;
4
5/// Result type alias using the library's error type.
6pub type Result<T> = std::result::Result<T, Error>;
7
8/// Errors that can occur when working with ADRs.
9#[derive(Debug, thiserror::Error)]
10pub enum Error {
11 /// The ADR directory was not found.
12 #[error("ADR directory not found. Run 'adrs init' to create one.")]
13 AdrDirNotFound,
14
15 /// The ADR directory already exists.
16 #[error("ADR directory already exists: {0}")]
17 AdrDirExists(PathBuf),
18
19 /// An ADR was not found.
20 #[error("ADR not found: {0}")]
21 AdrNotFound(String),
22
23 /// Multiple ADRs matched a query.
24 #[error("Multiple ADRs match '{query}': {matches:?}")]
25 AmbiguousAdr {
26 /// The query string that matched more than one ADR.
27 query: String,
28 /// Human-readable identifiers of the ADRs that matched.
29 matches: Vec<String>,
30 },
31
32 /// Invalid ADR number.
33 #[error("Invalid ADR number: {0}")]
34 InvalidNumber(String),
35
36 /// Invalid ADR format (parsing failed).
37 #[error("Invalid ADR format in {path}: {reason}")]
38 InvalidFormat {
39 /// Path to the ADR file that failed to parse.
40 path: PathBuf,
41 /// Why parsing failed.
42 reason: String,
43 },
44
45 /// Missing required field in ADR.
46 #[error("Missing required field '{field}' in {path}")]
47 MissingField {
48 /// Path to the ADR file missing the field.
49 path: PathBuf,
50 /// Name of the required field that was missing.
51 field: String,
52 },
53
54 /// Invalid status value.
55 #[error("Invalid status: {0}")]
56 InvalidStatus(String),
57
58 /// Invalid link format.
59 #[error("Invalid link format: {0}")]
60 InvalidLink(String),
61
62 /// `Repository::renumber`'s `from` number matched more than one record
63 /// and no `--file` was given to disambiguate.
64 #[error(
65 "ADR {number} is ambiguous: {} records are numbered {number} ({candidates:?}). Use --file <path> to select one.",
66 candidates.len()
67 )]
68 AmbiguousRenumberSource {
69 /// The ambiguous source number.
70 number: u32,
71 /// Paths of every record numbered `number`.
72 candidates: Vec<String>,
73 },
74
75 /// `Repository::renumber`'s `--file` did not match any record numbered `from`.
76 #[error("{file} does not match any ADR numbered {number}. Candidates: {candidates:?}")]
77 RenumberFileMismatch {
78 /// The source number `--file` was expected to disambiguate.
79 number: u32,
80 /// The `--file` path given.
81 file: PathBuf,
82 /// Paths of every record numbered `number`.
83 candidates: Vec<String>,
84 },
85
86 /// `Repository::renumber`'s `to` number is already used by another record.
87 #[error(
88 "ADR {to} is already used by '{occupant_title}' ({occupant_path}); try {suggestion} instead"
89 )]
90 RenumberTargetOccupied {
91 /// The requested destination number.
92 to: u32,
93 /// Title of the record currently occupying `to`.
94 occupant_title: String,
95 /// Path of the record currently occupying `to`.
96 occupant_path: PathBuf,
97 /// The smallest free number, offered as a suggestion.
98 suggestion: u32,
99 },
100
101 /// Template not found.
102 #[error("Template not found: {0}")]
103 TemplateNotFound(String),
104
105 /// Template rendering error.
106 #[error("Template error: {0}")]
107 TemplateError(String),
108
109 /// Configuration error.
110 #[error("Configuration error: {0}")]
111 ConfigError(String),
112
113 /// I/O error.
114 #[error("I/O error: {0}")]
115 Io(#[from] std::io::Error),
116
117 /// YAML parsing error.
118 #[error("YAML error: {0}")]
119 Yaml(#[from] serde_yaml_neo::Error),
120
121 /// TOML parsing error.
122 #[error("TOML error: {0}")]
123 Toml(#[from] toml::de::Error),
124}