mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-07-12 22:21:53 +00:00
Rip out quick-xml
This commit is contained in:
parent
0fcb8285c5
commit
ea366c2334
15 changed files with 135 additions and 176 deletions
|
@ -21,5 +21,4 @@ edition = "2018"
|
||||||
gitlab = { repository = "xmpp-rs/xmpp-rs" }
|
gitlab = { repository = "xmpp-rs/xmpp-rs" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
quick-xml = "0.22.0"
|
rxml = "^0.8.0"
|
||||||
rxml = "^0.7.1"
|
|
||||||
|
|
|
@ -20,19 +20,58 @@ use crate::prefixes::{Namespace, Prefix, Prefixes};
|
||||||
use crate::tree_builder::TreeBuilder;
|
use crate::tree_builder::TreeBuilder;
|
||||||
|
|
||||||
use std::collections::{btree_map, BTreeMap};
|
use std::collections::{btree_map, BTreeMap};
|
||||||
|
use std::convert::{TryFrom, TryInto};
|
||||||
use std::io::{BufRead, Write};
|
use std::io::{BufRead, Write};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use quick_xml::events::{BytesDecl, BytesEnd, BytesStart, Event};
|
use rxml::writer::{Encoder, Item, TrackNamespace};
|
||||||
use quick_xml::Writer as EventWriter;
|
use rxml::{EventRead, Lexer, PullDriver, RawParser, XmlVersion};
|
||||||
use rxml::{EventRead, Lexer, PullDriver, RawParser};
|
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
|
fn encode_and_write<W: Write, T: rxml::writer::TrackNamespace>(
|
||||||
|
item: Item<'_>,
|
||||||
|
enc: &mut Encoder<T>,
|
||||||
|
mut w: W,
|
||||||
|
) -> rxml::Result<()> {
|
||||||
|
let mut buf = rxml::bytes::BytesMut::new();
|
||||||
|
enc.encode_into_bytes(item, &mut buf)
|
||||||
|
.expect("encoder driven incorrectly");
|
||||||
|
w.write_all(&buf[..])?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wrapper around a [`std::io::Write`] and an [`rxml::writer::Encoder`], to
|
||||||
|
/// provide a simple function to write an rxml Item to a writer.
|
||||||
|
pub struct CustomItemWriter<W, T> {
|
||||||
|
writer: W,
|
||||||
|
encoder: Encoder<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: Write> CustomItemWriter<W, rxml::writer::SimpleNamespaces> {
|
||||||
|
pub(crate) fn new(writer: W) -> Self {
|
||||||
|
Self {
|
||||||
|
writer,
|
||||||
|
encoder: Encoder::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: Write, T: rxml::writer::TrackNamespace> CustomItemWriter<W, T> {
|
||||||
|
pub(crate) fn write(&mut self, item: Item<'_>) -> rxml::Result<()> {
|
||||||
|
encode_and_write(item, &mut self.encoder, &mut self.writer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Type alias to simplify the use for the default namespace tracking
|
||||||
|
/// implementation.
|
||||||
|
pub type ItemWriter<W> = CustomItemWriter<W, rxml::writer::SimpleNamespaces>;
|
||||||
|
|
||||||
/// helper function to escape a `&[u8]` and replace all
|
/// helper function to escape a `&[u8]` and replace all
|
||||||
/// xml special characters (<, >, &, ', ") with their corresponding
|
/// xml special characters (<, >, &, ', ") with their corresponding
|
||||||
/// xml escaped value.
|
/// xml escaped value.
|
||||||
|
@ -81,9 +120,6 @@ pub fn escape(raw: &[u8]) -> Cow<[u8]> {
|
||||||
pub struct Element {
|
pub struct Element {
|
||||||
name: String,
|
name: String,
|
||||||
namespace: String,
|
namespace: String,
|
||||||
/// This is only used when deserializing. If you have to use a custom prefix use
|
|
||||||
/// `ElementBuilder::prefix`.
|
|
||||||
pub(crate) prefix: Option<Prefix>,
|
|
||||||
/// Namespace declarations
|
/// Namespace declarations
|
||||||
pub prefixes: Prefixes,
|
pub prefixes: Prefixes,
|
||||||
attributes: BTreeMap<String, String>,
|
attributes: BTreeMap<String, String>,
|
||||||
|
@ -123,7 +159,6 @@ impl Element {
|
||||||
pub(crate) fn new<P: Into<Prefixes>>(
|
pub(crate) fn new<P: Into<Prefixes>>(
|
||||||
name: String,
|
name: String,
|
||||||
namespace: String,
|
namespace: String,
|
||||||
prefix: Option<Prefix>,
|
|
||||||
prefixes: P,
|
prefixes: P,
|
||||||
attributes: BTreeMap<String, String>,
|
attributes: BTreeMap<String, String>,
|
||||||
children: Vec<Node>,
|
children: Vec<Node>,
|
||||||
|
@ -131,7 +166,6 @@ impl Element {
|
||||||
Element {
|
Element {
|
||||||
name,
|
name,
|
||||||
namespace,
|
namespace,
|
||||||
prefix,
|
|
||||||
prefixes: prefixes.into(),
|
prefixes: prefixes.into(),
|
||||||
attributes,
|
attributes,
|
||||||
children,
|
children,
|
||||||
|
@ -162,7 +196,6 @@ impl Element {
|
||||||
name.as_ref().to_string(),
|
name.as_ref().to_string(),
|
||||||
namespace.into(),
|
namespace.into(),
|
||||||
None,
|
None,
|
||||||
None,
|
|
||||||
BTreeMap::new(),
|
BTreeMap::new(),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
),
|
),
|
||||||
|
@ -188,7 +221,6 @@ impl Element {
|
||||||
name.into(),
|
name.into(),
|
||||||
namespace.into(),
|
namespace.into(),
|
||||||
None,
|
None,
|
||||||
None,
|
|
||||||
BTreeMap::new(),
|
BTreeMap::new(),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
)
|
)
|
||||||
|
@ -316,119 +348,66 @@ impl Element {
|
||||||
|
|
||||||
/// Output a document to a `Writer`.
|
/// Output a document to a `Writer`.
|
||||||
pub fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
|
pub fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
|
||||||
self.to_writer(&mut EventWriter::new(writer))
|
self.to_writer(&mut ItemWriter::new(writer))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Output a document to a `Writer`.
|
/// Output a document to a `Writer`.
|
||||||
pub fn write_to_decl<W: Write>(&self, writer: &mut W) -> Result<()> {
|
pub fn write_to_decl<W: Write>(&self, writer: &mut W) -> Result<()> {
|
||||||
self.to_writer_decl(&mut EventWriter::new(writer))
|
self.to_writer_decl(&mut ItemWriter::new(writer))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Output the document to quick-xml `Writer`
|
/// Output the document to quick-xml `Writer`
|
||||||
pub fn to_writer<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<()> {
|
pub fn to_writer<W: Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
|
||||||
self.write_to_inner(writer, &mut BTreeMap::new())
|
self.write_to_inner(writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Output the document to quick-xml `Writer`
|
/// Output the document to quick-xml `Writer`
|
||||||
pub fn to_writer_decl<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<()> {
|
pub fn to_writer_decl<W: Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
|
||||||
writer.write_event(Event::Decl(BytesDecl::new(b"1.0", Some(b"utf-8"), None)))?;
|
writer
|
||||||
self.write_to_inner(writer, &mut BTreeMap::new())
|
.write(Item::XmlDeclaration(XmlVersion::V1_0))
|
||||||
|
.unwrap(); // TODO: error return
|
||||||
|
self.write_to_inner(writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like `write_to()` but without the `<?xml?>` prelude
|
/// Like `write_to()` but without the `<?xml?>` prelude
|
||||||
pub fn write_to_inner<W: Write>(
|
pub fn write_to_inner<W: Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
|
||||||
&self,
|
for (prefix, namespace) in self.prefixes.declared_prefixes() {
|
||||||
writer: &mut EventWriter<W>,
|
assert!(writer.encoder.inner_mut().declare_fixed(
|
||||||
all_prefixes: &mut BTreeMap<Prefix, Namespace>,
|
prefix.as_ref().map(|x| (&**x).try_into()).transpose()?,
|
||||||
) -> Result<()> {
|
Some(Arc::new(namespace.clone().try_into()?))
|
||||||
let local_prefixes: &BTreeMap<Option<String>, String> = self.prefixes.declared_prefixes();
|
));
|
||||||
|
|
||||||
// Element namespace
|
|
||||||
// If the element prefix hasn't been set yet via a custom prefix, add it.
|
|
||||||
let mut existing_self_prefix: Option<Option<String>> = None;
|
|
||||||
for (prefix, ns) in local_prefixes.iter().chain(all_prefixes.iter()) {
|
|
||||||
if ns == &self.namespace {
|
|
||||||
existing_self_prefix = Some(prefix.clone());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut all_keys = all_prefixes.keys().cloned();
|
let namespace = if self.namespace.len() == 0 {
|
||||||
let mut local_keys = local_prefixes.keys().cloned();
|
None
|
||||||
let self_prefix: (Option<String>, bool) = match existing_self_prefix {
|
} else {
|
||||||
// No prefix exists already for our namespace
|
Some(Arc::new(self.namespace.clone().try_into()?))
|
||||||
None => {
|
|
||||||
if !local_keys.any(|p| p.is_none()) {
|
|
||||||
// Use the None prefix if available
|
|
||||||
(None, true)
|
|
||||||
} else {
|
|
||||||
// Otherwise generate one. Check if it isn't already used, if so increase the
|
|
||||||
// number until we find a suitable one.
|
|
||||||
let mut prefix_n = 0u8;
|
|
||||||
while all_keys.any(|p| p == Some(format!("ns{}", prefix_n))) {
|
|
||||||
prefix_n += 1;
|
|
||||||
}
|
|
||||||
(Some(format!("ns{}", prefix_n)), true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Some prefix has already been declared (or is going to be) for our namespace. We
|
|
||||||
// don't need to declare a new one. We do however need to remember which one to use in
|
|
||||||
// the tag name.
|
|
||||||
Some(prefix) => (prefix, false),
|
|
||||||
};
|
};
|
||||||
|
writer.write(Item::ElementHeadStart(namespace, (*self.name).try_into()?))?;
|
||||||
|
|
||||||
let name = match self_prefix {
|
for (key, value) in self.attributes.iter() {
|
||||||
(Some(ref prefix), _) => Cow::Owned(format!("{}:{}", prefix, self.name)),
|
let (prefix, name) = <&rxml::NameStr>::try_from(&**key)
|
||||||
_ => Cow::Borrowed(&self.name),
|
.unwrap()
|
||||||
};
|
.split_name()
|
||||||
let mut start = BytesStart::borrowed(name.as_bytes(), name.len());
|
.unwrap();
|
||||||
|
let namespace = match prefix {
|
||||||
|
Some(prefix) => match writer.encoder.inner().lookup_prefix(Some(prefix)) {
|
||||||
|
Ok(v) => Some(v),
|
||||||
|
Err(rxml::writer::PrefixError::Undeclared) => return Err(Error::InvalidPrefix),
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
writer.write(Item::Attribute(namespace, name, (&**value).try_into()?))?;
|
||||||
|
}
|
||||||
|
|
||||||
// Write self prefix if necessary
|
if !self.children.is_empty() {
|
||||||
match self_prefix {
|
writer.write(Item::ElementHeadEnd)?;
|
||||||
(Some(ref p), true) => {
|
for child in self.children.iter() {
|
||||||
let key = format!("xmlns:{}", p);
|
child.write_to_inner(writer)?;
|
||||||
start.push_attribute((key.as_bytes(), self.namespace.as_bytes()));
|
|
||||||
all_prefixes.insert(self_prefix.0, self.namespace.clone());
|
|
||||||
}
|
|
||||||
(None, true) => {
|
|
||||||
let key = String::from("xmlns");
|
|
||||||
start.push_attribute((key.as_bytes(), self.namespace.as_bytes()));
|
|
||||||
all_prefixes.insert(self_prefix.0, self.namespace.clone());
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Custom prefixes/namespace sets
|
|
||||||
for (prefix, ns) in local_prefixes {
|
|
||||||
match all_prefixes.get(prefix) {
|
|
||||||
p @ Some(_) if p == prefix.as_ref() => (),
|
|
||||||
_ => {
|
|
||||||
let key = match prefix {
|
|
||||||
None => String::from("xmlns"),
|
|
||||||
Some(p) => format!("xmlns:{}", p),
|
|
||||||
};
|
|
||||||
|
|
||||||
start.push_attribute((key.as_bytes(), ns.as_ref()));
|
|
||||||
all_prefixes.insert(prefix.clone(), ns.clone());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writer.write(Item::ElementFoot)?;
|
||||||
|
|
||||||
for (key, value) in &self.attributes {
|
|
||||||
start.push_attribute((key.as_bytes(), escape(value.as_bytes()).as_ref()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.children.is_empty() {
|
|
||||||
writer.write_event(Event::Empty(start))?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.write_event(Event::Start(start))?;
|
|
||||||
|
|
||||||
for child in &self.children {
|
|
||||||
child.write_to_inner(writer, &mut all_prefixes.clone())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.write_event(Event::End(BytesEnd::borrowed(name.as_bytes())))?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -888,7 +867,6 @@ mod tests {
|
||||||
let elem = Element::new(
|
let elem = Element::new(
|
||||||
"name".to_owned(),
|
"name".to_owned(),
|
||||||
"namespace".to_owned(),
|
"namespace".to_owned(),
|
||||||
None,
|
|
||||||
(None, "namespace".to_owned()),
|
(None, "namespace".to_owned()),
|
||||||
BTreeMap::from_iter(vec![("name".to_string(), "value".to_string())].into_iter()),
|
BTreeMap::from_iter(vec![("name".to_string(), "value".to_string())].into_iter()),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
|
|
|
@ -17,11 +17,8 @@ use std::error::Error as StdError;
|
||||||
/// Our main error type.
|
/// Our main error type.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// An error from quick_xml.
|
/// Error from rxml parsing or writing
|
||||||
XmlError(::quick_xml::Error),
|
XmlError(rxml::Error),
|
||||||
|
|
||||||
/// Error from rxml parsing
|
|
||||||
ParserError(rxml::Error),
|
|
||||||
|
|
||||||
/// An error which is returned when the end of the document was reached prematurely.
|
/// An error which is returned when the end of the document was reached prematurely.
|
||||||
EndOfDocument,
|
EndOfDocument,
|
||||||
|
@ -41,7 +38,6 @@ impl StdError for Error {
|
||||||
fn cause(&self) -> Option<&dyn StdError> {
|
fn cause(&self) -> Option<&dyn StdError> {
|
||||||
match self {
|
match self {
|
||||||
Error::XmlError(e) => Some(e),
|
Error::XmlError(e) => Some(e),
|
||||||
Error::ParserError(e) => Some(e),
|
|
||||||
Error::EndOfDocument => None,
|
Error::EndOfDocument => None,
|
||||||
Error::InvalidPrefix => None,
|
Error::InvalidPrefix => None,
|
||||||
Error::MissingNamespace => None,
|
Error::MissingNamespace => None,
|
||||||
|
@ -54,7 +50,6 @@ impl std::fmt::Display for Error {
|
||||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Error::XmlError(e) => write!(fmt, "XML error: {}", e),
|
Error::XmlError(e) => write!(fmt, "XML error: {}", e),
|
||||||
Error::ParserError(e) => write!(fmt, "XML parser error: {}", e),
|
|
||||||
Error::EndOfDocument => {
|
Error::EndOfDocument => {
|
||||||
write!(fmt, "the end of the document has been reached prematurely")
|
write!(fmt, "the end of the document has been reached prematurely")
|
||||||
}
|
}
|
||||||
|
@ -65,15 +60,15 @@ impl std::fmt::Display for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<::quick_xml::Error> for Error {
|
impl From<rxml::Error> for Error {
|
||||||
fn from(err: ::quick_xml::Error) -> Error {
|
fn from(err: rxml::Error) -> Error {
|
||||||
Error::XmlError(err)
|
Error::XmlError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<rxml::Error> for Error {
|
impl From<rxml::error::XmlError> for Error {
|
||||||
fn from(err: rxml::Error) -> Error {
|
fn from(err: rxml::error::XmlError) -> Error {
|
||||||
Error::ParserError(err)
|
Error::XmlError(err.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,6 @@
|
||||||
//! minidom = "*"
|
//! minidom = "*"
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
pub use quick_xml;
|
|
||||||
|
|
||||||
pub mod convert;
|
pub mod convert;
|
||||||
pub mod element;
|
pub mod element;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
|
@ -8,14 +8,13 @@
|
||||||
|
|
||||||
//! Provides the `Node` struct, which represents a node in the DOM.
|
//! Provides the `Node` struct, which represents a node in the DOM.
|
||||||
|
|
||||||
use crate::element::{Element, ElementBuilder};
|
use crate::element::{Element, ElementBuilder, ItemWriter};
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use rxml::writer::Item;
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
use quick_xml::events::{BytesText, Event};
|
use std::convert::TryInto;
|
||||||
use quick_xml::Writer as EventWriter;
|
use std::io::Write;
|
||||||
|
|
||||||
/// A node in an element tree.
|
/// A node in an element tree.
|
||||||
#[derive(Clone, Debug, Eq)]
|
#[derive(Clone, Debug, Eq)]
|
||||||
|
@ -160,15 +159,11 @@ impl Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub(crate) fn write_to_inner<W: Write>(
|
pub(crate) fn write_to_inner<W: Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
|
||||||
&self,
|
|
||||||
writer: &mut EventWriter<W>,
|
|
||||||
prefixes: &mut BTreeMap<Option<String>, String>,
|
|
||||||
) -> Result<()> {
|
|
||||||
match *self {
|
match *self {
|
||||||
Node::Element(ref elmt) => elmt.write_to_inner(writer, prefixes)?,
|
Node::Element(ref elmt) => elmt.write_to_inner(writer)?,
|
||||||
Node::Text(ref s) => {
|
Node::Text(ref s) => {
|
||||||
writer.write_event(Event::Text(BytesText::from_plain_str(s)))?;
|
writer.write(Item::Text((&**s).try_into()?))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
use crate::element::Element;
|
use crate::element::Element;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
|
||||||
const TEST_STRING: &'static [u8] = br#"<root xmlns="root_ns" a="b" xml:lang="en">meow<child c="d"/><child xmlns="child_ns" d="e" xml:lang="fr"/>nya</root>"#;
|
const TEST_STRING: &'static [u8] = br#"<root xmlns='root_ns' a="b" xml:lang="en">meow<child c="d"/><child xmlns='child_ns' d="e" xml:lang="fr"/>nya</root>"#;
|
||||||
|
|
||||||
fn build_test_tree() -> Element {
|
fn build_test_tree() -> Element {
|
||||||
let mut root = Element::builder("root", "root_ns")
|
let mut root = Element::builder("root", "root_ns")
|
||||||
|
@ -151,7 +151,7 @@ fn writer_with_decl_works() {
|
||||||
root.write_to_decl(&mut writer).unwrap();
|
root.write_to_decl(&mut writer).unwrap();
|
||||||
}
|
}
|
||||||
let result = format!(
|
let result = format!(
|
||||||
r#"<?xml version="1.0" encoding="utf-8"?>{}"#,
|
"<?xml version='1.0' encoding='utf-8'?>\n{}",
|
||||||
String::from_utf8(TEST_STRING.to_owned()).unwrap()
|
String::from_utf8(TEST_STRING.to_owned()).unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(String::from_utf8(writer).unwrap(), result);
|
assert_eq!(String::from_utf8(writer).unwrap(), result);
|
||||||
|
@ -167,7 +167,7 @@ fn writer_with_prefix() {
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
String::from(&root),
|
String::from(&root),
|
||||||
r#"<p1:root xmlns="ns2" xmlns:p1="ns1"/>"#,
|
r#"<p1:root xmlns='ns2' xmlns:p1='ns1'/>"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ fn writer_no_prefix_namespace() {
|
||||||
// TODO: Note that this isn't exactly equal to a None prefix. it's just that the None prefix is
|
// TODO: Note that this isn't exactly equal to a None prefix. it's just that the None prefix is
|
||||||
// the most obvious when it's not already used. Maybe fix tests so that it only checks that the
|
// the most obvious when it's not already used. Maybe fix tests so that it only checks that the
|
||||||
// prefix used equals the one declared for the namespace.
|
// prefix used equals the one declared for the namespace.
|
||||||
assert_eq!(String::from(&root), r#"<root xmlns="ns1"/>"#);
|
assert_eq!(String::from(&root), r#"<root xmlns='ns1'/>"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -185,7 +185,7 @@ fn writer_no_prefix_namespace_child() {
|
||||||
let child = Element::builder("child", "ns1").build();
|
let child = Element::builder("child", "ns1").build();
|
||||||
let root = Element::builder("root", "ns1").append(child).build();
|
let root = Element::builder("root", "ns1").append(child).build();
|
||||||
// TODO: Same remark as `writer_no_prefix_namespace`.
|
// TODO: Same remark as `writer_no_prefix_namespace`.
|
||||||
assert_eq!(String::from(&root), r#"<root xmlns="ns1"><child/></root>"#);
|
assert_eq!(String::from(&root), r#"<root xmlns='ns1'><child/></root>"#);
|
||||||
|
|
||||||
let child = Element::builder("child", "ns2")
|
let child = Element::builder("child", "ns2")
|
||||||
.prefix(None, "ns3")
|
.prefix(None, "ns3")
|
||||||
|
@ -195,7 +195,7 @@ fn writer_no_prefix_namespace_child() {
|
||||||
// TODO: Same remark as `writer_no_prefix_namespace`.
|
// TODO: Same remark as `writer_no_prefix_namespace`.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
String::from(&root),
|
String::from(&root),
|
||||||
r#"<root xmlns="ns1"><ns0:child xmlns:ns0="ns2" xmlns="ns3"/></root>"#
|
r#"<root xmlns='ns1'><tns0:child xmlns='ns3' xmlns:tns0='ns2'/></root>"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ fn writer_prefix_namespace_child() {
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
String::from(&root),
|
String::from(&root),
|
||||||
r#"<p1:root xmlns:p1="ns1"><p1:child/></p1:root>"#
|
r#"<p1:root xmlns:p1='ns1'><p1:child/></p1:root>"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ fn writer_with_prefix_deduplicate() {
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
String::from(&root),
|
String::from(&root),
|
||||||
r#"<p1:root xmlns="ns2" xmlns:p1="ns1"><p1:child/></p1:root>"#,
|
r#"<p1:root xmlns='ns2' xmlns:p1='ns1'><p1:child/></p1:root>"#,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Ensure descendants don't just reuse ancestors' prefixes that have been shadowed in between
|
// Ensure descendants don't just reuse ancestors' prefixes that have been shadowed in between
|
||||||
|
@ -236,7 +236,7 @@ fn writer_with_prefix_deduplicate() {
|
||||||
let root = Element::builder("root", "ns1").append(child).build();
|
let root = Element::builder("root", "ns1").append(child).build();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
String::from(&root),
|
String::from(&root),
|
||||||
r#"<root xmlns="ns1"><child xmlns="ns2"><grandchild xmlns="ns1"/></child></root>"#,
|
r#"<root xmlns='ns1'><child xmlns='ns2'><grandchild xmlns='ns1'/></child></root>"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ fn writer_escapes_attributes() {
|
||||||
}
|
}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
String::from_utf8(writer).unwrap(),
|
String::from_utf8(writer).unwrap(),
|
||||||
r#"<root xmlns="ns1" a=""Air" quotes"/>"#
|
r#"<root xmlns='ns1' a=""Air" quotes"/>"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ fn writer_escapes_text() {
|
||||||
}
|
}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
String::from_utf8(writer).unwrap(),
|
String::from_utf8(writer).unwrap(),
|
||||||
r#"<root xmlns="ns1"><3</root>"#
|
r#"<root xmlns='ns1'><3</root>"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,15 +431,15 @@ fn fail_comments() {
|
||||||
#[test]
|
#[test]
|
||||||
fn xml_error() {
|
fn xml_error() {
|
||||||
match "<a xmlns='ns1'></b>".parse::<Element>() {
|
match "<a xmlns='ns1'></b>".parse::<Element>() {
|
||||||
Err(crate::error::Error::ParserError(rxml::Error::NotWellFormed(
|
Err(crate::error::Error::XmlError(rxml::Error::Xml(
|
||||||
rxml::error::WFError::ElementMismatch,
|
rxml::error::XmlError::ElementMismatch,
|
||||||
))) => (),
|
))) => (),
|
||||||
err => panic!("No or wrong error: {:?}", err),
|
err => panic!("No or wrong error: {:?}", err),
|
||||||
}
|
}
|
||||||
|
|
||||||
match "<a xmlns='ns1'></".parse::<Element>() {
|
match "<a xmlns='ns1'></".parse::<Element>() {
|
||||||
Err(crate::error::Error::ParserError(rxml::Error::NotWellFormed(
|
Err(crate::error::Error::XmlError(rxml::Error::Xml(
|
||||||
rxml::error::WFError::InvalidEof(_),
|
rxml::error::XmlError::InvalidEof(_),
|
||||||
))) => (),
|
))) => (),
|
||||||
err => panic!("No or wrong error: {:?}", err),
|
err => panic!("No or wrong error: {:?}", err),
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ impl TreeBuilder {
|
||||||
/// Process a Event that you got out of a RawParser
|
/// Process a Event that you got out of a RawParser
|
||||||
pub fn process_event(&mut self, event: RawEvent) -> Result<(), Error> {
|
pub fn process_event(&mut self, event: RawEvent) -> Result<(), Error> {
|
||||||
match event {
|
match event {
|
||||||
RawEvent::XMLDeclaration(_, _) => {}
|
RawEvent::XmlDeclaration(_, _) => {}
|
||||||
|
|
||||||
RawEvent::ElementHeadOpen(_, (prefix, name)) => {
|
RawEvent::ElementHeadOpen(_, (prefix, name)) => {
|
||||||
self.next_tag = Some((
|
self.next_tag = Some((
|
||||||
|
@ -132,14 +132,8 @@ impl TreeBuilder {
|
||||||
.lookup_prefix(&prefix.clone().map(|prefix| prefix.as_str().to_owned()))
|
.lookup_prefix(&prefix.clone().map(|prefix| prefix.as_str().to_owned()))
|
||||||
.ok_or(Error::MissingNamespace)?
|
.ok_or(Error::MissingNamespace)?
|
||||||
.to_owned();
|
.to_owned();
|
||||||
let el = Element::new(
|
let el =
|
||||||
name.as_str().to_owned(),
|
Element::new(name.as_str().to_owned(), namespace, prefixes, attrs, vec![]);
|
||||||
namespace,
|
|
||||||
Some(prefix.map(|prefix| prefix.as_str().to_owned())),
|
|
||||||
prefixes,
|
|
||||||
attrs,
|
|
||||||
vec![],
|
|
||||||
);
|
|
||||||
self.stack.push(el);
|
self.stack.push(el);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,15 +233,15 @@ mod tests {
|
||||||
#[cfg(target_pointer_width = "32")]
|
#[cfg(target_pointer_width = "32")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_size() {
|
fn test_size() {
|
||||||
assert_size!(IqType, 136);
|
assert_size!(IqType, 120);
|
||||||
assert_size!(Iq, 228);
|
assert_size!(Iq, 212);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_size() {
|
fn test_size() {
|
||||||
assert_size!(IqType, 272);
|
assert_size!(IqType, 240);
|
||||||
assert_size!(Iq, 456);
|
assert_size!(Iq, 424);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -689,7 +689,7 @@ mod tests {
|
||||||
assert_size!(Senders, 1);
|
assert_size!(Senders, 1);
|
||||||
assert_size!(Disposition, 1);
|
assert_size!(Disposition, 1);
|
||||||
assert_size!(ContentId, 12);
|
assert_size!(ContentId, 12);
|
||||||
assert_size!(Content, 252);
|
assert_size!(Content, 228);
|
||||||
assert_size!(Reason, 1);
|
assert_size!(Reason, 1);
|
||||||
assert_size!(ReasonElement, 16);
|
assert_size!(ReasonElement, 16);
|
||||||
assert_size!(SessionId, 12);
|
assert_size!(SessionId, 12);
|
||||||
|
@ -704,7 +704,7 @@ mod tests {
|
||||||
assert_size!(Senders, 1);
|
assert_size!(Senders, 1);
|
||||||
assert_size!(Disposition, 1);
|
assert_size!(Disposition, 1);
|
||||||
assert_size!(ContentId, 24);
|
assert_size!(ContentId, 24);
|
||||||
assert_size!(Content, 504);
|
assert_size!(Content, 456);
|
||||||
assert_size!(Reason, 1);
|
assert_size!(Reason, 1);
|
||||||
assert_size!(ReasonElement, 32);
|
assert_size!(ReasonElement, 32);
|
||||||
assert_size!(SessionId, 24);
|
assert_size!(SessionId, 24);
|
||||||
|
|
|
@ -110,13 +110,13 @@ mod tests {
|
||||||
#[cfg(target_pointer_width = "32")]
|
#[cfg(target_pointer_width = "32")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_size() {
|
fn test_size() {
|
||||||
assert_size!(JingleMI, 92);
|
assert_size!(JingleMI, 76);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_size() {
|
fn test_size() {
|
||||||
assert_size!(JingleMI, 184);
|
assert_size!(JingleMI, 152);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -346,46 +346,46 @@ mod tests {
|
||||||
fn serialise() {
|
fn serialise() {
|
||||||
let elem: Element = Join::from_nick_and_nodes("coucou", &["foo", "bar"]).into();
|
let elem: Element = Join::from_nick_and_nodes("coucou", &["foo", "bar"]).into();
|
||||||
let xml = String::from(&elem);
|
let xml = String::from(&elem);
|
||||||
assert_eq!(xml, "<join xmlns=\"urn:xmpp:mix:core:1\"><nick>coucou</nick><subscribe node=\"foo\"/><subscribe node=\"bar\"/></join>");
|
assert_eq!(xml, "<join xmlns='urn:xmpp:mix:core:1'><nick>coucou</nick><subscribe node=\"foo\"/><subscribe node=\"bar\"/></join>");
|
||||||
|
|
||||||
let elem: Element = UpdateSubscription::from_nodes(&["foo", "bar"]).into();
|
let elem: Element = UpdateSubscription::from_nodes(&["foo", "bar"]).into();
|
||||||
let xml = String::from(&elem);
|
let xml = String::from(&elem);
|
||||||
assert_eq!(xml, "<update-subscription xmlns=\"urn:xmpp:mix:core:1\"><subscribe node=\"foo\"/><subscribe node=\"bar\"/></update-subscription>");
|
assert_eq!(xml, "<update-subscription xmlns='urn:xmpp:mix:core:1'><subscribe node=\"foo\"/><subscribe node=\"bar\"/></update-subscription>");
|
||||||
|
|
||||||
let elem: Element = Leave.into();
|
let elem: Element = Leave.into();
|
||||||
let xml = String::from(&elem);
|
let xml = String::from(&elem);
|
||||||
assert_eq!(xml, "<leave xmlns=\"urn:xmpp:mix:core:1\"/>");
|
assert_eq!(xml, "<leave xmlns='urn:xmpp:mix:core:1'/>");
|
||||||
|
|
||||||
let elem: Element = SetNick::new("coucou").into();
|
let elem: Element = SetNick::new("coucou").into();
|
||||||
let xml = String::from(&elem);
|
let xml = String::from(&elem);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
xml,
|
xml,
|
||||||
"<setnick xmlns=\"urn:xmpp:mix:core:1\"><nick>coucou</nick></setnick>"
|
"<setnick xmlns='urn:xmpp:mix:core:1'><nick>coucou</nick></setnick>"
|
||||||
);
|
);
|
||||||
|
|
||||||
let elem: Element = Mix::new("coucou", "coucou@example").into();
|
let elem: Element = Mix::new("coucou", "coucou@example").into();
|
||||||
let xml = String::from(&elem);
|
let xml = String::from(&elem);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
xml,
|
xml,
|
||||||
"<mix xmlns=\"urn:xmpp:mix:core:1\"><nick>coucou</nick><jid>coucou@example</jid></mix>"
|
"<mix xmlns='urn:xmpp:mix:core:1'><nick>coucou</nick><jid>coucou@example</jid></mix>"
|
||||||
);
|
);
|
||||||
|
|
||||||
let elem: Element = Create::new().into();
|
let elem: Element = Create::new().into();
|
||||||
let xml = String::from(&elem);
|
let xml = String::from(&elem);
|
||||||
assert_eq!(xml, "<create xmlns=\"urn:xmpp:mix:core:1\"/>");
|
assert_eq!(xml, "<create xmlns='urn:xmpp:mix:core:1'/>");
|
||||||
|
|
||||||
let elem: Element = Create::from_channel_id("coucou").into();
|
let elem: Element = Create::from_channel_id("coucou").into();
|
||||||
let xml = String::from(&elem);
|
let xml = String::from(&elem);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
xml,
|
xml,
|
||||||
"<create xmlns=\"urn:xmpp:mix:core:1\" channel=\"coucou\"/>"
|
"<create xmlns='urn:xmpp:mix:core:1' channel=\"coucou\"/>"
|
||||||
);
|
);
|
||||||
|
|
||||||
let elem: Element = Destroy::new("coucou").into();
|
let elem: Element = Destroy::new("coucou").into();
|
||||||
let xml = String::from(&elem);
|
let xml = String::from(&elem);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
xml,
|
xml,
|
||||||
"<destroy xmlns=\"urn:xmpp:mix:core:1\" channel=\"coucou\"/>"
|
"<destroy xmlns='urn:xmpp:mix:core:1' channel=\"coucou\"/>"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,7 +318,7 @@ mod tests {
|
||||||
fn test_size() {
|
fn test_size() {
|
||||||
assert_size!(ErrorType, 1);
|
assert_size!(ErrorType, 1);
|
||||||
assert_size!(DefinedCondition, 1);
|
assert_size!(DefinedCondition, 1);
|
||||||
assert_size!(StanzaError, 132);
|
assert_size!(StanzaError, 116);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
@ -326,7 +326,7 @@ mod tests {
|
||||||
fn test_size() {
|
fn test_size() {
|
||||||
assert_size!(ErrorType, 1);
|
assert_size!(ErrorType, 1);
|
||||||
assert_size!(DefinedCondition, 1);
|
assert_size!(DefinedCondition, 1);
|
||||||
assert_size!(StanzaError, 264);
|
assert_size!(StanzaError, 232);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -596,7 +596,7 @@ mod tests {
|
||||||
assert_eq!(html, "Hello world!");
|
assert_eq!(html, "Hello world!");
|
||||||
|
|
||||||
let elem = Element::from(parsed2);
|
let elem = Element::from(parsed2);
|
||||||
assert_eq!(String::from(&elem), "<html xmlns=\"http://jabber.org/protocol/xhtml-im\"><body xmlns=\"http://www.w3.org/1999/xhtml\">Hello world!</body></html>");
|
assert_eq!(String::from(&elem), "<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>Hello world!</body></html>");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -27,7 +27,7 @@ trust-dns-proto = "0.20"
|
||||||
trust-dns-resolver = "0.20"
|
trust-dns-resolver = "0.20"
|
||||||
xmpp-parsers = "0.19"
|
xmpp-parsers = "0.19"
|
||||||
minidom = "0.14"
|
minidom = "0.14"
|
||||||
rxml = "^0.7.1"
|
rxml = "^0.8.0"
|
||||||
webpki-roots = { version = "0.22", optional = true }
|
webpki-roots = { version = "0.22", optional = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -336,7 +336,7 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
framed.get_ref().get_ref(),
|
framed.get_ref().get_ref(),
|
||||||
&format!(
|
&format!(
|
||||||
"<message xmlns=\"jabber:client\"><body>{}</body></message>",
|
"<message xmlns='jabber:client'><body>{}</body></message>",
|
||||||
text
|
text
|
||||||
)
|
)
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
|
|
Loading…
Reference in a new issue