Don't convert XML to minidom::Element anymore

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2023-01-17 18:46:38 +01:00
parent 309be31d45
commit e9c6d32445
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
4 changed files with 25 additions and 46 deletions

View file

@ -9,7 +9,6 @@ description = "Parser for the Scansion DSL"
[dependencies]
nom = "7.1"
jid = "0.9"
minidom = "0.15.1"
nom_locate = "4.0.0"
[dev-dependencies]

View file

@ -7,5 +7,8 @@
mod parsers;
mod types;
pub static DEFAULT_NS: &str = "jabber:client";
pub static SCANSION_NS: &str = "https://matthewwild.co.uk/projects/scansion";
pub use parsers::parse_spec;
pub use types::{Spec, Action, Client, Metadata};
pub use types::{Action, Client, Metadata, Spec};

View file

@ -4,13 +4,12 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
use crate::types::{Spec, Action, Client, ClientName, Metadata};
use crate::types::{Action, Client, ClientName, Metadata, Spec};
use std::collections::{BTreeMap, HashMap};
use std::collections::HashMap;
use std::str::FromStr;
use jid::Jid;
use minidom::Element;
use nom::{
self,
branch::alt,
@ -42,9 +41,6 @@ impl<'a> From<NomErr<nom::error::Error<LocatedSpan<&'a str>>>> for Token<'a> {
}
}
pub static DEFAULT_NS: &str = "jabber:client";
pub static SCANSION_NS: &str = "https://matthewwild.co.uk/projects/scansion";
fn allspaces(s: Span) -> IResult<Span, Token> {
let (s, (pos, _, comments)) = tuple((position, multispace0, opt(comment)))(s)?;
@ -247,21 +243,20 @@ fn parse_action_subline(s: Span) -> IResult<Span, &str> {
Ok((s, line.fragment()))
}
fn parse_send_receive<'a>(tagname: &str, name: String, s: Span<'a>) -> IResult<Span<'a>, Action> {
fn parse_send_receive<'a>(
tagname: &str,
name: String,
s: Span<'a>,
) -> IResult<Span<'a>, Action<'a>> {
let (s, (_, lines)) = tuple((
take_while(|c| c == ' ' || c == '\r' || c == '\n'), // Spaces but \t
recognize(many1(parse_action_subline)),
))(s)?;
let lines = lines.trim();
// Namespaces
let mut prefixes = BTreeMap::new();
prefixes.insert(None, String::from(DEFAULT_NS));
prefixes.insert(Some(String::from("scansion")), String::from(SCANSION_NS));
let elem: Element = Element::from_reader_with_prefixes(lines.as_bytes(), prefixes).unwrap();
Ok(match tagname {
"sends:" => (s, Action::Send(name, elem)),
"receives:" => (s, Action::Receive(name, elem)),
"sends:" => (s, Action::Send(name, lines.clone())),
"receives:" => (s, Action::Receive(name, lines)),
_ => unreachable!(),
})
}
@ -493,11 +488,9 @@ mod tests {
/>
"#;
let xml = b"<presence\n\t\ttype=\"unavailable\"\t\n/>";
let send = Action::Send(
String::from("rosa"),
Element::from_reader_with_prefixes(&xml[..], String::from(DEFAULT_NS)).unwrap(),
"<presence\n\t\ttype=\"unavailable\"\n\t/>",
);
assert_eq!(parse_action(buf.into()).unwrap().1, send);
}
@ -511,11 +504,9 @@ mod tests {
/>
"#;
let xml = b"<presence\n\t\ttype=\"unavailable\"\t\n/>";
let receive = Action::Receive(
String::from("rosa"),
Element::from_reader_with_prefixes(&xml[..], String::from(DEFAULT_NS)).unwrap(),
"<presence\n\t\ttype=\"unavailable\"\n\t/>",
);
assert_eq!(parse_action(buf.into()).unwrap().1, receive);
}
@ -523,16 +514,9 @@ mod tests {
#[test]
fn test_actions_take_until() {
let buf = "Rosa receives:\n\t<presence/>\n\n\n# Comment\n\nPeter sends:\n\t<presence/>\n";
let xml = b"<presence/>";
let actions = vec![
Action::Receive(
String::from("Rosa"),
Element::from_reader_with_prefixes(&xml[..], String::from(DEFAULT_NS)).unwrap(),
),
Action::Send(
String::from("Peter"),
Element::from_reader_with_prefixes(&xml[..], String::from(DEFAULT_NS)).unwrap(),
),
Action::Receive(String::from("Rosa"), "<presence/>"),
Action::Send(String::from("Peter"), "<presence/>"),
];
assert_eq!(parse_actions(buf.into()).unwrap().1, actions);
}
@ -576,18 +560,12 @@ louise receives:
let mut clients: HashMap<ClientName, Client> = HashMap::new();
clients.insert(String::from("louise"), get_client("louise"));
let xml1 = b"<presence to=\"some@room\" />\n\n";
let xml2 = b"<message from=\"louise@localhost\"\n\t\t/>\n\n";
let actions = vec![
Action::Connect(String::from("louise")),
Action::Send(
String::from("louise"),
Element::from_reader_with_prefixes(&xml1[..], String::from(DEFAULT_NS)).unwrap(),
),
Action::Send(String::from("louise"), "<presence to=\"some@room\" />"),
Action::Receive(
String::from("louise"),
Element::from_reader_with_prefixes(&xml2[..], String::from(DEFAULT_NS)).unwrap(),
"<message from=\"louise@localhost\"\n\t\t/>",
),
];

View file

@ -4,9 +4,8 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
use std::collections::HashMap;
use jid::Jid;
use minidom::Element;
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq)]
pub struct Metadata {
@ -62,17 +61,17 @@ impl Client {
}
#[derive(Debug, Clone, PartialEq)]
pub enum Action {
pub enum Action<'a> {
Connect(ClientName),
Send(ClientName, Element),
Receive(ClientName, Element),
Send(ClientName, &'a str),
Receive(ClientName, &'a str),
ReceiveNone(ClientName),
Disconnect(ClientName),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Spec {
pub struct Spec<'a> {
pub metadata: Option<Metadata>,
pub clients: HashMap<ClientName, Client>,
pub actions: Vec<Action>,
pub actions: Vec<Action<'a>>,
}