diff --git a/src/mutators/helpers.rs b/src/mutators/helpers.rs index 27d8d22..314790f 100644 --- a/src/mutators/helpers.rs +++ b/src/mutators/helpers.rs @@ -62,6 +62,45 @@ pub fn splice_extend( Some(((dst_start..dst_end), (src_start..src_end))) } +/// Copy a random sub-slice from `src` into a random subslice of `dst`. +/// This will potentially grow or shrink the destination vector. +/// This will call clone on every element. Use [`splice_extend`] if your type is `Copy` for better +/// performance. +#[inline] +pub fn splice_clone_extend( + dst: &mut Vec, + src: &[C], + rng: &mut impl rand::Rng, +) -> Option<(std::ops::Range, std::ops::Range)> { + if src.is_empty() { + return None; + } + + let src_start = rng.gen_range(0..src.len()); + let src_end = rng.gen_range(src_start..=src.len()); + if dst.is_empty() { + dst.extend( + src.iter() + .skip(src_start) + .take(src_end - src_start) + .cloned(), + ); + return Some((0..0, src_start..src_end)); + } + + let dst_start = rng.gen_range(0..dst.len()); + let dst_end = rng.gen_range(dst_start..=dst.len()); + + dst.splice( + dst_start..dst_end, + src.iter() + .skip(src_start) + .take(src_end - src_start) + .cloned(), + ); + Some(((dst_start..dst_end), (src_start..src_end))) +} + /// Copy sub-slice from another slice into the current one. /// /// # returns