use crate::util::Utf16String;
use crate::util::string_case_utils::to_lower_case_default;
use super::{AttributeName, AttributeNameError, AttributeNameKind};
pub struct HTMLAttributeName {
attribute_name: AttributeName,
complete_namespaced_attribute_name: Utf16String,
complete_html5_attribute_name: Utf16String,
}
impl HTMLAttributeName {
pub(super) fn for_name(
prefix: Option<Utf16String>,
attribute_name: Option<Utf16String>,
) -> Result<Self, AttributeNameError> {
let normalized_attribute = attribute_name
.filter(|value| !value.is_empty())
.map(|value| to_lower_case_default(&value));
let normalized_prefix = prefix
.as_ref()
.filter(|value| !value.is_empty())
.map(to_lower_case_default);
let raw_attribute = normalized_attribute
.as_ref()
.ok_or(AttributeNameError::InvalidAttributeName)?;
let (namespaced, html5, complete_names) = if let Some(prefix) = normalized_prefix.as_ref() {
let namespaced = join(prefix, b':', raw_attribute, None);
let html5 = join(prefix, b'-', raw_attribute, Some("data-"));
(
namespaced.clone(),
html5.clone(),
vec![Some(namespaced), Some(html5)],
)
} else {
(
raw_attribute.clone(),
raw_attribute.clone(),
vec![Some(raw_attribute.clone())],
)
};
let base = AttributeName::new(
AttributeNameKind::Html,
normalized_prefix,
normalized_attribute,
complete_names,
)?;
Ok(Self {
attribute_name: base,
complete_namespaced_attribute_name: namespaced,
complete_html5_attribute_name: html5,
})
}
#[must_use]
pub const fn as_attribute_name(&self) -> &AttributeName {
&self.attribute_name
}
#[must_use]
pub const fn get_complete_namespaced_attribute_name(&self) -> &Utf16String {
&self.complete_namespaced_attribute_name
}
#[must_use]
pub const fn get_complete_html5_attribute_name(&self) -> &Utf16String {
&self.complete_html5_attribute_name
}
}
fn join(
prefix: &Utf16String,
separator: u8,
name: &Utf16String,
leading: Option<&str>,
) -> Utf16String {
let mut result = leading.map_or_else(Vec::new, |value| value.encode_utf16().collect());
result.extend_from_slice(prefix.as_utf16());
result.push(u16::from(separator));
result.extend_from_slice(name.as_utf16());
Utf16String::from_utf16(result)
}