#[cfg_attr(test, derive(PartialEq))] #[derive(Debug)] pub struct InlineSrc<'a> { pub lang: &'a str, pub option: Option<&'a str>, pub body: &'a str, } impl<'a> InlineSrc<'a> { pub fn parse(src: &'a str) -> Option<(InlineSrc, usize)> { starts_with!(src, "src_"); let lang = until_while!(src, 4, |c| c == b'[' || c == b'{', |c: u8| !c .is_ascii_whitespace())?; if lang == 4 { return None; } if src.as_bytes()[lang] == b'[' { let option = until_while!(src, lang, b']', |c| c != b'\n')?; let body = until_while!(src, option, b'}', |c| c != b'\n')?; Some(( InlineSrc { lang: &src[4..lang], option: Some(&src[lang + 1..option]), body: &src[option + 2..body], }, body + 1, )) } else { let body = until_while!(src, lang, b'}', |c| c != b'\n')?; Some(( InlineSrc { lang: &src[4..lang], option: None, body: &src[lang + 1..body], }, body + 1, )) } } } #[test] fn parse() { assert_eq!( InlineSrc::parse("src_C{int a = 0;}").unwrap(), ( InlineSrc { lang: "C", option: None, body: "int a = 0;" }, "src_C{int a = 0;}".len() ) ); assert_eq!( InlineSrc::parse("src_xml[:exports code]{text}").unwrap(), ( InlineSrc { lang: "xml", option: Some(":exports code"), body: "text" }, "src_xml[:exports code]{text}".len() ) ); assert!(InlineSrc::parse("src_xml[:exports code]{text").is_none()); assert!(InlineSrc::parse("src_[:exports code]{text}").is_none()); assert!(InlineSrc::parse("src_xml[:exports code]").is_none()); }