my fork of dmp
Diffstat (limited to 'src/traits.rs')
| -rw-r--r-- | src/traits.rs | 114 |
1 files changed, 110 insertions, 4 deletions
diff --git a/src/traits.rs b/src/traits.rs index 8a5c9bb..20e0025 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,8 +1,11 @@ +use std::hash::Hash; + use chrono::NaiveTime; use crate::dmp::{Diff, DiffMatchPatch}; -pub trait BisectSplit: Copy + Ord + Eq { + +pub trait DType: Copy + Ord + Eq + Hash { fn bisect_split( dmp: &DiffMatchPatch, old: &[Self], @@ -11,9 +14,18 @@ pub trait BisectSplit: Copy + Ord + Eq { y: usize, deadline: Option<NaiveTime>, ) -> Result<Vec<Diff<Self>>, crate::errors::Error>; + + fn from_char(c: char) -> Self; + + fn as_char(&self) -> Option<char>; + + fn from_str(str: &str) -> Vec<Self>; + + fn is_linebreak_end(input: &[Self]) -> bool; + fn is_linebreak_start(input: &[Self]) -> bool; } -impl BisectSplit for u8 { +impl DType for u8 { fn bisect_split( dmp: &DiffMatchPatch, old: &[u8], @@ -34,9 +46,82 @@ impl BisectSplit for u8 { Ok(diffs_a) } + + fn from_char(c: char) -> Self { + c as u8 + } + + fn as_char(&self) -> Option<char> { + Some(*self as char) + } + + fn from_str(str: &str) -> Vec<Self> { + str.as_bytes().to_vec() + } + + #[inline] + fn is_linebreak_end(input: &[Self]) -> bool { + input.ends_with(b"\n\n") || input.ends_with(b"\n\r\n") + } + + #[inline] + fn is_linebreak_start(input: &[Self]) -> bool { + input.starts_with(b"\r\n\n") + || input.starts_with(b"\r\n\r\n") + || input.starts_with(b"\n\r\n") + || input.starts_with(b"\n\n") + } +} + +impl DType for char { + fn bisect_split( + dmp: &DiffMatchPatch, + old: &[char], + new: &[char], + x: usize, + y: usize, + deadline: Option<NaiveTime>, + ) -> Result<Vec<Diff<char>>, crate::errors::Error> { + let old_a = &old[..x]; + let new_a = &new[..y]; + + let old_b = &old[x..]; + let new_b = &new[y..]; + + // Compute both diffs serially. + let mut diffs_a = dmp.diff_internal(old_a, new_a, false, deadline)?; + diffs_a.append(&mut dmp.diff_internal(old_b, new_b, false, deadline)?); + + Ok(diffs_a) + } + + fn from_char(c: char) -> Self { + c + } + + fn as_char(&self) -> Option<char> { + Some(*self) + } + + fn from_str(str: &str) -> Vec<Self> { + str.chars().collect::<Vec<_>>() + } + + #[inline] + fn is_linebreak_end(input: &[Self]) -> bool { + input.ends_with(&['\n', '\n']) || input.ends_with(&['\n', '\r', '\n']) + } + + #[inline] + fn is_linebreak_start(input: &[Self]) -> bool { + input.starts_with(&['\r', '\n', '\n']) + || input.starts_with(&['\r', '\n', '\r', '\n']) + || input.starts_with(&['\n', '\r', '\n']) + || input.starts_with(&['\n', '\n']) + } } -impl BisectSplit for usize { +impl DType for usize { fn bisect_split( dmp: &DiffMatchPatch, old: &[usize], @@ -57,4 +142,25 @@ impl BisectSplit for usize { Ok(diffs_a) } -} + + fn from_char(c: char) -> Self { + (c as u8) as usize + } + + fn as_char(&self) -> Option<char> { + char::from_digit(*self as u32, 10) + } + + fn from_str(_: &str) -> Vec<Self> { + unimplemented!() + } + + fn is_linebreak_end(_: &[Self]) -> bool { + unimplemented!() + } + + #[inline] + fn is_linebreak_start(_: &[Self]) -> bool { + unimplemented!() + } +}
\ No newline at end of file |