less-rs 0.0.0

A Rust implementation of the Less CSS preprocessor.
Documentation
use std::cell::{Cell, RefCell};

use cssparser::{CowRcStr, Delimiter, Token};
use less_allocator::{Allocator, Vec};

use crate::{
  error::ParserError, properties::PropertyDeclaration, traits::ToCss, values::token::TokenList,
};

#[derive(Debug)]
pub enum VariableValue<'i> {
  Unparsed(&'i str),
  Parsed(TokenList<'i>),
}

impl<'i> ToCss<'i> for VariableValue<'i> {
  fn to_css<W>(
    &self,
    dest: &mut crate::printer::Printer<'_, 'i, W>,
  ) -> Result<(), crate::printer::PrinterError<'i>>
  where
    W: std::fmt::Write,
  {
    match self {
      VariableValue::Unparsed(_) => unreachable!(),
      VariableValue::Parsed(property_declaration) => todo!(),
    }
  }
}

impl<'i> VariableValue<'i> {
  fn as_unparsed(&self) -> Option<&'i str> {
    if let VariableValue::Unparsed(raw) = self {
      return Some(raw);
    }
    None
  }
}

impl<'i> crate::traits::Parse<'i> for VariableValue<'i> {
  fn parse<'t>(
    _allocator: &'i Allocator,
    input: &mut cssparser::Parser<'i, 't>,
  ) -> Result<Self, cssparser::ParseError<'i, crate::error::ParserError<'i>>> {
    let start_position = input.position();
    input.parse_until_before(Delimiter::Semicolon, |input| {
      while input.next().is_ok() {}
      Ok(())
    })?;
    Ok(Self::Unparsed(input.slice_from(start_position)))
  }
}

/// A Less variable.
///
///   @font-size: 16px;
///
#[derive(Debug)]
pub struct Variable<'i> {
  pub(crate) name: cssparser::CowRcStr<'i>,
  pub(crate) raw: &'i str,
  pub(crate) evaluating: Cell<bool>,
  pub(crate) value: RefCell<VariableValue<'i>>,
}

impl<'i> Variable<'i> {
  pub fn new(name: cssparser::CowRcStr<'i>, value: VariableValue<'i>) -> Self {
    let raw = match value.as_unparsed() {
      Some(v) => v,
      None => unreachable!("Variable value must be unparsed when creating a new variable"),
    };
    Self {
      name,
      raw,
      evaluating: Cell::new(false),
      value: RefCell::new(value),
    }
  }
}

#[derive(Clone, PartialEq, Eq, Hash)]
pub struct VariableCurly<'i> {
  name: cssparser::CowRcStr<'i>,
}

// FIXTHIS
// I believe `ToCss` is used to generate css. Shouldn't use this to print debuginfo.
// That's werid for `Selector` to use this as a way to debug.
// impl<'i> ToCss for VariableCurly<'i> {
//   fn to_css<W>(&self, dest: &mut W) -> std::fmt::Result
//   where
//     W: std::fmt::Write,
//   {
//     dest.write_str("@{")?;
//     dest.write_str(&self.name)?;
//     dest.write_str("}")
//   }
// }

impl<'i> From<CowRcStr<'i>> for VariableCurly<'i> {
  fn from(value: CowRcStr<'i>) -> Self {
    Self { name: value }
  }
}

impl<'i> crate::traits::Parse<'i> for VariableCurly<'i> {
  fn parse<'t>(
    _allocator: &'i Allocator,
    input: &mut cssparser::Parser<'i, 't>,
  ) -> Result<Self, cssparser::ParseError<'i, ParserError<'i>>> {
    let variable = input.expect_less_variable_curly()?;
    dbg!(&variable);
    Ok(VariableCurly {
      name: variable.clone(),
    })
  }
}