orgize/src/elements/target.rs

49 lines
1.3 KiB
Rust

use nom::{
bytes::complete::{tag, take_while},
combinator::verify,
sequence::delimited,
IResult,
};
use crate::elements::Element;
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[derive(Debug)]
pub struct Target<'a> {
pub target: &'a str,
}
impl Target<'_> {
#[inline]
pub(crate) fn parse(input: &str) -> IResult<&str, Element<'_>> {
let (input, target) = delimited(
tag("<<"),
verify(
take_while(|c: char| c != '<' && c != '\n' && c != '>'),
|s: &str| s.starts_with(|c| c != ' ') && s.ends_with(|c| c != ' '),
),
tag(">>"),
)(input)?;
Ok((input, Element::Target(Target { target })))
}
}
#[test]
fn parse() {
assert_eq!(
Target::parse("<<target>>"),
Ok(("", Element::Target(Target { target: "target" })))
);
assert_eq!(
Target::parse("<<tar get>>"),
Ok(("", Element::Target(Target { target: "tar get" })))
);
assert!(Target::parse("<<target >>").is_err());
assert!(Target::parse("<< target>>").is_err());
assert!(Target::parse("<<ta<get>>").is_err());
assert!(Target::parse("<<ta>get>>").is_err());
assert!(Target::parse("<<ta\nget>>").is_err());
assert!(Target::parse("<<target>").is_err());
}