mottle/
lib.rs

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}