aboutsummaryrefslogtreecommitdiff
path: root/src/attribute.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/attribute.rs')
-rw-r--r--src/attribute.rs74
1 files changed, 67 insertions, 7 deletions
diff --git a/src/attribute.rs b/src/attribute.rs
index 8fb4778..4ae2142 100644
--- a/src/attribute.rs
+++ b/src/attribute.rs
@@ -1,30 +1,78 @@
//! Attribute.
+use std::borrow::Cow;
+use std::str::Utf8Error;
+
use quick_xml::events::attributes::{
AttrError,
Attribute as QuickXMLAttribute,
Attributes,
};
+use quick_xml::name::QName;
+use quick_xml::Error as QuickXMLError;
+
+use crate::escape::EscapeError;
/// Represent a XML attribute.
#[derive(Debug, Clone, PartialEq)]
-pub struct Attribute<'a>
+pub struct Attribute<'data>
{
- inner: QuickXMLAttribute<'a>,
+ inner: QuickXMLAttribute<'data>,
}
-impl<'a> Attribute<'a>
+impl<'data> Attribute<'data>
{
- /// Attribute key.
+ /// Returns a new `Attribute`.
+ pub fn new(key: &'data impl AsRef<[u8]>, value: impl Into<Cow<'data, [u8]>>) -> Self
+ {
+ Self {
+ inner: QuickXMLAttribute {
+ key: QName(key.as_ref()),
+ value: value.into(),
+ },
+ }
+ }
+
+ /// Returns the key.
+ ///
+ /// # Errors
+ /// Will return `Err` if the key is invalid UTF-8.
+ pub fn key(&self) -> Result<&str, Error>
+ {
+ std::str::from_utf8(self.key_bytes()).map_err(Error::KeyNotUTF8)
+ }
+
+ /// Returns the key as bytes.
#[must_use]
- pub fn key(&self) -> &[u8]
+ pub fn key_bytes(&self) -> &[u8]
{
self.inner.key.as_ref()
}
- /// Attribute value.
+ /// Returns the value.
+ ///
+ /// # Errors
+ /// Will return `Err` if:
+ /// - The value is invalid UTF-8
+ /// - Unescaping the value fails
+ pub fn value(&self) -> Result<Cow<str>, Error>
+ {
+ self.inner.unescape_value().map_err(|err| match err {
+ QuickXMLError::NonDecodable(Some(utf8_error)) => {
+ Error::ValueNotUTF8(utf8_error)
+ }
+ QuickXMLError::EscapeError(escape_err) => {
+ Error::UnescapeValueFailed(EscapeError::from_quick_xml(escape_err))
+ }
+ _ => {
+ unreachable!();
+ }
+ })
+ }
+
+ /// Returns the value as bytes. They may or may not be escaped.
#[must_use]
- pub fn value(&self) -> &[u8]
+ pub fn value_bytes(&self) -> &[u8]
{
&self.inner.value
}
@@ -124,6 +172,18 @@ pub enum Error
/// ```
#[error("Position {0}: duplicated attribute, previous declaration at position {1}")]
Duplicated(usize, usize),
+
+ /// Attribute key is not valid UTF-8.
+ #[error("Attribute key is not valid UTF-8")]
+ KeyNotUTF8(#[source] Utf8Error),
+
+ /// Attribute value is not valid UTF-8.
+ #[error("Attribute value is not valid UTF-8")]
+ ValueNotUTF8(#[source] Utf8Error),
+
+ /// Failed to unescape value.
+ #[error("Failed to unescape value")]
+ UnescapeValueFailed(#[source] EscapeError),
}
impl From<AttrError> for Error