1use core::str;
2use std::borrow::Cow;
3use std::collections::BTreeMap;
4use std::io::Write;
5use std::ops::DerefMut;
6
7use quick_xml::events::{BytesCData, BytesDecl, BytesEnd, BytesPI, BytesStart, BytesText, Event};
8use quick_xml::writer::Writer as QuickXmlWriter;
9
10use xmlity::ser::IncludePrefix;
11use xmlity::{ser, ExpandedName, Prefix, QName, Serialize, XmlNamespace};
12
13use crate::{declaration_into_attribute, Attribute, OwnedQuickName, XmlnsDeclaration};
14
15use super::Error;
16
17pub fn to_string<T>(value: &T) -> Result<String, Error>
18where
19 T: Serialize,
20{
21 let serializer = QuickXmlWriter::new(Vec::new());
22 let mut serializer = Serializer::from(serializer);
23 value.serialize(&mut serializer)?;
24 let bytes = serializer.into_inner();
25
26 String::from_utf8(bytes).map_err(Error::InvalidUtf8)
27}
28
29struct NamespaceScope<'a> {
30 pub defined_namespaces: BTreeMap<Prefix<'a>, XmlNamespace<'a>>,
31}
32
33impl<'a> NamespaceScope<'a> {
34 pub fn new() -> Self {
35 Self {
36 defined_namespaces: BTreeMap::new(),
37 }
38 }
39
40 pub fn get_namespace<'b>(&'b self, prefix: &'b Prefix<'b>) -> Option<&'b XmlNamespace<'a>> {
41 self.defined_namespaces.get(prefix)
42 }
43}
44
45struct NamespaceScopeContainer<'a> {
46 scopes: Vec<NamespaceScope<'a>>,
47 prefix_generator: PrefixGenerator,
48}
49
50struct PrefixGenerator {
51 count: usize,
52}
53
54impl PrefixGenerator {
55 pub fn index_to_name(index: usize) -> Prefix<'static> {
56 let letter = (index / 26) as u8 + b'a';
65 let number = (index % 26) as u8 + b'0';
66 let mut name = String::with_capacity(2);
67 name.push(letter as char);
68 name.push(number as char);
69 Prefix::new(name).expect("Invalid prefix generated")
70 }
71
72 pub fn new() -> Self {
73 Self { count: 0 }
74 }
75
76 pub fn new_prefix(&mut self) -> Prefix<'static> {
77 let name = Self::index_to_name(self.count);
78 self.count += 1;
79 name
80 }
81}
82
83impl<'a> NamespaceScopeContainer<'a> {
84 pub fn new() -> Self {
85 Self {
86 scopes: Vec::new(),
87 prefix_generator: PrefixGenerator::new(),
88 }
89 }
90
91 pub fn push_scope(&mut self) {
92 self.scopes.push(NamespaceScope::new())
93 }
94
95 pub fn pop_scope(&mut self) -> Option<NamespaceScope> {
96 self.scopes.pop()
97 }
98
99 pub fn get_namespace<'b>(&'b self, prefix: &'b Prefix<'b>) -> Option<&'b XmlNamespace<'a>> {
100 self.scopes
101 .iter()
102 .rev()
103 .find_map(|a| a.get_namespace(prefix))
104 }
105
106 pub fn find_matching_namespace<'b>(
108 &'b self,
109 namespace: &'b XmlNamespace<'b>,
110 ) -> Option<&'b Prefix<'a>> {
111 self.scopes.iter().rev().find_map(|a| {
112 a.defined_namespaces
113 .iter()
114 .find(|(_, found_namespace)| namespace == *found_namespace)
115 .map(|(prefix, _)| prefix)
116 })
117 }
118
119 pub fn resolve_namespace<'b>(
121 &'b mut self,
122 namespace: &'b XmlNamespace<'b>,
123 preferred_prefix: Option<&'b Prefix<'b>>,
124 always_declare: IncludePrefix,
125 ) -> (Prefix<'b>, Option<XmlnsDeclaration<'b>>) {
126 let existing_prefix = self
127 .find_matching_namespace(namespace)
128 .filter(|_p| always_declare != IncludePrefix::Always);
130
131 if let Some(existing_prefix) = existing_prefix {
132 return (existing_prefix.clone(), None);
133 }
134
135 let prefix = preferred_prefix
138 .filter(|p| self.get_namespace(p).is_none_or(|n| n == namespace))
139 .or_else(|| {
141 preferred_prefix
142 .filter(|p| self.get_namespace(p).is_none_or(|n| n == namespace))
144 })
145 .cloned()
146 .unwrap_or_else(|| self.prefix_generator.new_prefix());
148
149 let xmlns = XmlnsDeclaration::new(prefix.clone(), namespace.clone());
150
151 self.scopes.last_mut().map(|a| {
152 a.defined_namespaces
153 .insert(prefix.clone().into_owned(), namespace.clone().into_owned())
154 });
155
156 (prefix, Some(xmlns))
157 }
158
159 pub fn resolve_name<'b>(
160 &mut self,
161 name: ExpandedName<'b>,
162 preferred_prefix: Option<&Prefix<'b>>,
163 always_declare: IncludePrefix,
164 ) -> (QName<'b>, Option<XmlnsDeclaration<'b>>) {
165 let (prefix, declaration) = name
166 .namespace()
167 .map(|namespace| self.resolve_namespace(namespace, preferred_prefix, always_declare))
168 .unzip();
169
170 let declaration = declaration.flatten().map(|a| a.into_owned());
171 let resolved_prefix = prefix.map(|a| a.into_owned());
172
173 let name = name.to_q_name(resolved_prefix);
174 (name.into_owned(), declaration)
175 }
176}
177
178pub struct Serializer<W: Write> {
179 writer: QuickXmlWriter<W>,
180 preferred_namespace_prefixes: BTreeMap<XmlNamespace<'static>, Prefix<'static>>,
181 namespace_scopes: NamespaceScopeContainer<'static>,
182}
183
184impl<W: Write> Serializer<W> {
185 pub fn new(writer: QuickXmlWriter<W>) -> Self {
186 Self::new_with_namespaces(writer, BTreeMap::new())
187 }
188
189 pub fn new_with_namespaces(
190 writer: QuickXmlWriter<W>,
191 preferred_namespace_prefixes: BTreeMap<XmlNamespace<'static>, Prefix<'static>>,
192 ) -> Self {
193 Self {
194 writer,
195 preferred_namespace_prefixes,
196 namespace_scopes: NamespaceScopeContainer::new(),
197 }
198 }
199
200 pub fn into_inner(self) -> W {
201 self.writer.into_inner()
202 }
203
204 pub fn push_namespace_scope(&mut self) {
205 self.namespace_scopes.push_scope()
206 }
207
208 pub fn pop_namespace_scope(&mut self) {
209 self.namespace_scopes.pop_scope();
210 }
211
212 pub fn add_preferred_prefix(
213 &mut self,
214 namespace: XmlNamespace<'static>,
215 prefix: Prefix<'static>,
216 ) {
217 self.preferred_namespace_prefixes.insert(namespace, prefix);
218 }
219
220 pub fn resolve_name<'b>(
221 &mut self,
222 name: ExpandedName<'b>,
223 preferred_prefix: Option<&Prefix<'b>>,
224 always_declare: IncludePrefix,
225 ) -> (QName<'b>, Option<XmlnsDeclaration<'b>>) {
226 let name2 = name.clone();
227 let preferred_prefix = preferred_prefix.or_else(|| {
228 name2
229 .namespace()
230 .and_then(|a| self.preferred_namespace_prefixes.get(a))
231 });
232
233 self.namespace_scopes
234 .resolve_name(name, preferred_prefix, always_declare)
235 }
236}
237
238impl<W: Write> From<QuickXmlWriter<W>> for Serializer<W> {
239 fn from(writer: QuickXmlWriter<W>) -> Self {
240 Self::new(writer)
241 }
242}
243
244impl<W: Write> From<W> for Serializer<W> {
245 fn from(writer: W) -> Self {
246 Self::new(QuickXmlWriter::new(writer))
247 }
248}
249
250pub struct SerializeElement<'s, W: Write> {
251 serializer: &'s mut Serializer<W>,
252 name: ExpandedName<'static>,
253 attributes: Vec<Attribute<'static>>,
254 preferred_prefix: Option<Prefix<'static>>,
255 enforce_prefix: IncludePrefix,
256}
257
258pub struct AttributeSerializer<'t> {
259 name: ExpandedName<'static>,
260 on_end_add_to: &'t mut Vec<Attribute<'static>>,
261 preferred_prefix: Option<Prefix<'static>>,
262 enforce_prefix: IncludePrefix,
263}
264
265impl ser::SerializeAttributeAccess for AttributeSerializer<'_> {
266 type Ok = ();
267 type Error = Error;
268
269 fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error> {
270 self.enforce_prefix = should_enforce;
271 Ok(())
272 }
273
274 fn preferred_prefix(
275 &mut self,
276 preferred_prefix: Option<xmlity::Prefix<'_>>,
277 ) -> Result<Self::Ok, Self::Error> {
278 self.preferred_prefix = preferred_prefix.map(Prefix::into_owned);
279 Ok(())
280 }
281
282 fn end<S: AsRef<str>>(self, value: S) -> Result<Self::Ok, Self::Error> {
283 self.on_end_add_to.push(Attribute {
284 name: self.name.into_owned(),
285 value: value.as_ref().to_owned(),
286 preferred_prefix: self.preferred_prefix,
287 enforce_prefix: self.enforce_prefix,
288 });
289
290 Ok(())
291 }
292}
293
294pub struct AttributeVecSerializer<'t> {
295 attributes: &'t mut Vec<Attribute<'static>>,
296}
297
298impl ser::AttributeSerializer for AttributeVecSerializer<'_> {
299 type Error = Error;
300
301 type Ok = ();
302 type SerializeAttribute<'a>
303 = AttributeSerializer<'a>
304 where
305 Self: 'a;
306
307 fn serialize_attribute(
308 &mut self,
309 name: &'_ ExpandedName<'_>,
310 ) -> Result<Self::SerializeAttribute<'_>, Self::Error> {
311 Ok(Self::SerializeAttribute {
312 name: name.clone().into_owned(),
313 on_end_add_to: &mut self.attributes,
314 preferred_prefix: None,
315 enforce_prefix: IncludePrefix::default(),
316 })
317 }
318
319 fn serialize_none(&mut self) -> Result<Self::Ok, Self::Error> {
320 Ok(())
321 }
322}
323
324pub struct OwnedBytesStart {
326 name: OwnedQuickName,
327 attributes: Vec<(OwnedQuickName, Vec<u8>)>,
328}
329
330impl OwnedBytesStart {
331 pub fn as_quick_xml(&self) -> BytesStart<'_> {
332 BytesStart::from(self.name.as_ref()).with_attributes(self.attributes.iter().map(
333 |(key, value)| quick_xml::events::attributes::Attribute {
334 key: key.as_ref(),
335 value: Cow::Borrowed(value),
336 },
337 ))
338 }
339}
340
341impl<'s, W: Write> SerializeElement<'s, W> {
342 fn finish_start(self) -> (OwnedBytesStart, QName<'static>, &'s mut Serializer<W>) {
343 let Self {
344 serializer,
345 name,
346 attributes,
347 enforce_prefix,
348 preferred_prefix,
349 } = self;
350
351 let mut resolve_name_or_declare =
352 |name: &ExpandedName<'_>,
353 preferred_prefix: Option<&Prefix<'_>>,
354 enforce_prefix: IncludePrefix|
355 -> (QName<'static>, Option<XmlnsDeclaration<'static>>) {
356 let (qname, decl) =
357 serializer.resolve_name(name.clone(), preferred_prefix, enforce_prefix);
358
359 (qname.into_owned(), decl.map(|a| a.into_owned()))
360 };
361
362 let (elem_qname, elem_name_decl) =
363 resolve_name_or_declare(&name, preferred_prefix.as_ref(), enforce_prefix);
364
365 let (attr_prefixes, attr_decls): (Vec<_>, Vec<_>) = attributes
366 .iter()
367 .map(|a| &a.name)
368 .map(|name| resolve_name_or_declare(name, None, IncludePrefix::default()))
369 .unzip();
370
371 let decls = elem_name_decl
372 .into_iter()
373 .chain(attr_decls.into_iter().flatten())
374 .collect::<Vec<_>>();
375
376 let mut q_attributes = decls
378 .iter()
379 .map(|decl| declaration_into_attribute(decl.clone()))
380 .map(|attr| {
381 (
382 OwnedQuickName::new(&attr.name),
383 attr.value.as_bytes().to_owned(),
384 )
385 })
386 .collect::<Vec<_>>();
387
388 q_attributes.extend(
390 attributes
391 .into_iter()
392 .zip(attr_prefixes)
393 .map(|(attr, qname)| attr.resolve(qname.prefix().cloned()))
394 .map(|attr| {
395 (
396 OwnedQuickName::new(&attr.name),
397 attr.value.as_bytes().to_owned(),
398 )
399 }),
400 );
401
402 let bytes_start = OwnedBytesStart {
403 name: OwnedQuickName::new(&elem_qname),
404 attributes: q_attributes,
405 };
406
407 (bytes_start, elem_qname, serializer)
408 }
409}
410
411impl<W: Write> ser::SerializeAttributes for SerializeElement<'_, W> {
412 type Ok = ();
413 type Error = Error;
414
415 fn serialize_attribute<A: ser::SerializeAttribute>(
416 &mut self,
417 a: &A,
418 ) -> Result<Self::Ok, Self::Error> {
419 a.serialize_attribute(AttributeVecSerializer {
420 attributes: &mut self.attributes,
421 })
422 }
423}
424
425impl<'s, W: Write> ser::SerializeElement for SerializeElement<'s, W> {
426 type SerializeElementChildren = SerializeElementChildren<'s, W>;
427
428 fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error> {
429 self.enforce_prefix = should_enforce;
430 Ok(())
431 }
432 fn preferred_prefix(
433 &mut self,
434 preferred_prefix: Option<Prefix<'_>>,
435 ) -> Result<Self::Ok, Self::Error> {
436 self.preferred_prefix = preferred_prefix.map(Prefix::into_owned);
437 Ok(())
438 }
439
440 fn serialize_children(self) -> Result<Self::SerializeElementChildren, Self::Error> {
441 self.serializer.push_namespace_scope();
442 let (bytes_start, end_name, serializer) = self.finish_start();
443
444 serializer
445 .writer
446 .write_event(Event::Start(bytes_start.as_quick_xml()))
447 .map_err(Error::Io)?;
448
449 Ok(SerializeElementChildren {
450 serializer,
451 end_name,
452 })
453 }
454
455 fn end(self) -> Result<Self::Ok, Self::Error> {
456 self.serializer.push_namespace_scope();
457 let (bytes_start, _, serializer) = self.finish_start();
458
459 serializer
460 .writer
461 .write_event(Event::Empty(bytes_start.as_quick_xml()))
462 .map_err(Error::Io)?;
463
464 serializer.pop_namespace_scope();
465
466 Ok(())
467 }
468}
469
470pub struct SerializeElementChildren<'s, W: Write> {
471 serializer: &'s mut Serializer<W>,
472 end_name: QName<'static>,
473}
474
475impl<W: Write> ser::SerializeChildren for SerializeElementChildren<'_, W> {
476 type Ok = ();
477 type Error = Error;
478
479 fn serialize_child<V: Serialize>(&mut self, value: &V) -> Result<Self::Ok, Self::Error> {
480 value.serialize(self.serializer.deref_mut())
481 }
482}
483
484impl<W: Write> ser::SerializeElementChildren for SerializeElementChildren<'_, W> {
485 fn end(self) -> Result<Self::Ok, Self::Error> {
486 let end_name = OwnedQuickName::new(&self.end_name);
487
488 let bytes_end = BytesEnd::from(end_name.as_ref());
489
490 self.serializer
491 .writer
492 .write_event(Event::End(bytes_end))
493 .map_err(Error::Io)?;
494
495 self.serializer.pop_namespace_scope();
496
497 Ok(())
498 }
499}
500
501pub struct SerializeSeq<'e, W: Write> {
502 serializer: &'e mut Serializer<W>,
503}
504
505impl<W: Write> ser::SerializeSeq for SerializeSeq<'_, W> {
506 type Ok = ();
507 type Error = Error;
508
509 fn serialize_element<V: Serialize>(&mut self, v: &V) -> Result<Self::Ok, Self::Error> {
510 v.serialize(self.serializer.deref_mut())
511 }
512
513 fn end(self) -> Result<Self::Ok, Self::Error> {
514 Ok(())
515 }
516}
517
518impl<'s, W: Write> xmlity::Serializer for &'s mut Serializer<W> {
519 type Ok = ();
520 type Error = Error;
521 type SerializeElement = SerializeElement<'s, W>;
522 type SerializeSeq = SerializeSeq<'s, W>;
523
524 fn serialize_cdata<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
525 self.writer
526 .write_event(Event::CData(BytesCData::new(text.as_ref())))
527 .map_err(Error::Io)
528 }
529
530 fn serialize_text<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
531 self.writer
532 .write_event(Event::Text(BytesText::new(text.as_ref())))
533 .map_err(Error::Io)
534 }
535
536 fn serialize_element<'a>(
537 self,
538 name: &'a ExpandedName<'a>,
539 ) -> Result<Self::SerializeElement, Self::Error> {
540 Ok(SerializeElement {
541 serializer: self,
542 name: name.clone().into_owned(),
543 attributes: Vec::new(),
544 preferred_prefix: None,
545 enforce_prefix: IncludePrefix::default(),
546 })
547 }
548
549 fn serialize_seq(self) -> Result<Self::SerializeSeq, Self::Error> {
550 Ok(SerializeSeq { serializer: self })
551 }
552
553 fn serialize_decl<S: AsRef<str>>(
554 self,
555 version: S,
556 encoding: Option<S>,
557 standalone: Option<S>,
558 ) -> Result<Self::Ok, Self::Error> {
559 self.writer
560 .write_event(Event::Decl(BytesDecl::new(
561 version.as_ref(),
562 encoding.as_ref().map(|s| s.as_ref()),
563 standalone.as_ref().map(|s| s.as_ref()),
564 )))
565 .map_err(Error::Io)
566 }
567
568 fn serialize_pi<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
569 self.writer
570 .write_event(Event::PI(BytesPI::new(
571 str::from_utf8(text.as_ref()).unwrap(),
572 )))
573 .map_err(Error::Io)
574 }
575
576 fn serialize_comment<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
577 self.writer
578 .write_event(Event::Comment(BytesText::new(
579 str::from_utf8(text.as_ref()).unwrap(),
580 )))
581 .map_err(Error::Io)
582 }
583
584 fn serialize_doctype<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
585 self.writer
586 .write_event(Event::DocType(BytesText::new(
587 str::from_utf8(text.as_ref()).unwrap(),
588 )))
589 .map_err(Error::Io)
590 }
591
592 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
593 Ok(())
594 }
595}