use nom::{ bytes::complete::tag, character::complete::space0, error::ErrorKind, sequence::{delimited, tuple}, IResult, InputTakeAtPosition, Parser, }; pub fn account(input: &str) -> IResult<&str, &str> { input.split_at_position1_complete(|item| item == ' ' || item == '\t', ErrorKind::AlphaNumeric) } pub fn metadatum(input: &str) -> IResult<&str, (&str, &str)> { tuple(( delimited(tag("-"), delimited(space0, key, space0), tag(":")), value, )) .map(|v| (v.0, v.1.trim())) .parse(input) } pub fn key(input: &str) -> IResult<&str, &str> { input.split_at_position1_complete(|item| item == ':', ErrorKind::AlphaNumeric) } pub fn value(input: &str) -> IResult<&str, &str> { input.split_at_position1_complete(|_| false, ErrorKind::AlphaNumeric) } #[cfg(test)] mod tests { use super::*; #[test] fn parse_metadatum() { assert_eq!( metadatum("- key: value").unwrap().1, ("key".into(), "value".into()) ); assert_eq!( metadatum("- key space: value space").unwrap().1, ("key space".into(), "value space".into()) ); } #[test] fn parse_metadatum_invalid() { assert!(metadatum("- key:").is_err()); assert!(metadatum("- : value").is_err()); assert!(metadatum("- : ").is_err()); } }