Skip to main content

quarto_source_map/
types.rs

1//! Core types for source mapping
2
3use serde::{Deserialize, Serialize};
4
5/// A unique identifier for a source file
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
7pub struct FileId(pub usize);
8
9/// A location in source text (0-indexed)
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
11pub struct Location {
12    /// Byte offset from start of source
13    pub offset: usize,
14    /// Row number (0-indexed)
15    pub row: usize,
16    /// Column number (0-indexed, in characters not bytes)
17    pub column: usize,
18}
19
20/// A range in source text from start to end
21#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
22pub struct Range {
23    /// Start location (inclusive)
24    pub start: Location,
25    /// End location (exclusive)
26    pub end: Location,
27}
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32
33    #[test]
34    fn test_file_id_equality() {
35        let id1 = FileId(0);
36        let id2 = FileId(0);
37        let id3 = FileId(1);
38
39        assert_eq!(id1, id2);
40        assert_ne!(id1, id3);
41    }
42
43    #[test]
44    fn test_location_ordering() {
45        let loc1 = Location {
46            offset: 0,
47            row: 0,
48            column: 0,
49        };
50        let loc2 = Location {
51            offset: 5,
52            row: 0,
53            column: 5,
54        };
55        let loc3 = Location {
56            offset: 10,
57            row: 1,
58            column: 0,
59        };
60
61        assert!(loc1 < loc2);
62        assert!(loc2 < loc3);
63        assert!(loc1 < loc3);
64    }
65
66    #[test]
67    fn test_location_equality() {
68        let loc1 = Location {
69            offset: 5,
70            row: 0,
71            column: 5,
72        };
73        let loc2 = Location {
74            offset: 5,
75            row: 0,
76            column: 5,
77        };
78        let loc3 = Location {
79            offset: 6,
80            row: 0,
81            column: 6,
82        };
83
84        assert_eq!(loc1, loc2);
85        assert_ne!(loc1, loc3);
86    }
87
88    #[test]
89    fn test_range_equality() {
90        let range1 = Range {
91            start: Location {
92                offset: 0,
93                row: 0,
94                column: 0,
95            },
96            end: Location {
97                offset: 5,
98                row: 0,
99                column: 5,
100            },
101        };
102        let range2 = Range {
103            start: Location {
104                offset: 0,
105                row: 0,
106                column: 0,
107            },
108            end: Location {
109                offset: 5,
110                row: 0,
111                column: 5,
112            },
113        };
114        let range3 = Range {
115            start: Location {
116                offset: 0,
117                row: 0,
118                column: 0,
119            },
120            end: Location {
121                offset: 10,
122                row: 0,
123                column: 10,
124            },
125        };
126
127        assert_eq!(range1, range2);
128        assert_ne!(range1, range3);
129    }
130
131    #[test]
132    fn test_serialization_file_id() {
133        let id = FileId(42);
134        let json = serde_json::to_string(&id).unwrap();
135        let deserialized: FileId = serde_json::from_str(&json).unwrap();
136        assert_eq!(id, deserialized);
137    }
138
139    #[test]
140    fn test_serialization_location() {
141        let loc = Location {
142            offset: 100,
143            row: 5,
144            column: 10,
145        };
146        let json = serde_json::to_string(&loc).unwrap();
147        let deserialized: Location = serde_json::from_str(&json).unwrap();
148        assert_eq!(loc, deserialized);
149    }
150
151    #[test]
152    fn test_serialization_range() {
153        let range = Range {
154            start: Location {
155                offset: 0,
156                row: 0,
157                column: 0,
158            },
159            end: Location {
160                offset: 50,
161                row: 2,
162                column: 10,
163            },
164        };
165        let json = serde_json::to_string(&range).unwrap();
166        let deserialized: Range = serde_json::from_str(&json).unwrap();
167        assert_eq!(range, deserialized);
168    }
169}