Skip to content
This repository has been archived by the owner on Nov 24, 2023. It is now read-only.

Commit

Permalink
Add special case for empty string
Browse files Browse the repository at this point in the history
  • Loading branch information
yaahc committed May 18, 2018
1 parent 52a9eb8 commit 6810c7f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
8 changes: 8 additions & 0 deletions proptest-regressions/replace.txt
@@ -0,0 +1,8 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
xs 358148376 3634975642 2528447681 3675516813 # shrinks to ref s = ""
xs 3127423015 3362740891 2605681441 2390162043 # shrinks to ref data = "", ref replacements = [(0..0, [])]
34 changes: 23 additions & 11 deletions src/replace.rs
Expand Up @@ -12,6 +12,16 @@ enum State {
Inserted(Rc<[u8]>),
}

impl State {
fn is_inserted(&self) -> bool {
if let &State::Inserted(..) = self {
true
} else {
false
}
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct Span {
/// Start of this span in parent data
Expand All @@ -37,14 +47,18 @@ impl Data {
Span {
data: State::Initial,
start: 0,
end: data.len() - 1,
end: data.len().saturating_sub(1),
},
],
}
}

/// Render this data as a vector of bytes
pub fn to_vec(&self) -> Vec<u8> {
if self.original.is_empty() {
return Vec::new();
}

self.parts.iter().fold(Vec::new(), |mut acc, d| {
match d.data {
State::Initial => acc.extend_from_slice(&self.original[d.start..=d.end]),
Expand Down Expand Up @@ -91,18 +105,10 @@ impl Data {
// the whole chunk. As an optimization and without loss of generality we
// don't add empty parts.
let new_parts = {
let is_inserted = |state| {
if let &State::Inserted(..) = state {
true
} else {
false
}
};

let index_of_part_to_split = self.parts
.iter()
.position(|p| {
!is_inserted(&p.data) && p.start <= from && p.end >= up_to_and_including
!p.data.is_inserted() && p.start <= from && p.end >= up_to_and_including
})
.ok_or_else(|| {
use log::Level::Debug;
Expand Down Expand Up @@ -152,7 +158,7 @@ impl Data {
if from > part_to_split.start {
new_parts.push(Span {
start: part_to_split.start,
end: from - 1,
end: from.saturating_sub(1),
data: State::Initial,
});
}
Expand Down Expand Up @@ -247,6 +253,12 @@ mod tests {
assert!(d.replace_range(0, 2, b"bar").is_ok());
}

#[test]
fn empty_to_vec_roundtrip() {
let s = "";
assert_eq!(s.as_bytes(), Data::new(s.as_bytes()).to_vec().as_slice());
}

#[test]
#[should_panic(expected = "Cannot replace slice of data that was already replaced")]
fn replace_overlapping_stuff_errs() {
Expand Down

0 comments on commit 6810c7f

Please sign in to comment.