2
2
//! replacement of parts of its content, with the ability to prevent changing
3
3
//! the same parts multiple times.
4
4
5
- use anyhow:: { anyhow, ensure, Error } ;
6
5
use std:: rc:: Rc ;
7
6
7
+ use crate :: error:: Error ;
8
+
8
9
/// Indicates the change state of a [`Span`].
9
10
#[ derive( Debug , Clone , PartialEq , Eq ) ]
10
11
enum State {
@@ -77,22 +78,13 @@ impl Data {
77
78
range : std:: ops:: Range < usize > ,
78
79
data : & [ u8 ] ,
79
80
) -> 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
+ }
96
88
97
89
let insert_only = range. start == range. end ;
98
90
@@ -106,42 +98,35 @@ impl Data {
106
98
// the whole chunk. As an optimization and without loss of generality we
107
99
// don't add empty parts.
108
100
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: {:?}" ,
141
122
range. start,
142
123
range. end,
143
- )
144
- } ) ?;
124
+ slices,
125
+ ) ;
126
+ }
127
+
128
+ return Err ( Error :: MaybeAlreadyReplaced ( range) ) ;
129
+ } ;
145
130
146
131
let part_to_split = & self . parts [ index_of_part_to_split] ;
147
132
@@ -161,10 +146,9 @@ impl Data {
161
146
}
162
147
}
163
148
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
+ }
168
152
169
153
let mut new_parts = Vec :: with_capacity ( self . parts . len ( ) + 2 ) ;
170
154
@@ -293,21 +277,25 @@ mod tests {
293
277
}
294
278
295
279
#[ test]
296
- #[ should_panic( expected = "Cannot replace slice of data that was already replaced" ) ]
297
280
fn replace_overlapping_stuff_errs ( ) {
298
281
let mut d = Data :: new ( b"foo bar baz" ) ;
299
282
300
283
d. replace_range ( 4 ..7 , b"lol" ) . unwrap ( ) ;
301
284
assert_eq ! ( "foo lol baz" , str ( & d. to_vec( ) ) ) ;
302
285
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
+ ) ) ;
304
290
}
305
291
306
292
#[ test]
307
- #[ should_panic( expected = "original data is only 3 byte long" ) ]
308
293
fn broken_replacements ( ) {
309
294
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
+ ) ) ;
311
299
}
312
300
313
301
#[ test]
0 commit comments