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 } ;
65use std:: rc:: Rc ;
76
7+ use crate :: error:: Error ;
8+
89/// Indicates the change state of a [`Span`].
910#[ derive( Debug , Clone , PartialEq , Eq ) ]
1011enum 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