diff options
| author | Mel <einebeere@gmail.com> | 2021-09-20 22:25:55 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2021-09-20 22:25:55 +0200 |
| commit | c25d22681f9bc6ddba512895182af0ce0252731b (patch) | |
| tree | eadcdec7d0b4d26d59e77169bd89b8db13e22fb6 /src/text_diff.rs | |
| parent | 8bcbf51cf4f7924600eae39db67ff653b48ad95d (diff) | |
| download | ka-c25d22681f9bc6ddba512895182af0ce0252731b.tar.zst ka-c25d22681f9bc6ddba512895182af0ce0252731b.zip | |
Split out common logic
Diffstat (limited to 'src/text_diff.rs')
| -rw-r--r-- | src/text_diff.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/text_diff.rs b/src/text_diff.rs new file mode 100644 index 0000000..bab8799 --- /dev/null +++ b/src/text_diff.rs @@ -0,0 +1,52 @@ +use difference::{Changeset, Difference}; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +pub enum TextChange { + Inserted { at: usize, new_content: String }, + Deleted { at: usize, upto: usize }, +} + +impl TextChange { + pub fn diff(old: &str, new: &str) -> Vec<Self> { + let change_set = Changeset::new(old, new, ""); + + let mut changes = Vec::new(); + let mut at: usize = 0; + + for diff in change_set.diffs.iter() { + match diff { + Difference::Add(new_content) => { + let change = TextChange::Inserted { + at, + new_content: new_content.to_owned(), + }; + at += new_content.len(); + changes.push(change); + } + Difference::Rem(removed_content) => { + changes.push(TextChange::Deleted { + at, + upto: removed_content.len(), + }); + } + Difference::Same(same_content) => { + at += same_content.len(); + } + } + } + + changes + } + + pub fn apply(&self, buffer: &mut String) { + match self { + TextChange::Deleted { at, upto } => { + buffer.replace_range(at..upto, ""); + } + TextChange::Inserted { at, new_content } => { + buffer.insert_str(*at, new_content); + } + } + } +} |
