1use std::path::PathBuf;
7
8#[derive(Debug, thiserror::Error)]
10pub enum Error {
11 #[error(
12 "Pack not found: {0}\n\nHint: Use 'mai list' to see installed packs, or 'mai install {0}' to install it."
13 )]
14 PackNotFound(String),
15
16 #[error(
17 "Tool not found: {0}\n\nAvailable tools: claude, cursor, windsurf\nHint: Use 'mai use <tool>' to switch tools."
18 )]
19 ToolNotFound(String),
20
21 #[error(
22 "Version conflict: {0}\n\nHint: Try specifying an explicit version or run 'mai update' to resolve conflicts."
23 )]
24 VersionConflict(String),
25
26 #[error(
27 "IO error: {0}\n\nContext: Failed to perform file operation. Check permissions and disk space."
28 )]
29 Io(#[from] std::io::Error),
30
31 #[error("Parse error: {0}\n\nHint: Check the syntax and ensure the file format is valid.")]
32 Parse(String),
33
34 #[error("Registry error: {0}")]
35 Registry(String),
36
37 #[error("Project error: {0}\n\nHint: Run 'mai project init' to create a new project manifest.")]
38 Project(String),
39
40 #[error("Lock file error: {0}\n\nHint: Run 'mai project sync' to regenerate the lock file.")]
41 LockFile(String),
42
43 #[error(
44 "Network error: {0}\n\nContext: Failed to fetch remote resource. Check your internet connection."
45 )]
46 Network(String),
47
48 #[error("TOML error: {0}\n\nContext: Failed to parse or serialize TOML configuration.")]
49 Toml(#[from] toml::de::Error),
50
51 #[error("TOML serialization error: {0}\n\nContext: Failed to serialize TOML configuration.")]
52 TomlSerialize(#[from] toml::ser::Error),
53
54 #[error("Version error: {0}")]
55 Version(String),
56
57 #[error("Config error: {0}")]
58 Config(String),
59
60 #[error("Path error: {0}")]
61 Path(PathBuf),
62}
63
64pub type Result<T, E = Error> = std::result::Result<T, E>;
66
67impl Error {
68 #[allow(dead_code)]
69 pub fn pack_not_found(pack: impl Into<String>) -> Self {
70 Error::PackNotFound(pack.into())
71 }
72
73 #[allow(dead_code)]
74 pub fn tool_not_found(tool: impl Into<String>) -> Self {
75 Error::ToolNotFound(tool.into())
76 }
77
78 #[allow(dead_code)]
79 pub fn version_conflict(msg: impl Into<String>) -> Self {
80 Error::VersionConflict(msg.into())
81 }
82
83 #[allow(dead_code)]
84 pub fn registry_error(msg: impl Into<String>) -> Self {
85 Error::Registry(msg.into())
86 }
87
88 #[allow(dead_code)]
89 pub fn project_error(msg: impl Into<String>) -> Self {
90 Error::Project(msg.into())
91 }
92
93 #[allow(dead_code)]
94 pub fn lock_file_error(msg: impl Into<String>) -> Self {
95 Error::LockFile(msg.into())
96 }
97
98 #[allow(dead_code)]
99 pub fn network_error(msg: impl Into<String>) -> Self {
100 Error::Network(msg.into())
101 }
102
103 #[allow(dead_code)]
104 pub fn parse_error(msg: impl Into<String>) -> Self {
105 Error::Parse(msg.into())
106 }
107
108 #[allow(dead_code)]
109 pub fn version_error(msg: impl Into<String>) -> Self {
110 Error::Version(msg.into())
111 }
112
113 #[allow(dead_code)]
114 pub fn config_error(msg: impl Into<String>) -> Self {
115 Error::Config(msg.into())
116 }
117
118 #[allow(dead_code)]
119 pub fn path_error(path: PathBuf) -> Self {
120 Error::Path(path)
121 }
122}