Skip to main content

socketry_markdown/
unist.rs

1// Released under the MIT License.
2// Copyright, 2022, by Titus Wormer.
3// Copyright, 2023, by Kyle McCarthy.
4// Copyright, 2023, by Rafael Bachmann.
5// Copyright, 2026, by Samuel Williams.
6
7//! abstract syntax trees: [unist][].
8//!
9//! [unist]: https://github.com/syntax-tree/unist
10use alloc::fmt;
11
12/// One place in a source file.
13#[derive(Clone, Eq, PartialEq)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct Point {
16    /// 1-indexed integer representing a line in a source file.
17    pub line: usize,
18    /// 1-indexed integer representing a column in a source file.
19    pub column: usize,
20    /// 0-indexed integer representing a character in a source file.
21    pub offset: usize,
22}
23
24impl Point {
25    #[must_use]
26    pub fn new(line: usize, column: usize, offset: usize) -> Point {
27        Point {
28            line,
29            column,
30            offset,
31        }
32    }
33}
34
35impl fmt::Debug for Point {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        write!(f, "{}:{} ({})", self.line, self.column, self.offset)
38    }
39}
40
41/// Location of a node in a source file.
42#[derive(Clone, Eq, PartialEq)]
43#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
44pub struct Position {
45    /// Represents the place of the first character of the parsed source region.
46    pub start: Point,
47    /// Represents the place of the first character after the parsed source
48    /// region, whether it exists or not.
49    pub end: Point,
50}
51
52impl Position {
53    #[must_use]
54    pub fn new(
55        start_line: usize,
56        start_column: usize,
57        start_offset: usize,
58        end_line: usize,
59        end_column: usize,
60        end_offset: usize,
61    ) -> Position {
62        Position {
63            start: Point::new(start_line, start_column, start_offset),
64            end: Point::new(end_line, end_column, end_offset),
65        }
66    }
67}
68
69impl fmt::Debug for Position {
70    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71        write!(
72            f,
73            "{}:{}-{}:{} ({}-{})",
74            self.start.line,
75            self.start.column,
76            self.end.line,
77            self.end.column,
78            self.start.offset,
79            self.end.offset
80        )
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87    use alloc::format;
88
89    #[test]
90    fn point() {
91        let point = Point::new(1, 1, 0);
92        assert_eq!(
93            format!("{point:?}"),
94            "1:1 (0)",
95            "should support `Debug` on unist points"
96        );
97    }
98
99    #[test]
100    fn position() {
101        let position = Position::new(1, 1, 0, 1, 3, 2);
102        assert_eq!(
103            format!("{position:?}"),
104            "1:1-1:3 (0-2)",
105            "should support `Debug` on unist positions"
106        );
107    }
108}