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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
// This file is part of rss.
//
// Copyright © 2015-2021 The rust-syndication Developers
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the MIT License and/or Apache 2.0 License.
use std::collections::BTreeMap;
use std::io::Write;
use std::str;
use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
use quick_xml::Error as XmlError;
use quick_xml::Writer;
use crate::toxml::ToXml;
/// Types and methods for [Atom](https://www.rssboard.org/rss-profile#namespace-elements-atom) extensions.
#[cfg(feature = "atom")]
pub mod atom;
/// Types and methods for
/// [iTunes](https://help.apple.com/itc/podcasts_connect/#/itcb54353390) extensions.
pub mod itunes;
/// Types and methods for [Dublin Core](http://dublincore.org/documents/dces/) extensions.
pub mod dublincore;
/// Types and methods for [Syndication](http://web.resource.org/rss/1.0/modules/syndication/) extensions.
pub mod syndication;
pub(crate) mod util;
/// A map of extension namespace prefixes to local names to elements.
pub type ExtensionMap = BTreeMap<String, BTreeMap<String, Vec<Extension>>>;
/// A namespaced extension such as iTunes or Dublin Core.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Default, Clone, PartialEq)]
#[cfg_attr(feature = "builders", derive(Builder))]
#[cfg_attr(
feature = "builders",
builder(
setter(into),
default,
build_fn(name = "build_impl", private, error = "never::Never")
)
)]
pub struct Extension {
/// The qualified name of the extension element.
pub name: String,
/// The content of the extension element.
pub value: Option<String>,
/// The attributes for the extension element.
#[cfg_attr(feature = "builders", builder(setter(each = "attr")))]
pub attrs: BTreeMap<String, String>,
/// The children of the extension element. This is a map of local names to child
/// elements.
#[cfg_attr(feature = "builders", builder(setter(each = "child")))]
pub children: BTreeMap<String, Vec<Extension>>,
}
impl Extension {
/// Return the qualified name of this extension.
pub fn name(&self) -> &str {
self.name.as_str()
}
/// Set the qualified name of this extension.
pub fn set_name<V>(&mut self, name: V)
where
V: Into<String>,
{
self.name = name.into();
}
/// Return the text content of this extension.
pub fn value(&self) -> Option<&str> {
self.value.as_deref()
}
/// Set the text content of this extension.
pub fn set_value<V>(&mut self, value: V)
where
V: Into<Option<String>>,
{
self.value = value.into();
}
/// Return the attributes for the extension element.
pub fn attrs(&self) -> &BTreeMap<String, String> {
&self.attrs
}
/// Return the children of the extension element.
///
/// This is a map of local names to child elements.
pub fn children(&self) -> &BTreeMap<String, Vec<Extension>> {
&self.children
}
}
impl ToXml for Extension {
fn to_xml<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), XmlError> {
let mut element = BytesStart::new(&self.name);
element.extend_attributes(self.attrs.iter().map(|a| (a.0.as_str(), a.1.as_str())));
writer.write_event(Event::Start(element))?;
if let Some(ref value) = self.value {
writer.write_event(Event::Text(BytesText::new(value)))?;
}
for extension in self.children.values().flatten() {
extension.to_xml(writer)?;
}
writer.write_event(Event::End(BytesEnd::new(&self.name)))?;
Ok(())
}
}
#[cfg(feature = "builders")]
impl ExtensionBuilder {
/// Builds a new `Extension`.
pub fn build(&self) -> Extension {
self.build_impl().unwrap()
}
}