1use anyhow::Result;
2use fs::Fs;
3use serde_json::{Map, Value};
4
5use std::sync::Arc;
6
7pub struct VsCodeSettings {
8 content: Map<String, Value>,
9}
10
11impl VsCodeSettings {
12 pub fn from_str(content: &str) -> Result<Self> {
13 Ok(Self {
14 content: serde_json_lenient::from_str(content)?,
15 })
16 }
17
18 pub async fn load_user_settings(fs: Arc<dyn Fs>) -> Result<Self> {
19 let content = fs.load(paths::vscode_settings_file()).await?;
20 Ok(Self {
21 content: serde_json_lenient::from_str(&content)?,
22 })
23 }
24
25 pub fn read_value(&self, setting: &str) -> Option<&Value> {
26 if let Some(value) = self.content.get(setting) {
27 return Some(value);
28 }
29 // TODO: maybe check if it's in [platform] settings for current platform as a fallback
30 // TODO: deal with language specific settings
31 None
32 }
33
34 pub fn read_string(&self, setting: &str) -> Option<&str> {
35 self.read_value(setting).and_then(|v| v.as_str())
36 }
37
38 pub fn read_bool(&self, setting: &str) -> Option<bool> {
39 self.read_value(setting).and_then(|v| v.as_bool())
40 }
41
42 pub fn string_setting(&self, key: &str, setting: &mut Option<String>) {
43 if let Some(s) = self.content.get(key).and_then(Value::as_str) {
44 *setting = Some(s.to_owned())
45 }
46 }
47
48 pub fn bool_setting(&self, key: &str, setting: &mut Option<bool>) {
49 if let Some(s) = self.content.get(key).and_then(Value::as_bool) {
50 *setting = Some(s)
51 }
52 }
53
54 pub fn u32_setting(&self, key: &str, setting: &mut Option<u32>) {
55 if let Some(s) = self.content.get(key).and_then(Value::as_u64) {
56 *setting = Some(s as u32)
57 }
58 }
59
60 pub fn u64_setting(&self, key: &str, setting: &mut Option<u64>) {
61 if let Some(s) = self.content.get(key).and_then(Value::as_u64) {
62 *setting = Some(s)
63 }
64 }
65
66 pub fn usize_setting(&self, key: &str, setting: &mut Option<usize>) {
67 if let Some(s) = self.content.get(key).and_then(Value::as_u64) {
68 *setting = Some(s.try_into().unwrap())
69 }
70 }
71
72 pub fn f32_setting(&self, key: &str, setting: &mut Option<f32>) {
73 if let Some(s) = self.content.get(key).and_then(Value::as_f64) {
74 *setting = Some(s as f32)
75 }
76 }
77
78 pub fn enum_setting<T>(
79 &self,
80 key: &str,
81 setting: &mut Option<T>,
82 f: impl FnOnce(&str) -> Option<T>,
83 ) {
84 if let Some(s) = self.content.get(key).and_then(Value::as_str).and_then(f) {
85 *setting = Some(s)
86 }
87 }
88}