#[derive(Clone, Debug, PartialEq)]
pub struct MediaQuery
{
pub qualifier: Option<Qualifier>,
pub media_type: MediaQueryType,
pub expressions: Vec<MediaExpression>,
}
impl Separated for MediaQuery
{
type Delimiter = Comma;
}
impl ToCss for MediaQuery
{
fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result
{
if let Some(qualifier) = self.qualifier
{
qualifier.to_css(dest)?;
dest.write_char(' ')?;
}
use self::MediaQueryType::*;
match self.media_type
{
All =>
{
if self.qualifier.is_some() || self.expressions.is_empty()
{
dest.write_str("all")?;
}
}
Concrete(ref value) => value.to_css(dest)?,
}
if self.expressions.is_empty()
{
return Ok(());
}
if self.media_type != All || self.qualifier.is_some()
{
dest.write_str(" and ")?;
}
self.expressions[0].to_css(dest)?;
for expression in self.expressions.iter().skip(1)
{
dest.write_str(" and ")?;
expression.to_css(dest)?;
}
Ok(())
}
}
impl MediaQuery
{
#[inline(always)]
fn never_matching() -> Self
{
Self
{
qualifier: Some(Qualifier::Not),
media_type: MediaQueryType::All,
expressions: vec![],
}
}
pub(crate) fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, CustomParseError<'i>>>
{
let mut expressions = vec![];
use self::Qualifier::*;
let qualifier = if input.try(|input| input.expect_ident_matching("only")).is_ok()
{
Some(Only)
}
else if input.try(|input| input.expect_ident_matching("not")).is_ok()
{
Some(Not)
}
else
{
None
};
let isThereAValidMediaType = input.try(|input|
{
if let Ok(ident) = input.expect_ident()
{
match MediaQueryType::parse(ident).map_err(|error| ParseError::Custom(error))
{
Ok(mediaType) => Ok(Left(mediaType)),
Err(error) => Ok(Right(error)),
}
}
else
{
Err(())
}
});
let media_type = match isThereAValidMediaType
{
Ok(Left(media_type)) => media_type,
Ok(Right(error)) => return Err(error),
Err(()) =>
{
if qualifier.is_some()
{
return Err(ParseError::Custom(CustomParseError::MediaTypeIsOnlyOptionalIfQualifiedIsNotSpecified))
}
expressions.push(MediaExpression::parse(context, input)?);
MediaQueryType::All
}
};
loop
{
if input.try(|input| input.expect_ident_matching("and")).is_err()
{
return Ok
(
Self
{
qualifier,
media_type,
expressions
}
);
}
expressions.push(MediaExpression::parse(context, input)?)
}
}
}