Skip to main content

shuck_server/session/
options.rs

1use lsp_types::Url;
2use rustc_hash::FxHashMap;
3use serde::Deserialize;
4use shuck_config::{FormatConfig, LintConfig, ShuckConfig};
5
6use crate::session::settings::GlobalClientSettings;
7use crate::{Client, logging};
8
9pub(crate) type WorkspaceOptionsMap = FxHashMap<Url, ClientOptions>;
10
11#[derive(Debug, Deserialize, Default)]
12#[serde(rename_all = "camelCase")]
13pub struct GlobalOptions {
14    #[serde(flatten)]
15    client: ClientOptions,
16    #[serde(default)]
17    pub(crate) tracing: TracingOptions,
18}
19
20impl GlobalOptions {
21    pub fn into_settings(self, client: Client) -> GlobalClientSettings {
22        GlobalClientSettings::new(self.client, client)
23    }
24}
25
26#[derive(Clone, Debug, Default, Deserialize)]
27#[serde(rename_all = "camelCase")]
28pub struct ClientOptions {
29    #[serde(default)]
30    pub lint: Option<LintConfig>,
31    #[serde(default)]
32    pub format: Option<FormatConfig>,
33    #[serde(default)]
34    pub fix_all: Option<bool>,
35    #[serde(default)]
36    pub unsafe_fixes: Option<bool>,
37    #[serde(default)]
38    pub show_syntax_errors: Option<bool>,
39}
40
41impl ClientOptions {
42    pub(crate) fn to_config_overrides(&self) -> ShuckConfig {
43        ShuckConfig {
44            lint: self.lint.clone().unwrap_or_default(),
45            format: self.format.clone().unwrap_or_default(),
46            ..ShuckConfig::default()
47        }
48    }
49}
50
51#[derive(Debug, Deserialize, Default)]
52#[serde(rename_all = "camelCase")]
53pub(crate) struct TracingOptions {
54    pub(crate) log_file: Option<std::path::PathBuf>,
55    pub(crate) log_level: Option<logging::LogLevel>,
56}
57
58#[derive(Debug, Default)]
59pub(crate) struct AllOptions {
60    pub(crate) global: GlobalOptions,
61    pub(crate) workspace: Option<WorkspaceOptionsMap>,
62}
63
64#[derive(Debug, Deserialize, Default)]
65#[serde(rename_all = "camelCase")]
66struct InitializationOptions {
67    #[serde(default)]
68    shuck: GlobalOptions,
69    #[serde(default)]
70    workspace: Option<WorkspaceOptionsMap>,
71}
72
73impl AllOptions {
74    pub(crate) fn from_value(value: serde_json::Value, _client: &Client) -> Self {
75        if value
76            .as_object()
77            .is_some_and(|object| object.contains_key("shuck"))
78        {
79            let options =
80                serde_json::from_value::<InitializationOptions>(value).unwrap_or_default();
81            return Self {
82                global: options.shuck,
83                workspace: options.workspace,
84            };
85        }
86
87        let global = serde_json::from_value::<GlobalOptions>(value).unwrap_or_default();
88        Self {
89            global,
90            workspace: None,
91        }
92    }
93}