use nom::{bytes::complete::tag, combinator::recognize, multi::many1, IResult,
Parser};
use crate::{fg_blue, fg_green, fg_red, md_parser::constants::NEW_LINE,
take_text_between_delims_err_on_new_line, DEBUG_MD_PARSER_STDOUT};
#[must_use]
pub fn count_delim_occurrences_until_eol<'i>(
input: &'i str,
delim: &'i str,
) -> (usize, bool, bool, &'i str) {
let (first_part, _) = input.split_at(input.find(NEW_LINE).unwrap_or(input.len()));
let num_of_delim_occurrences = first_part.matches(delim).count();
(
num_of_delim_occurrences,
input.starts_with(delim),
input == delim,
delim,
)
}
#[rustfmt::skip]
pub fn take_starts_with_delim_no_new_line<'i>(
input: &'i str,
delim: &'i str,
) -> IResult<&'i str, &'i str> {
let (num_of_delim_occurrences, starts_with_delim, input_is_delim, _) =
count_delim_occurrences_until_eol(input, delim);
DEBUG_MD_PARSER_STDOUT.then(|| {
println!(
"\n{} specialized parser {}: \ninput: {:?}, delim: {:?}",
fg_green("■■"),
delim,
input,
delim
);
println!(
"count: {num_of_delim_occurrences}, starts_w: {starts_with_delim}, input=delim: {input_is_delim}"
);
});
if
!starts_with_delim
||
input_is_delim
||
num_of_delim_occurrences == 1
{
DEBUG_MD_PARSER_STDOUT.then(|| {
println!("{a} parser error out for input: {i:?}",
a = fg_red("⬢⬢"),
i = input
);
});
return Err(nom::Err::Error(nom::error::Error {
input,
code: nom::error::ErrorKind::Fail,
}));
}
if num_of_delim_occurrences > 1 {
let it = take_text_between_delims_err_on_new_line(input, delim, delim);
DEBUG_MD_PARSER_STDOUT.then(|| {
println!("{a} it: {b:?}",
a = fg_blue("▲▲"),
b = it
);
});
return it;
}
let (rem, output) = recognize(many1(tag(delim))).parse(input)?;
DEBUG_MD_PARSER_STDOUT.then(|| {
println!("{a}, rem: {r:?}, output: {o:?}",
a = fg_blue("▲▲"),
r = rem,
o = output
);
});
Ok((rem, output))
}