Skip to content

Commit 2f61970

Browse files
committed
Make attribute creation more uniform
closes #410
1 parent 0febc2b commit 2f61970

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

2931
### Bug Fixes
3032

@@ -38,6 +40,9 @@
3840
returns `ResolveResult::Unknown` if prefix was not registered in namespace buffer
3941
- [#393]: Fix breaking processing after encounter an attribute with a reserved name (started with "xmlns")
4042
- [#363]: Do not generate empty `Event::Text` events
43+
- [#413]: `Attribute::from((&[u8], &[u8]))` was made consistent with `Attribute::from((&str, &str))`
44+
in that both will now escape the value. WARNING: if you were passing escaped values via this
45+
approach before, your values will be double-escaped and incorrect.
4146

4247
### Misc Changes
4348

@@ -117,6 +122,7 @@
117122
[#395]: https://github.com/tafia/quick-xml/pull/395
118123
[#403]: https://github.com/tafia/quick-xml/pull/403
119124
[#407]: https://github.com/tafia/quick-xml/pull/407
125+
[#413]: https://github.com/tafia/quick-xml/pull/413
120126

121127
## 0.23.0 -- 2022-05-08
122128

src/events/attributes.rs

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

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

133209
impl<'a> From<(&'a [u8], &'a [u8])> for Attribute<'a> {
134210
/// Creates new attribute from raw bytes.
135-
/// Does not apply any transformation to both key and value.
211+
/// Key is stored as-is, but the value will be escaped.
136212
///
137213
/// # Examples
138214
///
139215
/// ```
140216
/// # use pretty_assertions::assert_eq;
141217
/// use quick_xml::events::attributes::Attribute;
142218
///
143-
/// let features = Attribute::from(("features".as_bytes(), "Bells &amp; whistles".as_bytes()));
219+
/// let features = Attribute::from(("features".as_bytes(), "Bells & whistles".as_bytes()));
144220
/// assert_eq!(features.value, "Bells &amp; whistles".as_bytes());
145221
/// ```
146222
fn from(val: (&'a [u8], &'a [u8])) -> Attribute<'a> {
147-
Attribute {
148-
key: QName(val.0),
149-
value: Cow::from(val.1),
150-
}
223+
Attribute::from_bytes(val.0, val.1)
151224
}
152225
}
153226

@@ -165,10 +238,7 @@ impl<'a> From<(&'a str, &'a str)> for Attribute<'a> {
165238
/// assert_eq!(features.value, "Bells &amp; whistles".as_bytes());
166239
/// ```
167240
fn from(val: (&'a str, &'a str)) -> Attribute<'a> {
168-
Attribute {
169-
key: QName(val.0.as_bytes()),
170-
value: escape(val.1.as_bytes()),
171-
}
241+
Attribute::from_str(val.0, val.1)
172242
}
173243
}
174244

0 commit comments

Comments
 (0)