2023-11-02 22:57:13 +00:00
|
|
|
mod theme_printer;
|
|
|
|
mod vscode;
|
|
|
|
|
2023-11-02 22:00:55 +00:00
|
|
|
use std::fs::{self, File};
|
2023-11-02 21:21:11 +00:00
|
|
|
use std::path::PathBuf;
|
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
|
|
use anyhow::{anyhow, Context, Result};
|
2023-11-02 22:24:38 +00:00
|
|
|
use gpui::serde_json;
|
2023-11-02 21:21:11 +00:00
|
|
|
use log::LevelFilter;
|
|
|
|
use serde::Deserialize;
|
|
|
|
use simplelog::SimpleLogger;
|
2023-11-02 22:57:13 +00:00
|
|
|
use theme::{default_color_scales, Appearance, ThemeFamily};
|
2023-11-02 22:24:38 +00:00
|
|
|
use vscode::VsCodeThemeConverter;
|
2023-11-02 22:00:55 +00:00
|
|
|
|
2023-11-02 22:57:13 +00:00
|
|
|
use crate::theme_printer::ThemeFamilyPrinter;
|
2023-11-02 22:00:55 +00:00
|
|
|
use crate::vscode::VsCodeTheme;
|
2023-11-02 21:21:11 +00:00
|
|
|
|
|
|
|
pub(crate) fn new_theme_family(name: String, author: String) -> ThemeFamily {
|
|
|
|
ThemeFamily {
|
|
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
|
|
name: name.into(),
|
|
|
|
author: author.into(),
|
|
|
|
themes: Vec::new(),
|
|
|
|
scales: default_color_scales(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-02 22:00:55 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
2023-11-02 22:24:38 +00:00
|
|
|
struct FamilyMetadata {
|
2023-11-02 21:21:11 +00:00
|
|
|
pub name: String,
|
2023-11-02 22:00:55 +00:00
|
|
|
pub author: String,
|
2023-11-02 22:24:38 +00:00
|
|
|
pub themes: Vec<ThemeMetadata>,
|
2023-11-02 21:21:11 +00:00
|
|
|
}
|
|
|
|
|
2023-11-02 22:00:55 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
2023-11-02 21:21:11 +00:00
|
|
|
#[serde(rename_all = "snake_case")]
|
2023-11-02 22:57:13 +00:00
|
|
|
pub enum ThemeAppearanceJson {
|
2023-11-02 21:21:11 +00:00
|
|
|
Light,
|
|
|
|
Dark,
|
|
|
|
}
|
|
|
|
|
2023-11-02 22:24:38 +00:00
|
|
|
impl From<ThemeAppearanceJson> for Appearance {
|
|
|
|
fn from(value: ThemeAppearanceJson) -> Self {
|
|
|
|
match value {
|
|
|
|
ThemeAppearanceJson::Light => Self::Light,
|
|
|
|
ThemeAppearanceJson::Dark => Self::Dark,
|
|
|
|
}
|
|
|
|
}
|
2023-11-02 21:21:11 +00:00
|
|
|
}
|
|
|
|
|
2023-11-02 22:24:38 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
2023-11-02 22:57:13 +00:00
|
|
|
pub struct ThemeMetadata {
|
2023-11-02 21:21:11 +00:00
|
|
|
pub name: String,
|
2023-11-02 22:24:38 +00:00
|
|
|
pub file_name: String,
|
|
|
|
pub appearance: ThemeAppearanceJson,
|
2023-11-02 21:21:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Load a vscode theme from json
|
|
|
|
// Load it's LICENSE from the same folder
|
|
|
|
// Create a ThemeFamily for the theme
|
|
|
|
// Create a ThemeVariant or Variants for the theme
|
|
|
|
// Output a rust file with the ThemeFamily and ThemeVariant(s) in it
|
|
|
|
|
|
|
|
fn main() -> Result<()> {
|
|
|
|
SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
|
|
|
|
|
|
|
|
let themes_path = PathBuf::from_str("crates/theme2/src/themes")?;
|
|
|
|
|
2023-11-02 22:00:55 +00:00
|
|
|
let vscode_themes_path = PathBuf::from_str("assets/themes/src/vscode/")?;
|
2023-11-02 21:21:11 +00:00
|
|
|
|
2023-11-02 22:00:55 +00:00
|
|
|
let mut theme_families = Vec::new();
|
2023-11-02 21:21:11 +00:00
|
|
|
|
2023-11-02 22:00:55 +00:00
|
|
|
for theme_family_dir in fs::read_dir(&vscode_themes_path)? {
|
|
|
|
let theme_family_dir = theme_family_dir?;
|
2023-11-02 21:21:11 +00:00
|
|
|
|
2023-11-02 22:00:55 +00:00
|
|
|
let theme_family_slug = theme_family_dir
|
|
|
|
.path()
|
|
|
|
.file_stem()
|
|
|
|
.ok_or(anyhow!("no file stem"))
|
|
|
|
.map(|stem| stem.to_string_lossy().to_string())?;
|
2023-11-02 21:21:11 +00:00
|
|
|
|
2023-11-02 22:00:55 +00:00
|
|
|
let family_metadata_file = File::open(theme_family_dir.path().join("family.json"))
|
|
|
|
.context(format!("no `family.json` found for '{theme_family_slug}'"))?;
|
2023-11-02 21:21:11 +00:00
|
|
|
|
2023-11-02 22:24:38 +00:00
|
|
|
let family_metadata: FamilyMetadata = serde_json::from_reader(family_metadata_file)
|
|
|
|
.context(format!(
|
|
|
|
"failed to parse `family.json` for '{theme_family_slug}'"
|
|
|
|
))?;
|
2023-11-02 21:21:11 +00:00
|
|
|
|
2023-11-02 22:00:55 +00:00
|
|
|
let mut themes = Vec::new();
|
2023-11-02 21:21:11 +00:00
|
|
|
|
2023-11-02 22:24:38 +00:00
|
|
|
for theme_metadata in family_metadata.themes {
|
|
|
|
let theme_file_path = theme_family_dir.path().join(&theme_metadata.file_name);
|
2023-11-02 21:21:11 +00:00
|
|
|
|
2023-11-02 22:00:55 +00:00
|
|
|
let theme_file = File::open(&theme_file_path)?;
|
2023-11-02 21:21:11 +00:00
|
|
|
|
2023-11-02 22:24:38 +00:00
|
|
|
let vscode_theme: VsCodeTheme = serde_json::from_reader(theme_file)
|
2023-11-02 22:00:55 +00:00
|
|
|
.context(format!("failed to parse theme {theme_file_path:?}"))?;
|
2023-11-02 21:21:11 +00:00
|
|
|
|
2023-11-02 22:24:38 +00:00
|
|
|
let converter = VsCodeThemeConverter::new(vscode_theme, theme_metadata);
|
|
|
|
|
|
|
|
let theme = converter.convert()?;
|
|
|
|
|
2023-11-02 22:00:55 +00:00
|
|
|
themes.push(theme);
|
|
|
|
}
|
|
|
|
|
|
|
|
let theme_family = ThemeFamily {
|
|
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
|
|
name: family_metadata.name.into(),
|
|
|
|
author: family_metadata.author.into(),
|
2023-11-02 22:24:38 +00:00
|
|
|
themes,
|
2023-11-02 22:00:55 +00:00
|
|
|
scales: default_color_scales(),
|
|
|
|
};
|
|
|
|
|
|
|
|
theme_families.push(theme_family);
|
|
|
|
}
|
2023-11-02 21:21:11 +00:00
|
|
|
|
2023-11-02 22:57:13 +00:00
|
|
|
for theme_family in theme_families {
|
|
|
|
println!("{:#?}", ThemeFamilyPrinter::new(theme_family));
|
|
|
|
}
|
|
|
|
|
2023-11-02 21:21:11 +00:00
|
|
|
Ok(())
|
|
|
|
}
|