Skip to content

Commit 63052f2

Browse files
refactor some things
1 parent ad90074 commit 63052f2

File tree

5 files changed

+46
-114
lines changed

5 files changed

+46
-114
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/djls-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ anyhow = { workspace = true }
1616
camino = { workspace = true }
1717
dashmap = { workspace = true }
1818
percent-encoding = { workspace = true }
19+
rustc-hash = { workspace = true }
1920
salsa = { workspace = true }
2021
serde = { workspace = true }
2122
serde_json = { workspace = true }

crates/djls-server/src/client.rs

Lines changed: 2 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use std::collections::HashMap;
2-
31
use djls_conf::Settings;
42
use djls_source::PositionEncoding;
3+
use rustc_hash::FxHashMap;
54
use serde::Deserialize;
65
use serde_json::Value;
76
use tower_lsp_server::lsp_types;
@@ -139,21 +138,7 @@ pub struct ClientOptions {
139138
pub settings: Settings,
140139

141140
#[serde(flatten)]
142-
pub unknown: HashMap<String, Value>,
143-
}
144-
145-
impl ClientOptions {
146-
#[must_use]
147-
pub fn from_value(value: Option<Value>) -> (Self, Option<serde_json::Error>) {
148-
let Some(value) = value else {
149-
return (Self::default(), None);
150-
};
151-
152-
match serde_json::from_value::<Self>(value) {
153-
Ok(client_opts) => (client_opts, None),
154-
Err(err) => (Self::default(), Some(err)),
155-
}
156-
}
141+
pub unknown: FxHashMap<String, Value>,
157142
}
158143

159144
#[cfg(test)]
@@ -306,77 +291,4 @@ mod tests {
306291
FileKind::Template
307292
);
308293
}
309-
310-
#[test]
311-
fn test_client_options_from_value_none() {
312-
let (opts, err) = super::ClientOptions::from_value(None);
313-
assert!(err.is_none());
314-
assert!(!opts.settings.debug());
315-
assert!(opts.unknown.is_empty());
316-
}
317-
318-
#[test]
319-
fn test_client_options_from_value_empty_object() {
320-
let value = serde_json::json!({});
321-
let (opts, err) = super::ClientOptions::from_value(Some(value));
322-
assert!(err.is_none());
323-
assert!(!opts.settings.debug());
324-
assert!(opts.unknown.is_empty());
325-
}
326-
327-
#[test]
328-
fn test_client_options_from_value_valid_settings() {
329-
let value = serde_json::json!({
330-
"debug": true,
331-
"venv_path": "/path/to/venv",
332-
"django_settings_module": "myproject.settings"
333-
});
334-
let (opts, err) = super::ClientOptions::from_value(Some(value));
335-
assert!(err.is_none());
336-
assert!(opts.settings.debug());
337-
assert_eq!(opts.settings.venv_path(), Some("/path/to/venv"));
338-
assert_eq!(
339-
opts.settings.django_settings_module(),
340-
Some("myproject.settings")
341-
);
342-
assert!(opts.unknown.is_empty());
343-
}
344-
345-
#[test]
346-
fn test_client_options_from_value_unknown_fields() {
347-
let value = serde_json::json!({
348-
"debug": true,
349-
"unknownOption": "value",
350-
"anotherUnknown": 42
351-
});
352-
let (opts, err) = super::ClientOptions::from_value(Some(value));
353-
assert!(err.is_none());
354-
assert!(opts.settings.debug());
355-
assert_eq!(opts.unknown.len(), 2);
356-
assert!(opts.unknown.contains_key("unknownOption"));
357-
assert!(opts.unknown.contains_key("anotherUnknown"));
358-
}
359-
360-
#[test]
361-
fn test_client_options_from_value_invalid_json() {
362-
let value = serde_json::json!({
363-
"debug": "not_a_boolean"
364-
});
365-
let (opts, err) = super::ClientOptions::from_value(Some(value));
366-
assert!(err.is_some());
367-
assert!(!opts.settings.debug());
368-
assert!(opts.unknown.is_empty());
369-
}
370-
371-
#[test]
372-
fn test_client_options_from_value_partial_settings() {
373-
let value = serde_json::json!({
374-
"venv_path": "/custom/venv"
375-
});
376-
let (opts, err) = super::ClientOptions::from_value(Some(value));
377-
assert!(err.is_none());
378-
assert!(!opts.settings.debug());
379-
assert_eq!(opts.settings.venv_path(), Some("/custom/venv"));
380-
assert_eq!(opts.settings.django_settings_module(), None);
381-
}
382294
}

