Skip to content

Commit 30efe86

Browse files
committed
Auto merge of #13050 - weihanglo:rustfix-error, r=epage
refactor: use custom error instead of anyhow
2 parents 3920bd5 + 21274da commit 30efe86

File tree

6 files changed

+79
-66
lines changed

6 files changed

+79
-66
lines changed

Cargo.lock

+2-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pulldown-cmark = { version = "0.9.3", default-features = false }
7575
rand = "0.8.5"
7676
regex = "1.9.3"
7777
rusqlite = { version = "0.29.0", features = ["bundled"] }
78-
rustfix = { version = "0.6.2", path = "crates/rustfix" }
78+
rustfix = { version = "0.7.0", path = "crates/rustfix" }
7979
same-file = "1.0.6"
8080
security-framework = "2.9.2"
8181
semver = { version = "1.0.20", features = ["serde"] }

crates/rustfix/Cargo.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustfix"
3-
version = "0.6.2"
3+
version = "0.7.0"
44
authors = [
55
"Pascal Hertleif <[email protected]>",
66
"Oliver Schneider <[email protected]>",
@@ -18,12 +18,13 @@ exclude = [
1818
]
1919

2020
[dependencies]
21-
anyhow.workspace = true
2221
serde = { workspace = true, features = ["derive"] }
2322
serde_json.workspace = true
23+
thiserror.workspace = true
2424
tracing.workspace = true
2525

2626
[dev-dependencies]
27+
anyhow.workspace = true
2728
proptest.workspace = true
2829
similar = "2.2.1"
2930
tempfile.workspace = true

crates/rustfix/src/error.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//! Error types.
2+
3+
use std::ops::Range;
4+
5+
#[derive(Debug, thiserror::Error)]
6+
pub enum Error {
7+
#[error("invalid range {0:?}, start is larger than end")]
8+
InvalidRange(Range<usize>),
9+
10+
#[error("invalid range {0:?}, original data is only {1} byte long")]
11+
DataLengthExceeded(Range<usize>, usize),
12+
13+
#[error("could not replace range {0:?}, maybe parts of it were already replaced?")]
14+
MaybeAlreadyReplaced(Range<usize>),
15+
16+
#[error("cannot replace slice of data that was already replaced")]
17+
AlreadyReplaced,
18+
19+
#[error(transparent)]
20+
Utf8(#[from] std::string::FromUtf8Error),
21+
}

crates/rustfix/src/lib.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@
2222
use std::collections::HashSet;
2323
use std::ops::Range;
2424

25-
use anyhow::Error;
26-
2725
pub mod diagnostics;
28-
use crate::diagnostics::{Diagnostic, DiagnosticSpan};
26+
mod error;
2927
mod replace;
3028

29+
use diagnostics::Diagnostic;
30+
use diagnostics::DiagnosticSpan;
31+
pub use error::Error;
32+
3133
/// A filter to control which suggestion should be applied.
3234
#[derive(Debug, Clone, Copy)]
3335
pub enum Filter {

crates/rustfix/src/replace.rs

+47-59
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
//! replacement of parts of its content, with the ability to prevent changing
33
//! the same parts multiple times.
44
5-
use anyhow::{anyhow, ensure, Error};
65
use std::rc::Rc;
76

7+
use crate::error::Error;
8+
89
/// Indicates the change state of a [`Span`].
910
#[derive(Debug, Clone, PartialEq, Eq)]
1011
enum State {
@@ -77,22 +78,13 @@ impl Data {
7778
range: std::ops::Range<usize>,
7879
data: &[u8],
7980
) -> Result<(), Error> {
80-
let exclusive_end = range.end;
81-
82-
ensure!(
83-
range.start <= exclusive_end,
84-
"Invalid range {}..{}, start is larger than end",
85-
range.start,
86-
range.end
87-
);
88-
89-
ensure!(
90-
exclusive_end <= self.original.len(),
91-
"Invalid range {}..{} given, original data is only {} byte long",
92-
range.start,
93-
range.end,
94-
self.original.len()
95-
);
81+
if range.start > range.end {
82+
return Err(Error::InvalidRange(range));
83+
}
84+
85+
if range.end > self.original.len() {
86+
return Err(Error::DataLengthExceeded(range, self.original.len()));
87+
}
9688

9789
let insert_only = range.start == range.end;
9890

@@ -106,42 +98,35 @@ impl Data {
10698
// the whole chunk. As an optimization and without loss of generality we
10799
// don't add empty parts.
108100
let new_parts = {
109-
let index_of_part_to_split = self
110-
.parts
111-
.iter()
112-
.position(|p| !p.data.is_inserted() && p.start <= range.start && p.end >= range.end)
113-
.ok_or_else(|| {
114-
if tracing::enabled!(tracing::Level::DEBUG) {
115-
let slices = self
116-
.parts
117-
.iter()
118-
.map(|p| {
119-
(
120-
p.start,
121-
p.end,
122-
match p.data {
123-
State::Initial => "initial",
124-
State::Replaced(..) => "replaced",
125-
State::Inserted(..) => "inserted",
126-
},
127-
)
128-
})
129-
.collect::<Vec<_>>();
130-
tracing::debug!(
131-
"no single slice covering {}..{}, current slices: {:?}",
132-
range.start,
133-
range.end,
134-
slices,
135-
);
136-
}
137-
138-
anyhow!(
139-
"Could not replace range {}..{} in file \
140-
-- maybe parts of it were already replaced?",
101+
let Some(index_of_part_to_split) = self.parts.iter().position(|p| {
102+
!p.data.is_inserted() && p.start <= range.start && p.end >= range.end
103+
}) else {
104+
if tracing::enabled!(tracing::Level::DEBUG) {
105+
let slices = self
106+
.parts
107+
.iter()
108+
.map(|p| {
109+
(
110+
p.start,
111+
p.end,
112+
match p.data {
113+
State::Initial => "initial",
114+
State::Replaced(..) => "replaced",
115+
State::Inserted(..) => "inserted",
116+
},
117+
)
118+
})
119+
.collect::<Vec<_>>();
120+
tracing::debug!(
121+
"no single slice covering {}..{}, current slices: {:?}",
141122
range.start,
142123
range.end,
143-
)
144-
})?;
124+
slices,
125+
);
126+
}
127+
128+
return Err(Error::MaybeAlreadyReplaced(range));
129+
};
145130

146131
let part_to_split = &self.parts[index_of_part_to_split];
147132

@@ -161,10 +146,9 @@ impl Data {
161146
}
162147
}
163148

164-
ensure!(
165-
part_to_split.data == State::Initial,
166-
"Cannot replace slice of data that was already replaced"
167-
);
149+
if part_to_split.data != State::Initial {
150+
return Err(Error::AlreadyReplaced);
151+
}
168152

169153
let mut new_parts = Vec::with_capacity(self.parts.len() + 2);
170154

@@ -293,21 +277,25 @@ mod tests {
293277
}
294278

295279
#[test]
296-
#[should_panic(expected = "Cannot replace slice of data that was already replaced")]
297280
fn replace_overlapping_stuff_errs() {
298281
let mut d = Data::new(b"foo bar baz");
299282

300283
d.replace_range(4..7, b"lol").unwrap();
301284
assert_eq!("foo lol baz", str(&d.to_vec()));
302285

303-
d.replace_range(4..7, b"lol2").unwrap();
286+
assert!(matches!(
287+
d.replace_range(4..7, b"lol2").unwrap_err(),
288+
Error::AlreadyReplaced,
289+
));
304290
}
305291

306292
#[test]
307-
#[should_panic(expected = "original data is only 3 byte long")]
308293
fn broken_replacements() {
309294
let mut d = Data::new(b"foo");
310-
d.replace_range(4..8, b"lol").unwrap();
295+
assert!(matches!(
296+
d.replace_range(4..8, b"lol").unwrap_err(),
297+
Error::DataLengthExceeded(std::ops::Range { start: 4, end: 8 }, 3),
298+
));
311299
}
312300

313301
#[test]

0 commit comments

Comments
 (0)