Add metadata support
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
54debb3e2f
commit
ab40eb688b
1 changed files with 51 additions and 3 deletions
54
src/lib.rs
54
src/lib.rs
|
@ -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 DEFAULT_NS: &'static str = "jabber:client";
|
||||||
pub static SCANSION_NS: &'static str = "https://matthewwild.co.uk/projects/scansion";
|
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;
|
pub type ClientName = String;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
@ -84,6 +96,7 @@ pub enum Action {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Spec {
|
pub struct Spec {
|
||||||
|
pub metadata: Option<Metadata>,
|
||||||
pub clients: HashMap<ClientName, Client>,
|
pub clients: HashMap<ClientName, Client>,
|
||||||
pub actions: Vec<Action>,
|
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)> {
|
fn parse_client(s: Span) -> IResult<Span, (ClientName, Client)> {
|
||||||
let (s, (_, _, _, name, _)) =
|
let (s, (_, _, _, name, _)) =
|
||||||
tuple((allspaces, tag("[Client]"), space0, take_until("\n"), space0))(s)?;
|
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> {
|
pub fn parse_spec(i: &str) -> Result<Spec, Token> {
|
||||||
let s: Span = i.into();
|
let s: Span = i.into();
|
||||||
|
let (s, metadata) = opt(parse_meta)(s)?;
|
||||||
let (s, clients) = parse_clients(s)?;
|
let (s, clients) = parse_clients(s)?;
|
||||||
let (s, _) = parse_sep(s)?;
|
let (s, _) = parse_sep(s)?;
|
||||||
let (_, actions) = parse_actions(s)?;
|
let (_, actions) = parse_actions(s)?;
|
||||||
Ok(Spec { clients, actions })
|
Ok(Spec {
|
||||||
|
metadata,
|
||||||
|
clients,
|
||||||
|
actions,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -450,7 +490,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_spec() {
|
fn test_parse_spec() {
|
||||||
let buf = r#"
|
let buf = r#"# Test title
|
||||||
|
# Description Foo
|
||||||
|
|
||||||
[Client] louise
|
[Client] louise
|
||||||
jid: louise@localhost
|
jid: louise@localhost
|
||||||
password: password
|
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();
|
let mut clients: HashMap<ClientName, Client> = HashMap::new();
|
||||||
clients.insert(String::from("louise"), get_client("louise"));
|
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));
|
assert_eq!(parse_spec(buf), Ok(spec));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue