devalang_core/config/
settings.rs

1use devalang_types::{TelemetrySettings, UserSettings};
2use serde_json::Value as JsonValue;
3use std::io::Write;
4
5pub fn get_home_dir() -> Option<std::path::PathBuf> {
6    dirs::home_dir()
7}
8
9pub fn get_devalang_homedir() -> std::path::PathBuf {
10    if let Some(home_dir) = get_home_dir() {
11        home_dir.join(".devalang")
12    } else {
13        std::path::PathBuf::from("~/.devalang")
14    }
15}
16
17pub fn get_default_user_config() -> UserSettings {
18    UserSettings {
19        session: "".into(),
20        telemetry: TelemetrySettings {
21            uuid: uuid::Uuid::new_v4().to_string(),
22            enabled: false,
23            level: "basic".into(),
24            stats: false,
25        },
26    }
27}
28
29pub fn get_user_config() -> Option<UserSettings> {
30    if let Some(config_path) = get_devalang_homedir().join("config.json").into() {
31        let file = std::fs::File::open(config_path).ok()?;
32        let settings = serde_json::from_reader(file).ok()?;
33        Some(settings)
34    } else {
35        None
36    }
37}
38
39pub fn write_user_config_file() {
40    if let Some(config_path) = get_devalang_homedir().join("config.json").into() {
41        let settings = get_user_config().unwrap_or_else(get_default_user_config);
42
43        let config_json = serde_json::to_string(&settings).unwrap();
44
45        if let Err(e) = write_config_atomic(&config_path, &config_json) {
46            println!("Could not write config file: {}", e);
47        }
48    } else {
49        println!("Could not create config file");
50    }
51}
52
53pub fn ensure_user_config_file_exists() {
54    if let Some(config_path) = get_devalang_homedir().join("config.json").into() {
55        if !config_path.exists() {
56            write_user_config_file();
57        }
58    }
59}
60
61pub fn set_user_config_value(key: &str, value: JsonValue) {
62    let mut settings = get_user_config().unwrap_or_default();
63
64    match (key, &value) {
65        ("telemetry", JsonValue::Bool(b)) => {
66            settings.telemetry.enabled = *b;
67        }
68        ("session", JsonValue::String(s)) => {
69            settings.session = s.clone();
70        }
71        _ => {
72            println!("Unsupported key or value type for '{}': {:?}", key, value);
73        }
74    }
75
76    if let Some(config_path) = get_devalang_homedir().join("config.json").into() {
77        let config_json = serde_json::to_string(&settings).unwrap();
78        if let Err(e) = write_config_atomic(&config_path, &config_json) {
79            println!("Could not write config file: {}", e);
80        }
81    } else {
82        println!("Could not create config file");
83    }
84}
85
86pub fn write_config_atomic(
87    config_path: &std::path::PathBuf,
88    contents: &str,
89) -> std::io::Result<()> {
90    if let Some(parent) = config_path.parent() {
91        std::fs::create_dir_all(parent)?;
92    }
93
94    let tmp_path = config_path.with_extension("json.tmp");
95    let mut tmp_file = std::fs::File::create(&tmp_path)?;
96    tmp_file.write_all(contents.as_bytes())?;
97    tmp_file.sync_all()?;
98    std::fs::rename(&tmp_path, config_path)?;
99
100    Ok(())
101}