1use std::path::{Path, PathBuf};
10
11#[derive(Debug, thiserror::Error)]
12pub enum Error {
13 #[error("invalid regex: {0}")]
14 InvalidRegex(#[from] regex::Error),
15
16 #[error("invalid glob: {0}")]
17 InvalidGlob(#[from] globset::Error),
18
19 #[error("walk failed: {0}")]
20 Walk(#[from] ignore::Error),
21
22 #[error("i/o error at {path}: {source}")]
23 Io { path: PathBuf, source: std::io::Error },
24
25 #[error("file {path} exceeds --max-bytes ({size} > {limit})")]
26 FileTooLarge { path: PathBuf, size: u64, limit: u64 },
27
28 #[error("scan touched {count} files; refusing (--max-files = {limit})")]
29 TooManyFiles { count: usize, limit: usize },
30
31 #[error(
32 "pattern is non-convergent: re-applying it to the rewrite of {path} would produce {extra} more match(es)"
33 )]
34 NonConvergent { path: PathBuf, extra: usize },
35
36 #[error("match-count guard violated: found {found}, required at least {required}")]
37 TooFewMatches { found: usize, required: usize },
38
39 #[error("match-count guard violated: found {found}, allowed at most {allowed}")]
40 TooManyMatches { found: usize, allowed: usize },
41
42 #[error("script parse error: {0}")]
43 ScriptParse(String),
44
45 #[error("script runtime error: {0}")]
46 ScriptRuntime(String),
47
48 #[error("structural: unknown language `{0}`")]
49 UnknownLanguage(String),
50
51 #[error("structural: query error: {0}")]
52 StructuralQuery(String),
53
54 #[error("structural: template error: {0}")]
55 StructuralTemplate(String),
56
57 #[error("structural: parse error")]
58 StructuralParse,
59
60 #[error(
61 "rewrite introduced {new_errors} new syntax error(s) in {path} ({lang}); pass allow_syntax_errors to override"
62 )]
63 SyntaxRegression { path: PathBuf, lang: &'static str, new_errors: usize },
64
65 #[error(
66 "another recast is already applying to this tree (lockfile {path} held); use --force to override"
67 )]
68 Locked { path: PathBuf },
69
70 #[error("invalid --threads value: must be at least 1")]
71 InvalidThreads,
72
73 #[error("failed to build worker thread pool: {0}")]
74 ThreadPool(String),
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq)]
80#[cfg_attr(feature = "serde", derive(serde::Serialize))]
81#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
82pub enum ErrorKind {
83 InvalidRegex,
84 InvalidGlob,
85 Walk,
86 Io,
87 FileTooLarge,
88 TooManyFiles,
89 NonConvergent,
90 TooFewMatches,
91 TooManyMatches,
92 ScriptParse,
93 ScriptRuntime,
94 UnknownLanguage,
95 StructuralQuery,
96 StructuralTemplate,
97 StructuralParse,
98 SyntaxRegression,
99 Locked,
100 InvalidThreads,
101 ThreadPool,
102}
103
104impl Error {
105 pub fn kind(&self) -> ErrorKind {
108 match self {
109 Error::InvalidRegex(_) => ErrorKind::InvalidRegex,
110 Error::InvalidGlob(_) => ErrorKind::InvalidGlob,
111 Error::Walk(_) => ErrorKind::Walk,
112 Error::Io { .. } => ErrorKind::Io,
113 Error::FileTooLarge { .. } => ErrorKind::FileTooLarge,
114 Error::TooManyFiles { .. } => ErrorKind::TooManyFiles,
115 Error::NonConvergent { .. } => ErrorKind::NonConvergent,
116 Error::TooFewMatches { .. } => ErrorKind::TooFewMatches,
117 Error::TooManyMatches { .. } => ErrorKind::TooManyMatches,
118 Error::ScriptParse(_) => ErrorKind::ScriptParse,
119 Error::ScriptRuntime(_) => ErrorKind::ScriptRuntime,
120 Error::UnknownLanguage(_) => ErrorKind::UnknownLanguage,
121 Error::StructuralQuery(_) => ErrorKind::StructuralQuery,
122 Error::StructuralTemplate(_) => ErrorKind::StructuralTemplate,
123 Error::StructuralParse => ErrorKind::StructuralParse,
124 Error::SyntaxRegression { .. } => ErrorKind::SyntaxRegression,
125 Error::Locked { .. } => ErrorKind::Locked,
126 Error::InvalidThreads => ErrorKind::InvalidThreads,
127 Error::ThreadPool(_) => ErrorKind::ThreadPool,
128 }
129 }
130}
131
132pub type Result<T> = std::result::Result<T, Error>;
133
134pub(crate) trait IoCtx<T> {
139 fn io_ctx(self, path: &Path) -> Result<T>;
140}
141
142impl<T> IoCtx<T> for std::result::Result<T, std::io::Error> {
143 fn io_ctx(self, path: &Path) -> Result<T> {
144 self.map_err(|source| Error::Io { path: path.to_path_buf(), source })
145 }
146}