#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct LanguageRange(Atom);
impl Separated for LanguageRange
{
type Delimiter = Comma;
}
impl ToCss for LanguageRange
{
fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result
{
let value = &(self.0).0;
let isCssIdentifier = if value.is_empty()
{
false
}
else
{
let mut characters = value.chars();
match characters.next().unwrap()
{
'a' ... 'z' | 'A' ... 'Z' | '-' =>
{
let mut isCssIdentifier = true;
for character in characters
{
match character
{
'a' ... 'z' | 'A' ... 'Z' | '-' | '0' ... '9' => continue,
_ =>
{
isCssIdentifier = false;
break
}
}
}
isCssIdentifier
}
_ => false
}
};
if isCssIdentifier
{
serialize_identifier(value, dest)
}
else
{
serialize_string(value, dest)
}
}
}
impl LanguageRange
{
pub fn matches_language(&self, tag: &str) -> bool
{
let mut range_subtags = (self.0).0.split('\x2d');
let mut tag_subtags = tag.split('\x2d');
if let (Some(range_subtag), Some(tag_subtag)) = (range_subtags.next(), tag_subtags.next())
{
if !(range_subtag.eq_ignore_ascii_case(tag_subtag) || range_subtag.eq_ignore_ascii_case("*"))
{
return false;
}
}
let mut current_tag_subtag = tag_subtags.next();
for range_subtag in range_subtags
{
if range_subtag == "*"
{
continue;
}
match current_tag_subtag.clone()
{
Some(tag_subtag) =>
{
if range_subtag.eq_ignore_ascii_case(tag_subtag)
{
current_tag_subtag = tag_subtags.next();
continue;
}
if tag_subtag.len() == 1
{
return false;
}
current_tag_subtag = tag_subtags.next();
if current_tag_subtag.is_none()
{
return false;
}
},
None =>
{
return false;
}
}
}
true
}
}