manatsu 0.3.1

CLI tools for Manatsu
Documentation
use anyhow::{anyhow, Context, Result};
use lightningcss::stylesheet::{ParserOptions, PrinterOptions, StyleSheet};
use std::path::Path;
use std::{env, fs};

/// Create a Manatsu theme from tokens generated by the
/// [Material Design theme builder](https://m3.material.io/theme-builder#/custom).
pub fn create<S: AsRef<str>, O: AsRef<Path>>(source: S, output: O) -> Result<()> {
  let source = env::current_dir()?.join(source.as_ref());
  let source = fs::read_to_string(source)?;
  let source = transform(source)?;

  let stylesheet = StyleSheet::parse(&source, ParserOptions::default())
    .map_err(|err| anyhow!("{:?}", err))
    .with_context(|| "Failed to parse stylesheet")?;

  let css = stylesheet.to_css(PrinterOptions::default())?;
  fs::write(output, css.code)?;

  Ok(())
}

fn transform<C: AsRef<str>>(css: C) -> Result<String> {
  let mut result = String::new();
  let mut dark_colors = String::from("\n\n[class~=manatsu-dark] {\n");

  macro_rules! push {
    ($vec:expr, $val:expr) => {
      $vec.push_str($val);
      $vec.push('\n');
      continue;
    };
  }

  for line in css.as_ref().lines() {
    if !line.contains("--md") {
      push!(result, line);
    }

    if line.contains("--md-sys-color") {
      let line = line.replace("md-sys", "m");
      if line.contains("-light") {
        let line = line.replace("-light", "");
        push!(result, &line);
      } else if line.contains("-dark") && !line.contains("fixed") {
        let line = line.replace("-dark", "");
        push!(dark_colors, &line);
      }
    }
  }

  dark_colors.push_str("}\n");
  result.push_str(&dark_colors);

  Ok(result)
}