1use crate::ids::Id;
8
9pub type FileId = Id<SourceFile>;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct SourceFile {
15 pub path: String,
17}
18
19impl SourceFile {
20 pub fn new(path: impl Into<String>) -> Self {
22 SourceFile { path: path.into() }
23 }
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub struct Position {
29 pub line: u32,
30 pub col: u32,
31}
32
33impl Position {
34 pub const fn new(line: u32, col: u32) -> Self {
36 Position { line, col }
37 }
38
39 pub const fn is_valid(self) -> bool {
41 self.line >= 1 && self.col >= 1
42 }
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
47pub struct Span {
48 pub file: FileId,
49 pub start: Position,
50 pub end: Position,
51}
52
53impl Span {
54 pub const fn new(file: FileId, start: Position, end: Position) -> Self {
56 Span { file, start, end }
57 }
58
59 pub const fn is_valid(self) -> bool {
62 self.start.is_valid()
63 && self.end.is_valid()
64 && (self.end.line > self.start.line
65 || (self.end.line == self.start.line && self.end.col >= self.start.col))
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::{Position, SourceFile, Span};
72 use crate::ids::Id;
73
74 #[test]
75 fn positions_are_one_based_and_validated() {
76 assert!(Position::new(1, 1).is_valid());
77 assert!(Position::new(10, 24).is_valid());
78 assert!(!Position::new(0, 1).is_valid());
79 assert!(!Position::new(1, 0).is_valid());
80 }
81
82 #[test]
83 fn spans_require_end_not_before_start() {
84 let file = Id::from_index(0);
85 assert!(Span::new(file, Position::new(1, 1), Position::new(1, 5)).is_valid());
86 assert!(Span::new(file, Position::new(1, 1), Position::new(2, 1)).is_valid());
87 assert!(Span::new(file, Position::new(1, 1), Position::new(1, 1)).is_valid());
88 assert!(!Span::new(file, Position::new(1, 5), Position::new(1, 1)).is_valid());
89 assert!(!Span::new(file, Position::new(2, 1), Position::new(1, 1)).is_valid());
90 }
91
92 #[test]
93 fn source_files_carry_paths() {
94 let file = SourceFile::new("source.opy");
95 assert_eq!(file.path, "source.opy");
96 }
97}