use std::{
fmt::Write,
ops::{Deref, DerefMut},
};
use less_allocator::{Box, Vec};
use variable::Variable;
use crate::{
parser::DeclarationList,
printer::{Printer, PrinterError},
selector::SelectorList,
traits::ToCss,
};
pub mod variable;
#[derive(Debug)]
pub struct CssRuleList<'i>(pub(crate) Vec<'i, CssRule<'i>>);
impl<'i> ToCss<'i> for CssRuleList<'i> {
fn to_css<W: std::fmt::Write>(
&self,
dest: &mut Printer<'_, 'i, W>,
) -> Result<(), PrinterError<'i>> {
let variables = Vec::from_iter_in(
self.0.iter().filter_map(|rule| {
if let CssRule::LessVariable(variable) = rule {
Some(&*variable.0)
} else {
None
}
}),
dest.allocator,
);
dest.with_context(variables, |dest| {
self.0.iter().try_for_each(|rule| rule.to_css(dest))
})?;
Ok(())
}
}
#[derive(Debug)]
pub struct StyleRule<'i> {
pub selector: SelectorList<'i>,
pub declarations: DeclarationList<'i>,
pub rules: CssRuleList<'i>,
}
impl<'i> ToCss<'i> for StyleRule<'i> {
fn to_css<W: std::fmt::Write>(
&self,
dest: &mut Printer<'_, 'i, W>,
) -> Result<(), PrinterError<'i>> {
let variables = Vec::from_iter_in(
self.rules.iter().filter_map(|rule| {
if let CssRule::LessVariable(variable) = rule {
Some(&*variable.0)
} else {
None
}
}),
dest.allocator,
);
dest.write_str(".class {")?;
dest.write_newline()?;
dest.with_context(variables, |dest| self.declarations.to_css(dest))?;
self.rules.to_css(dest)?;
dest.write_char('}')?;
Ok(())
}
}
#[derive(Debug)]
pub enum CssRule<'i> {
Style(Box<'i, StyleRule<'i>>),
LessVariable(Box<'i, Variable<'i>>),
}
impl<'i> ToCss<'i> for CssRule<'i> {
fn to_css<W: std::fmt::Write>(
&self,
dest: &mut Printer<'_, 'i, W>,
) -> Result<(), PrinterError<'i>> {
match self {
CssRule::Style(rule) => {
rule.to_css(dest)?;
}
CssRule::LessVariable(_) => {}
}
Ok(())
}
}
impl<'i> Deref for CssRuleList<'i> {
type Target = Vec<'i, CssRule<'i>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for CssRuleList<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}