use html5ever::tendril::StrTendril;
use super::parse::HtmlTagInfo;
pub struct NsDefaults {
pub(super) html: String,
pub(super) tag_info: HtmlTagInfo,
pub(super) added_xmlns: String,
}
impl NsDefaults {
fn build_html_string(&self) -> String {
if self.added_xmlns.is_empty() {
self.html.clone()
} else {
let mut result = String::with_capacity(self.html.len() + self.added_xmlns.len());
result.push_str(&self.html[..self.tag_info.tag_close_start]);
result.push_str(&self.added_xmlns);
result.push_str(&self.html[self.tag_info.tag_close_start..]);
result
}
}
fn slices(&self) -> Vec<&str> {
if self.added_xmlns.is_empty() {
vec![&self.html]
} else {
vec![
&self.html[..self.tag_info.tag_close_start],
&self.added_xmlns,
&self.html[self.tag_info.tag_close_start..],
]
}
}
}
impl std::fmt::Display for NsDefaults {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.build_html_string())
}
}
impl From<NsDefaults> for String {
fn from(ns_defaults: NsDefaults) -> Self {
ns_defaults.build_html_string()
}
}
impl From<NsDefaults> for StrTendril {
fn from(ns_defaults: NsDefaults) -> Self {
StrTendril::from(ns_defaults.build_html_string())
}
}
impl IntoIterator for NsDefaults {
type Item = StrTendril;
type IntoIter = std::vec::IntoIter<StrTendril>;
fn into_iter(self) -> Self::IntoIter {
let slices = self.slices();
slices
.into_iter()
.map(StrTendril::from)
.collect::<Vec<_>>()
.into_iter()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_display_no_additions() {
let html = "<html><body>Test</body></html>";
let ns_defaults = NsDefaults {
html: html.to_string(),
tag_info: HtmlTagInfo {
tag_start: 0,
tag_close_start: 5,
tag_end: 6,
existing_xmlns: vec![],
},
added_xmlns: String::new(),
};
assert_eq!(ns_defaults.to_string(), html);
}
#[test]
fn test_display_with_additions() {
let html = "<html><body>Test</body></html>";
let ns_defaults = NsDefaults {
html: html.to_string(),
tag_info: HtmlTagInfo {
tag_start: 0,
tag_close_start: 5,
tag_end: 6,
existing_xmlns: vec![],
},
added_xmlns: " xmlns:svg=\"http://www.w3.org/2000/svg\"".to_string(),
};
let expected = "<html xmlns:svg=\"http://www.w3.org/2000/svg\"><body>Test</body></html>";
assert_eq!(ns_defaults.to_string(), expected);
}
#[test]
fn test_into_string() {
let html = "<html><body>Test</body></html>";
let ns_defaults = NsDefaults {
html: html.to_string(),
tag_info: HtmlTagInfo {
tag_start: 0,
tag_close_start: 5,
tag_end: 6,
existing_xmlns: vec![],
},
added_xmlns: String::new(),
};
let html_string: String = ns_defaults.into();
assert_eq!(html_string, html);
}
#[test]
fn test_into_str_tendril() {
let html = "<html><body>Test</body></html>";
let ns_defaults = NsDefaults {
html: html.to_string(),
tag_info: HtmlTagInfo {
tag_start: 0,
tag_close_start: 5,
tag_end: 6,
existing_xmlns: vec![],
},
added_xmlns: String::new(),
};
let tendril: StrTendril = ns_defaults.into();
assert_eq!(tendril.as_ref(), html);
}
#[test]
fn test_into_iterator_no_additions() {
let html = "<html><body>Test</body></html>";
let ns_defaults = NsDefaults {
html: html.to_string(),
tag_info: HtmlTagInfo {
tag_start: 0,
tag_close_start: 5,
tag_end: 6,
existing_xmlns: vec![],
},
added_xmlns: String::new(),
};
let tendrils: Vec<StrTendril> = ns_defaults.into_iter().collect();
assert_eq!(tendrils.len(), 1);
assert_eq!(tendrils[0].as_ref(), html);
}
#[test]
fn test_into_iterator_with_additions() {
let html = "<html><body>Test</body></html>";
let ns_defaults = NsDefaults {
html: html.to_string(),
tag_info: HtmlTagInfo {
tag_start: 0,
tag_close_start: 5,
tag_end: 6,
existing_xmlns: vec![],
},
added_xmlns: " xmlns:svg=\"http://www.w3.org/2000/svg\"".to_string(),
};
let tendrils: Vec<StrTendril> = ns_defaults.into_iter().collect();
assert_eq!(tendrils.len(), 3);
assert_eq!(tendrils[0].as_ref(), "<html");
assert_eq!(
tendrils[1].as_ref(),
" xmlns:svg=\"http://www.w3.org/2000/svg\""
);
assert_eq!(tendrils[2].as_ref(), "><body>Test</body></html>");
}
}