1use std::path::PathBuf;
2
3pub type Result<T> = std::result::Result<T, Error>;
4
5#[derive(Debug, thiserror::Error)]
6pub enum Error {
7 #[error("not initialized: no `.bears` directory found")]
8 NotInitialized,
9
10 #[error("task not found: {0}")]
11 TaskNotFound(String),
12
13 #[error("ambiguous prefix '{prefix}' matches multiple tasks: {matches}")]
14 AmbiguousPrefix { prefix: String, matches: String },
15
16 #[error("task {0} is not an epic — plans can only be generated for epics")]
17 NotAnEpic(String),
18
19 #[error("parent {0} is not an epic — only epics can have child tasks")]
20 ParentNotEpic(String),
21
22 #[error("adding dependency would create a cycle: {from} -> {to}")]
23 CycleDetected { from: String, to: String },
24
25 #[error("unknown dependency ID(s): {}", ids.join(", "))]
26 UnknownDependency { ids: Vec<String> },
27
28 #[error("invalid config: {reason}")]
29 InvalidConfig { reason: String },
30
31 #[error("{0}")]
32 InvalidUsage(String),
33
34 #[error("invalid frontmatter in {path}: {reason}")]
35 InvalidFrontmatter { path: PathBuf, reason: String },
36
37 #[error("editor failed: {reason}")]
38 EditorFailed { reason: String },
39
40 #[error("task {id} is not archivable — active dependents: {}", blockers.join(", "))]
42 NotArchivable { id: String, blockers: Vec<String> },
43
44 #[error("task not found in archive: {0}")]
46 NotArchived(String),
47
48 #[error(transparent)]
49 Io(#[from] std::io::Error),
50
51 #[error(transparent)]
52 Yaml(#[from] serde_yml::Error),
53
54 #[error(transparent)]
55 Json(#[from] serde_json::Error),
56}