1#[cfg(feature = "serde")]
93pub mod serde;
94
95#[cfg(any(test, bench))]
96pub mod utilities;
97
98use bytecount::num_chars;
99use std::{cmp::Ordering, error::Error, fmt, iter::FromIterator};
100
101#[derive(Debug, Clone, PartialEq)]
103pub enum Operation {
104 Delete(u64),
106 Retain(u64),
108 Insert(String),
110}
111
112#[derive(Clone, Debug, PartialEq, Default)]
114pub struct OperationSeq {
115 ops: Vec<Operation>,
117 base_len: usize,
119 target_len: usize,
122}
123
124impl FromIterator<Operation> for OperationSeq {
125 fn from_iter<T: IntoIterator<Item = Operation>>(ops: T) -> Self {
126 let mut operations = OperationSeq::default();
127 for op in ops {
128 operations.add(op);
129 }
130 operations
131 }
132}
133
134#[derive(Clone, Debug)]
136pub struct OTError;
137
138impl fmt::Display for OTError {
139 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140 write!(f, "incompatible lengths")
141 }
142}
143
144impl Error for OTError {
145 fn source(&self) -> Option<&(dyn Error + 'static)> {
146 None
147 }
148}
149
150impl OperationSeq {
151 #[inline]
154 pub fn with_capacity(capacity: usize) -> Self {
155 Self {
156 ops: Vec::with_capacity(capacity),
157 base_len: 0,
158 target_len: 0,
159 }
160 }
161
162 pub fn compose(&self, other: &Self) -> Result<Self, OTError> {
173 if self.target_len != other.base_len {
174 return Err(OTError);
175 }
176
177 let mut new_op_seq = OperationSeq::default();
178 let mut ops1 = self.ops.iter().cloned();
179 let mut ops2 = other.ops.iter().cloned();
180
181 let mut maybe_op1 = ops1.next();
182 let mut maybe_op2 = ops2.next();
183 loop {
184 match (&maybe_op1, &maybe_op2) {
185 (None, None) => break,
186 (Some(Operation::Delete(i)), _) => {
187 new_op_seq.delete(*i);
188 maybe_op1 = ops1.next();
189 }
190 (_, Some(Operation::Insert(s))) => {
191 new_op_seq.insert(s);
192 maybe_op2 = ops2.next();
193 }
194 (None, _) | (_, None) => {
195 return Err(OTError);
196 }
197 (Some(Operation::Retain(i)), Some(Operation::Retain(j))) => match i.cmp(j) {
198 Ordering::Less => {
199 new_op_seq.retain(*i);
200 maybe_op2 = Some(Operation::Retain(*j - *i));
201 maybe_op1 = ops1.next();
202 }
203 std::cmp::Ordering::Equal => {
204 new_op_seq.retain(*i);
205 maybe_op1 = ops1.next();
206 maybe_op2 = ops2.next();
207 }
208 std::cmp::Ordering::Greater => {
209 new_op_seq.retain(*j);
210 maybe_op1 = Some(Operation::Retain(*i - *j));
211 maybe_op2 = ops2.next();
212 }
213 },
214 (Some(Operation::Insert(s)), Some(Operation::Delete(j))) => {
215 match (num_chars(s.as_bytes()) as u64).cmp(j) {
216 Ordering::Less => {
217 maybe_op2 =
218 Some(Operation::Delete(*j - num_chars(s.as_bytes()) as u64));
219 maybe_op1 = ops1.next();
220 }
221 Ordering::Equal => {
222 maybe_op1 = ops1.next();
223 maybe_op2 = ops2.next();
224 }
225 Ordering::Greater => {
226 maybe_op1 =
227 Some(Operation::Insert(s.chars().skip(*j as usize).collect()));
228 maybe_op2 = ops2.next();
229 }
230 }
231 }
232 (Some(Operation::Insert(s)), Some(Operation::Retain(j))) => {
233 match (num_chars(s.as_bytes()) as u64).cmp(j) {
234 Ordering::Less => {
235 new_op_seq.insert(s);
236 maybe_op2 =
237 Some(Operation::Retain(*j - num_chars(s.as_bytes()) as u64));
238 maybe_op1 = ops1.next();
239 }
240 Ordering::Equal => {
241 new_op_seq.insert(s);
242 maybe_op1 = ops1.next();
243 maybe_op2 = ops2.next();
244 }
245 Ordering::Greater => {
246 let chars = &mut s.chars();
247 new_op_seq.insert(&chars.take(*j as usize).collect::<String>());
248 maybe_op1 = Some(Operation::Insert(chars.collect()));
249 maybe_op2 = ops2.next();
250 }
251 }
252 }
253 (Some(Operation::Retain(i)), Some(Operation::Delete(j))) => match i.cmp(j) {
254 Ordering::Less => {
255 new_op_seq.delete(*i);
256 maybe_op2 = Some(Operation::Delete(*j - *i));
257 maybe_op1 = ops1.next();
258 }
259 Ordering::Equal => {
260 new_op_seq.delete(*j);
261 maybe_op2 = ops2.next();
262 maybe_op1 = ops1.next();
263 }
264 Ordering::Greater => {
265 new_op_seq.delete(*j);
266 maybe_op1 = Some(Operation::Retain(*i - *j));
267 maybe_op2 = ops2.next();
268 }
269 },
270 };
271 }
272 Ok(new_op_seq)
273 }
274
275 fn add(&mut self, op: Operation) {
276 match op {
277 Operation::Delete(i) => self.delete(i),
278 Operation::Insert(s) => self.insert(&s),
279 Operation::Retain(i) => self.retain(i),
280 }
281 }
282
283 pub fn delete(&mut self, n: u64) {
285 if n == 0 {
286 return;
287 }
288 self.base_len += n as usize;
289 if let Some(Operation::Delete(n_last)) = self.ops.last_mut() {
290 *n_last += n;
291 } else {
292 self.ops.push(Operation::Delete(n));
293 }
294 }
295
296 pub fn insert(&mut self, s: &str) {
298 if s.is_empty() {
299 return;
300 }
301 self.target_len += num_chars(s.as_bytes());
302 let new_last = match self.ops.as_mut_slice() {
303 [.., Operation::Insert(s_last)] => {
304 *s_last += s;
305 return;
306 }
307 [.., Operation::Insert(s_pre_last), Operation::Delete(_)] => {
308 *s_pre_last += s;
309 return;
310 }
311 [.., op_last @ Operation::Delete(_)] => {
312 let new_last = op_last.clone();
313 *op_last = Operation::Insert(s.to_owned());
314 new_last
315 }
316 _ => Operation::Insert(s.to_owned()),
317 };
318 self.ops.push(new_last);
319 }
320
321 pub fn retain(&mut self, n: u64) {
323 if n == 0 {
324 return;
325 }
326 self.base_len += n as usize;
327 self.target_len += n as usize;
328 if let Some(Operation::Retain(i_last)) = self.ops.last_mut() {
329 *i_last += n;
330 } else {
331 self.ops.push(Operation::Retain(n));
332 }
333 }
334
335 pub fn transform(&self, other: &Self) -> Result<(Self, Self), OTError> {
345 if self.base_len != other.base_len {
346 return Err(OTError);
347 }
348
349 let mut a_prime = OperationSeq::default();
350 let mut b_prime = OperationSeq::default();
351
352 let mut ops1 = self.ops.iter().cloned();
353 let mut ops2 = other.ops.iter().cloned();
354
355 let mut maybe_op1 = ops1.next();
356 let mut maybe_op2 = ops2.next();
357 loop {
358 match (&maybe_op1, &maybe_op2) {
359 (None, None) => break,
360 (Some(Operation::Insert(s)), _) => {
361 a_prime.insert(s);
362 b_prime.retain(num_chars(s.as_bytes()) as _);
363 maybe_op1 = ops1.next();
364 }
365 (_, Some(Operation::Insert(s))) => {
366 a_prime.retain(num_chars(s.as_bytes()) as _);
367 b_prime.insert(s);
368 maybe_op2 = ops2.next();
369 }
370 (None, _) => {
371 return Err(OTError);
372 }
373 (_, None) => {
374 return Err(OTError);
375 }
376 (Some(Operation::Retain(i)), Some(Operation::Retain(j))) => {
377 match i.cmp(j) {
378 Ordering::Less => {
379 a_prime.retain(*i);
380 b_prime.retain(*i);
381 maybe_op2 = Some(Operation::Retain(*j - *i));
382 maybe_op1 = ops1.next();
383 }
384 Ordering::Equal => {
385 a_prime.retain(*i);
386 b_prime.retain(*i);
387 maybe_op1 = ops1.next();
388 maybe_op2 = ops2.next();
389 }
390 Ordering::Greater => {
391 a_prime.retain(*j);
392 b_prime.retain(*j);
393 maybe_op1 = Some(Operation::Retain(*i - *j));
394 maybe_op2 = ops2.next();
395 }
396 };
397 }
398 (Some(Operation::Delete(i)), Some(Operation::Delete(j))) => match i.cmp(j) {
399 Ordering::Less => {
400 maybe_op2 = Some(Operation::Delete(*j - *i));
401 maybe_op1 = ops1.next();
402 }
403 Ordering::Equal => {
404 maybe_op1 = ops1.next();
405 maybe_op2 = ops2.next();
406 }
407 Ordering::Greater => {
408 maybe_op1 = Some(Operation::Delete(*i - *j));
409 maybe_op2 = ops2.next();
410 }
411 },
412 (Some(Operation::Delete(i)), Some(Operation::Retain(j))) => {
413 match i.cmp(j) {
414 Ordering::Less => {
415 a_prime.delete(*i);
416 maybe_op2 = Some(Operation::Retain(*j - *i));
417 maybe_op1 = ops1.next();
418 }
419 Ordering::Equal => {
420 a_prime.delete(*i);
421 maybe_op1 = ops1.next();
422 maybe_op2 = ops2.next();
423 }
424 Ordering::Greater => {
425 a_prime.delete(*j);
426 maybe_op1 = Some(Operation::Delete(*i - *j));
427 maybe_op2 = ops2.next();
428 }
429 };
430 }
431 (Some(Operation::Retain(i)), Some(Operation::Delete(j))) => {
432 match i.cmp(j) {
433 Ordering::Less => {
434 b_prime.delete(*i);
435 maybe_op2 = Some(Operation::Delete(*j - *i));
436 maybe_op1 = ops1.next();
437 }
438 Ordering::Equal => {
439 b_prime.delete(*i);
440 maybe_op1 = ops1.next();
441 maybe_op2 = ops2.next();
442 }
443 Ordering::Greater => {
444 b_prime.delete(*j);
445 maybe_op1 = Some(Operation::Retain(*i - *j));
446 maybe_op2 = ops2.next();
447 }
448 };
449 }
450 }
451 }
452
453 Ok((a_prime, b_prime))
454 }
455
456 pub fn apply(&self, s: &str) -> Result<String, OTError> {
463 if num_chars(s.as_bytes()) != self.base_len {
464 return Err(OTError);
465 }
466 let mut new_s = String::new();
467 let chars = &mut s.chars();
468 for op in &self.ops {
469 match op {
470 Operation::Retain(retain) => {
471 for c in chars.take(*retain as usize) {
472 new_s.push(c);
473 }
474 }
475 Operation::Delete(delete) => {
476 for _ in 0..*delete {
477 chars.next();
478 }
479 }
480 Operation::Insert(insert) => {
481 new_s += insert;
482 }
483 }
484 }
485 Ok(new_s)
486 }
487
488 pub fn invert(&self, s: &str) -> Self {
494 let mut inverse = OperationSeq::default();
495 let chars = &mut s.chars();
496 for op in &self.ops {
497 match op {
498 Operation::Retain(retain) => {
499 inverse.retain(*retain);
500 for _ in 0..*retain {
501 chars.next();
502 }
503 }
504 Operation::Insert(insert) => {
505 inverse.delete(num_chars(insert.as_bytes()) as u64);
506 }
507 Operation::Delete(delete) => {
508 inverse.insert(&chars.take(*delete as usize).collect::<String>());
509 }
510 }
511 }
512 inverse
513 }
514
515 #[inline]
517 pub fn is_noop(&self) -> bool {
518 matches!(self.ops.as_slice(), [] | [Operation::Retain(_)])
519 }
520
521 #[inline]
523 pub fn base_len(&self) -> usize {
524 self.base_len
525 }
526
527 #[inline]
530 pub fn target_len(&self) -> usize {
531 self.target_len
532 }
533
534 #[inline]
536 pub fn ops(&self) -> &[Operation] {
537 &self.ops
538 }
539}
540
541#[cfg(test)]
542mod tests {
543 use super::*;
544 use crate::utilities::Rng;
545
546 #[test]
547 fn lengths() {
548 let mut o = OperationSeq::default();
549 assert_eq!(o.base_len, 0);
550 assert_eq!(o.target_len, 0);
551 o.retain(5);
552 assert_eq!(o.base_len, 5);
553 assert_eq!(o.target_len, 5);
554 o.insert("abc");
555 assert_eq!(o.base_len, 5);
556 assert_eq!(o.target_len, 8);
557 o.retain(2);
558 assert_eq!(o.base_len, 7);
559 assert_eq!(o.target_len, 10);
560 o.delete(2);
561 assert_eq!(o.base_len, 9);
562 assert_eq!(o.target_len, 10);
563 }
564
565 #[test]
566 fn sequence() {
567 let mut o = OperationSeq::default();
568 o.retain(5);
569 o.retain(0);
570 o.insert("lorem");
571 o.insert("");
572 o.delete(3);
573 o.delete(0);
574 assert_eq!(o.ops.len(), 3);
575 }
576
577 #[test]
578 fn apply() {
579 for _ in 0..1000 {
580 let mut rng = Rng::default();
581 let s = rng.gen_string(50);
582 let o = rng.gen_operation_seq(&s);
583 assert_eq!(num_chars(s.as_bytes()), o.base_len);
584 assert_eq!(o.apply(&s).unwrap().chars().count(), o.target_len);
585 }
586 }
587
588 #[test]
589 fn invert() {
590 for _ in 0..1000 {
591 let mut rng = Rng::default();
592 let s = rng.gen_string(50);
593 let o = rng.gen_operation_seq(&s);
594 let p = o.invert(&s);
595 assert_eq!(o.base_len, p.target_len);
596 assert_eq!(o.target_len, p.base_len);
597 assert_eq!(p.apply(&o.apply(&s).unwrap()).unwrap(), s);
598 }
599 }
600
601 #[test]
602 fn empty_ops() {
603 let mut o = OperationSeq::default();
604 o.retain(0);
605 o.insert("");
606 o.delete(0);
607 assert_eq!(o.ops.len(), 0);
608 }
609
610 #[test]
611 fn eq() {
612 let mut o1 = OperationSeq::default();
613 o1.delete(1);
614 o1.insert("lo");
615 o1.retain(2);
616 o1.retain(3);
617 let mut o2 = OperationSeq::default();
618 o2.delete(1);
619 o2.insert("l");
620 o2.insert("o");
621 o2.retain(5);
622 assert_eq!(o1, o2);
623 o1.delete(1);
624 o2.retain(1);
625 assert_ne!(o1, o2);
626 }
627
628 #[test]
629 fn ops_merging() {
630 let mut o = OperationSeq::default();
631 assert_eq!(o.ops.len(), 0);
632 o.retain(2);
633 assert_eq!(o.ops.len(), 1);
634 assert_eq!(o.ops.last(), Some(&Operation::Retain(2)));
635 o.retain(3);
636 assert_eq!(o.ops.len(), 1);
637 assert_eq!(o.ops.last(), Some(&Operation::Retain(5)));
638 o.insert("abc");
639 assert_eq!(o.ops.len(), 2);
640 assert_eq!(o.ops.last(), Some(&Operation::Insert("abc".to_owned())));
641 o.insert("xyz");
642 assert_eq!(o.ops.len(), 2);
643 assert_eq!(o.ops.last(), Some(&Operation::Insert("abcxyz".to_owned())));
644 o.delete(1);
645 assert_eq!(o.ops.len(), 3);
646 assert_eq!(o.ops.last(), Some(&Operation::Delete(1)));
647 o.delete(1);
648 assert_eq!(o.ops.len(), 3);
649 assert_eq!(o.ops.last(), Some(&Operation::Delete(2)));
650 }
651
652 #[test]
653 fn is_noop() {
654 let mut o = OperationSeq::default();
655 assert!(o.is_noop());
656 o.retain(5);
657 assert!(o.is_noop());
658 o.retain(3);
659 assert!(o.is_noop());
660 o.insert("lorem");
661 assert!(!o.is_noop());
662 }
663
664 #[test]
665 fn compose() {
666 for _ in 0..1000 {
667 let mut rng = Rng::default();
668 let s = rng.gen_string(20);
669 let a = rng.gen_operation_seq(&s);
670 let after_a = a.apply(&s).unwrap();
671 assert_eq!(a.target_len, num_chars(after_a.as_bytes()));
672 let b = rng.gen_operation_seq(&after_a);
673 let after_b = b.apply(&after_a).unwrap();
674 assert_eq!(b.target_len, num_chars(after_b.as_bytes()));
675 let ab = a.compose(&b).unwrap();
676 assert_eq!(ab.target_len, b.target_len);
677 let after_ab = ab.apply(&s).unwrap();
678 assert_eq!(after_b, after_ab);
679 }
680 }
681
682 #[test]
683 fn transform() {
684 for _ in 0..1000 {
685 let mut rng = Rng::default();
686 let s = rng.gen_string(20);
687 let a = rng.gen_operation_seq(&s);
688 let b = rng.gen_operation_seq(&s);
689 let (a_prime, b_prime) = a.transform(&b).unwrap();
690 let ab_prime = a.compose(&b_prime).unwrap();
691 let ba_prime = b.compose(&a_prime).unwrap();
692 let after_ab_prime = ab_prime.apply(&s).unwrap();
693 let after_ba_prime = ba_prime.apply(&s).unwrap();
694 assert_eq!(ab_prime, ba_prime);
695 assert_eq!(after_ab_prime, after_ba_prime);
696 }
697 }
698
699 #[test]
700 #[cfg(feature = "serde")]
701 fn serde() {
702 use serde_json;
703
704 let mut rng = Rng::default();
705
706 let o: OperationSeq = serde_json::from_str("[1,-1,\"abc\"]").unwrap();
707 let mut o_exp = OperationSeq::default();
708 o_exp.retain(1);
709 o_exp.delete(1);
710 o_exp.insert("abc");
711 assert_eq!(o, o_exp);
712 for _ in 0..1000 {
713 let s = rng.gen_string(20);
714 let o = rng.gen_operation_seq(&s);
715 assert_eq!(
716 o,
717 serde_json::from_str(&serde_json::to_string(&o).unwrap()).unwrap()
718 );
719 }
720 }
721}