codemp/src/lib/operation/factory.rs

54 lines
1.3 KiB
Rust
Raw Normal View History

use operational_transform::OperationSeq;
use similar::{TextDiff, ChangeTag};
pub trait OperationFactory {
fn content(&self) -> String;
fn replace(&self, txt: &str) -> OperationSeq {
let mut out = OperationSeq::default();
2023-04-18 21:46:19 +02:00
let content = self.content();
if content == txt {
return out; // TODO this won't work, should we return a noop instead?
}
2023-04-18 21:46:19 +02:00
let diff = TextDiff::from_chars(content.as_str(), txt);
for change in diff.iter_all_changes() {
match change.tag() {
ChangeTag::Equal => out.retain(1),
ChangeTag::Delete => out.delete(1),
ChangeTag::Insert => out.insert(change.value()),
}
}
out
}
fn insert(&self, txt: &str, pos: u64) -> OperationSeq {
let mut out = OperationSeq::default();
let total = self.content().len() as u64;
out.retain(pos);
out.insert(txt);
out.retain(total - pos);
out
}
fn delete(&self, pos: u64, count: u64) -> OperationSeq {
let mut out = OperationSeq::default();
let len = self.content().len() as u64;
out.retain(pos - count);
out.delete(count);
out.retain(len - pos);
out
}
fn cancel(&self, pos: u64, count: u64) -> OperationSeq {
let mut out = OperationSeq::default();
let len = self.content().len() as u64;
out.retain(pos);
out.delete(count);
out.retain(len - (pos+count));
out
}
}