Skip to main content

harn_cli/package/
errors.rs

1//! Typed error enum for the `package` module.
2//!
3//! Variants carry the exact user-facing message via `Display`, keeping CLI
4//! output byte-for-byte identical to the previous `Result<T, String>` API
5//! while letting library callers pattern-match on the error category.
6
7use std::result::Result as StdResult;
8
9#[derive(Debug, thiserror::Error)]
10pub enum PackageError {
11    #[error("{0}")]
12    Manifest(String),
13    #[error("{0}")]
14    Lockfile(String),
15    #[error("{0}")]
16    Registry(String),
17    #[error("{0}")]
18    Validation(String),
19    #[error("{0}")]
20    Ops(String),
21    #[error("{0}")]
22    Extensions(String),
23    #[error("{0}")]
24    Skill(String),
25    /// Generic message captured during the migration from
26    /// `Result<T, String>`. New code should prefer one of the categorical
27    /// variants above; this exists so legacy `format!(...)` strings can
28    /// flow through `?` without losing their wording.
29    #[error("{0}")]
30    Other(String),
31}
32
33impl PackageError {
34    pub fn message(&self) -> &str {
35        match self {
36            PackageError::Manifest(s)
37            | PackageError::Lockfile(s)
38            | PackageError::Registry(s)
39            | PackageError::Validation(s)
40            | PackageError::Ops(s)
41            | PackageError::Extensions(s)
42            | PackageError::Skill(s)
43            | PackageError::Other(s) => s.as_str(),
44        }
45    }
46}
47
48impl From<String> for PackageError {
49    fn from(value: String) -> Self {
50        PackageError::Other(value)
51    }
52}
53
54impl From<&str> for PackageError {
55    fn from(value: &str) -> Self {
56        PackageError::Other(value.to_string())
57    }
58}
59
60/// Migration bridge: lets callers that still return `Result<T, String>`
61/// receive a `PackageError` via `?` without losing the user-facing
62/// message. Once all CLI command modules adopt typed errors this can be
63/// removed.
64impl From<PackageError> for String {
65    fn from(error: PackageError) -> Self {
66        error.to_string()
67    }
68}
69
70#[allow(dead_code)]
71pub type PackageResult<T> = StdResult<T, PackageError>;