Lines
100 %
Functions
53.33 %
Branches
//! Whitespace skipping and the `; @annotation` reader-comment
//! collector. The annotation handler is the only place that pulls
//! `parse_expr` back in from the surrounding module — annotations
//! evaluate their RHS as an expression so the sample harness can
//! attach metadata like `; @test (= (count 'defun) 5)`.
use winnow::ascii::{line_ending, space0, till_line_ending};
use winnow::combinator::opt;
use winnow::error::ModalResult;
use winnow::prelude::*;
use winnow::token::take_while;
use crate::ast::{Annotation, Expr};
pub(super) fn skip_ws_and_comments(
input: &mut &str,
annotations: &mut Vec<Annotation>,
) -> ModalResult<()> {
loop {
let _ = space0.parse_next(input)?;
if input.starts_with("; @") {
let _ = "; @".parse_next(input)?;
let name: &str = take_while(1.., |c: char| c.is_alphanumeric() || c == '-' || c == '_')
.parse_next(input)?;
let value = super::parse_expr(input).unwrap_or(Expr::Nil);
annotations.push(Annotation {
name: name.to_string(),
value,
});
let _ = till_line_ending.parse_next(input)?;
let _ = opt(line_ending).parse_next(input)?;
} else if input.starts_with(';') {
} else if input.starts_with('\n') || input.starts_with('\r') {
let _ = line_ending.parse_next(input)?;
} else {
break;
}
Ok(())
pub(super) fn skip_ws_and_comments_no_annotations(input: &mut &str) -> ModalResult<()> {
let mut dummy = Vec::new();
skip_ws_and_comments(input, &mut dummy)