use crate::IncludeToken;
use crate::{wr, ParseContainer};
use nom::branch::alt;
use nom::character::complete::{line_ending, space0};
use nom::combinator::eof;
use nom::sequence::tuple;
use nom::IResult;
#[derive(Clone, Debug)]
pub struct IncludeLine {
token: IncludeToken,
}
impl IncludeLine {
pub fn parse(input: ParseContainer) -> IResult<ParseContainer, (Vec<ParseContainer>, Self)> {
let (input, parsed) = tuple((
wr!(space0),
IncludeToken::parse,
wr!(space0),
alt((wr!(eof), wr!(line_ending))),
))(input)?;
let (token_raws, token_parsed) = parsed.1;
let ret0 = [parsed.0]
.into_iter()
.chain(token_raws)
.chain([parsed.2, parsed.3])
.collect();
let ret1 = Self {
token: token_parsed,
};
Ok((input, (ret0, ret1)))
}
pub fn token(&self) -> IncludeToken {
self.token.clone()
}
pub fn filepath(&self) -> &str {
self.token.filepath()
}
pub fn index(&self) -> Option<usize> {
self.token.index()
}
pub fn id(&self) -> Option<&str> {
self.token.id()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_start_line() -> anyhow::Result<()> {
let testdata = " !include foo.puml\n";
let (rest, (parsed, IncludeLine { token })) = IncludeLine::parse(testdata.into())?;
assert_eq!(rest, "");
assert_eq!(testdata, parsed.join(""));
assert_eq!(token.filepath(), "foo.puml");
assert_eq!(token.index(), None);
assert_eq!(token.id(), None);
let testdata = " !include bar.puml!1\n";
let (rest, (parsed, IncludeLine { token })) = IncludeLine::parse(testdata.into())?;
assert_eq!(rest, "");
assert_eq!(testdata, parsed.join(""));
assert_eq!(token.filepath(), "bar.puml");
assert_eq!(token.index(), Some(1));
assert_eq!(token.id(), Some("1"));
let testdata = "\t !include buz.puml!qux\n";
let (rest, (parsed, IncludeLine { token })) = IncludeLine::parse(testdata.into())?;
assert_eq!(rest, "");
assert_eq!(testdata, parsed.join(""));
assert_eq!(token.filepath(), "buz.puml");
assert_eq!(token.index(), None);
assert_eq!(token.id(), Some("qux"));
Ok(())
}
}