Thanks to visit codestin.com
Credit goes to docs.rs

Skip to main content

csvpp/source_code/
mod.rs

1//! # `SourceCode`
2//!
3use std::path;
4
5mod arc_source_code;
6mod display;
7mod errors;
8mod try_from;
9
10pub(crate) use arc_source_code::ArcSourceCode;
11
12/// the line number - counts from `0` but renders the first line as `"1"`
13pub type LineNumber = usize;
14
15/// the amount of characters offset from the beginning of the line
16pub type CharOffset = usize;
17
18#[derive(Debug, serde::Deserialize, serde::Serialize)]
19pub struct SourceCode {
20    pub filename: path::PathBuf,
21    pub(crate) lines: LineNumber,
22    pub(crate) length_of_code_section: LineNumber,
23    pub(crate) length_of_csv_section: LineNumber,
24    pub(crate) code_section: Option<String>,
25    pub(crate) csv_section: String,
26    pub(crate) original: String,
27}
28
29impl SourceCode {
30    /// Open the source code and do a rough first pass where we split the code section from the CSV
31    /// section by looking for `---`.
32    // TODO: make `filename` optional - we don't have it when reading from CLI key/values.  or if
33    // we were ever to support from stdin
34    pub(crate) fn new<S, P>(input: S, filename: P) -> SourceCode
35    where
36        S: Into<String>,
37        P: Into<path::PathBuf>,
38    {
39        let str_input: String = input.into();
40
41        if let Some(p) = str_input
42            .lines()
43            .position(|l| regex::Regex::new(r"^\s*---\s*$").unwrap().is_match(l))
44        {
45            let lines: Vec<_> = str_input.lines().collect();
46            let csv_lines = &lines[(p + 1)..];
47            let code_lines = &lines[..p];
48
49            SourceCode {
50                filename: filename.into(),
51                lines: lines.len(),
52                // +1 because `code_lines` will account for the separator `---`
53                length_of_code_section: code_lines.len() + 1,
54                length_of_csv_section: csv_lines.len(),
55                csv_section: csv_lines.join("\n"),
56                code_section: Some(code_lines.join("\n")),
57                original: str_input.clone(),
58            }
59        } else {
60            let csv_lines = str_input.lines().count();
61
62            SourceCode {
63                filename: filename.into(),
64                lines: csv_lines,
65                length_of_code_section: 0,
66                length_of_csv_section: csv_lines,
67                csv_section: str_input.clone(),
68                code_section: None,
69                original: str_input.clone(),
70            }
71        }
72    }
73
74    pub(crate) fn object_code_filename(&self) -> path::PathBuf {
75        let mut f = self.filename.clone();
76        f.set_extension("csvpo");
77        f
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84    use std::path;
85
86    fn build_source_code() -> SourceCode {
87        SourceCode {
88            filename: path::PathBuf::from("test.csvpp".to_string()),
89            lines: 25,
90            length_of_code_section: 10,
91            length_of_csv_section: 15,
92            code_section: Some("\n".repeat(10)),
93            csv_section: "foo,bar,baz".to_string(),
94            original: "\n\n\n\n\n\n\n\n\n\n---\nfoo,bar,baz".to_string(),
95        }
96    }
97
98    #[test]
99    fn object_code_filename() {
100        assert_eq!(
101            path::PathBuf::from("test.csvpo"),
102            build_source_code().object_code_filename()
103        );
104    }
105
106    #[test]
107    fn new() {
108        let source_code = SourceCode::new(
109            "foo := 2
110bar := 3
111---
112foo,bar,baz
113=foo",
114            "foo.csvpp",
115        );
116
117        assert_eq!(source_code.lines, 5);
118        assert_eq!(source_code.length_of_csv_section, 2);
119        assert_eq!(source_code.length_of_code_section, 3);
120    }
121
122    #[test]
123    fn new_no_scope() {
124        let source_code = SourceCode::new("foo,bar,baz", "foo.csvpp");
125
126        assert_eq!(source_code.lines, 1);
127        assert_eq!(source_code.length_of_csv_section, 1);
128        assert_eq!(source_code.length_of_code_section, 0);
129        assert_eq!(source_code.code_section, None);
130        assert_eq!(source_code.csv_section, "foo,bar,baz".to_string());
131    }
132}