From ab40eb688b10b38c40740423abbcf3e2e64efcc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Thu, 12 Jan 2023 23:33:14 +0100 Subject: [PATCH] Add metadata support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime “pep” Buquet --- src/lib.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4462b4b..cec9336 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,6 +43,18 @@ impl<'a> From>>> for Token<'a> { pub static DEFAULT_NS: &'static str = "jabber:client"; pub static SCANSION_NS: &'static str = "https://matthewwild.co.uk/projects/scansion"; +#[derive(Debug, Clone, PartialEq)] +pub struct Metadata { + pub title: String, + pub description: Option, +} + +impl Metadata { + pub fn new, T: Into>(title: S, desc: Option) -> Metadata { + Metadata { title: title.into(), description: desc.map(|t| t.into()) } + } +} + pub type ClientName = String; #[derive(Debug, Clone, PartialEq)] @@ -84,6 +96,7 @@ pub enum Action { #[derive(Debug, Clone, PartialEq)] pub struct Spec { + pub metadata: Option, pub clients: HashMap, pub actions: Vec, } @@ -139,6 +152,28 @@ where } } +fn parse_meta(s: Span) -> IResult { + let (s, (_pos, title)) = + tuple((position, delimited(tag("#"), take_until("\n"), tag("\n"))))(s)?; + + let optdesc = opt(tuple(( + position, + delimited(tag("#"), take_until("\n"), tag("\n")), + )))(s)?; + + let mut desc: Option<&str> = None; + let s = match optdesc { + (s, Some((_pos, val))) => { + desc = Some(val.trim()); + s + } + (s, None) => s, + }; + + let meta = Metadata::new(title.trim(), desc); + Ok((s, meta)) +} + fn parse_client(s: Span) -> IResult { let (s, (_, _, _, name, _)) = tuple((allspaces, tag("[Client]"), space0, take_until("\n"), space0))(s)?; @@ -268,10 +303,15 @@ fn parse_actions(s: Span) -> IResult> { pub fn parse_spec(i: &str) -> Result { let s: Span = i.into(); + let (s, metadata) = opt(parse_meta)(s)?; let (s, clients) = parse_clients(s)?; let (s, _) = parse_sep(s)?; let (_, actions) = parse_actions(s)?; - Ok(Spec { clients, actions }) + Ok(Spec { + metadata, + clients, + actions, + }) } #[cfg(test)] @@ -450,7 +490,9 @@ mod tests { #[test] fn test_parse_spec() { - let buf = r#" + let buf = r#"# Test title +# Description Foo + [Client] louise jid: louise@localhost password: password @@ -468,6 +510,8 @@ louise receives: "#; + let metadata = Some(Metadata::new("Test title", Some("Description Foo"))); + let mut clients: HashMap = HashMap::new(); clients.insert(String::from("louise"), get_client("louise")); @@ -486,7 +530,11 @@ louise receives: ), ]; - let spec = Spec { clients, actions }; + let spec = Spec { + metadata, + clients, + actions, + }; assert_eq!(parse_spec(buf), Ok(spec)); }