Language struct + header reading
This commit is contained in:
parent
fc09286364
commit
be6e6089f0
65
src/main.rs
65
src/main.rs
|
@ -16,6 +16,71 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with Saul. If not, see <https://www.gnu.org/licenses/>.
|
// along with Saul. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
|
io::{self, BufRead},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Configuration of a particular language. Affects parsing and output.
|
||||||
|
pub struct Language {
|
||||||
|
/// A string that appears before all commented lines.
|
||||||
|
pub comment: Cow<'static, str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Language {
|
||||||
|
/// The default Rust language config.
|
||||||
|
pub const RUST: Self = Self {
|
||||||
|
comment: Cow::Borrowed("// "),
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Extracts a header (as a list of lines) from an input in this language.
|
||||||
|
///
|
||||||
|
/// Don't reply on the state of the reader being consistent after this function
|
||||||
|
/// is called.
|
||||||
|
pub fn read_header(&self, f: &mut impl BufRead) -> io::Result<Vec<String>> {
|
||||||
|
let mut header = Vec::new();
|
||||||
|
let mut is_first_line = true;
|
||||||
|
|
||||||
|
for line in f.lines() {
|
||||||
|
let line = line?;
|
||||||
|
|
||||||
|
if is_first_line && line.starts_with("#!") {
|
||||||
|
is_first_line = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_first_line = false;
|
||||||
|
|
||||||
|
let Some(content) = line.strip_prefix(self.comment.as_ref()) else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
header.push(content.trim().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(header)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn header() {
|
||||||
|
let src = b"// header content\n// header content 2\nbody";
|
||||||
|
let lines = Language::RUST.read_header(&mut src.as_slice()).unwrap();
|
||||||
|
assert_eq!(lines, vec!["header content", "header content 2"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn skip_header_shebang() {
|
||||||
|
let src = b"#!/bin/sh\n// header content\nbody goes here";
|
||||||
|
let lines = Language::RUST.read_header(&mut src.as_slice()).unwrap();
|
||||||
|
assert_eq!(lines, vec!["header content"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue