@@ -1842,7 +1842,8 @@ use crate::{
1842
1842
errors:: Error ,
1843
1843
events:: { BytesCData , BytesEnd , BytesStart , BytesText , Event } ,
1844
1844
name:: QName ,
1845
- reader:: Reader ,
1845
+ reader:: Reader ,
1846
+ resolver:: { EntityResolver , DefaultEntityResolver } ,
1846
1847
} ;
1847
1848
use serde:: de:: { self , Deserialize , DeserializeOwned , DeserializeSeed , SeqAccess , Visitor } ;
1848
1849
use std:: borrow:: Cow ;
@@ -1954,26 +1955,34 @@ impl<'a> PayloadEvent<'a> {
1954
1955
}
1955
1956
}
1956
1957
1958
+
1957
1959
/// An intermediate reader that consumes [`PayloadEvent`]s and produces final [`DeEvent`]s.
1958
1960
/// [`PayloadEvent::Text`] events, that followed by any event except
1959
1961
/// [`PayloadEvent::Text`] or [`PayloadEvent::CData`], are trimmed from the end.
1960
- struct XmlReader < ' i , R : XmlRead < ' i > > {
1962
+ struct XmlReader < ' i , R : XmlRead < ' i > , E : EntityResolver < ' i > = DefaultEntityResolver > {
1961
1963
/// A source of low-level XML events
1962
1964
reader : R ,
1963
1965
/// Intermediate event, that could be returned by the next call to `next()`.
1964
1966
/// If that is the `Text` event then leading spaces already trimmed, but
1965
1967
/// trailing spaces is not. Before the event will be returned, trimming of
1966
1968
/// the spaces could be necessary
1967
1969
lookahead : Result < PayloadEvent < ' i > , DeError > ,
1970
+
1971
+ entity_resolver : E
1968
1972
}
1969
1973
1970
- impl < ' i , R : XmlRead < ' i > > XmlReader < ' i , R > {
1971
- fn new ( mut reader : R ) -> Self {
1974
+ impl < ' i , R : XmlRead < ' i > , E : EntityResolver < ' i > > XmlReader < ' i , R , E > {
1975
+ fn new ( reader : R ) -> Self
1976
+ where E : Default {
1977
+ Self :: with_resolver ( reader, E :: default ( ) )
1978
+ }
1979
+
1980
+ fn with_resolver ( mut reader : R , entity_resolver : E ) -> Self {
1972
1981
// Lookahead by one event immediately, so we do not need to check in the
1973
1982
// loop if we need lookahead or not
1974
1983
let lookahead = reader. next ( ) ;
1975
1984
1976
- Self { reader, lookahead }
1985
+ Self { reader, lookahead, entity_resolver }
1977
1986
}
1978
1987
1979
1988
/// Read next event and put it in lookahead, return the current lookahead
@@ -2029,7 +2038,7 @@ impl<'i, R: XmlRead<'i>> XmlReader<'i, R> {
2029
2038
if self . need_trim_end ( ) {
2030
2039
e. inplace_trim_end ( ) ;
2031
2040
}
2032
- Ok ( e. unescape ( ) ?)
2041
+ Ok ( e. unescape_with ( | ent : & str | self . entity_resolver . resolve_entity ( ent ) ) ?)
2033
2042
}
2034
2043
PayloadEvent :: CData ( e) => Ok ( e. decode ( ) ?) ,
2035
2044
@@ -2167,12 +2176,12 @@ where
2167
2176
////////////////////////////////////////////////////////////////////////////////////////////////////
2168
2177
2169
2178
/// A structure that deserializes XML into Rust values.
2170
- pub struct Deserializer < ' de , R >
2179
+ pub struct Deserializer < ' de , R , S : EntityResolver < ' de > = DefaultEntityResolver >
2171
2180
where
2172
2181
R : XmlRead < ' de > ,
2173
2182
{
2174
2183
/// An XML reader that streams events into this deserializer
2175
- reader : XmlReader < ' de , R > ,
2184
+ reader : XmlReader < ' de , R , S > ,
2176
2185
2177
2186
/// When deserializing sequences sometimes we have to skip unwanted events.
2178
2187
/// That events should be stored and then replayed. This is a replay buffer,
@@ -2557,17 +2566,46 @@ where
2557
2566
/// instead, because it will borrow instead of copy. If you have `&[u8]` which
2558
2567
/// is known to represent UTF-8, you can decode it first before using [`from_str`].
2559
2568
pub fn from_reader ( reader : R ) -> Self {
2569
+ Self :: with_resolver ( reader, DefaultEntityResolver )
2570
+ }
2571
+ }
2572
+
2573
+
2574
+ impl < ' de , R , E : EntityResolver < ' de > > Deserializer < ' de , IoReader < R > , E >
2575
+ where
2576
+ R : BufRead ,
2577
+ {
2578
+ /// Create new deserializer that will copy data from the specified reader
2579
+ /// into internal buffer. If you already have a string use [`Self::from_str`]
2580
+ /// instead, because it will borrow instead of copy. If you have `&[u8]` which
2581
+ /// is known to represent UTF-8, you can decode it first before using [`from_str`].
2582
+ pub fn with_resolver ( reader : R , entity_resolver : E ) -> Self {
2560
2583
let mut reader = Reader :: from_reader ( reader) ;
2561
2584
reader. expand_empty_elements ( true ) . check_end_names ( true ) ;
2562
2585
2563
- Self :: new ( IoReader {
2586
+ let io_reader = IoReader {
2564
2587
reader,
2565
2588
start_trimmer : StartTrimmer :: default ( ) ,
2566
2589
buf : Vec :: new ( ) ,
2567
- } )
2590
+ } ;
2591
+
2592
+ Self {
2593
+ reader : XmlReader :: with_resolver ( io_reader, entity_resolver) ,
2594
+
2595
+ #[ cfg( feature = "overlapped-lists" ) ]
2596
+ read : VecDeque :: new ( ) ,
2597
+ #[ cfg( feature = "overlapped-lists" ) ]
2598
+ write : VecDeque :: new ( ) ,
2599
+ #[ cfg( feature = "overlapped-lists" ) ]
2600
+ limit : None ,
2601
+
2602
+ #[ cfg( not( feature = "overlapped-lists" ) ) ]
2603
+ peek : None ,
2604
+ }
2568
2605
}
2569
2606
}
2570
2607
2608
+
2571
2609
impl < ' de , ' a , R > de:: Deserializer < ' de > for & ' a mut Deserializer < ' de , R >
2572
2610
where
2573
2611
R : XmlRead < ' de > ,
0 commit comments