Thanks to visit codestin.com
Credit goes to docs.rs

Skip to main content

rxml/writer/
mod.rs

1/*!
2# Writer for restricted XML 1.0
3*/
4use alloc::boxed::Box;
5use alloc::collections::btree_map::Entry;
6use alloc::collections::BTreeMap;
7use alloc::collections::BTreeSet;
8use alloc::format;
9use alloc::vec::Vec;
10
11use bytes::{BufMut, BytesMut};
12
13use crate::error::{Error, ErrorContext, Result};
14use crate::parser::{Event, XmlVersion, XMLNS_XML, XMLNS_XMLNS};
15use crate::strings::{Name, Namespace, NcName, NcNameStr};
16
17const XML_DECL: &[u8] = b"<?xml version='1.0' encoding='utf-8'?>\n";
18
19/// The static prefix used for XML built-in attributes (`xml`).
20pub const PREFIX_XML: &NcNameStr = unsafe { core::mem::transmute("xml") };
21
22/// The static prefix used for XML namespace declarations (`xmlns`).
23pub const PREFIX_XMLNS: &NcNameStr = unsafe { core::mem::transmute("xmlns") };
24
25fn escape_text<'a, B: BufMut>(
26	out: &'a mut B,
27	data: &'a str,
28	attribute_context: bool,
29) -> core::result::Result<(), rxml_validation::Error> {
30	let data = data.as_bytes();
31	let mut last_index = 0;
32	for i in 0..data.len() {
33		let ch = data[i];
34		let escaped: &[u8] = match ch {
35			b'\x00'..=b'\x08' | b'\x0b' | b'\x0c' | b'\x0e'..=b'\x1f' => {
36				return Err(rxml_validation::Error::InvalidChar(ch.into()));
37			}
38			b'"' if attribute_context => &b"&#34;"[..],
39			b'\'' if attribute_context => &b"&#39;"[..],
40			b'<' => &b"&lt;"[..],
41			b'>' => &b"&gt;"[..],
42			b'&' => &b"&amp;"[..],
43			b'\r' => &b"&#xd;"[..],
44			b'\n' if attribute_context => &b"&#xa;"[..],
45			b'\t' if attribute_context => &b"&#x9;"[..],
46			b'\xbe' | b'\xbf' => {
47				if i >= 2 && data[i - 2] == b'\xef' && data[i - 1] == b'\xbf' {
48					// U+FFFE or U+FFFF
49					let low_bit = ch & 0x01;
50					// SAFETY: we are passing only 16 bits and the upper
51					// nibble is set to all ones, so this is within the bounds
52					// of a unicode code point and not a surrogate.
53					return Err(rxml_validation::Error::InvalidChar(unsafe {
54						char::from_u32_unchecked(0xfffe | low_bit as u32)
55					}));
56				} else {
57					continue;
58				}
59			}
60			_ => continue,
61		};
62		if i > last_index {
63			out.put_slice(&data[last_index..i]);
64		}
65		out.put_slice(escaped);
66		last_index = i + 1;
67	}
68	out.put_slice(&data[last_index..data.len()]);
69	Ok(())
70}
71
72/// An encodable item.
73///
74/// This is separate from [`Event`], because events are owned, while
75/// items can be borrowed to improve efficiency (as a copy will have to take
76/// place anyway).
77///
78///   [`Event`]: crate::parser::Event
79#[derive(Debug)]
80pub enum Item<'x> {
81	/// XML declaration
82	XmlDeclaration(XmlVersion),
83
84	/// Start of an element header
85	ElementHeadStart(
86		/// Namespace name
87		Namespace<'x>,
88		/// Local name of the attribute
89		&'x NcNameStr,
90	),
91
92	/// An attribute key/value pair
93	Attribute(
94		/// Namespace name
95		Namespace<'x>,
96		/// Local name of the attribute
97		&'x NcNameStr,
98		/// Value of the attribute
99		&'x str,
100	),
101
102	/// End of an element header
103	ElementHeadEnd,
104
105	/// A piece of text (in element content, not attributes)
106	Text(&'x str),
107
108	/// Footer of an element
109	///
110	/// This can be used either in places where [`Text`] could be used to
111	/// close the most recently opened unclosed element, or it can be used
112	/// instead of [`ElementHeadEnd`] to close the element using `/>`, without
113	/// any child content.
114	///
115	///   [`Text`]: Self::Text
116	///   [`ElementHeadEnd`]: Self::ElementHeadEnd
117	ElementFoot,
118}
119
120impl Item<'_> {
121	fn name(&self) -> &'static str {
122		match self {
123			Self::XmlDeclaration { .. } => "xml declaration",
124			Self::ElementHeadStart { .. } => "element start",
125			Self::Attribute { .. } => "attribute",
126			Self::ElementHeadEnd => "element head end",
127			Self::Text { .. } => "text",
128			Self::ElementFoot => "element foot",
129		}
130	}
131}
132
133/// Represent an error returned by a prefix operation on [`TrackNamespace`].
134#[derive(Debug)]
135pub enum PrefixError {
136	/// The requested prefix is not declared yet.
137	Undeclared,
138}
139
140/// Trait for a thing tracking namespace declarations.
141///
142/// Indirection via this trait allows to have different paradigms for
143/// declaring and managing namespace prefixes.
144///
145/// Objects implementing this trait expect the following protocol:
146///
147/// 1. Declare all namespace URIs introduced on an element using `declare` and `declare_auto`.
148/// 2. Commit to the element using `push`
149/// 3. Process all child elements by recursion
150/// 4. Call `pop` to end the element.
151///
152/// Asymmetric calls to push/pop may cause panics or memory leaks.
153pub trait TrackNamespace {
154	/// Declare a namespace URI with a defined prefix.
155	///
156	/// Note: There is no guarantee that the given `prefix` will be returned
157	/// from calls to `get_prefix` or `get_prefix_or_default` after the next
158	/// call to `push`.
159	///
160	/// Returns whether the prefix is freshly declared.
161	///
162	/// # Panics
163	///
164	/// Calling this twice between two calls to `push` with the same `prefix`
165	/// is a programming error and causes a panic.
166	fn declare_fixed(&mut self, prefix: Option<&NcNameStr>, name: Namespace<'static>) -> bool;
167
168	/// Declare a namespace URI with an auto-generated prefix or by using the
169	/// default namespace.
170	///
171	/// Note: There is no guarantee that the returned `prefix` will be
172	/// returned from calls to `get_prefix_or_default` after the next call to
173	/// `push`.
174	///
175	/// Returns whether the prefix is freshly declared and the
176	/// resulting prefix (or None, if prefixless).
177	///
178	/// This may return a non-auto-generated prefix if the namespace URI is
179	/// already declared on this or a parent element.
180	fn declare_auto(&mut self, name: Namespace<'static>) -> (bool, Option<&NcNameStr>);
181
182	/// Declare a namespace URI with an auto-generated prefix.
183	///
184	/// Note: There is no guarantee that the returned `prefix` will be
185	/// returned from calls to `get_prefix` or `get_prefix_or_default` after
186	/// the next call to `push`.
187	///
188	/// Returns whether the prefix is freshly declared and the resulting
189	/// prefix.
190	///
191	/// This may return a non-auto-generated prefix if the namespace URI is
192	/// already declared on this or a parent element. If the URI is already
193	/// used for the default namespace, this function will nontheless return
194	/// a prefix.
195	fn declare_with_auto_prefix(&mut self, name: Namespace<'static>) -> (bool, &NcNameStr);
196
197	/// Get the prefix for a given URI, which may be empty if the namespace
198	/// with that URI is defined as the default namespace.
199	fn get_prefix_or_default(
200		&self,
201		name: Namespace<'static>,
202	) -> core::result::Result<Option<&NcNameStr>, PrefixError>;
203
204	/// Get the prefix for a given URI.
205	///
206	/// This returns an error if the given URI is declared as default
207	/// namespace and there is no matching prefix.
208	fn get_prefix(&self, name: Namespace<'static>)
209		-> core::result::Result<&NcNameStr, PrefixError>;
210
211	/// Complete an element declaration.
212	fn push(&mut self);
213
214	/// Signal end of element to undeclare nested namespace declarations.
215	fn pop(&mut self);
216
217	/// Return the newly declared default namespace, if any.
218	///
219	/// This returns `None` if and only if no default namespace has been
220	/// declared yet for the upcoming element.
221	///
222	/// *Note:* In the root element, `None` will be returned even if the
223	/// default namespace has been explicitly set to the empty namespace name,
224	/// as that is the default.
225	fn new_default_declaration(&self) -> Option<&Namespace<'static>>;
226
227	/// Return an iterator over the the newly declared prefixes.
228	fn new_prefix_declarations(
229		&self,
230	) -> Box<dyn Iterator<Item = (&Namespace<'static>, &NcNameStr)> + '_>;
231}
232
233/// Simple namespace tracker.
234///
235/// This is the default namespace tracker used by [`Encoder::new`]. At the
236/// cost of increased output size, it reduces memory footprint by only
237/// tracking unprefixed namespaces. Prefixed namespaces may be declared, but
238/// are forgotten about once the element start is over.
239///
240/// Effectively, when used with an [`Encoder`], this means that prefixed
241/// namespaces will only ever be used for attributes, and may be re-declared
242/// a lot.
243///
244/// One exception is that prefixed namespaces declared on the root element
245/// will actually be made available on all child elements.
246#[derive(Debug, Default)]
247pub struct SimpleNamespaces {
248	// persistent state
249	global_ns: BTreeMap<Namespace<'static>, NcName>,
250	global_ns_rev: BTreeSet<NcName>,
251	global_ns_ctr: usize,
252	default_ns_stack: Vec<Namespace<'static>>,
253
254	// temporary per-element state
255	next_default_ns: Option<Namespace<'static>>,
256	temp_ns_ctr: usize,
257	temp_ns: BTreeMap<Namespace<'static>, NcName>,
258	temp_ns_rev: BTreeSet<NcName>,
259}
260
261impl SimpleNamespaces {
262	/// Create a new, empty namespace tracker.
263	pub fn new() -> Self {
264		Self::default()
265	}
266
267	/// Look up the namespace URI for a given prefix
268	///
269	/// *Note:* This function is implemented as O(n) function because it
270	/// should rarely, if ever, be necessary to use. Speeding up runtime of
271	/// this function would increase memory cost at neglegible gain.
272	///
273	/// The namespace URIs for the `xml` and `xmlns` prefixes are always
274	/// returned, even if not explicitly declared.
275	pub fn lookup_prefix(
276		&self,
277		prefix: Option<&NcNameStr>,
278	) -> core::result::Result<Namespace<'static>, PrefixError> {
279		match prefix {
280			Some(prefix) if prefix == PREFIX_XML => Ok(Namespace::XML),
281			Some(prefix) if prefix == PREFIX_XMLNS => Ok(Namespace::XMLNS),
282			Some(prefix) => {
283				for (decl_uri, decl_prefix) in self.temp_ns.iter().chain(self.global_ns.iter()) {
284					if decl_prefix == prefix {
285						return Ok(decl_uri.clone());
286					}
287				}
288				Err(PrefixError::Undeclared)
289			}
290			None => {
291				if let Some(uri) = self.next_default_ns.as_ref() {
292					return Ok(uri.clone());
293				}
294				match self.default_ns_stack.last() {
295					Some(uri) => Ok(uri.clone()),
296					_ => Err(PrefixError::Undeclared),
297				}
298			}
299		}
300	}
301}
302
303impl TrackNamespace for SimpleNamespaces {
304	fn declare_fixed(&mut self, prefix: Option<&NcNameStr>, name: Namespace<'static>) -> bool {
305		match prefix.as_ref() {
306			Some(v) if *v == PREFIX_XML => {
307				if name == XMLNS_XML {
308					return false;
309				}
310				panic!("xml is a reserved prefix")
311			}
312			Some(v) if *v == PREFIX_XMLNS => {
313				if name == XMLNS_XMLNS {
314					return false;
315				}
316				panic!("xmlns is a reserved prefix")
317			}
318			_ => {}
319		}
320
321		if name == XMLNS_XML {
322			panic!("{} must be bound to xml prefix", name)
323		}
324		if name == XMLNS_XMLNS {
325			panic!("{} must be bound to xmlns prefix", name)
326		}
327
328		match prefix {
329			Some(prefix) => {
330				if self.global_ns_rev.contains(prefix) {
331					panic!(
332						"prefix declaration conflicts with global prefix: {:?}",
333						prefix
334					)
335				}
336				if self.temp_ns_rev.contains(prefix) {
337					panic!("duplicate prefix: {:?}", prefix);
338				}
339				self.temp_ns.insert(name, prefix.to_ncname());
340				self.temp_ns_rev.insert(prefix.to_ncname());
341				true
342			}
343			None => {
344				if self.next_default_ns.is_some() {
345					panic!("duplicate default namespace")
346				}
347				self.next_default_ns = Some(name);
348				true
349			}
350		}
351	}
352
353	fn declare_auto(&mut self, name: Namespace<'static>) -> (bool, Option<&NcNameStr>) {
354		if name == XMLNS_XML {
355			return (false, Some(PREFIX_XML));
356		}
357		if name == XMLNS_XMLNS {
358			return (false, Some(PREFIX_XMLNS));
359		}
360
361		// XXX: due to a limitation in the borrowchecker <https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md#problem-case-3-conditional-control-flow-across-functions>, we have to re-implement the entirety of get_prefix_or_default here.
362
363		// Check if the namespace has been declared without prefix
364		match self
365			.next_default_ns
366			.as_ref()
367			.or(self.default_ns_stack.last())
368		{
369			// .. it has, return it prefixless.
370			Some(default_name) if *default_name == name => return (false, None),
371			// .. it has not, move on.
372			_ => (),
373		};
374
375		// Check if the namespace has been declared locally already
376		match self.temp_ns.entry(name) {
377			// .. it has, return the prefix.
378			Entry::Occupied(o) => (false, Some(o.into_mut())),
379			// .. it has not, check if it has been declared globally
380			Entry::Vacant(v_temp) => match self.global_ns.entry(v_temp.key().clone()) {
381				// .. it has, return the prefix.
382				Entry::Occupied(o) => (false, Some(o.into_mut())),
383				// .. it has not, declare it.
384				Entry::Vacant(_) => {
385					// checked above already that it does not match the default namespace, but we need to see whether we can use the default namespace.
386					match self.next_default_ns.as_ref() {
387						// the default namespace has been declared at this element already, so we need to create a prefix.
388						Some(_) => {
389							let ctr = self.temp_ns_ctr;
390							let temp_ns_prefix: NcName = format!("tns{}", ctr)
391								.try_into()
392								.expect("auto-generated prefix must always be valid");
393							if self.global_ns_rev.contains(&temp_ns_prefix) {
394								panic!(
395									"automatic prefix declaration conflicts with global prefix: {:?}",
396									temp_ns_prefix
397								)
398							}
399							if self.temp_ns_rev.contains(&temp_ns_prefix) {
400								panic!(
401									"automatic prefix declaration conflicts with local prefix: {:?}",
402									temp_ns_prefix
403								)
404							}
405							self.temp_ns_ctr += 1;
406							self.temp_ns_rev.insert(temp_ns_prefix.clone());
407							(true, Some(v_temp.insert(temp_ns_prefix)))
408						}
409						// the default namespace has *not* been declared at this element yet, so we use it.
410						None => {
411							let name = v_temp.into_key();
412							let new = match self.default_ns_stack.last() {
413								Some(v) if v == &name => {
414									// re-use the previous instad of cloning this one, might be more efficient.
415									self.next_default_ns = Some(v.clone());
416									// it wasn't new.
417									false
418								}
419								_ => {
420									// treat it as new iff it is in fact a namespace
421									// this is to correctly return `new == false` if `declare_auto` is called with the empty namespace name on the root element.
422									// this can only happen on the root element, because otherwise default_ns_stack would have had an element and we wouldn't be in this branch.
423									let new = !name.is_none();
424									// assign the new object as next default namespace
425									self.next_default_ns = Some(name);
426									new
427								}
428							};
429							(new, None)
430						}
431					}
432				}
433			},
434		}
435	}
436
437	fn declare_with_auto_prefix(&mut self, name: Namespace<'static>) -> (bool, &NcNameStr) {
438		if name == XMLNS_XML {
439			return (false, PREFIX_XML);
440		}
441		if name == XMLNS_XMLNS {
442			return (false, PREFIX_XMLNS);
443		}
444
445		match self.temp_ns.entry(name.clone()) {
446			Entry::Occupied(o) => (false, o.into_mut()),
447			Entry::Vacant(v) => match self.global_ns.entry(name.clone()) {
448				Entry::Occupied(o) => (false, o.into_mut()),
449				Entry::Vacant(_) => {
450					let ctr = self.temp_ns_ctr;
451					let temp_ns_prefix: NcName = format!("tns{}", ctr)
452						.try_into()
453						.expect("auto-generated prefix must always be valid");
454					if self.global_ns_rev.contains(&temp_ns_prefix) {
455						panic!(
456							"automatic prefix declaration conflicts with global prefix: {:?}",
457							temp_ns_prefix
458						)
459					}
460					if self.temp_ns_rev.contains(&temp_ns_prefix) {
461						panic!(
462							"automatic prefix declaration conflicts with local prefix: {:?}",
463							temp_ns_prefix
464						)
465					}
466					self.temp_ns_ctr += 1;
467					self.temp_ns_rev.insert(temp_ns_prefix.clone());
468					(true, v.insert(temp_ns_prefix))
469				}
470			},
471		}
472	}
473
474	fn get_prefix_or_default(
475		&self,
476		name: Namespace<'static>,
477	) -> core::result::Result<Option<&NcNameStr>, PrefixError> {
478		match self
479			.next_default_ns
480			.as_ref()
481			.or(self.default_ns_stack.last())
482		{
483			Some(default_name) if *default_name == name => Ok(None),
484			_ => Ok(Some(self.get_prefix(name)?)),
485		}
486	}
487
488	fn get_prefix(
489		&self,
490		name: Namespace<'static>,
491	) -> core::result::Result<&NcNameStr, PrefixError> {
492		self.temp_ns
493			.get(&name)
494			.or(self.global_ns.get(&name))
495			.map(|x| &**x)
496			.ok_or(PrefixError::Undeclared)
497	}
498
499	fn push(&mut self) {
500		match self.next_default_ns.take() {
501			None => {
502				// duplicate the most recent one
503				// if there is no previous one, we go with the default namespace.
504				let old = self
505					.default_ns_stack
506					.last()
507					.unwrap_or(Namespace::none())
508					.clone();
509				self.default_ns_stack.push(old);
510			}
511			Some(v) => self.default_ns_stack.push(v),
512		}
513		if self.default_ns_stack.len() == 1 {
514			// the first element! globalize the declarations
515			core::mem::swap(&mut self.global_ns, &mut self.temp_ns);
516			core::mem::swap(&mut self.global_ns_rev, &mut self.temp_ns_rev);
517			self.global_ns_ctr = self.temp_ns_ctr;
518		}
519
520		self.temp_ns_ctr = self.global_ns_ctr;
521		self.temp_ns.clear();
522		self.temp_ns_rev.clear();
523	}
524
525	fn pop(&mut self) {
526		self.default_ns_stack.pop();
527	}
528
529	fn new_default_declaration(&self) -> Option<&Namespace<'static>> {
530		match self.next_default_ns.as_ref() {
531			// if this is the root element, we do not expose the empty default namespace as declaration
532			Some(ns) if ns.is_none() && self.default_ns_stack.is_empty() => None,
533			other => other,
534		}
535	}
536
537	fn new_prefix_declarations(
538		&self,
539	) -> Box<dyn Iterator<Item = (&Namespace<'static>, &NcNameStr)> + '_> {
540		Box::new(self.temp_ns.iter().map(|(k, v)| (k, &**v)))
541	}
542}
543
544#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
545enum EncoderState {
546	#[default]
547	Start,
548	Declared,
549	ElementHead,
550	Content,
551	EndOfDocument,
552}
553
554impl EncoderState {
555	fn ctx(&self) -> Option<ErrorContext> {
556		Some(match self {
557			Self::Start => ErrorContext::XmlDeclarationStart,
558			Self::Declared => ErrorContext::DocumentBegin,
559			Self::ElementHead => ErrorContext::Element,
560			Self::Content => ErrorContext::Text,
561			Self::EndOfDocument => ErrorContext::DocumentEnd,
562		})
563	}
564}
565
566/**
567Encodes XML into buffers.
568
569Encoders are stateful. They can only be used to encode a single XML document and have then to be disposed.
570
571```rust
572use rxml::{Encoder, Item, XmlVersion};
573use bytes::BytesMut;
574
575let mut enc = Encoder::new();
576let mut buf = BytesMut::new();
577enc.encode(Item::XmlDeclaration(XmlVersion::V1_0), &mut buf);
578assert_eq!(&buf[..], b"<?xml version='1.0' encoding='utf-8'?>\n");
579```
580*/
581#[derive(Default)]
582pub struct Encoder<T> {
583	state: EncoderState,
584	qname_stack: Vec<Name>,
585	ns: T,
586}
587
588impl Encoder<SimpleNamespaces> {
589	/// Create a new default encoder.
590	///
591	/// This encoder uses the [`SimpleNamespaces`] strategy, which is not
592	/// optimal with respect to the number of bytes written, but has reduced
593	/// memory cost.
594	pub fn new() -> Self {
595		Self::default()
596	}
597}
598
599impl<T: TrackNamespace> From<T> for Encoder<T> {
600	/// Create an encoder from a [`TrackNamespace`] instance.
601	///
602	/// Use your own custom namespace strategy.
603	fn from(ns: T) -> Self {
604		Self {
605			state: EncoderState::Start,
606			qname_stack: Vec::new(),
607			ns,
608		}
609	}
610}
611
612impl<T: TrackNamespace> Encoder<T> {
613	fn encode_nsdecl<O: BufMut>(
614		prefix: Option<&NcNameStr>,
615		nsuri: &str,
616		output: &mut O,
617	) -> core::result::Result<(), rxml_validation::Error> {
618		match prefix {
619			Some(prefix) => {
620				output.put_slice(b" xmlns:");
621				output.put_slice(prefix.as_bytes());
622				output.put_slice(b"='");
623			}
624			None => {
625				output.put_slice(b" xmlns='");
626			}
627		}
628		escape_text(output, nsuri, true)?;
629		output.put_u8(b'\'');
630		Ok(())
631	}
632
633	/// Access the namespace tracking implementation.
634	pub fn ns_tracker(&self) -> &T {
635		&self.ns
636	}
637
638	/// Access the namespace tracking implementation, mutably.
639	pub fn ns_tracker_mut(&mut self) -> &mut T {
640		&mut self.ns
641	}
642
643	/// Encode a single item into a buffer.
644	///
645	/// There is no requirement for the buffer to be the same for subsequent
646	/// calls to this function. This allows users to use small, but
647	/// long-lived, buffers for serialization before sending data over the
648	/// network, for instance.
649	pub fn encode<O: BufMut>(&mut self, item: Item<'_>, output: &mut O) -> Result<()> {
650		if self.state == EncoderState::EndOfDocument {
651			return Err(Error::UnexpectedToken(self.state.ctx(), item.name(), None));
652		}
653
654		match item {
655			Item::XmlDeclaration(XmlVersion::V1_0) => match self.state {
656				EncoderState::Start => {
657					output.put_slice(XML_DECL);
658					self.state = EncoderState::Declared;
659					Ok(())
660				}
661				_ => Err(Error::UnexpectedToken(self.state.ctx(), item.name(), None)),
662			},
663			Item::ElementHeadStart(ref nsuri, local_name) => match self.state {
664				EncoderState::Start | EncoderState::Declared | EncoderState::Content => {
665					output.put_u8(b'<');
666					let (_, prefix) = self.ns.declare_auto(nsuri.clone().into_static());
667					let qname = match prefix {
668						Some(prefix) => {
669							output.put_slice(prefix.as_bytes());
670							output.put_u8(b':');
671							output.put_slice(local_name.as_bytes());
672							prefix.with_suffix(local_name)
673						}
674						None => {
675							output.put_slice(local_name.as_bytes());
676							local_name.to_name()
677						}
678					};
679					self.qname_stack.push(qname);
680					if let Some(name) = self.ns.new_default_declaration() {
681						Self::encode_nsdecl(None, name, output)?;
682					}
683					for (name, prefix) in self.ns.new_prefix_declarations() {
684						// if new, we have to declare it
685						Self::encode_nsdecl(Some(prefix), name, output)?;
686					}
687					self.state = EncoderState::ElementHead;
688					Ok(())
689				}
690				_ => Err(Error::UnexpectedToken(self.state.ctx(), item.name(), None)),
691			},
692			Item::Attribute(ref nsuri, local_name, value) => match self.state {
693				EncoderState::ElementHead => {
694					match nsuri.as_namespace_name() {
695						Some(v) => {
696							let (new, prefix) = self
697								.ns
698								.declare_with_auto_prefix(nsuri.clone().into_static());
699							if new {
700								Self::encode_nsdecl(Some(prefix), v, output)?;
701							}
702							output.put_u8(b' ');
703							output.put_slice(prefix.as_bytes());
704							output.put_u8(b':');
705							output.put_slice(local_name.as_bytes());
706						}
707						None => {
708							output.put_u8(b' ');
709							output.put_slice(local_name.as_bytes());
710						}
711					}
712					output.put_u8(b'=');
713					output.put_u8(b'\'');
714					escape_text(output, value, true)?;
715					output.put_u8(b'\'');
716					Ok(())
717				}
718				_ => Err(Error::UnexpectedToken(self.state.ctx(), item.name(), None)),
719			},
720			Item::ElementHeadEnd => match self.state {
721				EncoderState::ElementHead => {
722					output.put_u8(b'>');
723					self.ns.push();
724					self.state = EncoderState::Content;
725					Ok(())
726				}
727				_ => Err(Error::UnexpectedToken(self.state.ctx(), item.name(), None)),
728			},
729			Item::Text(cdata) => match self.state {
730				EncoderState::Content => {
731					escape_text(output, cdata, false)?;
732					Ok(())
733				}
734				_ => Err(Error::UnexpectedToken(self.state.ctx(), item.name(), None)),
735			},
736			Item::ElementFoot => match self.state {
737				EncoderState::Content => {
738					self.ns.pop();
739					output.put_slice(b"</");
740					output.put_slice(self.qname_stack.pop().unwrap().as_bytes());
741					output.put_u8(b'>');
742					if self.qname_stack.is_empty() {
743						self.state = EncoderState::EndOfDocument
744					}
745					Ok(())
746				}
747				EncoderState::ElementHead => {
748					output.put_slice(b"/>");
749					self.ns.push();
750					self.ns.pop();
751					self.qname_stack.pop();
752					if self.qname_stack.is_empty() {
753						self.state = EncoderState::EndOfDocument
754					} else {
755						self.state = EncoderState::Content;
756					}
757					Ok(())
758				}
759				_ => Err(Error::UnexpectedToken(self.state.ctx(), item.name(), None)),
760			},
761		}
762	}
763
764	/// Encode a single item into a BytesMut.
765	///
766	/// This might have a slight performance advantage over
767	/// [`encode`] in some scenarios, as it might be able to give
768	/// the BytesMut a heads up about required space, thus avoiding frequent
769	/// reallocations.
770	///
771	/// There is no requirement for the buffer to be the same for subsequent
772	/// calls to this function. This allows users to use small, but
773	/// long-lived, buffers for serialization before sending data over the
774	/// network, for instance.
775	///
776	///   [`encode`]: Self::encode
777	pub fn encode_into_bytes(&mut self, item: Item<'_>, output: &mut BytesMut) -> Result<()> {
778		self.encode(item, output)
779	}
780
781	/// Encode a single event into a buffer.
782	///
783	/// This internally decomposes the event into multiple items and then
784	/// encodes these into the given buffer using [`encode`].
785	///
786	///    [`encode`]: Self::encode.
787	pub fn encode_event<O: BufMut>(&mut self, ev: &Event, output: &mut O) -> Result<()> {
788		match ev {
789			Event::XmlDeclaration(_, version) => {
790				self.encode(Item::XmlDeclaration(*version), output)?;
791			}
792			Event::StartElement(_, (ns, name), attrs) => {
793				self.encode(Item::ElementHeadStart(ns.borrow(), name.as_ref()), output)?;
794				for ((ns, name), v) in attrs.iter() {
795					self.encode(Item::Attribute(ns.borrow(), name.as_ref(), v), output)?
796				}
797				self.encode(Item::ElementHeadEnd, output)?;
798			}
799			Event::EndElement(_) => self.encode(Item::ElementFoot, output)?,
800			Event::Text(_, text) => self.encode(Item::Text(text.as_ref()), output)?,
801		}
802		Ok(())
803	}
804
805	/// Encode a single event into a BytesMut.
806	///
807	/// This internally decomposes the event into multiple items and then
808	/// encodes these into the given buffer using [`encode_into_bytes`].
809	///
810	///    [`encode_into_bytes`]: Self::encode_into_bytes.
811	pub fn encode_event_into_bytes(&mut self, ev: &Event, output: &mut BytesMut) -> Result<()> {
812		self.encode_event(ev, output)
813	}
814}
815
816#[cfg(test)]
817mod tests_simple_namespaces {
818	use super::*;
819
820	fn ns1() -> Namespace<'static> {
821		Namespace::try_from("uri:foo").unwrap()
822	}
823
824	fn ns2() -> Namespace<'static> {
825		Namespace::try_from("uri:bar").unwrap()
826	}
827
828	fn ns3() -> Namespace<'static> {
829		Namespace::try_from("uri:baz").unwrap()
830	}
831
832	fn mk() -> SimpleNamespaces {
833		SimpleNamespaces::new()
834	}
835
836	#[test]
837	fn prefers_setting_default_namespace() {
838		let mut ns = mk();
839		let (new, prefix) = ns.declare_auto(ns1());
840		assert!(new);
841		assert!(prefix.is_none());
842	}
843
844	#[test]
845	fn unset_namespace_is_not_new_initially() {
846		let mut ns = mk();
847		let (new, prefix) = ns.declare_auto(Namespace::NONE);
848		assert!(prefix.is_none());
849		assert!(!new);
850	}
851
852	#[test]
853	fn predefined_prefixes_can_be_looked_up() {
854		let ns = mk();
855		assert_eq!(ns.lookup_prefix(Some(PREFIX_XML)).unwrap(), XMLNS_XML);
856		assert_eq!(ns.lookup_prefix(Some(PREFIX_XMLNS)).unwrap(), XMLNS_XMLNS);
857	}
858
859	#[test]
860	fn hardcoded_xmlns_namespace_for_declare_auto() {
861		let mut ns = mk();
862		let (new, prefix) = ns.declare_auto(Namespace::XMLNS);
863		assert!(!new);
864		assert!(prefix.unwrap() == PREFIX_XMLNS);
865	}
866
867	#[test]
868	fn hardcoded_xml_namespace_for_declare_auto() {
869		let mut ns = mk();
870		let (new, prefix) = ns.declare_auto(Namespace::XML);
871		assert!(!new);
872		assert!(prefix.unwrap() == PREFIX_XML);
873	}
874
875	#[test]
876	fn hardcoded_xmlns_namespace_for_declare_with_auto_prefix() {
877		let mut ns = mk();
878		let (new, prefix) = ns.declare_with_auto_prefix(Namespace::XMLNS);
879		assert!(!new);
880		assert!(prefix == "xmlns");
881	}
882
883	#[test]
884	fn hardcoded_xml_namespace_for_declare_with_auto_prefix() {
885		let mut ns = mk();
886		let (new, prefix) = ns.declare_with_auto_prefix(Namespace::XML);
887		assert!(!new);
888		assert!(prefix == "xml");
889	}
890
891	#[test]
892	fn hardcoded_xmlns_namespace_for_declare_fixed() {
893		let mut ns = mk();
894		let new = ns.declare_fixed(Some(PREFIX_XMLNS), Namespace::XMLNS);
895		assert!(!new);
896	}
897
898	#[test]
899	fn hardcoded_xml_namespace_for_declare_fixed() {
900		let mut ns = mk();
901		let new = ns.declare_fixed(Some(PREFIX_XML), Namespace::XML);
902		assert!(!new);
903	}
904
905	#[test]
906	#[should_panic(expected = "xml is a reserved prefix")]
907	fn reject_xml_as_fixed_prefix_for_random_namespace() {
908		let mut ns = mk();
909		ns.declare_fixed(Some(PREFIX_XML), ns1());
910	}
911
912	#[test]
913	#[should_panic(expected = "xmlns is a reserved prefix")]
914	fn reject_xmlns_fixed_prefix_for_random_namespace() {
915		let mut ns = mk();
916		ns.declare_fixed(Some(PREFIX_XMLNS), ns1());
917	}
918
919	#[test]
920	#[should_panic(expected = "must be bound to xml prefix")]
921	fn reject_xml_namespace_with_other_prefix() {
922		let mut ns = mk();
923		ns.declare_fixed(Some("foo".try_into().unwrap()), Namespace::XML);
924	}
925
926	#[test]
927	#[should_panic(expected = "must be bound to xmlns prefix")]
928	fn reject_xmlns_namespace_with_other_prefix() {
929		let mut ns = mk();
930		ns.declare_fixed(Some("foo".try_into().unwrap()), Namespace::XMLNS);
931	}
932
933	#[test]
934	fn retrieve_default_namespace() {
935		let mut ns = mk();
936		ns.declare_auto(ns1());
937		match ns.get_prefix_or_default(ns1()) {
938			Ok(None) => {}
939			other => panic!("unexpected get_prefix_or_default result: {:?}", other),
940		};
941		match ns.lookup_prefix(None) {
942			Ok(name) => {
943				assert_eq!(name, ns1());
944			}
945			other => panic!("unexpected lookup_prefix result: {:?}", other),
946		}
947	}
948
949	#[test]
950	fn declaration_causes_lookup_to_return_a_thing() {
951		let mut ns = mk();
952		match ns.lookup_prefix(None) {
953			Err(PrefixError::Undeclared) => (),
954			other => panic!("unexpected lookup_prefix result: {:?}", other),
955		}
956		ns.declare_auto(ns1());
957		match ns.lookup_prefix(None) {
958			Ok(name) => {
959				assert_eq!(name, ns1());
960			}
961			other => panic!("unexpected lookup_prefix result: {:?}", other),
962		}
963	}
964
965	#[test]
966	fn reuses_existing_declaration_if_available() {
967		let mut ns = mk();
968		ns.declare_auto(ns1());
969		let (new, prefix) = ns.declare_auto(ns1());
970		assert!(!new);
971		assert!(prefix.is_none());
972	}
973
974	#[test]
975	fn allocates_prefix_if_default_is_already_set() {
976		let mut ns = mk();
977		ns.declare_auto(ns1());
978		let (new, prefix) = ns.declare_auto(ns2());
979		assert!(new);
980		assert!(prefix.is_some());
981	}
982
983	#[test]
984	fn retrieve_prefixed_namespace() {
985		let mut ns = mk();
986		let prefix = ns.declare_with_auto_prefix(ns1()).1.to_ncname();
987		match ns.get_prefix_or_default(ns1()) {
988			Ok(Some(v)) => {
989				assert_eq!(v, prefix);
990			}
991			other => panic!("unexpected get_prefix_or_default result: {:?}", other),
992		};
993	}
994
995	#[test]
996	fn declaration_causes_lookup_to_return_a_thing_for_a_prefix() {
997		let mut ns = mk();
998		match ns.lookup_prefix(None) {
999			Err(PrefixError::Undeclared) => (),
1000			other => panic!("unexpected lookup_prefix result: {:?}", other),
1001		}
1002		let prefix = ns.declare_with_auto_prefix(ns1()).1.to_ncname();
1003		match ns.lookup_prefix(Some(&prefix)) {
1004			Ok(name) => {
1005				assert_eq!(name, ns1());
1006			}
1007			other => panic!("unexpected lookup_prefix result: {:?}", other),
1008		}
1009		match ns.lookup_prefix(None) {
1010			Err(PrefixError::Undeclared) => (),
1011			other => panic!("unexpected lookup_prefix result: {:?}", other),
1012		}
1013	}
1014
1015	#[test]
1016	fn reuses_auto_allocated_prefix_for_same_ns() {
1017		let mut ns = mk();
1018		let prefix1 = ns.declare_with_auto_prefix(ns1()).1.to_ncname();
1019		let prefix2 = ns.declare_with_auto_prefix(ns1()).1.to_ncname();
1020		assert_eq!(prefix1, prefix2);
1021	}
1022
1023	#[test]
1024	fn auto_allocates_different_prefixes_for_different_ns() {
1025		let mut ns = mk();
1026		let prefix1 = ns.declare_with_auto_prefix(ns1()).1.to_ncname();
1027		let prefix2 = ns.declare_with_auto_prefix(ns2()).1.to_ncname();
1028		assert_ne!(prefix1, prefix2);
1029	}
1030
1031	#[test]
1032	fn preserves_default_ns_across_elements() {
1033		let mut ns = mk();
1034		ns.declare_auto(ns1());
1035		ns.get_prefix_or_default(ns1()).unwrap();
1036		ns.push();
1037		let (new, prefix) = ns.declare_auto(ns1());
1038		assert!(!new);
1039		assert!(prefix.is_none());
1040		assert!(ns.get_prefix_or_default(ns1()).unwrap().is_none());
1041		match ns.lookup_prefix(None) {
1042			Ok(name) => {
1043				assert_eq!(name, ns1());
1044			}
1045			other => panic!("unexpected lookup_prefix result: {:?}", other),
1046		}
1047	}
1048
1049	#[test]
1050	fn declare_with_fixed_prefix() {
1051		let mut ns = mk();
1052		ns.declare_fixed(Some(NcNameStr::from_str("stream").unwrap()), ns1());
1053		match ns.get_prefix(ns1()) {
1054			Ok(v) => {
1055				assert_eq!(v, "stream");
1056			}
1057			other => panic!("unexpected get_prefix result: {:?}", other),
1058		}
1059		match ns.get_prefix_or_default(ns1()) {
1060			Ok(Some(v)) => {
1061				assert_eq!(v, "stream");
1062			}
1063			other => panic!("unexpected get_prefix result: {:?}", other),
1064		}
1065	}
1066
1067	#[test]
1068	fn declare_fixed_prefixless() {
1069		let mut ns = mk();
1070		ns.declare_fixed(None, ns1());
1071		match ns.get_prefix_or_default(ns1()) {
1072			Ok(None) => (),
1073			other => panic!("unexpected get_prefix result: {:?}", other),
1074		}
1075		match ns.get_prefix(ns1()) {
1076			Err(PrefixError::Undeclared) => (),
1077			other => panic!("unexpected get_prefix result: {:?}", other),
1078		}
1079	}
1080
1081	#[test]
1082	fn preserves_global_prefixed_across_elements() {
1083		let mut ns = mk();
1084		ns.declare_fixed(Some(NcNameStr::from_str("stream").unwrap()), ns1());
1085		ns.declare_fixed(None, ns2());
1086		ns.push();
1087		match ns.get_prefix(ns1()) {
1088			Ok(v) => {
1089				assert_eq!(v, "stream");
1090			}
1091			other => panic!("unexpected get_prefix result: {:?}", other),
1092		}
1093		match ns.get_prefix_or_default(ns1()) {
1094			Ok(Some(v)) => {
1095				assert_eq!(v, "stream");
1096			}
1097			other => panic!("unexpected get_prefix result: {:?}", other),
1098		}
1099		match ns.get_prefix_or_default(ns2()) {
1100			Ok(None) => (),
1101			other => panic!("unexpected get_prefix result: {:?}", other),
1102		}
1103		match ns.get_prefix(ns2()) {
1104			Err(PrefixError::Undeclared) => (),
1105			other => panic!("unexpected get_prefix result: {:?}", other),
1106		}
1107	}
1108
1109	#[test]
1110	#[should_panic(expected = "conflict")]
1111	fn prohibits_overriding_global_prefix() {
1112		let mut ns = mk();
1113		ns.declare_fixed(Some(NcNameStr::from_str("stream").unwrap()), ns1());
1114		ns.declare_fixed(None, ns2());
1115		ns.push();
1116		ns.declare_fixed(Some(NcNameStr::from_str("stream").unwrap()), ns2());
1117	}
1118
1119	#[test]
1120	fn auto_allocations_stay_global_and_do_not_cause_conflicts() {
1121		let mut ns = mk();
1122		let prefix1 = ns.declare_with_auto_prefix(ns1()).1.to_ncname();
1123		let prefix2 = ns.declare_with_auto_prefix(ns2()).1.to_ncname();
1124		ns.push();
1125		let (new, prefix3) = ns.declare_with_auto_prefix(ns3());
1126		assert!(new);
1127		let prefix3 = prefix3.to_ncname();
1128		assert_ne!(prefix1, prefix3);
1129		assert_ne!(prefix2, prefix3);
1130	}
1131
1132	#[test]
1133	#[should_panic(expected = "conflict")]
1134	fn fixed_global_decl_can_conflict_with_auto_decl() {
1135		let mut ns = mk();
1136		ns.declare_fixed(Some(NcNameStr::from_str("tns0").unwrap()), ns1());
1137		ns.push();
1138		ns.declare_with_auto_prefix(ns3());
1139	}
1140
1141	#[test]
1142	#[should_panic(expected = "conflict")]
1143	fn fixed_local_decl_can_conflict_with_auto_decl() {
1144		let mut ns = mk();
1145		ns.declare_fixed(Some(NcNameStr::from_str("tns0").unwrap()), ns1());
1146		ns.declare_with_auto_prefix(ns3());
1147	}
1148}
1149
1150#[cfg(test)]
1151mod tests_encoder {
1152	use alloc::string::String;
1153	use std::io;
1154	use std::println;
1155
1156	use super::*;
1157
1158	use crate::parser::EventMetrics;
1159
1160	fn mkencoder() -> Encoder<SimpleNamespaces> {
1161		Encoder::new()
1162	}
1163
1164	fn ns1() -> Namespace<'static> {
1165		Namespace::try_from("uri:foo").unwrap()
1166	}
1167
1168	fn ns2() -> Namespace<'static> {
1169		Namespace::try_from("uri:bar").unwrap()
1170	}
1171
1172	fn ns3() -> Namespace<'static> {
1173		Namespace::try_from("uri:baz").unwrap()
1174	}
1175
1176	fn parse(mut input: &[u8]) -> (Vec<Event>, io::Result<bool>) {
1177		let mut parser: crate::Reader<_> = crate::Reader::new(&mut input);
1178		let mut events = Vec::new();
1179		let result = crate::as_eof_flag(parser.read_all(|ev| events.push(ev)));
1180		(events, result)
1181	}
1182
1183	fn encode_events(evs: &[Event]) -> Result<BytesMut> {
1184		let mut out = BytesMut::new();
1185		let mut encoder = mkencoder();
1186		for ev in evs {
1187			encoder.encode_event(&ev, &mut out)?;
1188		}
1189		Ok(out)
1190	}
1191
1192	fn encode_events_via_into_bytes(evs: &[Event]) -> Result<BytesMut> {
1193		let mut out = BytesMut::new();
1194		let mut encoder = mkencoder();
1195		for ev in evs {
1196			encoder.encode_event_into_bytes(&ev, &mut out)?;
1197		}
1198		Ok(out)
1199	}
1200
1201	fn collapse_cdata(evs: &mut Vec<Event>) {
1202		let mut buf = Vec::new();
1203		core::mem::swap(&mut buf, evs);
1204		let mut cdata_hold = None;
1205		for event in buf.drain(..) {
1206			match event {
1207				Event::Text(_, txt) => match cdata_hold.take() {
1208					None => cdata_hold = Some(txt),
1209					Some(existing) => cdata_hold = Some(existing + &*txt),
1210				},
1211				_ => {
1212					match cdata_hold.take() {
1213						Some(txt) => evs.push(Event::Text(EventMetrics::new(0), txt)),
1214						None => (),
1215					};
1216					evs.push(event);
1217				}
1218			}
1219		}
1220		match cdata_hold.take() {
1221			Some(txt) => evs.push(Event::Text(EventMetrics::new(0), txt)),
1222			None => (),
1223		};
1224	}
1225
1226	fn assert_event_eq(a: &Event, b: &Event) {
1227		match (a, b) {
1228			(Event::XmlDeclaration(_, v1), Event::XmlDeclaration(_, v2)) => {
1229				assert_eq!(v1, v2);
1230			}
1231			(Event::StartElement(_, name1, attrs1), Event::StartElement(_, name2, attrs2)) => {
1232				assert_eq!(name1, name2);
1233				assert_eq!(attrs1, attrs2);
1234			}
1235			(Event::EndElement(_), Event::EndElement(_)) => {}
1236			(Event::Text(_, text1), Event::Text(_, text2)) => {
1237				assert_eq!(text1, text2);
1238			}
1239			// will always raise
1240			(a, b) => panic!("event types differ: {:?} != {:?}", a, b),
1241		}
1242	}
1243
1244	fn assert_events_eq(initial: &[Event], reparsed: &[Event]) {
1245		for (a, b) in initial.iter().zip(reparsed.iter()) {
1246			assert_event_eq(a, b);
1247		}
1248		if initial.len() > reparsed.len() {
1249			panic!(
1250				"missing {} events in reparsed version",
1251				initial.len() - reparsed.len()
1252			)
1253		}
1254		if reparsed.len() > initial.len() {
1255			panic!(
1256				"{} additional events in reparsed version: {:?}",
1257				reparsed.len() - initial.len(),
1258				&reparsed[initial.len()..]
1259			)
1260		}
1261	}
1262
1263	fn check_reserialized(
1264		input: &[u8],
1265		initial: &[Event],
1266		initial_eof: bool,
1267		reserialized: &[u8],
1268		via: &'static str,
1269	) {
1270		let (mut reparsed, reparsed_result) = parse(&reserialized[..]);
1271		collapse_cdata(&mut reparsed);
1272		let reparsed_eof = match reparsed_result {
1273			Ok(eof) => eof,
1274			Err(e) => {
1275				panic!(
1276					"reserialized (via {}) XML\n\n{:?}\n\n  of\n\n{:?}\n\nfails to parse: {}",
1277					via,
1278					String::from_utf8_lossy(&reserialized[..]),
1279					String::from_utf8_lossy(input),
1280					e
1281				)
1282			}
1283		};
1284		println!("checking (via {})", via);
1285		println!(
1286			"reserialized: {:?}",
1287			String::from_utf8_lossy(&reserialized[..])
1288		);
1289		assert_events_eq(initial, &reparsed);
1290		assert_eq!(initial_eof, reparsed_eof);
1291	}
1292
1293	fn roundtrip_test(input: &[u8]) {
1294		// goal: test that a parsed thing can be serialized again and then parsed to the semantically equivalent series of events
1295		let (mut initial, initial_result) = parse(input);
1296		collapse_cdata(&mut initial);
1297		let initial_eof = initial_result.expect("test input must parse correctly");
1298		let reserialized_via_buf =
1299			encode_events(&initial[..]).expect("parsed input must be encodable");
1300		let reserialized_via_bytes =
1301			encode_events_via_into_bytes(&initial[..]).expect("parsed input must be encodable");
1302		check_reserialized(
1303			input,
1304			&initial,
1305			initial_eof,
1306			&reserialized_via_buf[..],
1307			"buf",
1308		);
1309		check_reserialized(
1310			input,
1311			&initial,
1312			initial_eof,
1313			&reserialized_via_bytes[..],
1314			"bytes",
1315		);
1316	}
1317
1318	#[test]
1319	fn reject_duplicate_xml_declaration() {
1320		let mut enc = mkencoder();
1321		let mut buf = BytesMut::new();
1322		match enc.encode(Item::XmlDeclaration(XmlVersion::V1_0), &mut buf) {
1323			Ok(()) => (),
1324			other => panic!("unexpected encode result: {:?}", other),
1325		};
1326		match enc.encode(Item::XmlDeclaration(XmlVersion::V1_0), &mut buf) {
1327			Err(Error::UnexpectedToken(_, "xml declaration", _)) => (),
1328			other => panic!("unexpected encode result: {:?}", other),
1329		};
1330	}
1331
1332	#[test]
1333	fn reject_text_at_global_level() {
1334		let mut enc = mkencoder();
1335		let mut buf = BytesMut::new();
1336		match enc.encode(Item::Text("".try_into().unwrap()), &mut buf) {
1337			Err(Error::UnexpectedToken(_, "text", _)) => (),
1338			other => panic!("unexpected encode result: {:?}", other),
1339		};
1340	}
1341
1342	#[test]
1343	fn reject_attribute_at_global_level() {
1344		let mut enc = mkencoder();
1345		let mut buf = BytesMut::new();
1346		match enc.encode(
1347			Item::Attribute(
1348				Namespace::NONE,
1349				"x".try_into().unwrap(),
1350				"".try_into().unwrap(),
1351			),
1352			&mut buf,
1353		) {
1354			Err(Error::UnexpectedToken(_, "attribute", _)) => (),
1355			other => panic!("unexpected encode result: {:?}", other),
1356		};
1357	}
1358
1359	#[test]
1360	fn allow_element_before_decl() {
1361		let mut enc = mkencoder();
1362		let mut buf = BytesMut::new();
1363		match enc.encode(
1364			Item::ElementHeadStart(Namespace::NONE, "x".try_into().unwrap()),
1365			&mut buf,
1366		) {
1367			Ok(()) => (),
1368			other => panic!("unexpected encode result: {:?}", other),
1369		};
1370	}
1371
1372	#[test]
1373	fn reject_xml_decl_in_element() {
1374		let mut enc = mkencoder();
1375		let mut buf = BytesMut::new();
1376		match enc.encode(
1377			Item::ElementHeadStart(Namespace::NONE, "x".try_into().unwrap()),
1378			&mut buf,
1379		) {
1380			Ok(()) => (),
1381			other => panic!("unexpected encode result: {:?}", other),
1382		};
1383		match enc.encode(Item::XmlDeclaration(XmlVersion::V1_0), &mut buf) {
1384			Err(Error::UnexpectedToken(_, "xml declaration", _)) => (),
1385			other => panic!("unexpected encode result: {:?}", other),
1386		};
1387	}
1388
1389	#[test]
1390	fn encode_self_closed_tag() {
1391		let mut enc = mkencoder();
1392		let mut buf = BytesMut::new();
1393		match enc.encode(
1394			Item::ElementHeadStart(Namespace::NONE, "x".try_into().unwrap()),
1395			&mut buf,
1396		) {
1397			Ok(()) => (),
1398			other => panic!("unexpected encode result: {:?}", other),
1399		};
1400		match enc.encode(Item::ElementFoot, &mut buf) {
1401			Ok(()) => (),
1402			other => panic!("unexpected encode result: {:?}", other),
1403		};
1404		assert_eq!(&buf, &b"<x/>"[..]);
1405	}
1406
1407	#[test]
1408	fn encode_root_prefix() {
1409		let mut enc = mkencoder();
1410		let mut buf = BytesMut::new();
1411		enc.ns.declare_fixed(Some("foo".try_into().unwrap()), ns1());
1412		match enc.encode(
1413			Item::ElementHeadStart(ns1(), "x".try_into().unwrap()),
1414			&mut buf,
1415		) {
1416			Ok(()) => (),
1417			other => panic!("unexpected encode result: {:?}", other),
1418		};
1419		match enc.encode(Item::ElementFoot, &mut buf) {
1420			Ok(()) => (),
1421			other => panic!("unexpected encode result: {:?}", other),
1422		};
1423		assert_eq!(&buf, &b"<foo:x xmlns:foo='uri:foo'/>"[..]);
1424	}
1425
1426	#[test]
1427	fn use_explicitly_set_at_root() {
1428		let mut enc = mkencoder();
1429		let mut buf = BytesMut::new();
1430		enc.ns.declare_fixed(Some("foo".try_into().unwrap()), ns1());
1431		match enc.encode(
1432			Item::ElementHeadStart(ns2(), "x".try_into().unwrap()),
1433			&mut buf,
1434		) {
1435			Ok(()) => (),
1436			other => panic!("unexpected encode result: {:?}", other),
1437		};
1438		match enc.encode(Item::ElementHeadEnd, &mut buf) {
1439			Ok(()) => (),
1440			other => panic!("unexpected encode result: {:?}", other),
1441		};
1442		match enc.encode(
1443			Item::ElementHeadStart(ns1(), "y".try_into().unwrap()),
1444			&mut buf,
1445		) {
1446			Ok(()) => (),
1447			other => panic!("unexpected encode result: {:?}", other),
1448		};
1449		match enc.encode(Item::ElementFoot, &mut buf) {
1450			Ok(()) => (),
1451			other => panic!("unexpected encode result: {:?}", other),
1452		};
1453		match enc.encode(Item::ElementFoot, &mut buf) {
1454			Ok(()) => (),
1455			other => panic!("unexpected encode result: {:?}", other),
1456		};
1457		assert_eq!(
1458			&buf,
1459			&b"<x xmlns='uri:bar' xmlns:foo='uri:foo'><foo:y/></x>"[..]
1460		);
1461	}
1462
1463	#[test]
1464	fn do_not_emit_duplicate_declarations() {
1465		let mut enc = mkencoder();
1466		let mut buf = BytesMut::new();
1467		enc.ns.declare_fixed(Some("foo".try_into().unwrap()), ns1());
1468		match enc.encode(
1469			Item::ElementHeadStart(ns2(), "x".try_into().unwrap()),
1470			&mut buf,
1471		) {
1472			Ok(()) => (),
1473			other => panic!("unexpected encode result: {:?}", other),
1474		};
1475		match enc.encode(
1476			Item::Attribute(ns1(), "a1".try_into().unwrap(), "v1".try_into().unwrap()),
1477			&mut buf,
1478		) {
1479			Ok(()) => (),
1480			other => panic!("unexpected encode result: {:?}", other),
1481		}
1482		match enc.encode(
1483			Item::Attribute(ns1(), "a2".try_into().unwrap(), "v2".try_into().unwrap()),
1484			&mut buf,
1485		) {
1486			Ok(()) => (),
1487			other => panic!("unexpected encode result: {:?}", other),
1488		}
1489		match enc.encode(
1490			Item::Attribute(ns2(), "a3".try_into().unwrap(), "v3".try_into().unwrap()),
1491			&mut buf,
1492		) {
1493			Ok(()) => (),
1494			other => panic!("unexpected encode result: {:?}", other),
1495		}
1496		match enc.encode(
1497			Item::Attribute(ns2(), "a4".try_into().unwrap(), "v4".try_into().unwrap()),
1498			&mut buf,
1499		) {
1500			Ok(()) => (),
1501			other => panic!("unexpected encode result: {:?}", other),
1502		}
1503		match enc.encode(
1504			Item::Attribute(ns3(), "a5".try_into().unwrap(), "v5".try_into().unwrap()),
1505			&mut buf,
1506		) {
1507			Ok(()) => (),
1508			other => panic!("unexpected encode result: {:?}", other),
1509		}
1510		match enc.encode(
1511			Item::Attribute(ns3(), "a6".try_into().unwrap(), "v6".try_into().unwrap()),
1512			&mut buf,
1513		) {
1514			Ok(()) => (),
1515			other => panic!("unexpected encode result: {:?}", other),
1516		}
1517		match enc.encode(Item::ElementHeadEnd, &mut buf) {
1518			Ok(()) => (),
1519			other => panic!("unexpected encode result: {:?}", other),
1520		};
1521		match enc.encode(
1522			Item::ElementHeadStart(ns1(), "y".try_into().unwrap()),
1523			&mut buf,
1524		) {
1525			Ok(()) => (),
1526			other => panic!("unexpected encode result: {:?}", other),
1527		};
1528		match enc.encode(Item::ElementFoot, &mut buf) {
1529			Ok(()) => (),
1530			other => panic!("unexpected encode result: {:?}", other),
1531		};
1532		match enc.encode(Item::ElementFoot, &mut buf) {
1533			Ok(()) => (),
1534			other => panic!("unexpected encode result: {:?}", other),
1535		};
1536		assert_eq!(&buf, &b"<x xmlns='uri:bar' xmlns:foo='uri:foo' foo:a1='v1' foo:a2='v2' xmlns:tns0='uri:bar' tns0:a3='v3' tns0:a4='v4' xmlns:tns1='uri:baz' tns1:a5='v5' tns1:a6='v6'><foo:y/></x>"[..]);
1537	}
1538
1539	#[test]
1540	fn reuses_existing_declaration_for_nested_namespaced_attributes_if_available() {
1541		let mut enc = mkencoder();
1542		let mut buf = BytesMut::new();
1543		enc.ns.declare_fixed(Some("foo".try_into().unwrap()), ns1());
1544		match enc.encode(
1545			Item::ElementHeadStart(ns2(), "x".try_into().unwrap()),
1546			&mut buf,
1547		) {
1548			Ok(()) => (),
1549			other => panic!("unexpected encode result: {:?}", other),
1550		};
1551		match enc.encode(
1552			Item::Attribute(ns1(), "a1".try_into().unwrap(), "v1".try_into().unwrap()),
1553			&mut buf,
1554		) {
1555			Ok(()) => (),
1556			other => panic!("unexpected encode result: {:?}", other),
1557		}
1558		match enc.encode(
1559			Item::Attribute(ns1(), "a2".try_into().unwrap(), "v2".try_into().unwrap()),
1560			&mut buf,
1561		) {
1562			Ok(()) => (),
1563			other => panic!("unexpected encode result: {:?}", other),
1564		}
1565		match enc.encode(
1566			Item::Attribute(ns2(), "a3".try_into().unwrap(), "v3".try_into().unwrap()),
1567			&mut buf,
1568		) {
1569			Ok(()) => (),
1570			other => panic!("unexpected encode result: {:?}", other),
1571		}
1572		match enc.encode(
1573			Item::Attribute(ns2(), "a4".try_into().unwrap(), "v4".try_into().unwrap()),
1574			&mut buf,
1575		) {
1576			Ok(()) => (),
1577			other => panic!("unexpected encode result: {:?}", other),
1578		}
1579		match enc.encode(
1580			Item::Attribute(ns3(), "a5".try_into().unwrap(), "v5".try_into().unwrap()),
1581			&mut buf,
1582		) {
1583			Ok(()) => (),
1584			other => panic!("unexpected encode result: {:?}", other),
1585		}
1586		match enc.encode(
1587			Item::Attribute(ns3(), "a6".try_into().unwrap(), "v6".try_into().unwrap()),
1588			&mut buf,
1589		) {
1590			Ok(()) => (),
1591			other => panic!("unexpected encode result: {:?}", other),
1592		}
1593		match enc.encode(Item::ElementHeadEnd, &mut buf) {
1594			Ok(()) => (),
1595			other => panic!("unexpected encode result: {:?}", other),
1596		};
1597		match enc.encode(
1598			Item::ElementHeadStart(ns1(), "y".try_into().unwrap()),
1599			&mut buf,
1600		) {
1601			Ok(()) => (),
1602			other => panic!("unexpected encode result: {:?}", other),
1603		};
1604		match enc.encode(
1605			Item::Attribute(ns1(), "a1".try_into().unwrap(), "v1".try_into().unwrap()),
1606			&mut buf,
1607		) {
1608			Ok(()) => (),
1609			other => panic!("unexpected encode result: {:?}", other),
1610		}
1611		match enc.encode(Item::ElementFoot, &mut buf) {
1612			Ok(()) => (),
1613			other => panic!("unexpected encode result: {:?}", other),
1614		};
1615		match enc.encode(Item::ElementFoot, &mut buf) {
1616			Ok(()) => (),
1617			other => panic!("unexpected encode result: {:?}", other),
1618		};
1619		assert_eq!(&buf, &b"<x xmlns='uri:bar' xmlns:foo='uri:foo' foo:a1='v1' foo:a2='v2' xmlns:tns0='uri:bar' tns0:a3='v3' tns0:a4='v4' xmlns:tns1='uri:baz' tns1:a5='v5' tns1:a6='v6'><foo:y foo:a1='v1'/></x>"[..]);
1620	}
1621
1622	#[test]
1623	fn self_closed_tag_encoding_ends_document_if_it_closes_the_root() {
1624		let mut enc = mkencoder();
1625		let mut buf = BytesMut::new();
1626		match enc.encode(
1627			Item::ElementHeadStart(Namespace::NONE, "x".try_into().unwrap()),
1628			&mut buf,
1629		) {
1630			Ok(()) => (),
1631			other => panic!("unexpected encode result: {:?}", other),
1632		};
1633		match enc.encode(Item::ElementFoot, &mut buf) {
1634			Ok(()) => (),
1635			other => panic!("unexpected encode result: {:?}", other),
1636		};
1637		match enc.encode(Item::Text("".try_into().unwrap()), &mut buf) {
1638			Err(Error::UnexpectedToken(Some(ErrorContext::DocumentEnd), "text", _)) => (),
1639			other => panic!("unexpected encode result: {:?}", other),
1640		};
1641	}
1642
1643	#[test]
1644	fn self_closed_tag_encoding_allows_content_thereafter() {
1645		let mut enc = mkencoder();
1646		let mut buf = BytesMut::new();
1647		match enc.encode(
1648			Item::ElementHeadStart(Namespace::NONE, "x".try_into().unwrap()),
1649			&mut buf,
1650		) {
1651			Ok(()) => (),
1652			other => panic!("unexpected encode result: {:?}", other),
1653		};
1654		match enc.encode(Item::ElementHeadEnd, &mut buf) {
1655			Ok(()) => (),
1656			other => panic!("unexpected encode result: {:?}", other),
1657		};
1658		match enc.encode(
1659			Item::ElementHeadStart(Namespace::NONE, "y".try_into().unwrap()),
1660			&mut buf,
1661		) {
1662			Ok(()) => (),
1663			other => panic!("unexpected encode result: {:?}", other),
1664		};
1665		match enc.encode(Item::ElementFoot, &mut buf) {
1666			Ok(()) => (),
1667			other => panic!("unexpected encode result: {:?}", other),
1668		};
1669		match enc.encode(Item::Text("foo".try_into().unwrap()), &mut buf) {
1670			Ok(()) => (),
1671			other => panic!("unexpected encode result: {:?}", other),
1672		};
1673		assert_eq!(&buf[..], b"<x><y/>foo");
1674	}
1675
1676	#[test]
1677	fn reject_element_after_end_of_document() {
1678		let mut enc = mkencoder();
1679		let mut buf = BytesMut::new();
1680		match enc.encode(
1681			Item::ElementHeadStart(Namespace::NONE, "x".try_into().unwrap()),
1682			&mut buf,
1683		) {
1684			Ok(()) => (),
1685			other => panic!("unexpected encode result: {:?}", other),
1686		};
1687		match enc.encode(Item::ElementHeadEnd, &mut buf) {
1688			Ok(()) => (),
1689			other => panic!("unexpected encode result: {:?}", other),
1690		};
1691		match enc.encode(Item::ElementFoot, &mut buf) {
1692			Ok(()) => (),
1693			other => panic!("unexpected encode result: {:?}", other),
1694		};
1695		match enc.encode(
1696			Item::ElementHeadStart(Namespace::NONE, "x".try_into().unwrap()),
1697			&mut buf,
1698		) {
1699			Err(Error::UnexpectedToken(Some(ErrorContext::DocumentEnd), "element start", _)) => (),
1700			other => panic!("unexpected encode result: {:?}", other),
1701		};
1702	}
1703
1704	#[test]
1705	fn reject_element_foot_before_start() {
1706		let mut enc = mkencoder();
1707		let mut buf = BytesMut::new();
1708		match enc.encode(Item::ElementFoot, &mut buf) {
1709			Err(Error::UnexpectedToken(_, "element foot", _)) => (),
1710			other => panic!("unexpected encode result: {:?}", other),
1711		};
1712	}
1713
1714	#[test]
1715	fn reject_element_head_end_outside_element_header() {
1716		let mut enc = mkencoder();
1717		let mut buf = BytesMut::new();
1718		match enc.encode(Item::ElementHeadEnd, &mut buf) {
1719			Err(Error::UnexpectedToken(_, "element head end", _)) => (),
1720			other => panic!("unexpected encode result: {:?}", other),
1721		};
1722		match enc.encode(
1723			Item::ElementHeadStart(Namespace::NONE, "x".try_into().unwrap()),
1724			&mut buf,
1725		) {
1726			Ok(()) => (),
1727			other => panic!("unexpected encode result: {:?}", other),
1728		};
1729		match enc.encode(Item::ElementHeadEnd, &mut buf) {
1730			Ok(()) => (),
1731			other => panic!("unexpected encode result: {:?}", other),
1732		};
1733		match enc.encode(Item::ElementHeadEnd, &mut buf) {
1734			Err(Error::UnexpectedToken(_, "element head end", _)) => (),
1735			other => panic!("unexpected encode result: {:?}", other),
1736		};
1737	}
1738
1739	#[test]
1740	fn reject_text_after_end_of_document() {
1741		let mut enc = mkencoder();
1742		let mut buf = BytesMut::new();
1743		match enc.encode(
1744			Item::ElementHeadStart(Namespace::NONE, "x".try_into().unwrap()),
1745			&mut buf,
1746		) {
1747			Ok(()) => (),
1748			other => panic!("unexpected encode result: {:?}", other),
1749		};
1750		match enc.encode(Item::ElementHeadEnd, &mut buf) {
1751			Ok(()) => (),
1752			other => panic!("unexpected encode result: {:?}", other),
1753		};
1754		match enc.encode(Item::ElementFoot, &mut buf) {
1755			Ok(()) => (),
1756			other => panic!("unexpected encode result: {:?}", other),
1757		};
1758		match enc.encode(Item::Text("".try_into().unwrap()), &mut buf) {
1759			Err(Error::UnexpectedToken(Some(ErrorContext::DocumentEnd), "text", _)) => (),
1760			other => panic!("unexpected encode result: {:?}", other),
1761		};
1762	}
1763
1764	#[test]
1765	fn single_element_roundtrip() {
1766		roundtrip_test(b"<?xml version='1.0'?>\n<a/>")
1767	}
1768
1769	#[test]
1770	fn nested_element_roundtrip() {
1771		roundtrip_test(b"<?xml version='1.0'?>\n<a><b/></a>")
1772	}
1773
1774	#[test]
1775	fn mixed_content_roundtrip() {
1776		roundtrip_test(b"<?xml version='1.0'?>\n<a>foo<b>bar</b>baz</a>")
1777	}
1778
1779	#[test]
1780	fn text_with_lt_roundtrip() {
1781		roundtrip_test(b"<?xml version='1.0'?>\n<a>&lt;</a>")
1782	}
1783
1784	#[test]
1785	fn text_with_gt_roundtrip() {
1786		roundtrip_test(b"<?xml version='1.0'?>\n<a>&gt;</a>")
1787	}
1788
1789	#[test]
1790	fn text_with_escaped_entity_roundtrip() {
1791		roundtrip_test(b"<?xml version='1.0'?>\n<a>&amp;amp;</a>")
1792	}
1793
1794	#[test]
1795	fn text_cdata_sequence_roundtrip() {
1796		roundtrip_test(b"<?xml version='1.0'?>\n<a>]]&gt;</a>")
1797	}
1798
1799	#[test]
1800	fn attribute_roundtrip() {
1801		roundtrip_test(b"<?xml version='1.0'?>\n<a a1='foo' a2=\"bar\"/>")
1802	}
1803
1804	#[test]
1805	fn attribute_whitespace_roundtrip() {
1806		roundtrip_test(b"<?xml version='1.0'?>\n<a a1='&#xd;&#xa;&#x9; '/>")
1807	}
1808
1809	#[test]
1810	fn attribute_quotes_roundtrip() {
1811		roundtrip_test(b"<?xml version='1.0'?>\n<a a1='&quot;&apos;'/>")
1812	}
1813
1814	#[test]
1815	fn namespace_roundtrip() {
1816		roundtrip_test(b"<?xml version='1.0'?>\n<a xmlns='uri:foo'/>")
1817	}
1818
1819	#[test]
1820	fn namespace_roundtrip_builtins() {
1821		roundtrip_test(b"<?xml version='1.0'?>\n<a xml:lang='de'/>")
1822	}
1823
1824	#[test]
1825	fn namespace_roundtrip_with_prefixes() {
1826		roundtrip_test(
1827			b"<?xml version='1.0'?>\n<a xmlns='uri:foo' xmlns:b='uri:bar'><b:b><c/></b:b></a>",
1828		)
1829	}
1830
1831	#[test]
1832	fn roundtrip_escaped_crlf() {
1833		roundtrip_test(b"<?xml version='1.0'?>\n<a>\r\n&#xd;&#xa;</a>")
1834	}
1835
1836	#[test]
1837	fn prefixed_attribute_roundtrip() {
1838		roundtrip_test(
1839			b"<?xml version='1.0'?>\n<a xmlns:b='uri:foo' b:a1='baz' a2='fnord' b:a3='foobar'/>",
1840		)
1841	}
1842
1843	#[test]
1844	fn escape_text_rejects_non_xml_chars() {
1845		let mut buf = String::with_capacity(4);
1846		let mut sink = BytesMut::with_capacity(8);
1847		for cp in 0x0..=0x10ffffu32 {
1848			if let Some(ch) = char::from_u32(cp) {
1849				buf.clear();
1850				buf.push(ch);
1851				let validation = rxml_validation::validate_cdata(&buf);
1852				assert_eq!(
1853					{
1854						sink.clear();
1855						escape_text(&mut sink, &buf, false)
1856					},
1857					validation,
1858					"in non-attribute context",
1859				);
1860				assert_eq!(
1861					{
1862						sink.clear();
1863						escape_text(&mut sink, &buf, true)
1864					},
1865					validation,
1866					"in attribute context",
1867				);
1868			}
1869		}
1870	}
1871}