2020-02-14 23:40:38 +00:00
|
|
|
// Copyright (c) 2020 lumi <lumi@pew.im>
|
|
|
|
// Copyright (c) 2020 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
|
|
|
// Copyright (c) 2020 Bastien Orivel <eijebong+minidom@bananium.fr>
|
|
|
|
// Copyright (c) 2020 Astro <astro@spaceboyz.net>
|
|
|
|
// Copyright (c) 2020 Maxime “pep” Buquet <pep@bouah.net>
|
|
|
|
// Copyright (c) 2020 Matt Bilker <me@mbilker.us>
|
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
// 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/.
|
|
|
|
|
2017-03-08 19:34:17 +00:00
|
|
|
//! Provides an error type for this crate.
|
|
|
|
|
2017-02-19 19:46:44 +00:00
|
|
|
use std::convert::From;
|
2019-09-07 14:02:40 +00:00
|
|
|
use std::error::Error as StdError;
|
2017-02-19 19:46:44 +00:00
|
|
|
|
2018-02-18 18:54:09 +00:00
|
|
|
/// Our main error type.
|
2019-09-05 18:06:17 +00:00
|
|
|
#[derive(Debug)]
|
2018-02-18 18:54:09 +00:00
|
|
|
pub enum Error {
|
|
|
|
/// An error from quick_xml.
|
2019-09-05 18:06:17 +00:00
|
|
|
XmlError(::quick_xml::Error),
|
2018-02-18 18:54:09 +00:00
|
|
|
|
|
|
|
/// An UTF-8 conversion error.
|
2019-09-05 18:06:17 +00:00
|
|
|
Utf8Error(::std::str::Utf8Error),
|
2018-02-18 18:54:09 +00:00
|
|
|
|
|
|
|
/// An I/O error, from std::io.
|
2019-09-05 18:06:17 +00:00
|
|
|
IoError(::std::io::Error),
|
2018-02-18 18:54:09 +00:00
|
|
|
|
|
|
|
/// An error which is returned when the end of the document was reached prematurely.
|
|
|
|
EndOfDocument,
|
|
|
|
|
|
|
|
/// An error which is returned when an element is closed when it shouldn't be
|
|
|
|
InvalidElementClosed,
|
|
|
|
|
2020-03-30 13:12:36 +00:00
|
|
|
/// An error which is returned when an elemet's name contains more colons than permitted
|
2018-02-18 18:54:09 +00:00
|
|
|
InvalidElement,
|
2019-08-22 16:04:47 +00:00
|
|
|
|
2020-03-29 16:32:16 +00:00
|
|
|
/// An error which is returned when an element being serialized doesn't contain a prefix
|
|
|
|
/// (be it None or Some(_)).
|
|
|
|
InvalidPrefix,
|
|
|
|
|
minidom: forcing a namespace on Element. Stop requiring prefixes.
Below is what I think I did.
A few changes:
- Change prefixes to be something less important in the API.
- Rework the Element struct to force a namespace. In XMPP everything is
namespaced.
- Remove parent ref on what was previously NamespaceSet and is now
Prefixes.
More specifically this means `Element::new` has changed to require
`Element`'s new new properties as parameters. `Element::builder` and
`Element::bare` now require a namespace unconditionally.
`Element::prefix` has been removed.
This new API is based on the fact that prefixes are non-essential
(really just an implementation detail) and shouldn't be visible to the
user. It is possible nonetheless to set custom prefixes for
compatibility reasons with `ElementBuilder::prefix`. **A prefix is
firstly mapped to a namespace, and then attached to an element**, there
cannot be a prefix without a namespace.
Prefix inheritance is used if possible but for the case with no
prefix ("xmlns") to be reused, we only check custom prefixes declared on
the tag itself and not ascendants. If it's already used then we generate
prefixes (ns0, ns1, ..) checking on what has been declared on all
ascendants (plus of course those already set on the current tag).
Example API:
```rust
let mut elem = ElementBuilder("stream", "http://etherx.jabber.org/streams")
.prefix(Some(String::from("stream")), "http://etherx.jabber.org/streams)
.prefix(None, "jabber:client")
.attr(..)
.build();
assert_eq!(elem.ns(), String::from("http://etherx.jabber.org/streams"));
```
See also the few tests added in src/tests.
TODO: Fix inconsistencies wrt. "prefix:name" format provided as a name
when creating an Element with `Element::new` or `Element::bare`.
`Element::builder` already handles this as it should, splitting name and
prefix.
TODO: Change `Element::name` method to `Element::local_name` to make it
more explicit.
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
2020-03-27 12:45:22 +00:00
|
|
|
/// An error which is returned when an element doesn't contain a namespace
|
|
|
|
MissingNamespace,
|
|
|
|
|
2019-08-22 16:04:47 +00:00
|
|
|
/// An error which is returned when a comment is to be parsed by minidom
|
2020-03-26 18:50:34 +00:00
|
|
|
NoComments,
|
2020-03-29 19:35:53 +00:00
|
|
|
|
|
|
|
/// An error which is returned when a prefixed is defined twice
|
|
|
|
DuplicatePrefix,
|
2018-02-18 18:54:09 +00:00
|
|
|
}
|
|
|
|
|
2019-09-07 14:02:40 +00:00
|
|
|
impl StdError for Error {
|
|
|
|
fn cause(&self) -> Option<&dyn StdError> {
|
|
|
|
match self {
|
2020-02-26 11:54:05 +00:00
|
|
|
Error::XmlError(e) => Some(e),
|
2019-09-07 14:02:40 +00:00
|
|
|
Error::Utf8Error(e) => Some(e),
|
|
|
|
Error::IoError(e) => Some(e),
|
|
|
|
Error::EndOfDocument => None,
|
|
|
|
Error::InvalidElementClosed => None,
|
|
|
|
Error::InvalidElement => None,
|
2020-03-29 16:32:16 +00:00
|
|
|
Error::InvalidPrefix => None,
|
minidom: forcing a namespace on Element. Stop requiring prefixes.
Below is what I think I did.
A few changes:
- Change prefixes to be something less important in the API.
- Rework the Element struct to force a namespace. In XMPP everything is
namespaced.
- Remove parent ref on what was previously NamespaceSet and is now
Prefixes.
More specifically this means `Element::new` has changed to require
`Element`'s new new properties as parameters. `Element::builder` and
`Element::bare` now require a namespace unconditionally.
`Element::prefix` has been removed.
This new API is based on the fact that prefixes are non-essential
(really just an implementation detail) and shouldn't be visible to the
user. It is possible nonetheless to set custom prefixes for
compatibility reasons with `ElementBuilder::prefix`. **A prefix is
firstly mapped to a namespace, and then attached to an element**, there
cannot be a prefix without a namespace.
Prefix inheritance is used if possible but for the case with no
prefix ("xmlns") to be reused, we only check custom prefixes declared on
the tag itself and not ascendants. If it's already used then we generate
prefixes (ns0, ns1, ..) checking on what has been declared on all
ascendants (plus of course those already set on the current tag).
Example API:
```rust
let mut elem = ElementBuilder("stream", "http://etherx.jabber.org/streams")
.prefix(Some(String::from("stream")), "http://etherx.jabber.org/streams)
.prefix(None, "jabber:client")
.attr(..)
.build();
assert_eq!(elem.ns(), String::from("http://etherx.jabber.org/streams"));
```
See also the few tests added in src/tests.
TODO: Fix inconsistencies wrt. "prefix:name" format provided as a name
when creating an Element with `Element::new` or `Element::bare`.
`Element::builder` already handles this as it should, splitting name and
prefix.
TODO: Change `Element::name` method to `Element::local_name` to make it
more explicit.
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
2020-03-27 12:45:22 +00:00
|
|
|
Error::MissingNamespace => None,
|
2020-03-26 18:50:34 +00:00
|
|
|
Error::NoComments => None,
|
2020-03-29 19:35:53 +00:00
|
|
|
Error::DuplicatePrefix => None,
|
2019-09-07 14:02:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-05 18:06:17 +00:00
|
|
|
impl std::fmt::Display for Error {
|
|
|
|
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
|
|
match self {
|
|
|
|
Error::XmlError(e) => write!(fmt, "XML error: {}", e),
|
|
|
|
Error::Utf8Error(e) => write!(fmt, "UTF-8 error: {}", e),
|
|
|
|
Error::IoError(e) => write!(fmt, "IO error: {}", e),
|
2019-10-22 23:32:41 +00:00
|
|
|
Error::EndOfDocument => {
|
|
|
|
write!(fmt, "the end of the document has been reached prematurely")
|
|
|
|
}
|
|
|
|
Error::InvalidElementClosed => {
|
|
|
|
write!(fmt, "the XML is invalid, an element was wrongly closed")
|
|
|
|
}
|
2019-09-05 18:06:17 +00:00
|
|
|
Error::InvalidElement => write!(fmt, "the XML element is invalid"),
|
2020-03-29 16:32:16 +00:00
|
|
|
Error::InvalidPrefix => write!(fmt, "the prefix is invalid"),
|
minidom: forcing a namespace on Element. Stop requiring prefixes.
Below is what I think I did.
A few changes:
- Change prefixes to be something less important in the API.
- Rework the Element struct to force a namespace. In XMPP everything is
namespaced.
- Remove parent ref on what was previously NamespaceSet and is now
Prefixes.
More specifically this means `Element::new` has changed to require
`Element`'s new new properties as parameters. `Element::builder` and
`Element::bare` now require a namespace unconditionally.
`Element::prefix` has been removed.
This new API is based on the fact that prefixes are non-essential
(really just an implementation detail) and shouldn't be visible to the
user. It is possible nonetheless to set custom prefixes for
compatibility reasons with `ElementBuilder::prefix`. **A prefix is
firstly mapped to a namespace, and then attached to an element**, there
cannot be a prefix without a namespace.
Prefix inheritance is used if possible but for the case with no
prefix ("xmlns") to be reused, we only check custom prefixes declared on
the tag itself and not ascendants. If it's already used then we generate
prefixes (ns0, ns1, ..) checking on what has been declared on all
ascendants (plus of course those already set on the current tag).
Example API:
```rust
let mut elem = ElementBuilder("stream", "http://etherx.jabber.org/streams")
.prefix(Some(String::from("stream")), "http://etherx.jabber.org/streams)
.prefix(None, "jabber:client")
.attr(..)
.build();
assert_eq!(elem.ns(), String::from("http://etherx.jabber.org/streams"));
```
See also the few tests added in src/tests.
TODO: Fix inconsistencies wrt. "prefix:name" format provided as a name
when creating an Element with `Element::new` or `Element::bare`.
`Element::builder` already handles this as it should, splitting name and
prefix.
TODO: Change `Element::name` method to `Element::local_name` to make it
more explicit.
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
2020-03-27 12:45:22 +00:00
|
|
|
Error::MissingNamespace => write!(
|
|
|
|
fmt,
|
|
|
|
"the XML element is missing a namespace",
|
|
|
|
),
|
2020-03-26 18:50:34 +00:00
|
|
|
Error::NoComments => write!(
|
2019-10-22 23:32:41 +00:00
|
|
|
fmt,
|
2020-03-26 18:50:34 +00:00
|
|
|
"a comment has been found even though comments are forbidden"
|
2019-10-22 23:32:41 +00:00
|
|
|
),
|
2020-03-29 19:35:53 +00:00
|
|
|
Error::DuplicatePrefix => write!(fmt, "the prefix is already defined"),
|
2019-09-05 18:06:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-11 01:01:18 +00:00
|
|
|
impl From<::quick_xml::Error> for Error {
|
|
|
|
fn from(err: ::quick_xml::Error) -> Error {
|
2018-02-18 18:54:09 +00:00
|
|
|
Error::XmlError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<::std::str::Utf8Error> for Error {
|
|
|
|
fn from(err: ::std::str::Utf8Error) -> Error {
|
|
|
|
Error::Utf8Error(err)
|
2017-02-19 19:46:44 +00:00
|
|
|
}
|
2018-02-18 18:54:09 +00:00
|
|
|
}
|
2017-02-19 19:46:44 +00:00
|
|
|
|
2018-02-18 18:54:09 +00:00
|
|
|
impl From<::std::io::Error> for Error {
|
|
|
|
fn from(err: ::std::io::Error) -> Error {
|
|
|
|
Error::IoError(err)
|
2017-02-19 19:46:44 +00:00
|
|
|
}
|
|
|
|
}
|
2018-02-18 18:54:09 +00:00
|
|
|
|
|
|
|
/// Our simplified Result type.
|
|
|
|
pub type Result<T> = ::std::result::Result<T, Error>;
|