use super::{Comment, CssString, Import, Selectors, Value};
use crate::output::CssBuf;
use std::io::{self, Write};
#[derive(Clone, Debug)]
pub struct Rule {
pub(crate) selectors: Selectors,
pub(crate) body: Vec<BodyItem>,
}
impl Rule {
pub fn new(selectors: Selectors) -> Rule {
Rule {
selectors,
body: Vec::new(),
}
}
pub fn push(&mut self, item: BodyItem) {
self.body.push(item)
}
pub(crate) fn write(&self, buf: &mut CssBuf) -> io::Result<()> {
if !self.body.is_empty() {
buf.do_indent_no_nl();
if buf.format().is_compressed() {
write!(buf, "{:#}", self.selectors)?;
} else {
write!(buf, "{}", self.selectors)?;
}
buf.start_block();
for item in &self.body {
item.write(buf)?;
}
buf.end_block();
}
Ok(())
}
}
#[derive(Clone, Debug)]
pub enum BodyItem {
Import(Import),
Property(Property),
CustomProperty(String, CssString),
Comment(Comment),
}
impl BodyItem {
pub(crate) fn write(&self, buf: &mut CssBuf) -> io::Result<()> {
match self {
BodyItem::Comment(c) => c.write(buf),
BodyItem::Import(import) => import.write(buf)?,
BodyItem::Property(property) => property.write(buf),
BodyItem::CustomProperty(ref name, ref val) => {
buf.do_indent_no_nl();
write!(
buf,
"{}:{}{}",
name,
if val.quotes().is_none() || buf.format().is_compressed()
{
""
} else {
" "
},
val,
)?;
buf.add_one(";\n", ";");
}
}
Ok(())
}
}
impl From<Comment> for BodyItem {
fn from(comment: Comment) -> BodyItem {
BodyItem::Comment(comment)
}
}
impl From<Import> for BodyItem {
fn from(import: Import) -> BodyItem {
BodyItem::Import(import)
}
}
impl From<Property> for BodyItem {
fn from(property: Property) -> BodyItem {
BodyItem::Property(property)
}
}
#[derive(Clone, Debug)]
pub struct Property {
name: String,
value: Value,
}
impl Property {
pub fn new(name: String, value: Value) -> Self {
Property { name, value }
}
pub fn prefix(self, prefix: &str) -> Self {
Property {
name: format!("{}-{}", prefix, self.name),
value: self.value,
}
}
pub(crate) fn write(&self, buf: &mut CssBuf) {
buf.do_indent_no_nl();
buf.add_str(&self.name);
buf.add_one(": ", ":");
buf.add_str(
&self
.value
.format(buf.format())
.to_string()
.replace('\n', " "),
);
buf.add_one(";\n", ";");
}
}