Skip to content

Commit 2553b62

Browse files
committed
Accept Decoder instead of Reader when decoding attributes.
This will allow decode them even if Reader does not exists, for example, when you only write events.
1 parent 31ca532 commit 2553b62

File tree

6 files changed

+24
-18
lines changed

6 files changed

+24
-18
lines changed

Changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919

2020
### Misc Changes
2121

22+
- [#760]: `Attribute::decode_and_unescape_value` and `Attribute::decode_and_unescape_value_with` now
23+
accepts `Decoder` instead of `Reader`. Use `Reader::decoder()` to get it.
24+
25+
[#760]: https://github.com/tafia/quick-xml/pull/760
26+
2227

2328
## 0.33.0 -- 2024-06-21
2429

benches/macrobenches.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ fn parse_document_from_str(doc: &str) -> XmlResult<()> {
5050
match criterion::black_box(r.read_event()?) {
5151
Event::Start(e) | Event::Empty(e) => {
5252
for attr in e.attributes() {
53-
criterion::black_box(attr?.decode_and_unescape_value(&r)?);
53+
criterion::black_box(attr?.decode_and_unescape_value(r.decoder())?);
5454
}
5555
}
5656
Event::Text(e) => {
@@ -75,7 +75,7 @@ fn parse_document_from_bytes(doc: &[u8]) -> XmlResult<()> {
7575
match criterion::black_box(r.read_event_into(&mut buf)?) {
7676
Event::Start(e) | Event::Empty(e) => {
7777
for attr in e.attributes() {
78-
criterion::black_box(attr?.decode_and_unescape_value(&r)?);
78+
criterion::black_box(attr?.decode_and_unescape_value(r.decoder())?);
7979
}
8080
}
8181
Event::Text(e) => {
@@ -101,7 +101,7 @@ fn parse_document_from_str_with_namespaces(doc: &str) -> XmlResult<()> {
101101
(resolved_ns, Event::Start(e) | Event::Empty(e)) => {
102102
criterion::black_box(resolved_ns);
103103
for attr in e.attributes() {
104-
criterion::black_box(attr?.decode_and_unescape_value(&r)?);
104+
criterion::black_box(attr?.decode_and_unescape_value(r.decoder())?);
105105
}
106106
}
107107
(resolved_ns, Event::Text(e)) => {
@@ -129,7 +129,7 @@ fn parse_document_from_bytes_with_namespaces(doc: &[u8]) -> XmlResult<()> {
129129
(resolved_ns, Event::Start(e) | Event::Empty(e)) => {
130130
criterion::black_box(resolved_ns);
131131
for attr in e.attributes() {
132-
criterion::black_box(attr?.decode_and_unescape_value(&r)?);
132+
criterion::black_box(attr?.decode_and_unescape_value(r.decoder())?);
133133
}
134134
}
135135
(resolved_ns, Event::Text(e)) => {

examples/custom_entities.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
4747
.attributes()
4848
.map(|a| {
4949
a.unwrap()
50-
.decode_and_unescape_value_with(&reader, |ent| {
50+
.decode_and_unescape_value_with(reader.decoder(), |ent| {
5151
custom_entities.get(ent).map(|s| s.as_str())
5252
})
5353
.unwrap()

examples/read_nodes.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ impl Translation {
7070
for attr_result in element.attributes() {
7171
let a = attr_result?;
7272
match a.key.as_ref() {
73-
b"Language" => lang = a.decode_and_unescape_value(reader)?,
74-
b"Tag" => tag = a.decode_and_unescape_value(reader)?,
73+
b"Language" => lang = a.decode_and_unescape_value(reader.decoder())?,
74+
b"Tag" => tag = a.decode_and_unescape_value(reader.decoder())?,
7575
_ => (),
7676
}
7777
}
@@ -138,7 +138,7 @@ fn main() -> Result<(), AppError> {
138138
Ok::<Cow<'_, str>, Infallible>(std::borrow::Cow::from(""))
139139
})
140140
.unwrap().to_string();
141-
let value = a.decode_and_unescape_value(&reader).or_else(|err| {
141+
let value = a.decode_and_unescape_value(reader.decoder()).or_else(|err| {
142142
dbg!("unable to read key in DefaultSettings attribute {:?}, utf8 error {:?}", &a, err);
143143
Ok::<Cow<'_, str>, Infallible>(std::borrow::Cow::from(""))
144144
}).unwrap().to_string();

src/events/attributes.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
//!
33
//! Provides an iterator over attributes key/value pairs
44
5+
use crate::encoding::Decoder;
56
use crate::errors::Result as XmlResult;
67
use crate::escape::{escape, resolve_predefined_entity, unescape_with};
78
use crate::name::QName;
8-
use crate::reader::Reader;
99
use crate::utils::{is_whitespace, write_byte_string, write_cow_string, Bytes};
10+
1011
use std::fmt::{self, Debug, Display, Formatter};
1112
use std::iter::FusedIterator;
1213
use std::{borrow::Cow, ops::Range};
@@ -84,23 +85,23 @@ impl<'a> Attribute<'a> {
8485
///
8586
/// This will allocate if the value contains any escape sequences or in
8687
/// non-UTF-8 encoding.
87-
pub fn decode_and_unescape_value<B>(&self, reader: &Reader<B>) -> XmlResult<Cow<'a, str>> {
88-
self.decode_and_unescape_value_with(reader, resolve_predefined_entity)
88+
pub fn decode_and_unescape_value(&self, decoder: Decoder) -> XmlResult<Cow<'a, str>> {
89+
self.decode_and_unescape_value_with(decoder, resolve_predefined_entity)
8990
}
9091

9192
/// Decodes then unescapes the value with custom entities.
9293
///
9394
/// This will allocate if the value contains any escape sequences or in
9495
/// non-UTF-8 encoding.
95-
pub fn decode_and_unescape_value_with<'entity, B>(
96+
pub fn decode_and_unescape_value_with<'entity>(
9697
&self,
97-
reader: &Reader<B>,
98+
decoder: Decoder,
9899
resolve_entity: impl FnMut(&str) -> Option<&'entity str>,
99100
) -> XmlResult<Cow<'a, str>> {
100101
let decoded = match &self.value {
101-
Cow::Borrowed(bytes) => reader.decoder().decode(bytes)?,
102+
Cow::Borrowed(bytes) => decoder.decode(bytes)?,
102103
// Convert to owned, because otherwise Cow will be bound with wrong lifetime
103-
Cow::Owned(bytes) => reader.decoder().decode(bytes)?.into_owned().into(),
104+
Cow::Owned(bytes) => decoder.decode(bytes)?.into_owned().into(),
104105
};
105106

106107
match unescape_with(&decoded, resolve_entity)? {

tests/fuzzing.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ fn fuzz_101() {
3030
match reader.read_event_into(&mut buf) {
3131
Ok(Event::Start(e)) | Ok(Event::Empty(e)) => {
3232
for a in e.attributes() {
33-
if a.ok()
34-
.map_or(true, |a| a.decode_and_unescape_value(&reader).is_err())
35-
{
33+
if a.ok().map_or(true, |a| {
34+
a.decode_and_unescape_value(reader.decoder()).is_err()
35+
}) {
3636
break;
3737
}
3838
}

0 commit comments

Comments
 (0)