1.8 KiB, 1 run
created by r2848102244:89, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | //! The two operations of design note section 4.6. |
| 2 | //! |
| 3 | //! Neither carries a numeric position, a line number, or a position identifier. |
| 4 | //! Every reference is a content id. |
| 5 | |
| 6 | use crate::id::{ |
| 7 | Anchor, |
| 8 | ContentRange, |
| 9 | OpId, |
| 10 | }; |
| 11 | |
| 12 | /// A splice, or a move. The prototype is single-file, so `file` and `to_file` |
| 13 | /// of section 4.6 are omitted. |
| 14 | #[derive(Clone, PartialEq, Eq, Debug)] |
| 15 | pub enum Op { |
| 16 | /// Inserts bytes and kills content ranges. |
| 17 | Splice { |
| 18 | /// Operation identity. |
| 19 | id: OpId, |
| 20 | /// Left Fugue origin for the inserted bytes. |
| 21 | left: Anchor, |
| 22 | /// Right Fugue origin for the inserted bytes. |
| 23 | right: Anchor, |
| 24 | /// What dies; may be empty. |
| 25 | remove: Vec<ContentRange>, |
| 26 | /// What is inserted; may be empty. |
| 27 | insert: Vec<u8>, |
| 28 | }, |
| 29 | /// Reclaims existing content ranges at a new position. |
| 30 | Move { |
| 31 | /// Operation identity. |
| 32 | id: OpId, |
| 33 | /// What moves, in content ids, in destination order. |
| 34 | src: Vec<ContentRange>, |
| 35 | /// Left Fugue origin for the destination. |
| 36 | left: Anchor, |
| 37 | /// Right Fugue origin for the destination. |
| 38 | right: Anchor, |
| 39 | }, |
| 40 | } |
| 41 | |
| 42 | impl Op { |
| 43 | /// The operation's identity. |
| 44 | pub fn id(&self) -> OpId { |
| 45 | match self { |
| 46 | Self::Splice { id, .. } => *id, |
| 47 | Self::Move { id, .. } => *id, |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | /// The operation's destination anchors. |
| 52 | pub fn anchors(&self) -> (Anchor, Anchor) { |
| 53 | match self { |
| 54 | Self::Splice { left, right, .. } => (*left, *right), |
| 55 | Self::Move { left, right, .. } => (*left, *right), |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | /// Whether the operation is a move. |
| 60 | pub fn is_move(&self) -> bool { |
| 61 | matches!(self, Self::Move { .. }) |
| 62 | } |
| 63 | |
| 64 | /// The total byte span this operation places, which is the inserted length |
| 65 | /// for a splice and the sum of the source range lengths for a move. |
| 66 | pub fn placed_len(&self) -> u32 { |
| 67 | match self { |
| 68 | Self::Splice { insert, .. } => insert.len() as u32, |
| 69 | Self::Move { src, .. } => src.iter().map(|r| r.len()).sum(), |
| 70 | } |
| 71 | } |
| 72 | } |