Skip to main content

anyxml/sax/
handler.rs

1use std::{fmt::Write as _, fs::File, sync::Arc};
2
3use crate::{
4    error::XMLError,
5    sax::{
6        AttributeType, ContentSpec, DOCUMENT_ENTITY_NAME, DefaultDecl, Locator,
7        attributes::Attributes, error::SAXParseError, source::InputSource,
8    },
9    uri::URIStr,
10};
11
12/// SAX Handler.
13///
14/// The default implementation of all methods does nothing.
15pub trait SAXHandler: EntityResolver + ErrorHandler {
16    /// Text content that appears between elements.
17    ///
18    /// The text may be chunked, and consecutive text content may be passed across multiple events.
19    ///
20    /// # Reference
21    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
22    fn characters(&mut self, data: &str) {
23        let _ = data;
24    }
25
26    /// XML declaration or Text declaration.
27    ///
28    /// If `encoding` and `standalone` are [`None`], they are not included in the declaration.
29    ///
30    /// # Reference
31    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
32    fn declaration(&mut self, version: &str, encoding: Option<&str>, standalone: Option<bool>) {
33        let _ = (version, encoding, standalone);
34    }
35
36    /// Whitespace appearing between element contents.
37    ///
38    /// Elements declared in the DTD to have element contents may contain whitespace as
39    /// children. This method can receive such whitespace.
40    ///
41    /// # Reference
42    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
43    fn ignorable_whitespace(&mut self, data: &str) {
44        let _ = data;
45    }
46
47    /// Processing instruction.
48    ///
49    /// # Reference
50    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
51    fn processing_instruction(&mut self, target: &str, data: Option<&str>) {
52        let _ = (target, data);
53    }
54
55    /// Comment.
56    ///
57    /// Comment delimiters ("<!--" and "-->") are not included.
58    ///
59    /// The text may be chunked, and consecutive text content may be passed across multiple events.
60    ///
61    /// # Reference
62    /// [`LexicalHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/LexicalHandler.html)
63    fn comment(&mut self, data: &str) {
64        let _ = data;
65    }
66
67    /// Locator receive event.
68    ///
69    /// The locator is updated by the parser. The locator allows the handler to determine
70    /// at which position within which entity the received event occurred.
71    ///
72    /// This method is called before any other method after parsing begins.  \
73    /// However, if acquiring the document entity is left to the parser,
74    /// [`EntityResolver::resolve_entity`] may be called first.
75    ///
76    /// # Reference
77    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
78    fn set_document_locator(&mut self, locator: Arc<Locator>) {
79        let _ = locator;
80    }
81
82    /// Entity reference that could not be resolved or was not resolved.
83    ///
84    /// # Reference
85    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
86    fn skipped_entity(&mut self, name: &str) {
87        let _ = name;
88    }
89
90    /// Parse start event.
91    ///
92    /// # Reference
93    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
94    fn start_document(&mut self) {}
95    /// Parse end event.
96    ///
97    /// # Reference
98    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
99    fn end_document(&mut self) {}
100
101    /// Element start event.
102    ///
103    /// If namespace support is disabled, `namespace_name` and `local_name` will always be [`None`].  \
104    /// If namespace support is enabled, `local_name` will always be [`Some`]. `namespace_name`
105    /// depends on whether the element is qualified.
106    ///
107    /// # Reference
108    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
109    fn start_element(
110        &mut self,
111        namespace_name: Option<&str>,
112        local_name: Option<&str>,
113        qname: &str,
114        atts: &Attributes,
115    ) {
116        let _ = (namespace_name, local_name, qname, atts);
117    }
118    /// Element end event.
119    ///
120    /// # Reference
121    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
122    fn end_element(&mut self, namespace_name: Option<&str>, local_name: Option<&str>, qname: &str) {
123        let _ = (namespace_name, local_name, qname);
124    }
125
126    /// Namespace scope start event.
127    ///
128    /// Whenever a namespace is declared, this method is called immediately before the
129    /// [`SAXHandler::start_element`] event for the element in which the declaration appears.
130    ///
131    /// The order in which events are reported between namespaces declared on the same element
132    /// is undefined.
133    ///
134    /// # Reference
135    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
136    fn start_prefix_mapping(&mut self, prefix: Option<&str>, namespace_name: &str) {
137        let _ = (prefix, namespace_name);
138    }
139    /// Namespace scope end event.
140    ///
141    /// For each namespace, this is called immediately after the [`SAXHandler::end_element`]
142    /// event of the element in which that namespace was declared.
143    ///
144    /// The order in which events related to namespace declarations defined with the same
145    /// element are reported does not correspond to the order of declaration or the order
146    /// in which [`SAXHandler::start_prefix_mapping`] is called; instead, they are called
147    /// in an arbitrary order.
148    ///
149    /// # Reference
150    /// [`ContentHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ContentHandler.html)
151    fn end_prefix_mapping(&mut self, prefix: Option<&str>) {
152        let _ = prefix;
153    }
154
155    /// Attribute list declaration in DTD.
156    ///
157    /// # Reference
158    /// [`DeclHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/DeclHandler.html)
159    fn attribute_decl(
160        &mut self,
161        element_name: &str,
162        attribute_name: &str,
163        attribute_type: &AttributeType,
164        default_decl: &DefaultDecl,
165    ) {
166        let _ = (element_name, attribute_name, attribute_type, default_decl);
167    }
168
169    /// Element declaration in DTD.
170    ///
171    /// # Reference
172    /// [`DeclHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/DeclHandler.html)
173    fn element_decl(&mut self, name: &str, contentspec: &ContentSpec) {
174        let _ = (name, contentspec);
175    }
176
177    /// Internal entity declaration in DTD.
178    ///
179    /// # Reference
180    /// [`DeclHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/DeclHandler.html)
181    fn internal_entity_decl(&mut self, name: &str, value: &str) {
182        let _ = (name, value);
183    }
184
185    /// External entity declaration in DTD.
186    ///
187    /// # Reference
188    /// [`DeclHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/DeclHandler.html)
189    fn external_entity_decl(&mut self, name: &str, public_id: Option<&str>, system_id: &URIStr) {
190        let _ = (name, public_id, system_id);
191    }
192
193    /// Unparsed external entity declaration in DTD.
194    ///
195    /// # Reference
196    /// [`DTDHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/DTDHandler.html)
197    fn unparsed_entity_decl(
198        &mut self,
199        name: &str,
200        public_id: Option<&str>,
201        system_id: &URIStr,
202        notation_name: &str,
203    ) {
204        let _ = (name, public_id, system_id, notation_name);
205    }
206
207    /// Notation declaration in DTD.
208    ///
209    /// # Reference
210    /// [`DTDHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/DTDHandler.html)
211    fn notation_decl(&mut self, name: &str, public_id: Option<&str>, system_id: Option<&URIStr>) {
212        let _ = (name, public_id, system_id);
213    }
214
215    /// CDATA section start event.
216    ///
217    /// # Reference
218    /// [`LexicalHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/LexicalHandler.html)
219    fn start_cdata(&mut self) {}
220    /// CDATA section end event.
221    ///
222    /// # Reference
223    /// [`LexicalHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/LexicalHandler.html)
224    fn end_cdata(&mut self) {}
225
226    /// DTD start event.
227    ///
228    /// This always occurs in documents that include a DTD, regardless of whether the DTD
229    /// validation option is disabled.
230    ///
231    /// # Reference
232    /// [`LexicalHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/LexicalHandler.html)
233    fn start_dtd(&mut self, name: &str, public_id: Option<&str>, system_id: Option<&URIStr>) {
234        let _ = (name, public_id, system_id);
235    }
236    /// DTD end event.
237    ///
238    /// # Reference
239    /// [`LexicalHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/LexicalHandler.html)
240    fn end_dtd(&mut self) {}
241
242    /// Parsed entity start event.
243    ///
244    /// # Reference
245    /// [`LexicalHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/LexicalHandler.html)
246    fn start_entity(&mut self, name: &str) {
247        let _ = name;
248    }
249    /// Parsed entity end event.
250    ///
251    /// # Reference
252    /// [`LexicalHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/LexicalHandler.html)
253    fn end_entity(&mut self) {}
254}
255
256/// Entity resolver.
257///
258/// This trait provides methods necessary for retrieving external entities. While it is
259/// possible to prevent any entity retrieval by implementing methods that always returns
260/// an error, if document entity retrieval is left to the parser, the document parsing will
261/// fail.
262pub trait EntityResolver {
263    /// This method provides an alternative external DTD subset when no external DTD subset
264    /// is specified in the document type declaration.
265    ///
266    /// `name` is the document element name specified in the document type declaration.
267    ///
268    /// # Reference
269    /// [`EntityResolver2` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/EntityResolver2.html)
270    fn get_external_subset(
271        &mut self,
272        name: &str,
273        base_uri: Option<&URIStr>,
274    ) -> Result<InputSource<'static>, XMLError> {
275        let _ = (name, base_uri);
276        Err(std::io::Error::new(
277            std::io::ErrorKind::NotFound,
278            format!("An external subset '{}' is not found.", name),
279        )
280        .into())
281    }
282
283    /// By default, it attempts to retrieve local files using `base_uri` and `system_id`.
284    ///
285    /// When handling untrusted XML documents, it is recommended to implement custom logic
286    /// to prevent unexpected access to local resources.
287    ///
288    /// `name` is the requested entity name. Special entity names such as "\[document\]" for
289    /// document entities and "\[dtd\]" for external DTD subsets are used.
290    ///
291    /// # Reference
292    /// [`EntityResolver2` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ext/EntityResolver2.html)
293    fn resolve_entity(
294        &mut self,
295        name: &str,
296        public_id: Option<&str>,
297        base_uri: &URIStr,
298        system_id: &URIStr,
299    ) -> Result<InputSource<'static>, XMLError> {
300        let (_, _) = (name, public_id);
301        let path = base_uri.resolve(system_id);
302        let file = File::open(path.path())?;
303        let mut reader = InputSource::from_reader(file, None)?;
304        reader.set_system_id(path);
305        Ok(reader)
306    }
307}
308
309/// Error handler.
310///
311/// By default, each method does nothing and discards the error.
312pub trait ErrorHandler {
313    /// # Reference
314    /// [`ErrorHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ErrorHandler.html)
315    fn error(&mut self, error: SAXParseError) {
316        let _ = error;
317    }
318
319    /// # Reference
320    /// [`ErrorHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ErrorHandler.html)
321    fn fatal_error(&mut self, error: SAXParseError) {
322        let _ = error;
323    }
324
325    /// # Reference
326    /// [`ErrorHandler` interface in Java SAX API](https://docs.oracle.com/javase/jp/21/docs/api/java.xml/org/xml/sax/ErrorHandler.html)
327    fn warning(&mut self, error: SAXParseError) {
328        let _ = error;
329    }
330}
331
332impl<H: EntityResolver + ?Sized> EntityResolver for &mut H {
333    fn resolve_entity(
334        &mut self,
335        name: &str,
336        public_id: Option<&str>,
337        base_uri: &URIStr,
338        system_id: &URIStr,
339    ) -> Result<InputSource<'static>, XMLError> {
340        (**self).resolve_entity(name, public_id, base_uri, system_id)
341    }
342
343    fn get_external_subset(
344        &mut self,
345        name: &str,
346        base_uri: Option<&URIStr>,
347    ) -> Result<InputSource<'static>, XMLError> {
348        (**self).get_external_subset(name, base_uri)
349    }
350}
351impl<H: ErrorHandler + ?Sized> ErrorHandler for &mut H {
352    fn error(&mut self, error: SAXParseError) {
353        (**self).error(error);
354    }
355
356    fn fatal_error(&mut self, error: SAXParseError) {
357        (**self).fatal_error(error);
358    }
359
360    fn warning(&mut self, error: SAXParseError) {
361        (**self).warning(error);
362    }
363}
364impl<H: SAXHandler + ?Sized> SAXHandler for &mut H {
365    fn attribute_decl(
366        &mut self,
367        element_name: &str,
368        attribute_name: &str,
369        attribute_type: &AttributeType,
370        default_decl: &DefaultDecl,
371    ) {
372        (**self).attribute_decl(element_name, attribute_name, attribute_type, default_decl);
373    }
374
375    fn characters(&mut self, data: &str) {
376        (**self).characters(data);
377    }
378
379    fn comment(&mut self, data: &str) {
380        (**self).comment(data);
381    }
382
383    fn declaration(&mut self, version: &str, encoding: Option<&str>, standalone: Option<bool>) {
384        (**self).declaration(version, encoding, standalone);
385    }
386
387    fn element_decl(&mut self, name: &str, contentspec: &ContentSpec) {
388        (**self).element_decl(name, contentspec);
389    }
390
391    fn end_cdata(&mut self) {
392        (**self).end_cdata();
393    }
394
395    fn end_document(&mut self) {
396        (**self).end_document();
397    }
398
399    fn end_dtd(&mut self) {
400        (**self).end_dtd();
401    }
402
403    fn end_element(&mut self, namespace_name: Option<&str>, local_name: Option<&str>, qname: &str) {
404        (**self).end_element(namespace_name, local_name, qname);
405    }
406
407    fn end_entity(&mut self) {
408        (**self).end_entity();
409    }
410
411    fn end_prefix_mapping(&mut self, prefix: Option<&str>) {
412        (**self).end_prefix_mapping(prefix);
413    }
414
415    fn external_entity_decl(&mut self, name: &str, public_id: Option<&str>, system_id: &URIStr) {
416        (**self).external_entity_decl(name, public_id, system_id);
417    }
418
419    fn ignorable_whitespace(&mut self, data: &str) {
420        (**self).ignorable_whitespace(data);
421    }
422
423    fn internal_entity_decl(&mut self, name: &str, value: &str) {
424        (**self).internal_entity_decl(name, value);
425    }
426
427    fn notation_decl(&mut self, name: &str, public_id: Option<&str>, system_id: Option<&URIStr>) {
428        (**self).notation_decl(name, public_id, system_id);
429    }
430
431    fn processing_instruction(&mut self, target: &str, data: Option<&str>) {
432        (**self).processing_instruction(target, data);
433    }
434
435    fn set_document_locator(&mut self, locator: Arc<Locator>) {
436        (**self).set_document_locator(locator);
437    }
438
439    fn skipped_entity(&mut self, name: &str) {
440        (**self).skipped_entity(name);
441    }
442
443    fn start_cdata(&mut self) {
444        (**self).start_cdata();
445    }
446
447    fn start_document(&mut self) {
448        (**self).start_document();
449    }
450
451    fn start_dtd(&mut self, name: &str, public_id: Option<&str>, system_id: Option<&URIStr>) {
452        (**self).start_dtd(name, public_id, system_id);
453    }
454
455    fn start_element(
456        &mut self,
457        namespace_name: Option<&str>,
458        local_name: Option<&str>,
459        qname: &str,
460        atts: &Attributes,
461    ) {
462        (**self).start_element(namespace_name, local_name, qname, atts);
463    }
464
465    fn start_entity(&mut self, name: &str) {
466        (**self).start_entity(name);
467    }
468
469    fn start_prefix_mapping(&mut self, prefix: Option<&str>, uri: &str) {
470        (**self).start_prefix_mapping(prefix, uri);
471    }
472
473    fn unparsed_entity_decl(
474        &mut self,
475        name: &str,
476        public_id: Option<&str>,
477        system_id: &URIStr,
478        notation_name: &str,
479    ) {
480        (**self).unparsed_entity_decl(name, public_id, system_id, notation_name);
481    }
482}
483
484impl<H: EntityResolver + ?Sized> EntityResolver for Box<H> {
485    fn get_external_subset(
486        &mut self,
487        name: &str,
488        base_uri: Option<&URIStr>,
489    ) -> Result<InputSource<'static>, XMLError> {
490        (**self).get_external_subset(name, base_uri)
491    }
492    fn resolve_entity(
493        &mut self,
494        name: &str,
495        public_id: Option<&str>,
496        base_uri: &URIStr,
497        system_id: &URIStr,
498    ) -> Result<InputSource<'static>, XMLError> {
499        (**self).resolve_entity(name, public_id, base_uri, system_id)
500    }
501}
502impl<H: ErrorHandler + ?Sized> ErrorHandler for Box<H> {
503    fn error(&mut self, error: SAXParseError) {
504        (**self).error(error);
505    }
506    fn fatal_error(&mut self, error: SAXParseError) {
507        (**self).fatal_error(error);
508    }
509    fn warning(&mut self, error: SAXParseError) {
510        (**self).warning(error);
511    }
512}
513impl<H: SAXHandler + ?Sized> SAXHandler for Box<H> {
514    fn attribute_decl(
515        &mut self,
516        element_name: &str,
517        attribute_name: &str,
518        attribute_type: &AttributeType,
519        default_decl: &DefaultDecl,
520    ) {
521        (**self).attribute_decl(element_name, attribute_name, attribute_type, default_decl);
522    }
523    fn characters(&mut self, data: &str) {
524        (**self).characters(data);
525    }
526    fn comment(&mut self, data: &str) {
527        (**self).comment(data);
528    }
529    fn declaration(&mut self, version: &str, encoding: Option<&str>, standalone: Option<bool>) {
530        (**self).declaration(version, encoding, standalone);
531    }
532    fn element_decl(&mut self, name: &str, contentspec: &ContentSpec) {
533        (**self).element_decl(name, contentspec);
534    }
535    fn end_cdata(&mut self) {
536        (**self).end_cdata();
537    }
538    fn end_document(&mut self) {
539        (**self).end_document();
540    }
541    fn end_dtd(&mut self) {
542        (**self).end_dtd();
543    }
544    fn end_element(&mut self, namespace_name: Option<&str>, local_name: Option<&str>, qname: &str) {
545        (**self).end_element(namespace_name, local_name, qname);
546    }
547    fn end_entity(&mut self) {
548        (**self).end_entity();
549    }
550    fn end_prefix_mapping(&mut self, prefix: Option<&str>) {
551        (**self).end_prefix_mapping(prefix);
552    }
553    fn external_entity_decl(&mut self, name: &str, public_id: Option<&str>, system_id: &URIStr) {
554        (**self).external_entity_decl(name, public_id, system_id);
555    }
556    fn ignorable_whitespace(&mut self, data: &str) {
557        (**self).ignorable_whitespace(data);
558    }
559    fn internal_entity_decl(&mut self, name: &str, value: &str) {
560        (**self).internal_entity_decl(name, value);
561    }
562    fn notation_decl(&mut self, name: &str, public_id: Option<&str>, system_id: Option<&URIStr>) {
563        (**self).notation_decl(name, public_id, system_id);
564    }
565    fn processing_instruction(&mut self, target: &str, data: Option<&str>) {
566        (**self).processing_instruction(target, data);
567    }
568    fn set_document_locator(&mut self, locator: Arc<Locator>) {
569        (**self).set_document_locator(locator);
570    }
571    fn skipped_entity(&mut self, name: &str) {
572        (**self).skipped_entity(name);
573    }
574    fn start_cdata(&mut self) {
575        (**self).start_cdata();
576    }
577    fn start_document(&mut self) {
578        (**self).start_document();
579    }
580    fn start_dtd(&mut self, name: &str, public_id: Option<&str>, system_id: Option<&URIStr>) {
581        (**self).start_dtd(name, public_id, system_id);
582    }
583    fn start_element(
584        &mut self,
585        namespace_name: Option<&str>,
586        local_name: Option<&str>,
587        qname: &str,
588        atts: &Attributes,
589    ) {
590        (**self).start_element(namespace_name, local_name, qname, atts);
591    }
592    fn start_entity(&mut self, name: &str) {
593        (**self).start_entity(name);
594    }
595    fn start_prefix_mapping(&mut self, prefix: Option<&str>, namespace_name: &str) {
596        (**self).start_prefix_mapping(prefix, namespace_name);
597    }
598    fn unparsed_entity_decl(
599        &mut self,
600        name: &str,
601        public_id: Option<&str>,
602        system_id: &URIStr,
603        notation_name: &str,
604    ) {
605        (**self).unparsed_entity_decl(name, public_id, system_id, notation_name);
606    }
607}
608
609/// Default SAX handler.
610///
611/// It uses the default implementation of each trait, except for printing errors to stderr.
612pub struct DefaultSAXHandler;
613
614impl ErrorHandler for DefaultSAXHandler {
615    fn error(&mut self, error: SAXParseError) {
616        eprintln!("{error}")
617    }
618
619    fn fatal_error(&mut self, error: SAXParseError) {
620        eprintln!("{error}")
621    }
622
623    fn warning(&mut self, error: SAXParseError) {
624        eprintln!("{error}")
625    }
626}
627impl EntityResolver for DefaultSAXHandler {}
628impl SAXHandler for DefaultSAXHandler {}
629
630/// Debug handler.
631///
632/// Writes each event to a buffer in a readable format.
633pub struct DebugHandler<Child: SAXHandler = DefaultSAXHandler> {
634    /// The buffer where generated events are written.
635    pub buffer: String,
636    /// Child handler.
637    ///
638    /// [`DebugHandler`] writes events to `buffer` and then redirects them to `child`.
639    pub child: Child,
640}
641
642impl<Child: SAXHandler> EntityResolver for DebugHandler<Child> {
643    fn get_external_subset(
644        &mut self,
645        name: &str,
646        base_uri: Option<&URIStr>,
647    ) -> Result<InputSource<'static>, XMLError> {
648        self.buffer.push_str("getExternalSubset(");
649        self.buffer.push_str(name);
650        self.buffer.push_str(")\n");
651        self.child.get_external_subset(name, base_uri)
652    }
653
654    fn resolve_entity(
655        &mut self,
656        name: &str,
657        public_id: Option<&str>,
658        base_uri: &URIStr,
659        system_id: &URIStr,
660    ) -> Result<InputSource<'static>, XMLError> {
661        if name != DOCUMENT_ENTITY_NAME {
662            self.buffer.push_str("resolveEntity(");
663            self.buffer.push_str(name);
664            self.buffer.push_str(")\n");
665        }
666        self.child
667            .resolve_entity(name, public_id, base_uri, system_id)
668    }
669}
670
671impl<Child: SAXHandler> ErrorHandler for DebugHandler<Child> {
672    fn error(&mut self, error: SAXParseError) {
673        self.child.error(error);
674    }
675
676    fn fatal_error(&mut self, error: SAXParseError) {
677        self.child.fatal_error(error);
678    }
679
680    fn warning(&mut self, error: SAXParseError) {
681        self.child.warning(error);
682    }
683}
684
685impl<Child: SAXHandler> SAXHandler for DebugHandler<Child> {
686    fn characters(&mut self, data: &str) {
687        self.buffer.push_str("characters(");
688        self.buffer.push_str(data);
689        self.buffer.push_str(")\n");
690        self.child.characters(data);
691    }
692
693    fn declaration(&mut self, version: &str, encoding: Option<&str>, standalone: Option<bool>) {
694        self.buffer.push_str("declaration(");
695        self.buffer.push_str(version);
696        self.buffer.push_str(", ");
697        self.buffer.push_str(encoding.unwrap_or("None"));
698        self.buffer.push_str(", ");
699        if let Some(standalone) = standalone {
700            if standalone {
701                self.buffer.push_str("yes)\n");
702            } else {
703                self.buffer.push_str("no)\n");
704            }
705        } else {
706            self.buffer.push_str("None)\n");
707        }
708        self.child.declaration(version, encoding, standalone);
709    }
710
711    fn ignorable_whitespace(&mut self, data: &str) {
712        self.buffer.push_str("ignorableWhitespace(");
713        self.buffer.push_str(data);
714        self.buffer.push_str(")\n");
715        self.child.ignorable_whitespace(data);
716    }
717
718    fn processing_instruction(&mut self, target: &str, data: Option<&str>) {
719        self.buffer.push_str("processingInstruction(");
720        self.buffer.push_str(target);
721        if let Some(data) = data {
722            self.buffer.push_str(", '");
723            self.buffer.push_str(data);
724            self.buffer.push_str("')\n");
725        } else {
726            self.buffer.push_str(", None)\n");
727        }
728        self.child.processing_instruction(target, data);
729    }
730
731    fn set_document_locator(&mut self, locator: Arc<Locator>) {
732        self.buffer.push_str("setDocumentLocator()\n");
733        self.child.set_document_locator(locator);
734    }
735
736    fn skipped_entity(&mut self, name: &str) {
737        self.buffer.push_str("skippedEntity(");
738        self.buffer.push_str(name);
739        self.buffer.push_str(")\n");
740        self.child.skipped_entity(name);
741    }
742
743    fn start_document(&mut self) {
744        self.buffer.push_str("startDocument()\n");
745        self.child.start_document();
746    }
747    fn end_document(&mut self) {
748        self.buffer.push_str("endDocument()\n");
749        self.child.end_document();
750    }
751
752    fn start_element(
753        &mut self,
754        namespace_name: Option<&str>,
755        local_name: Option<&str>,
756        qname: &str,
757        atts: &Attributes,
758    ) {
759        self.buffer.push_str("startElement(");
760        self.buffer.push_str(namespace_name.unwrap_or("None"));
761        self.buffer.push_str(", ");
762        self.buffer.push_str(local_name.unwrap_or("None"));
763        self.buffer.push_str(", ");
764        self.buffer.push_str(qname);
765        for att in atts {
766            self.buffer.push_str(", ");
767            if let Some(local_name) = att.local_name.as_deref() {
768                if let Some(uri) = att.namespace_name.as_deref() {
769                    self.buffer.push('{');
770                    self.buffer.push_str(uri);
771                    self.buffer.push('}');
772                }
773                self.buffer.push_str(local_name);
774                self.buffer.push_str("='");
775                self.buffer.push_str(&att.value);
776                self.buffer.push('\'');
777            } else {
778                self.buffer.push_str(&att.qname);
779                self.buffer.push_str("='");
780                self.buffer.push_str(&att.value);
781                self.buffer.push('\'');
782            }
783        }
784        self.buffer.push_str(")\n");
785        self.child
786            .start_element(namespace_name, local_name, qname, atts);
787    }
788    fn end_element(&mut self, namespace_name: Option<&str>, local_name: Option<&str>, qname: &str) {
789        self.buffer.push_str("endElement(");
790        self.buffer.push_str(namespace_name.unwrap_or("None"));
791        self.buffer.push_str(", ");
792        self.buffer.push_str(local_name.unwrap_or("None"));
793        self.buffer.push_str(", ");
794        self.buffer.push_str(qname);
795        self.buffer.push_str(")\n");
796        self.child.end_element(namespace_name, local_name, qname);
797    }
798
799    fn start_prefix_mapping(&mut self, prefix: Option<&str>, uri: &str) {
800        self.buffer.push_str("startPrefixMapping(");
801        self.buffer.push_str(prefix.unwrap_or("None"));
802        self.buffer.push_str(", ");
803        self.buffer.push_str(uri);
804        self.buffer.push_str(")\n");
805        self.child.start_prefix_mapping(prefix, uri);
806    }
807    fn end_prefix_mapping(&mut self, prefix: Option<&str>) {
808        self.buffer.push_str("endPrefixMapping(");
809        self.buffer.push_str(prefix.unwrap_or("None"));
810        self.buffer.push_str(")\n");
811        self.child.end_prefix_mapping(prefix);
812    }
813
814    fn attribute_decl(
815        &mut self,
816        element_name: &str,
817        attribute_name: &str,
818        attribute_type: &AttributeType,
819        default_decl: &DefaultDecl,
820    ) {
821        writeln!(
822            self.buffer,
823            "attributeDecl({element_name}, {attribute_name}, {attribute_type}, {default_decl})"
824        )
825        .ok();
826        self.child
827            .attribute_decl(element_name, attribute_name, attribute_type, default_decl);
828    }
829
830    fn element_decl(&mut self, name: &str, contentspec: &ContentSpec) {
831        writeln!(self.buffer, "elementDecl({name}, {contentspec})").ok();
832        self.child.element_decl(name, contentspec);
833    }
834
835    fn external_entity_decl(&mut self, name: &str, public_id: Option<&str>, system_id: &URIStr) {
836        writeln!(
837            self.buffer,
838            "externalEntityDecl({name}, {}, {})",
839            public_id.unwrap_or("None"),
840            system_id.as_escaped_str()
841        )
842        .ok();
843        self.child.external_entity_decl(name, public_id, system_id);
844    }
845
846    fn internal_entity_decl(&mut self, name: &str, value: &str) {
847        writeln!(self.buffer, "internalEntityDecl({name}, {value})").ok();
848        self.child.internal_entity_decl(name, value);
849    }
850
851    fn notation_decl(&mut self, name: &str, public_id: Option<&str>, system_id: Option<&URIStr>) {
852        writeln!(
853            self.buffer,
854            "notationDecl({name}, {}, {})",
855            public_id.unwrap_or("None"),
856            system_id.map_or("None", |id| id.as_escaped_str())
857        )
858        .ok();
859        self.child.notation_decl(name, public_id, system_id);
860    }
861
862    fn unparsed_entity_decl(
863        &mut self,
864        name: &str,
865        public_id: Option<&str>,
866        system_id: &URIStr,
867        notation_name: &str,
868    ) {
869        writeln!(
870            self.buffer,
871            "unparsedEntityDecl({name}, {public_id:?}, {}, {notation_name})",
872            system_id.as_escaped_str()
873        )
874        .ok();
875        self.child
876            .unparsed_entity_decl(name, public_id, system_id, notation_name);
877    }
878
879    fn comment(&mut self, data: &str) {
880        self.buffer.push_str("comment(");
881        self.buffer.push_str(data);
882        self.buffer.push_str(")\n");
883        self.child.comment(data);
884    }
885
886    fn start_cdata(&mut self) {
887        writeln!(self.buffer, "startCDATA()").ok();
888        self.child.start_cdata();
889    }
890    fn end_cdata(&mut self) {
891        writeln!(self.buffer, "endCDATA()").ok();
892        self.child.end_cdata();
893    }
894
895    fn start_dtd(&mut self, name: &str, public_id: Option<&str>, system_id: Option<&URIStr>) {
896        writeln!(
897            self.buffer,
898            "startDTD({name}, {}, {})",
899            public_id.unwrap_or("None"),
900            system_id.map_or("None", |id| id.as_escaped_str())
901        )
902        .ok();
903        self.child.start_dtd(name, public_id, system_id);
904    }
905    fn end_dtd(&mut self) {
906        writeln!(self.buffer, "endDTD()").ok();
907        self.child.end_dtd();
908    }
909
910    fn start_entity(&mut self, name: &str) {
911        writeln!(self.buffer, "startEntity({name})").ok();
912        self.child.start_entity(name);
913    }
914    fn end_entity(&mut self) {
915        writeln!(self.buffer, "endEntity()").ok();
916        self.child.end_entity();
917    }
918}
919
920impl Default for DebugHandler {
921    fn default() -> Self {
922        Self {
923            buffer: String::new(),
924            child: DefaultSAXHandler,
925        }
926    }
927}