use crate::structs::InlineTag;
use nom::{
branch::alt,
bytes::complete::tag,
combinator::{fail, value},
multi::fold_many0,
sequence::delimited,
IResult,
};
pub fn no_textile(input: &str) -> IResult<&str, InlineTag> {
let (rest, content) = delimited(
tag("=="),
fold_many0(
alt((
value("\\", tag("\\\\")),
value("==", tag("\\==")),
no_textile_content,
)),
String::new,
|mut acc, s| {
acc.push_str(s);
acc
},
),
tag("=="),
)(input)?;
Ok((rest, InlineTag::NoTextile(content)))
}
fn no_textile_content(input: &str) -> IResult<&str, &str> {
let res: IResult<&str, &str> = alt((tag("=="), tag("\\")))(input);
if let Err(_) = res {
if input != "" {
return Ok((&input[1..], &input[0..1]));
}
}
fail(input)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn no_textile_basic() {
let input = "==hello *world!*==";
let result = no_textile(input);
assert_eq!(
result,
Ok(("", InlineTag::NoTextile(String::from("hello *world!*",))))
);
}
#[test]
fn no_textile_with_equals() {
let input =
"==This is two equals signs: \\== here are two more: \\====";
let result = no_textile(input);
assert_eq!(
result,
Ok((
"",
InlineTag::NoTextile(String::from(
"This is two equals signs: == here are two more: ==",
))
))
);
}
}