1use miette::Diagnostic;
2use std::path::PathBuf;
3use thiserror::Error;
4
5#[derive(Error, Debug, Diagnostic)]
6pub enum SizelintError {
7 #[error(transparent)]
8 #[diagnostic(transparent)]
9 Git(#[from] crate::git::GitError),
10
11 #[error("Failed to read config file {path}")]
12 #[diagnostic(
13 code(sizelint::config::read_error),
14 help("Check that the file exists and you have read permissions")
15 )]
16 ConfigRead {
17 path: PathBuf,
18 #[source]
19 source: std::io::Error,
20 },
21
22 #[error("Failed to parse config file {path}")]
23 #[diagnostic(
24 code(sizelint::config::parse_error),
25 help("Check your TOML syntax - visit https://toml.io for format documentation")
26 )]
27 ConfigParse {
28 path: PathBuf,
29 #[source]
30 source: toml::de::Error,
31 },
32
33 #[error("Invalid configuration: {field} = '{value}'")]
34 #[diagnostic(code(sizelint::config::invalid_value), help("Expected: {expected}"))]
35 ConfigInvalid {
36 field: String,
37 value: String,
38 expected: String,
39 },
40
41 #[error("Invalid exclude pattern '{pattern}'")]
42 #[diagnostic(
43 code(sizelint::config::invalid_pattern),
44 help("Check your glob pattern syntax - use wildcards like *.txt or **/*.rs")
45 )]
46 ConfigInvalidPattern {
47 pattern: String,
48 #[source]
49 source: globset::Error,
50 },
51
52 #[error("Failed to {operation} {path}")]
54 #[diagnostic(code(sizelint::filesystem::operation_failed))]
55 FileSystem {
56 operation: String,
57 path: PathBuf,
58 #[source]
59 source: std::io::Error,
60 },
61
62 #[error("Failed to get current directory")]
63 #[diagnostic(
64 code(sizelint::filesystem::current_dir_error),
65 help("Check your working directory permissions")
66 )]
67 CurrentDirectory {
68 #[source]
69 source: std::io::Error,
70 },
71
72 #[error("Invalid size format '{input}': {reason}")]
73 #[diagnostic(
74 code(sizelint::rule::invalid_size_format),
75 help("Use formats like: 10MB, 1GB, 500KB, 1024B")
76 )]
77 InvalidSizeFormat { input: String, reason: String },
78
79 #[error("JSON serialization error: {0}")]
81 #[diagnostic(code(sizelint::json::serialize_error))]
82 Serialize(#[from] serde_json::Error),
83
84 #[error("I/O error: {0}")]
85 #[diagnostic(code(sizelint::io::error))]
86 Io(#[from] std::io::Error),
87}
88
89pub type Result<T> = miette::Result<T, SizelintError>;
90
91impl SizelintError {
92 pub fn config_read(path: PathBuf, source: std::io::Error) -> Self {
93 Self::ConfigRead { path, source }
94 }
95
96 pub fn config_parse(path: PathBuf, source: toml::de::Error) -> Self {
97 Self::ConfigParse { path, source }
98 }
99
100 pub fn config_invalid(field: String, value: String, expected: String) -> Self {
101 Self::ConfigInvalid {
102 field,
103 value,
104 expected,
105 }
106 }
107
108 pub fn config_invalid_pattern(pattern: String, source: globset::Error) -> Self {
109 Self::ConfigInvalidPattern { pattern, source }
110 }
111
112 pub fn filesystem(operation: String, path: PathBuf, source: std::io::Error) -> Self {
113 Self::FileSystem {
114 operation,
115 path,
116 source,
117 }
118 }
119
120 pub fn invalid_size_format(input: String, reason: String) -> Self {
121 Self::InvalidSizeFormat { input, reason }
122 }
123}