use crate::parser::Stream;
use crate::parser::parts::chars::content_char;
use winnow::combinator::{alt, cut_err, peek};
use winnow::stream::AsChar;
use winnow::token::{one_of, take_while};
use winnow::{ModalResult, Parser, seq};
use winnow::{
ascii::line_ending,
error::{StrContext, StrContextValue},
};
pub(crate) fn p_comment<'s>(is: &mut Stream<'s>) -> ModalResult<&'s str> {
let m = seq!(
_: ';',
cut_err(alt((
peek(line_ending).map(|_| {("",)}),
seq!(
_: cut_err(one_of(AsChar::is_space)).context(StrContext::Label("comment"))
.context(StrContext::Expected(StrContextValue::Description("space character"))),
take_while(0.., content_char),
_: cut_err(peek(line_ending)).context(StrContext::Label("comment"))
.context(StrContext::Expected(StrContextValue::Description("valid unicode text and newline")))
)
)).map(|x| x.0))
.context(StrContext::Expected(StrContextValue::Description("comment starts with `;` character, followed by space"))),
)
.map(|x| x.0)
.parse_next(is)?;
Ok(m)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::kernel::Settings;
use crate::parser::tests::content_data;
#[test]
fn test_p_comment() {
let mut count = 0;
let pok_tests = content_data();
for t in &pok_tests {
let mut settings = Settings::default();
let i = format!("; {t}\n");
let mut is = Stream {
input: i.as_str(),
state: &mut settings,
};
let res = p_comment(&mut is);
assert!(
res.is_ok(),
"\nPOK is error: Offending test vector item: #{}, '{}'\n",
count + 1,
t
);
let code = res.unwrap();
assert_eq!(t, code);
count += 1;
}
assert_eq!(count, pok_tests.len());
}
}