Add metadata support

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2023-01-12 23:33:14 +01:00
parent 54debb3e2f
commit ab40eb688b

View file

@ -43,6 +43,18 @@ impl<'a> From<NomErr<nom::error::Error<LocatedSpan<&'a str>>>> 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<String>,
}
impl Metadata {
pub fn new<S: Into<String>, T: Into<String>>(title: S, desc: Option<T>) -> 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<Metadata>,
pub clients: HashMap<ClientName, Client>,
pub actions: Vec<Action>,
}
@ -139,6 +152,28 @@ where
}
}
fn parse_meta(s: Span) -> IResult<Span, Metadata> {
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<Span, (ClientName, Client)> {
let (s, (_, _, _, name, _)) =
tuple((allspaces, tag("[Client]"), space0, take_until("\n"), space0))(s)?;
@ -268,10 +303,15 @@ fn parse_actions(s: Span) -> IResult<Span, Vec<Action>> {
pub fn parse_spec(i: &str) -> Result<Spec, Token> {
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<ClientName, Client> = 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));
}