1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// SPDX-License-Identifier: MIT OR Apache-2.0
// Copyright (c) 2026 oxml. All rights reserved.
//! Reading a document as a sequence of events, without building a
//! tree.
//!
//! [`parse`] builds a tree, which is the right trade when you are
//! going to query it. When you are not -- when you want the third
//! `<price>` and nothing else, or you are converting a document to
//! something else on the way past -- the tree is a cost with no
//! return.
//!
//! # Three entry points, one machine
//!
//! - [`Reader::new`] reads a `&str` already in memory.
//! - [`Reader::from_reader`] reads a `std::io::BufRead` a buffer at a
//! time, holding only the construct in hand; a document larger than
//! memory is readable.
//! - [`AsyncReader`] does the same over a `tokio::io::AsyncBufRead`
//! (feature `async`).
//!
//! All three are loops around [`Core`], which does no I/O at all:
//! bytes are fed to it and events pulled from it, so any other way of
//! getting bytes -- another runtime, a ring buffer, a parser
//! combinator -- can drive it directly.
//!
//! # What this saves, and what it does not
//!
//! Measured on the 16,004-node document in the allocation tests,
//! reading holds **191,967 bytes at peak against the tree's
//! 1,809,822** -- 89% less. [`Reader::new`] does **not** let you read
//! a document larger than memory: it takes a `&str`, and normalising
//! line endings copies it once, so nearly all of that 191,967 bytes
//! *is* the document. What it removes is everything that outlives the
//! event that produced it: the arena, the interned names, the node
//! table.
//!
//! [`Reader::from_reader`] does. Measured on a 185 KB document and a
//! 1,929 KB one -- ten times the input -- both held **34,722 bytes**,
//! the same figure to the byte.
//!
//! Reading is not faster than parsing. An owned [`Event`] copies its
//! names and text out of the buffer, and [`BorrowedEvent`] copies only
//! what was rewritten -- an expanded entity, a merged `CDATA` section
//! -- but a name is resolved and owned either way. Measured with the
//! allocation harness in `tests/allocations.rs`, reading the 6,001
//! events of a 2,000-item catalogue costs about 2.6 allocations per
//! event against 0.5 per *node* for a parse. This trades time for
//! memory, and the trade is only worth making when the memory
//! matters.
//!
//! [`Reader`] runs **the same scanner** [`parse`] does. That is the
//! design constraint, not an implementation detail: two XML scanners
//! in one crate would drift, and the one with fewer users would be the
//! one that was wrong. Everything below `parse_element_inner` -- start
//! tags, attribute values, entity expansion, comments, processing
//! instructions, `CDATA`, character references, name rules, the
//! document type declaration -- is shared verbatim. What is not shared
//! is the arena.
//!
//! # Examples
//!
//! ```
//! use oxml::stream::{Event, Reader};
//!
//! let mut reader = Reader::new("<a><b>text</b></a>")?;
//! let mut names = Vec::new();
//! while let Some(event) = reader.next_event()? {
//! if let Event::StartElement { name, .. } = event {
//! names.push(name.local);
//! }
//! }
//! assert_eq!(names, ["a", "b"]);
//! # Ok::<(), oxml::Error>(())
//! ```
//!
//! A reader is also an iterator, which ends after the document or
//! after the first error:
//!
//! ```
//! use oxml::stream::{Event, Reader};
//!
//! let texts: Vec<String> = Reader::new("<a>one<b>two</b></a>")?
//! .filter_map(|event| match event {
//! Ok(Event::Text(text)) => Some(text),
//! _ => None,
//! })
//! .collect();
//! assert_eq!(texts, ["one", "two"]);
//! # Ok::<(), oxml::Error>(())
//! ```
//!
//! [`parse`]: crate::parse
pub use AsyncReader;
pub use ;
pub use Core;
pub use ;