Skip to content

Commit

Permalink
Annotate everything to make it work
Browse files Browse the repository at this point in the history
  • Loading branch information
dralley committed Jul 12, 2022
1 parent fda559a commit e36d5e2
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 20 deletions.
18 changes: 10 additions & 8 deletions examples/custom_entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,21 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
match reader.read_event_into(&mut buf) {
Ok(Event::DocType(ref e)) => {
for cap in entity_re.captures_iter(&e) {
custom_entities.insert(cap[1].to_vec(), String::from_utf8(cap[2].to_vec())?);
custom_entities.insert(
cap[1].to_vec(),
reader.decoder().decode(&cap[2])?.into_owned(),
);
}
}
Ok(Event::Start(ref e)) => match e.name().as_ref() {
b"test" => {
let lookup_custom_entity = |ent| custom_entities.get(ent).map(|s| s.as_str());
let attributes = e
.attributes()
.map(|a| {
a.unwrap()
.unescape_and_decode_value_with_custom_entities(
&reader,
lookup_custom_entity,
)
.unescape_and_decode_value_with_custom_entities(&reader, |ent| {
custom_entities.get(ent).map(|s| s.as_str())
})
.unwrap()
})
.collect::<Vec<_>>();
Expand All @@ -57,10 +58,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
_ => (),
},
Ok(Event::Text(ref e)) => {
let lookup_custom_entity = |ent| custom_entities.get(ent).map(|s| s.as_str());
println!(
"text value: {}",
e.unescape_and_decode_with_custom_entities(&reader, lookup_custom_entity)
e.unescape_and_decode_with_custom_entities(&reader, |ent| custom_entities
.get(ent)
.map(|s| s.as_str()))
.unwrap()
);
}
Expand Down
11 changes: 9 additions & 2 deletions src/escapei.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,15 @@ pub fn unescape(raw: &[u8]) -> Result<Cow<[u8]>, EscapeError> {
///
/// # Pre-condition
///
/// The implementation of `lookup_custom_entity` is expected to operate over UTF-8 inputs.
pub fn unescape_with<'a>(raw: &'a [u8], resolve_entity: impl Fn(&[u8]) -> Option<&str>) -> Result<Cow<'a, [u8]>, EscapeError> {
/// The implementation of `resolve_entity` is expected to operate over UTF-8 inputs.
pub fn unescape_with<'input, 'entity, F>(
raw: &'input [u8],
resolve_entity: F,
) -> Result<Cow<'input, [u8]>, EscapeError>
where
// the lifetime of the output comes from a capture or is `'static`
F: Fn(&[u8]) -> Option<&'entity str>,
{
let mut unescaped = None;
let mut last_end = 0;
let mut iter = memchr::memchr2_iter(b'&', b';', raw);
Expand Down
8 changes: 4 additions & 4 deletions src/events/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ impl<'a> Attribute<'a> {
/// # Pre-condition
///
/// The keys and values of `custom_entities`, if any, must be valid UTF-8.
pub fn unescaped_value_with_custom_entities<'s>(
pub fn unescaped_value_with_custom_entities<'s, 'entity>(
&'s self,
resolve_entity: impl Fn(&[u8]) -> Option<&str>,
resolve_entity: impl Fn(&[u8]) -> Option<&'entity str>,
) -> XmlResult<Cow<'s, [u8]>> {
unescape_with(&*self.value, resolve_entity).map_err(Error::EscapeError)
}
Expand Down Expand Up @@ -90,10 +90,10 @@ impl<'a> Attribute<'a> {
/// # Pre-condition
///
/// The keys and values of `custom_entities`, if any, must be valid UTF-8.
pub fn unescape_and_decode_value_with_custom_entities<B>(
pub fn unescape_and_decode_value_with_custom_entities<'entity, B>(
&self,
reader: &Reader<B>,
resolve_entity: impl Fn(&[u8]) -> Option<&str>,
resolve_entity: impl Fn(&[u8]) -> Option<&'entity str>,
) -> XmlResult<String> {
let decoded = reader.decoder().decode(&*self.value)?;
let unescaped = unescape_with(decoded.as_bytes(), resolve_entity)?;
Expand Down
12 changes: 6 additions & 6 deletions src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,12 +765,12 @@ impl<'a> BytesText<'a> {
///
/// # Pre-condition
///
/// The implementation of `lookup_custom_entity` is expected to operate over UTF-8 inputs.
/// The implementation of `resolve_entity` is expected to operate over UTF-8 inputs.
///
/// See also [`unescaped()`](Self::unescaped)
pub fn unescaped_with_custom_entities<'s>(
pub fn unescaped_with_custom_entities<'s, 'entity>(
&'s self,
resolve_entity: impl Fn(&[u8]) -> Option<&str>,
resolve_entity: impl Fn(&[u8]) -> Option<&'entity str>,
) -> Result<Cow<'s, [u8]>> {
unescape_with(self, resolve_entity).map_err(Error::EscapeError)
}
Expand All @@ -794,11 +794,11 @@ impl<'a> BytesText<'a> {
///
/// # Pre-condition
///
/// The implementation of `lookup_custom_entity` is expected to operate over UTF-8 inputs.
pub fn unescape_and_decode_with_custom_entities<B>(
/// The implementation of `resolve_entity` is expected to operate over UTF-8 inputs.
pub fn unescape_and_decode_with_custom_entities<'entity, B>(
&self,
reader: &Reader<B>,
resolve_entity: impl Fn(&[u8]) -> Option<&str>,
resolve_entity: impl Fn(&[u8]) -> Option<&'entity str>,
) -> Result<String> {
let decoded = reader.decoder().decode(&*self)?;

Expand Down

0 comments on commit e36d5e2

Please sign in to comment.