mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-22 15:24:48 +01:00
fix: added factory doctests, caught bugs
This commit is contained in:
parent
265b0480b8
commit
db0c696cf9
1 changed files with 92 additions and 6 deletions
|
@ -2,10 +2,73 @@
|
||||||
//!
|
//!
|
||||||
//! a helper trait to produce Operation Sequences, knowing the current
|
//! a helper trait to produce Operation Sequences, knowing the current
|
||||||
//! state of the buffer
|
//! state of the buffer
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! use codemp::buffer::factory::{OperationFactory, SimpleOperationFactory};
|
||||||
|
//!
|
||||||
|
//! let mut factory = SimpleOperationFactory::from("");
|
||||||
|
//! let op = factory.insert("asd", 0);
|
||||||
|
//! factory.update(op)?;
|
||||||
|
//! assert_eq!(factory.content(), "asd");
|
||||||
|
//! # Ok::<(), codemp::ot::OTError>(())
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! use [OperationFactory::insert] to add new characters at a specific index
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! # use codemp::buffer::factory::{OperationFactory, SimpleOperationFactory};
|
||||||
|
//! # let mut factory = SimpleOperationFactory::from("asd");
|
||||||
|
//! factory.update(factory.insert(" dsa", 3))?;
|
||||||
|
//! assert_eq!(factory.content(), "asd dsa");
|
||||||
|
//! # Ok::<(), codemp::ot::OTError>(())
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! use [OperationFactory::delta] to arbitrarily change text at any position
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! # use codemp::buffer::factory::{OperationFactory, SimpleOperationFactory};
|
||||||
|
//! # let mut factory = SimpleOperationFactory::from("asd dsa");
|
||||||
|
//! let op = factory.delta(2, " xxx ", 5).expect("replaced region is equal to origin");
|
||||||
|
//! factory.update(op)?;
|
||||||
|
//! assert_eq!(factory.content(), "as xxx sa");
|
||||||
|
//! # Ok::<(), codemp::ot::OTError>(())
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! use [OperationFactory::delete] to remove characters from given index
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! # use codemp::buffer::factory::{OperationFactory, SimpleOperationFactory};
|
||||||
|
//! # let mut factory = SimpleOperationFactory::from("as xxx sa");
|
||||||
|
//! factory.update(factory.delete(2, 5))?;
|
||||||
|
//! assert_eq!(factory.content(), "assa");
|
||||||
|
//! # Ok::<(), codemp::ot::OTError>(())
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! use [OperationFactory::replace] to completely replace buffer content
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! # use codemp::buffer::factory::{OperationFactory, SimpleOperationFactory};
|
||||||
|
//! # let mut factory = SimpleOperationFactory::from("assa");
|
||||||
|
//! let op = factory.replace("from scratch").expect("replace is equal to origin");
|
||||||
|
//! factory.update(op)?;
|
||||||
|
//! assert_eq!(factory.content(), "from scratch");
|
||||||
|
//! # Ok::<(), codemp::ot::OTError>(())
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! use [OperationFactory::cancel] to remove characters at index, but backwards
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! # use codemp::buffer::factory::{OperationFactory, SimpleOperationFactory};
|
||||||
|
//! # let mut factory = SimpleOperationFactory::from("from scratch");
|
||||||
|
//! factory.update(factory.cancel(12, 8))?;
|
||||||
|
//! assert_eq!(factory.content(), "from");
|
||||||
|
//! # Ok::<(), codemp::ot::OTError>(())
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use operational_transform::{OperationSeq, Operation};
|
use operational_transform::{OperationSeq, Operation, OTError};
|
||||||
use similar::{TextDiff, ChangeTag};
|
use similar::{TextDiff, ChangeTag};
|
||||||
|
|
||||||
/// calculate leading no-ops in given opseq
|
/// calculate leading no-ops in given opseq
|
||||||
|
@ -44,7 +107,7 @@ pub trait OperationFactory {
|
||||||
let mut out = OperationSeq::default();
|
let mut out = OperationSeq::default();
|
||||||
let content = self.content();
|
let content = self.content();
|
||||||
let tail_skip = content.len() - end; // TODO len is number of bytes, not chars
|
let tail_skip = content.len() - end; // TODO len is number of bytes, not chars
|
||||||
let content_slice = &content[start..tail_skip];
|
let content_slice = &content[start..end];
|
||||||
|
|
||||||
if content_slice == txt {
|
if content_slice == txt {
|
||||||
// if slice equals given text, no operation should be taken
|
// if slice equals given text, no operation should be taken
|
||||||
|
@ -82,9 +145,9 @@ pub trait OperationFactory {
|
||||||
fn delete(&self, pos: u64, count: u64) -> OperationSeq {
|
fn delete(&self, pos: u64, count: u64) -> OperationSeq {
|
||||||
let mut out = OperationSeq::default();
|
let mut out = OperationSeq::default();
|
||||||
let len = self.content().len() as u64;
|
let len = self.content().len() as u64;
|
||||||
out.retain(pos - count);
|
out.retain(pos);
|
||||||
out.delete(count);
|
out.delete(count);
|
||||||
out.retain(len - pos);
|
out.retain(len - (pos+count));
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,9 +155,32 @@ pub trait OperationFactory {
|
||||||
fn cancel(&self, pos: u64, count: u64) -> OperationSeq {
|
fn cancel(&self, pos: u64, count: u64) -> OperationSeq {
|
||||||
let mut out = OperationSeq::default();
|
let mut out = OperationSeq::default();
|
||||||
let len = self.content().len() as u64;
|
let len = self.content().len() as u64;
|
||||||
out.retain(pos);
|
out.retain(pos - count);
|
||||||
out.delete(count);
|
out.delete(count);
|
||||||
out.retain(len - (pos+count));
|
out.retain(len - pos);
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// a simple example operation factory that just wraps a string
|
||||||
|
pub struct SimpleOperationFactory(String);
|
||||||
|
|
||||||
|
impl SimpleOperationFactory {
|
||||||
|
/// applies given OperationSeq to underlying string, changing it
|
||||||
|
pub fn update(&mut self, op: OperationSeq) -> Result<(), OTError> {
|
||||||
|
self.0 = op.apply(&self.0)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From::<&str> for SimpleOperationFactory {
|
||||||
|
fn from(value: &str) -> Self {
|
||||||
|
SimpleOperationFactory(value.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OperationFactory for SimpleOperationFactory {
|
||||||
|
fn content(&self) -> String {
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue