From be6e6089f0d4713af3460d8c1f3efad331b92adc Mon Sep 17 00:00:00 2001 From: mars Date: Sat, 10 Feb 2024 15:55:37 -0700 Subject: [PATCH] Language struct + header reading --- src/main.rs | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/main.rs b/src/main.rs index 3790416..6890bcd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,71 @@ // You should have received a copy of the GNU Affero General Public License // along with Saul. If not, see . +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> { + 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() { 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"]); + } +}