1pub mod dsl;
2pub mod proto;
3
4use serde::Serialize;
5use serde_json::ser::PrettyFormatter;
6use serde_json::Serializer;
7use std::path::{Path, PathBuf};
8use std::{fs, io};
9use thiserror::Error;
10
11pub fn save_theme(theme: &proto::Theme) -> Result<(), SaveThemeError> {
12 let themes_dir = prepare_themes_dir()?;
13 let theme_path = themes_dir.join(format!("{}-color-theme.json", theme.name));
14
15 fs::write(&theme_path, serialize_theme(theme))
16 .map_err(|e| SaveThemeError::WriteTheme(e, theme_path))?;
17
18 Ok(())
19}
20
21pub fn serialize_theme(theme: &proto::Theme) -> String {
22 let mut v = b"// Do not edit directly; this file is generated.\n".to_vec();
23 let mut serializer = Serializer::with_formatter(&mut v, PrettyFormatter::with_indent(b" "));
24 theme.serialize(&mut serializer).unwrap();
25 v.push(b'\n');
26
27 String::from_utf8(v).unwrap()
28}
29
30fn prepare_themes_dir() -> Result<&'static Path, SaveThemeError> {
31 let themes_dir = Path::new("themes");
32
33 if !themes_dir.exists() {
34 fs::create_dir(themes_dir).map_err(SaveThemeError::CreateThemesDir)?;
35 } else if !themes_dir.is_dir() {
36 return Err(SaveThemeError::ThemesDirIsNotDir);
37 }
38
39 Ok(themes_dir)
40}
41
42#[derive(Debug, Error)]
43pub enum SaveThemeError {
44 #[error("failed creating `themes/` directory")]
45 CreateThemesDir(#[source] io::Error),
46 #[error("`themes/` already exists and is not a directory")]
47 ThemesDirIsNotDir,
48 #[error("failed writing theme to `{1}`")]
49 WriteTheme(#[source] io::Error, PathBuf),
50}