Skip to main content

sizelint/
error.rs

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    // File system errors
53    #[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    // Auto-converted errors for external types
80    #[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}