Skip to content

Commit 6b34514

Browse files
committed
Make attribute creation more uniform
closes #410
1 parent a6588c2 commit 6b34514

File tree

2 files changed

+86
-10
lines changed

2 files changed

+86
-10
lines changed

Changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
- [#395]: Add support for XML Schema `xs:list`
2626
- [#324]: `Reader::from_str` / `Deserializer::from_str` / `from_str` now ignore
2727
the XML declared encoding and always use UTF-8
28+
- [#413]: Added `Attribute::from_bytes()`, `Attribute::from_escaped_bytes()`,
29+
`Attribute::from_str()` and `Attribute::from_escaped_str()` constructors.
2830
- [#416]: Add `borrow()` methods in all event structs which allows to get
2931
a borrowed version of any event
3032

@@ -42,6 +44,9 @@
4244
- [#363]: Do not generate empty `Event::Text` events
4345
- [#412]: Fix using incorrect encoding if `read_to_end` family of methods or `read_text`
4446
method not found a corresponding end tag and reader has non-UTF-8 encoding
47+
- [#413]: `Attribute::from((&[u8], &[u8]))` was made consistent with `Attribute::from((&str, &str))`
48+
in that both will now escape the value. WARNING: if you were passing escaped values via this
49+
approach before, your values will be double-escaped and incorrect.
4550

4651
### Misc Changes
4752

@@ -137,6 +142,7 @@
137142
[#403]: https://github.com/tafia/quick-xml/pull/403
138143
[#407]: https://github.com/tafia/quick-xml/pull/407
139144
[#412]: https://github.com/tafia/quick-xml/pull/412
145+
[#413]: https://github.com/tafia/quick-xml/pull/413
140146
[#416]: https://github.com/tafia/quick-xml/pull/416
141147
[#418]: https://github.com/tafia/quick-xml/pull/418
142148

src/events/attributes.rs

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,82 @@ pub struct Attribute<'a> {
3030
}
3131

3232
impl<'a> Attribute<'a> {
33+
/// Creates new attribute from text representation.
34+
/// Key is stored as-is, but the value will be escaped.
35+
///
36+
/// # Examples
37+
///
38+
/// ```
39+
/// # use pretty_assertions::assert_eq;
40+
/// use quick_xml::events::attributes::Attribute;
41+
///
42+
/// let features = Attribute::from_str("features", "Bells & whistles");
43+
/// assert_eq!(features.value, "Bells &amp; whistles".as_bytes());
44+
/// ```
45+
pub fn from_str(key: &'a str, val: &'a str) -> Attribute<'a> {
46+
Attribute {
47+
key: QName(key.as_bytes()),
48+
value: escape(val.as_bytes()),
49+
}
50+
}
51+
52+
/// Creates new attribute from text representation.
53+
/// Does not apply any transformation to either key or value.
54+
///
55+
/// # Examples
56+
///
57+
/// ```
58+
/// # use pretty_assertions::assert_eq;
59+
/// use quick_xml::events::attributes::Attribute;
60+
///
61+
/// let features = Attribute::from_escaped_str("features", "Bells &amp; whistles");
62+
/// assert_eq!(features.value, "Bells &amp; whistles".as_bytes());
63+
/// ```
64+
pub fn from_escaped_str(key: &'a str, val: &'a str) -> Attribute<'a> {
65+
Attribute {
66+
key: QName(key.as_bytes()),
67+
value: Cow::from(val.as_bytes()),
68+
}
69+
}
70+
71+
/// Creates new attribute from raw bytes.
72+
/// Key is stored as-is, but the value will be escaped.
73+
///
74+
/// # Examples
75+
///
76+
/// ```
77+
/// # use pretty_assertions::assert_eq;
78+
/// use quick_xml::events::attributes::Attribute;
79+
///
80+
/// let features = Attribute::from_bytes("features".as_bytes(), "Bells & whistles".as_bytes());
81+
/// assert_eq!(features.value, "Bells &amp; whistles".as_bytes());
82+
/// ```
83+
pub fn from_bytes(key: &'a [u8], val: &'a [u8]) -> Attribute<'a> {
84+
Attribute {
85+
key: QName(key),
86+
value: escape(val),
87+
}
88+
}
89+
90+
/// Creates new attribute from raw bytes.
91+
/// Does not apply any transformation to either key or value.
92+
///
93+
/// # Examples
94+
///
95+
/// ```
96+
/// # use pretty_assertions::assert_eq;
97+
/// use quick_xml::events::attributes::Attribute;
98+
///
99+
/// let features = Attribute::from_escaped_bytes("features".as_bytes(), "Bells &amp; whistles".as_bytes());
100+
/// assert_eq!(features.value, "Bells &amp; whistles".as_bytes());
101+
/// ```
102+
pub fn from_escaped_bytes(key: &'a [u8], val: &'a [u8]) -> Attribute<'a> {
103+
Attribute {
104+
key: QName(key),
105+
value: Cow::from(val),
106+
}
107+
}
108+
33109
/// Returns the unescaped value.
34110
///
35111
/// This is normally the value you are interested in. Escape sequences such as `&gt;` are
@@ -130,22 +206,19 @@ impl<'a> Debug for Attribute<'a> {
130206

131207
impl<'a> From<(&'a [u8], &'a [u8])> for Attribute<'a> {
132208
/// Creates new attribute from raw bytes.
133-
/// Does not apply any transformation to both key and value.
209+
/// Key is stored as-is, but the value will be escaped.
134210
///
135211
/// # Examples
136212
///
137213
/// ```
138214
/// # use pretty_assertions::assert_eq;
139215
/// use quick_xml::events::attributes::Attribute;
140216
///
141-
/// let features = Attribute::from(("features".as_bytes(), "Bells &amp; whistles".as_bytes()));
217+
/// let features = Attribute::from(("features".as_bytes(), "Bells & whistles".as_bytes()));
142218
/// assert_eq!(features.value, "Bells &amp; whistles".as_bytes());
143219
/// ```
144220
fn from(val: (&'a [u8], &'a [u8])) -> Attribute<'a> {
145-
Attribute {
146-
key: QName(val.0),
147-
value: Cow::from(val.1),
148-
}
221+
Attribute::from_bytes(val.0, val.1)
149222
}
150223
}
151224

@@ -163,10 +236,7 @@ impl<'a> From<(&'a str, &'a str)> for Attribute<'a> {
163236
/// assert_eq!(features.value, "Bells &amp; whistles".as_bytes());
164237
/// ```
165238
fn from(val: (&'a str, &'a str)) -> Attribute<'a> {
166-
Attribute {
167-
key: QName(val.0.as_bytes()),
168-
value: escape(val.1.as_bytes()),
169-
}
239+
Attribute::from_str(val.0, val.1)
170240
}
171241
}
172242

0 commit comments

Comments
 (0)