Registry / RepositoryTypeScriptRustPython
Rollpie
ReadmeFiles
Versions
Info
Download
0.4.01085.8 KB2026-10-160.3.21087.6 KB2026-10-160.3.11087.5 KB2026-10-160.3.0117.8 KB2026-10-160.2.1106.1 KB2026-10-150.2.0105.5 KB2026-10-15
Version
0.3.0
Copyright
Rollpie, Irohabook
Publisher
math
Published
2026-10-16
Size
117.8 KB
Downloads
24
Checksum
91f9899559d38e059baa788310473f349f3d218d16f6afbd045fc9d087ba00c3
Dependencies
rust/[email protected]
rust/[email protected]

error.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! The error for when reading or building fails

use std::fmt;


/// The reason for the failure, and where it is in the original string
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Error {
    /// A description of what happened
    pub message: String,
    /// The character position counted from the start of the original string (starting at 0)
    pub position: usize,
}


impl Error {
    pub fn new(message: impl Into<String>, position: usize) -> Error {
        Error {message: message.into(), position}
    }
}


impl fmt::Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "{} ({} 文字目)", self.message, self.position + 1)
    }
}


impl std::error::Error for Error {}


/// Converts a character position to a line and a column. Both count from 1
pub fn place(source: &[char], position: usize) -> (usize, usize) {
    let mut line = 1;
    let mut column = 1;

    for character in source.iter().take(position) {
        if *character == '\n' {
            line += 1;
            column = 1;

        } else {
            column += 1;
        }
    }

    (line, column)
}


/// Restates the position of the error as a line and a column
pub fn describe(source: &[char], error: &Error) -> String {
    let (line, column) = place(source, error.position);

    format!("{line} 行 {column} 桁: {}", error.message)
}


#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn a_position_becomes_a_line_and_a_column() {
        let source: Vec<char> = "abc\ndef".chars().collect();
        assert_eq!(place(&source, 0), (1, 1));
        assert_eq!(place(&source, 4), (2, 1));
        assert_eq!(place(&source, 6), (2, 3));
    }
}