crates/djls-server/src/ext.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use tower_lsp_server::lsp_types;
1313
use tower_lsp_server::UriExt as TowerUriExt;
1414

1515
use crate::client::Client;
16+
use crate::client::ClientOptions;
1617

1718
pub(crate) trait PositionExt {
1819
fn to_line_col(&self) -> LineCol;
@@ -96,6 +97,43 @@ impl TextDocumentIdentifierExt for lsp_types::TextDocumentIdentifier {
9697
}
9798
}
9899

100+
pub(crate) trait InitializeParamsExt {
101+
fn client_options(&self) -> ClientOptions;
102+
}
103+
104+
impl InitializeParamsExt for lsp_types::InitializeParams {
105+
fn client_options(&self) -> ClientOptions {
106+
let client_options: ClientOptions = self
107+
.initialization_options
108+
.as_ref()
109+
.and_then(|v| match serde_json::from_value(v.clone()) {
110+
Ok(opts) => Some(opts),
111+
Err(err) => {
112+
tracing::error!(
113+
"Failed to deserialize initialization options: {}. Using defaults.",
114+
err
115+
);
116+
None
117+
}
118+
})
119+
.unwrap_or_default();
120+
121+
if !client_options.unknown.is_empty() {
122+
tracing::warn!(
123+
"Received unknown initialization options: {}",
124+
client_options
125+
.unknown
126+
.keys()
127+
.map(String::as_str)
128+
.collect::<Vec<_>>()
129+
.join(", ")
130+
);
131+
}
132+
133+
client_options
134+
}
135+
}
136+
99137
pub(crate) trait ClientInfoExt {
100138
fn to_client(&self) -> Client;
101139
}

crates/djls-server/src/session.rs

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use djls_workspace::Workspace;
1414
use tower_lsp_server::lsp_types;
1515

1616
use crate::client::ClientInfo;
17-
use crate::client::ClientOptions;
1817
use crate::db::DjangoDatabase;
18+
use crate::ext::InitializeParamsExt;
1919
use crate::ext::TextDocumentContentChangeEventExt;
2020
use crate::ext::TextDocumentItemExt;
2121
use crate::ext::UriExt;
@@ -57,29 +57,9 @@ impl Session {
5757
.and_then(|p| Utf8PathBuf::from_path_buf(p).ok())
5858
});
5959

60-
let (client_opts, deser_error) =
61-
ClientOptions::from_value(params.initialization_options.clone());
60+
let client_options = params.client_options();
6261

63-
if let Some(err) = deser_error {
64-
tracing::error!(
65-
"Failed to deserialize initialization options: {}. Falling back to file-based configuration.",
66-
err
67-
);
68-
}
69-
70-
if !client_opts.unknown.is_empty() {
71-
tracing::warn!(
72-
"Received unknown initialization options: {}",
73-
client_opts
74-
.unknown
75-
.keys()
76-
.map(String::as_str)
77-
.collect::<Vec<_>>()
78-
.join(", ")
79-
);
80-
}
81-
82-
let client_settings = client_opts.settings.clone();
62+
let client_settings = client_options.settings.clone();
8363

8464
let workspace = Workspace::new();
8565
let settings = project_path
@@ -92,7 +72,7 @@ impl Session {
9272
let client_info = ClientInfo::new(
9373
&params.capabilities,
9474
params.client_info.as_ref(),
95-
client_opts,
75+
client_options,
9676
);
9777

9878
Self {

0 commit comments

Comments
 (0)