7
7
//! which will validate that the changes do not conflict with one another.
8
8
//! At any time, you can "checkpoint" the current changes with [`Data::commit`]
9
9
//! or roll them back (perhaps due to a conflict) with [`Data::restore`].
10
- //! When you're done, use [`Data::to_vec`]
10
+ //! When you're done, use [`Data::to_vec`] or [`Data::to_string`]
11
11
//! to merge the original data with the changes.
12
12
//!
13
13
//! # Notes
14
14
//!
15
- //! The [`Data::to_vec`] method includes uncommitted changes, if present.
15
+ //! The [`Data::to_vec`] and [`Data::to_string`] methods include uncommitted changes, if present.
16
16
//! The reason for including uncommitted changes is that typically, once you're calling those,
17
17
//! you're done with edits and will be dropping the [`Data`] struct in a moment.
18
18
//! In this case, requiring an extra call to `commit` would be unnecessary work.
@@ -138,6 +138,14 @@ impl<'orig> Data<'orig> {
138
138
s
139
139
}
140
140
141
+ /// Merge the original data with changes, **including** uncommitted changes,
142
+ /// and validate that the result is a valid UTF-8 string.
143
+ ///
144
+ /// See the module-level documentation for more information on why uncommitted changes are included.
145
+ pub fn to_string ( & self ) -> Result < String , Error > {
146
+ Ok ( String :: from_utf8 ( self . to_vec ( ) ) ?)
147
+ }
148
+
141
149
/// Record a provisional change.
142
150
///
143
151
/// If committed, the original data in the given `range` will be replaced by the given data.
@@ -198,61 +206,57 @@ mod tests {
198
206
use super :: * ;
199
207
use proptest:: prelude:: * ;
200
208
201
- fn str ( i : & [ u8 ] ) -> & str {
202
- :: std:: str:: from_utf8 ( i) . unwrap ( )
203
- }
204
-
205
209
#[ test]
206
210
fn insert_at_beginning ( ) {
207
211
let mut d = Data :: new ( "foo bar baz" ) ;
208
212
d. replace_range ( 0 ..0 , "oh no " ) . unwrap ( ) ;
209
- assert_eq ! ( "oh no foo bar baz" , str ( & d. to_vec ( ) ) ) ;
213
+ assert_eq ! ( "oh no foo bar baz" , & d. to_string ( ) . unwrap ( ) ) ;
210
214
}
211
215
212
216
#[ test]
213
217
fn insert_at_end ( ) {
214
218
let mut d = Data :: new ( "foo bar baz" ) ;
215
219
d. replace_range ( 11 ..11 , " oh no" ) . unwrap ( ) ;
216
- assert_eq ! ( "foo bar baz oh no" , str ( & d. to_vec ( ) ) ) ;
220
+ assert_eq ! ( "foo bar baz oh no" , & d. to_string ( ) . unwrap ( ) ) ;
217
221
}
218
222
219
223
#[ test]
220
224
fn replace_some_stuff ( ) {
221
225
let mut d = Data :: new ( "foo bar baz" ) ;
222
226
d. replace_range ( 4 ..7 , "lol" ) . unwrap ( ) ;
223
- assert_eq ! ( "foo lol baz" , str ( & d. to_vec ( ) ) ) ;
227
+ assert_eq ! ( "foo lol baz" , & d. to_string ( ) . unwrap ( ) ) ;
224
228
}
225
229
226
230
#[ test]
227
231
fn replace_a_single_char ( ) {
228
232
let mut d = Data :: new ( "let y = true;" ) ;
229
233
d. replace_range ( 4 ..5 , "mut y" ) . unwrap ( ) ;
230
- assert_eq ! ( "let mut y = true;" , str ( & d. to_vec ( ) ) ) ;
234
+ assert_eq ! ( "let mut y = true;" , & d. to_string ( ) . unwrap ( ) ) ;
231
235
}
232
236
233
237
#[ test]
234
238
fn replace_multiple_lines ( ) {
235
239
let mut d = Data :: new ( "lorem\n ipsum\n dolor" ) ;
236
240
237
241
d. replace_range ( 6 ..11 , "lol" ) . unwrap ( ) ;
238
- assert_eq ! ( "lorem\n lol\n dolor" , str ( & d. to_vec ( ) ) ) ;
242
+ assert_eq ! ( "lorem\n lol\n dolor" , & d. to_string ( ) . unwrap ( ) ) ;
239
243
240
244
d. replace_range ( 12 ..17 , "lol" ) . unwrap ( ) ;
241
- assert_eq ! ( "lorem\n lol\n lol" , str ( & d. to_vec ( ) ) ) ;
245
+ assert_eq ! ( "lorem\n lol\n lol" , & d. to_string ( ) . unwrap ( ) ) ;
242
246
}
243
247
244
248
#[ test]
245
249
fn replace_multiple_lines_with_insert_only ( ) {
246
250
let mut d = Data :: new ( "foo!" ) ;
247
251
248
252
d. replace_range ( 3 ..3 , "bar" ) . unwrap ( ) ;
249
- assert_eq ! ( "foobar!" , str ( & d. to_vec ( ) ) ) ;
253
+ assert_eq ! ( "foobar!" , & d. to_string ( ) . unwrap ( ) ) ;
250
254
251
255
d. replace_range ( 0 ..3 , "baz" ) . unwrap ( ) ;
252
- assert_eq ! ( "bazbar!" , str ( & d. to_vec ( ) ) ) ;
256
+ assert_eq ! ( "bazbar!" , & d. to_string ( ) . unwrap ( ) ) ;
253
257
254
258
d. replace_range ( 3 ..4 , "?" ) . unwrap ( ) ;
255
- assert_eq ! ( "bazbar?" , str ( & d. to_vec ( ) ) ) ;
259
+ assert_eq ! ( "bazbar?" , & d. to_string ( ) . unwrap ( ) ) ;
256
260
}
257
261
258
262
#[ test]
@@ -264,17 +268,17 @@ mod tests {
264
268
}
265
269
266
270
#[ test]
267
- fn empty_to_vec_roundtrip ( ) {
271
+ fn empty_to_string_roundtrip ( ) {
268
272
let s = "" ;
269
- assert_eq ! ( s. as_bytes ( ) , Data :: new( s. as_bytes ( ) ) . to_vec ( ) . as_slice ( ) ) ;
273
+ assert_eq ! ( s, & Data :: new( s) . to_string ( ) . unwrap ( ) ) ;
270
274
}
271
275
272
276
#[ test]
273
277
fn replace_same_range_diff_data ( ) {
274
278
let mut d = Data :: new ( "foo bar baz" ) ;
275
279
276
280
d. replace_range ( 4 ..7 , "lol" ) . unwrap ( ) ;
277
- assert_eq ! ( "foo lol baz" , str ( & d. to_vec ( ) ) ) ;
281
+ assert_eq ! ( "foo lol baz" , & d. to_string ( ) . unwrap ( ) ) ;
278
282
279
283
assert ! ( matches!(
280
284
d. replace_range( 4 ..7 , "lol2" ) . unwrap_err( ) ,
@@ -290,7 +294,7 @@ mod tests {
290
294
let mut d = Data :: new ( "foo bar baz" ) ;
291
295
292
296
d. replace_range ( 4 ..7 , "lol" ) . unwrap ( ) ;
293
- assert_eq ! ( "foo lol baz" , str ( & d. to_vec ( ) ) ) ;
297
+ assert_eq ! ( "foo lol baz" , & d. to_string ( ) . unwrap ( ) ) ;
294
298
295
299
assert ! ( matches!(
296
300
d. replace_range( 4 ..7 , "lol" ) . unwrap_err( ) ,
@@ -314,50 +318,50 @@ mod tests {
314
318
fn insert_same_twice ( ) {
315
319
let mut d = Data :: new ( "foo" ) ;
316
320
d. replace_range ( 1 ..1 , "b" ) . unwrap ( ) ;
317
- assert_eq ! ( "fboo" , str ( & d. to_vec ( ) ) ) ;
321
+ assert_eq ! ( "fboo" , & d. to_string ( ) . unwrap ( ) ) ;
318
322
assert ! ( matches!(
319
323
d. replace_range( 1 ..1 , "b" ) . unwrap_err( ) ,
320
324
Error :: AlreadyReplaced {
321
325
is_identical: true ,
322
326
..
323
327
} ,
324
328
) ) ;
325
- assert_eq ! ( "fboo" , str ( & d. to_vec ( ) ) ) ;
329
+ assert_eq ! ( "fboo" , & d. to_string ( ) . unwrap ( ) ) ;
326
330
}
327
331
328
332
#[ test]
329
333
fn commit_restore ( ) {
330
334
let mut d = Data :: new ( ", " ) ;
331
- assert_eq ! ( ", " , str ( & d. to_vec ( ) ) ) ;
335
+ assert_eq ! ( ", " , & d. to_string ( ) . unwrap ( ) ) ;
332
336
333
337
d. replace_range ( 2 ..2 , "world" ) . unwrap ( ) ;
334
338
d. replace_range ( 0 ..0 , "hello" ) . unwrap ( ) ;
335
- assert_eq ! ( "hello, world" , str ( & d. to_vec ( ) ) ) ;
339
+ assert_eq ! ( "hello, world" , & d. to_string ( ) . unwrap ( ) ) ;
336
340
337
341
d. restore ( ) ;
338
- assert_eq ! ( ", " , str ( & d. to_vec ( ) ) ) ;
342
+ assert_eq ! ( ", " , & d. to_string ( ) . unwrap ( ) ) ;
339
343
340
344
d. commit ( ) ;
341
- assert_eq ! ( ", " , str ( & d. to_vec ( ) ) ) ;
345
+ assert_eq ! ( ", " , & d. to_string ( ) . unwrap ( ) ) ;
342
346
343
347
d. replace_range ( 2 ..2 , "world" ) . unwrap ( ) ;
344
- assert_eq ! ( ", world" , str ( & d. to_vec ( ) ) ) ;
348
+ assert_eq ! ( ", world" , & d. to_string ( ) . unwrap ( ) ) ;
345
349
d. commit ( ) ;
346
- assert_eq ! ( ", world" , str ( & d. to_vec ( ) ) ) ;
350
+ assert_eq ! ( ", world" , & d. to_string ( ) . unwrap ( ) ) ;
347
351
d. restore ( ) ;
348
- assert_eq ! ( ", world" , str ( & d. to_vec ( ) ) ) ;
352
+ assert_eq ! ( ", world" , & d. to_string ( ) . unwrap ( ) ) ;
349
353
350
354
d. replace_range ( 0 ..0 , "hello" ) . unwrap ( ) ;
351
- assert_eq ! ( "hello, world" , str ( & d. to_vec ( ) ) ) ;
355
+ assert_eq ! ( "hello, world" , & d. to_string ( ) . unwrap ( ) ) ;
352
356
d. commit ( ) ;
353
- assert_eq ! ( "hello, world" , str ( & d. to_vec ( ) ) ) ;
357
+ assert_eq ! ( "hello, world" , & d. to_string ( ) . unwrap ( ) ) ;
354
358
d. restore ( ) ;
355
- assert_eq ! ( "hello, world" , str ( & d. to_vec ( ) ) ) ;
359
+ assert_eq ! ( "hello, world" , & d. to_string ( ) . unwrap ( ) ) ;
356
360
}
357
361
358
362
proptest ! {
359
363
#[ test]
360
- fn new_to_vec_roundtrip ( ref s in "\\ PC*" ) {
364
+ fn new_to_string_roundtrip ( ref s in "\\ PC*" ) {
361
365
assert_eq!( s. as_bytes( ) , & Data :: new( s) . to_vec( ) ) ;
362
366
}
363
367
0 commit comments