Skip to main content

xml_3dm/diff/
diff_operation.rs

1//! Diff operation types.
2//!
3//! Represents the different operations that can appear in a diff document.
4
5/// Types of operations in a diff document.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum DiffOpType {
8    /// Root tag with copy operation (base root matches branch root).
9    RootCopy,
10    /// Root tag with insert operation (new root).
11    RootInsert,
12    /// Copy a subtree from the base tree.
13    Copy,
14    /// Insert new content not from base.
15    Insert,
16}
17
18/// A diff operation with source, destination, and run count.
19#[derive(Debug, Clone)]
20pub struct DiffOperation {
21    /// The type of operation.
22    pub op_type: DiffOpType,
23    /// Source node ID (for copy operations).
24    pub source: Option<u64>,
25    /// Destination node ID (for positioning).
26    pub destination: Option<u64>,
27    /// Run count for consecutive copies.
28    pub run: Option<u64>,
29}
30
31impl DiffOperation {
32    /// Creates a new diff operation.
33    pub fn new(
34        op_type: DiffOpType,
35        source: Option<u64>,
36        destination: Option<u64>,
37        run: Option<u64>,
38    ) -> Self {
39        DiffOperation {
40            op_type,
41            source,
42            destination,
43            run,
44        }
45    }
46
47    /// Creates a root copy operation.
48    pub fn root_copy() -> Self {
49        DiffOperation::new(DiffOpType::RootCopy, None, None, None)
50    }
51
52    /// Creates a root insert operation.
53    pub fn root_insert() -> Self {
54        DiffOperation::new(DiffOpType::RootInsert, None, None, None)
55    }
56
57    /// Creates a copy operation.
58    pub fn copy(source: u64, destination: Option<u64>, run: u64) -> Self {
59        DiffOperation::new(DiffOpType::Copy, Some(source), destination, Some(run))
60    }
61
62    /// Creates an insert operation.
63    pub fn insert(destination: Option<u64>) -> Self {
64        DiffOperation::new(DiffOpType::Insert, None, destination, None)
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn test_root_copy() {
74        let op = DiffOperation::root_copy();
75        assert_eq!(op.op_type, DiffOpType::RootCopy);
76        assert!(op.source.is_none());
77    }
78
79    #[test]
80    fn test_root_insert() {
81        let op = DiffOperation::root_insert();
82        assert_eq!(op.op_type, DiffOpType::RootInsert);
83    }
84
85    #[test]
86    fn test_copy() {
87        let op = DiffOperation::copy(5, Some(10), 3);
88        assert_eq!(op.op_type, DiffOpType::Copy);
89        assert_eq!(op.source, Some(5));
90        assert_eq!(op.destination, Some(10));
91        assert_eq!(op.run, Some(3));
92    }
93
94    #[test]
95    fn test_insert() {
96        let op = DiffOperation::insert(Some(7));
97        assert_eq!(op.op_type, DiffOpType::Insert);
98        assert!(op.source.is_none());
99        assert_eq!(op.destination, Some(7));
100    }
101}