Skip to content

Commit f77b64c

Browse files
committed
Reduce repetition in config_data! macro by splitting ConfigData into fields
1 parent fda1935 commit f77b64c

File tree

1 file changed

+95
-158
lines changed

1 file changed

+95
-158
lines changed

crates/rust-analyzer/src/config.rs

Lines changed: 95 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ mod patch_old_style;
5959
// To deprecate an option by replacing it with another name use `new_name | `old_name` so that we keep
6060
// parsing the old name.
6161
config_data! {
62-
struct GlobalConfigData {
62+
global: struct GlobalConfigData {
6363
/// Whether to insert #[must_use] when generating `as_` methods
6464
/// for enum variants.
6565
assist_emitMustUse: bool = false,
@@ -361,8 +361,11 @@ config_data! {
361361
workspace_symbol_search_limit: usize = 128,
362362
/// Workspace symbol search scope.
363363
workspace_symbol_search_scope: WorkspaceSymbolSearchScopeDef = WorkspaceSymbolSearchScopeDef::Workspace,
364-
},
365-
struct LocalConfigData {
364+
}
365+
}
366+
367+
config_data! {
368+
local: struct LocalConfigData {
366369
/// Toggles the additional completions that automatically add imports when completed.
367370
/// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.
368371
completion_autoimport_enable: bool = true,
@@ -535,8 +538,11 @@ config_data! {
535538
/// By disabling semantic tokens for strings, other grammars can be used to highlight
536539
/// their contents.
537540
semanticHighlighting_strings_enable: bool = true,
538-
},
539-
struct ClientConfigData {}
541+
}
542+
}
543+
544+
config_data! {
545+
client: struct ClientConfigData {}
540546
}
541547

542548
impl Default for ConfigData {
@@ -563,15 +569,15 @@ impl Default for RootConfigData {
563569
fn default() -> Self {
564570
RootConfigData {
565571
local: RootLocalConfigData(LocalConfigData::from_json(
566-
serde_json::Value::Null,
572+
&mut serde_json::Value::Null,
567573
&mut Vec::new(),
568574
)),
569575
global: RootGlobalConfigData(GlobalConfigData::from_json(
570-
serde_json::Value::Null,
576+
&mut serde_json::Value::Null,
571577
&mut Vec::new(),
572578
)),
573579
client: RootClientConfigData(ClientConfigData::from_json(
574-
serde_json::Value::Null,
580+
&mut serde_json::Value::Null,
575581
&mut Vec::new(),
576582
)),
577583
}
@@ -1147,7 +1153,7 @@ impl Config {
11471153
.collect();
11481154
patch_old_style::patch_json_for_outdated_configs(&mut json);
11491155
self.root_config.global =
1150-
RootGlobalConfigData(GlobalConfigData::from_json(json, &mut errors));
1156+
RootGlobalConfigData(GlobalConfigData::from_json(&mut json, &mut errors));
11511157
tracing::debug!("deserialized config data: {:#?}", self.root_config.global);
11521158
self.snippets.clear();
11531159
for (name, def) in self.root_config.local.0.completion_snippets_custom.iter() {
@@ -2200,33 +2206,22 @@ pub enum TargetDirectory {
22002206
}
22012207

22022208
macro_rules! _config_data {
2203-
(struct $name:ident {
2209+
// modname is for the tests
2210+
($modname:ident: struct $name:ident {
22042211
$(
22052212
$(#[doc=$doc:literal])*
22062213
$field:ident $(| $alias:ident)*: $ty:ty = $default:expr,
22072214
)*
2208-
},
2209-
struct $name2:ident {
2210-
$(
2211-
$(#[doc=$doc2:literal])*
2212-
$field2:ident $(| $alias2:ident)*: $ty2:ty = $default2:expr,
2213-
)*
2214-
},
2215-
struct $name3:ident {
2216-
$(
2217-
$(#[doc=$doc3:literal])*
2218-
$field3:ident $(| $alias3:ident)*: $ty3:ty = $default3:expr,
2219-
)*
2220-
}
2221-
) => {
2215+
}) => {
22222216
#[allow(non_snake_case)]
2223-
#[derive(Debug, Clone)]
2217+
#[derive(Debug, Clone, Serialize)]
22242218
struct $name { $($field: $ty,)* }
22252219
impl $name {
2226-
fn from_json(mut json: serde_json::Value, error_sink: &mut Vec<(String, serde_json::Error)>) -> $name {
2220+
#[allow(unused)]
2221+
fn from_json(json: &mut serde_json::Value, error_sink: &mut Vec<(String, serde_json::Error)>) -> $name {
22272222
$name {$(
22282223
$field: get_field(
2229-
&mut json,
2224+
json,
22302225
error_sink,
22312226
stringify!($field),
22322227
None$(.or(Some(stringify!($alias))))*,
@@ -2235,158 +2230,98 @@ macro_rules! _config_data {
22352230
)*}
22362231
}
22372232

2238-
}
2239-
2240-
#[allow(non_snake_case)]
2241-
#[derive(Debug, Clone)]
2242-
struct $name2 { $($field2: $ty2,)* }
2243-
impl $name2 {
2244-
fn from_json(mut json: serde_json::Value, error_sink: &mut Vec<(String, serde_json::Error)>) -> $name2 {
2245-
$name2 {$(
2246-
$field2: get_field(
2247-
&mut json,
2248-
error_sink,
2249-
stringify!($field2),
2250-
None$(.or(Some(stringify!($alias2))))*,
2251-
{ let default_: $ty2 = $default2; default_ },
2252-
),
2253-
)*}
2254-
}
2255-
}
2256-
2257-
#[allow(non_snake_case)]
2258-
#[derive(Debug, Clone)]
2259-
struct $name3 { $($field3: $ty3,)* }
2260-
impl $name3 {
2261-
fn from_json(mut json: serde_json::Value, error_sink: &mut Vec<(String, serde_json::Error)>) -> $name3 {
2262-
$name3 {$(
2263-
$field3: get_field(
2264-
&mut json,
2265-
error_sink,
2266-
stringify!($field3),
2267-
None$(.or(Some(stringify!($alias3))))*,
2268-
{ let default_: $ty3 = $default3; default_ },
2269-
),
2270-
)*}
2271-
}
2272-
}
2273-
2274-
#[allow(non_snake_case)]
2275-
#[derive(Debug, Clone, Deserialize, Serialize)]
2276-
struct ConfigData {
2277-
$($field: $ty,)*
2278-
$($field2: $ty2,)*
2279-
$($field3: $ty3,)*
2280-
}
2281-
2282-
impl ConfigData {
2283-
2284-
fn from_toml(mut toml: toml::Table , error_sink: &mut Vec<(String, toml::de::Error)>) -> ConfigData {
2285-
ConfigData {$(
2233+
#[allow(unused)]
2234+
fn from_toml(toml: &mut toml::Table , error_sink: &mut Vec<(String, toml::de::Error)>) -> $name {
2235+
$name {$(
22862236
$field: get_field_toml::<$ty>(
2287-
&mut toml,
2237+
toml,
22882238
error_sink,
22892239
stringify!($field),
22902240
None$(.or(Some(stringify!($alias))))*,
22912241
{ let default_: $ty = $default; default_ },
22922242
),
2293-
)*
2294-
$(
2295-
$field2: get_field_toml::<$ty2>(
2296-
&mut toml,
2297-
error_sink,
2298-
stringify!($field2),
2299-
None$(.or(Some(stringify!($alias2))))*,
2300-
{ let default_: $ty2 = $default2; default_ },
2301-
),
2302-
)*
2303-
$(
2304-
$field3: get_field_toml::<$ty3>(
2305-
&mut toml,
2306-
error_sink,
2307-
stringify!($field3),
2308-
None$(.or(Some(stringify!($alias3))))*,
2309-
{ let default_: $ty3 = $default3; default_ },
2310-
),
23112243
)*}
23122244
}
23132245

2314-
fn from_json(mut json: serde_json::Value, error_sink: &mut Vec<(String, serde_json::Error)>) -> ConfigData {
2315-
ConfigData {$(
2316-
$field: get_field::<$ty>(
2317-
&mut json,
2318-
error_sink,
2319-
stringify!($field),
2320-
None$(.or(Some(stringify!($alias))))*,
2321-
{ let default_: $ty = $default; default_ },
2322-
),
2323-
)*
2324-
$(
2325-
$field2: get_field::<$ty2>(
2326-
&mut json,
2327-
error_sink,
2328-
stringify!($field2),
2329-
None$(.or(Some(stringify!($alias2))))*,
2330-
{ let default_: $ty2 = $default2; default_ },
2331-
),
2332-
)*
2333-
$(
2334-
$field3: get_field::<$ty3>(
2335-
&mut json,
2336-
error_sink,
2337-
stringify!($field3),
2338-
None$(.or(Some(stringify!($alias3))))*,
2339-
{ let default_: $ty3 = $default3; default_ },
2340-
),
2341-
)*}
2342-
}
2343-
2344-
fn json_schema() -> serde_json::Value {
2345-
schema(&[
2246+
fn schema_fields(sink: &mut Vec<SchemaField>) {
2247+
sink.extend_from_slice(&[
23462248
$({
23472249
let field = stringify!($field);
23482250
let ty = stringify!($ty);
23492251

2350-
(field, ty, &[$($doc),*], serde_json::to_string(&{ let default_: $ty = $default; default_ }).unwrap().as_str())
2351-
},)*
2352-
$({
2353-
let field = stringify!($field2);
2354-
let ty = stringify!($ty2);
2355-
2356-
(field, ty, &[$($doc2),*], serde_json::to_string(&{ let default_: $ty2 = $default2; default_ }).unwrap().as_str())
2357-
},)*
2358-
$({
2359-
let field = stringify!($field3);
2360-
let ty = stringify!($ty3);
2361-
2362-
(field, ty, &[$($doc3),*], serde_json::to_string(&{ let default_: $ty3 = $default3; default_ }).unwrap().as_str())
2363-
},)*
2364-
])
2365-
}
2366-
2367-
#[cfg(test)]
2368-
fn manual() -> String {
2369-
manual(&[
2370-
$({
2371-
let field = stringify!($field3);
2372-
let ty = stringify!($ty3);
2373-
2374-
(field, ty, &[$($doc3),*], $default3 as $ty3)
2252+
(
2253+
field,
2254+
ty,
2255+
&[$($doc),*],
2256+
serde_json::to_string(&{ let default_: $ty = $default; default_ }).unwrap(),
2257+
)
23752258
},)*
23762259
])
23772260
}
23782261
}
23792262

2380-
#[test]
2381-
fn fields_are_sorted() {
2382-
[$(stringify!($field)),*].windows(2).for_each(|w| assert!(w[0] <= w[1], "{} <= {} does not hold", w[0], w[1]));
2383-
[$(stringify!($field2)),*].windows(2).for_each(|w| assert!(w[0] <= w[1], "{} <= {} does not hold", w[0], w[1]));
2384-
// [$(stringify!($field3)),*].windows(2).for_each(|w| assert!(w[0] <= w[1], "{} <= {} does not hold", w[0], w[1]));
2263+
mod $modname {
2264+
#[test]
2265+
fn fields_are_sorted() {
2266+
let field_names: &'static [&'static str] = &[$(stringify!($field)),*];
2267+
field_names.windows(2).for_each(|w| assert!(w[0] <= w[1], "{} <= {} does not hold", w[0], w[1]));
2268+
}
23852269
}
23862270
};
23872271
}
23882272
use _config_data as config_data;
23892273

2274+
#[derive(Debug, Clone, Serialize)]
2275+
struct ConfigData {
2276+
#[serde(flatten)]
2277+
global: GlobalConfigData,
2278+
#[serde(flatten)]
2279+
local: LocalConfigData,
2280+
#[serde(flatten)]
2281+
client: ClientConfigData,
2282+
}
2283+
2284+
impl ConfigData {
2285+
fn from_json(
2286+
mut json: serde_json::Value,
2287+
error_sink: &mut Vec<(String, serde_json::Error)>,
2288+
) -> ConfigData {
2289+
ConfigData {
2290+
global: GlobalConfigData::from_json(&mut json, error_sink),
2291+
local: LocalConfigData::from_json(&mut json, error_sink),
2292+
client: ClientConfigData::from_json(&mut json, error_sink),
2293+
}
2294+
}
2295+
2296+
fn from_toml(
2297+
mut toml: toml::Table,
2298+
error_sink: &mut Vec<(String, toml::de::Error)>,
2299+
) -> ConfigData {
2300+
ConfigData {
2301+
global: GlobalConfigData::from_toml(&mut toml, error_sink),
2302+
local: LocalConfigData::from_toml(&mut toml, error_sink),
2303+
client: ClientConfigData::from_toml(&mut toml, error_sink),
2304+
}
2305+
}
2306+
2307+
fn schema_fields() -> Vec<SchemaField> {
2308+
let mut fields = Vec::new();
2309+
GlobalConfigData::schema_fields(&mut fields);
2310+
LocalConfigData::schema_fields(&mut fields);
2311+
ClientConfigData::schema_fields(&mut fields);
2312+
fields
2313+
}
2314+
2315+
fn json_schema() -> serde_json::Value {
2316+
schema(&Self::schema_fields())
2317+
}
2318+
2319+
#[cfg(test)]
2320+
fn manual() -> String {
2321+
manual(&Self::schema_fields())
2322+
}
2323+
}
2324+
23902325
fn get_field_toml<T: DeserializeOwned>(
23912326
val: &toml::Table,
23922327
error_sink: &mut Vec<(String, toml::de::Error)>,
@@ -2454,7 +2389,9 @@ fn get_field<T: DeserializeOwned>(
24542389
.unwrap_or(default)
24552390
}
24562391

2457-
fn schema(fields: &[(&'static str, &'static str, &[&str], &str)]) -> serde_json::Value {
2392+
type SchemaField = (&'static str, &'static str, &'static [&'static str], String);
2393+
2394+
fn schema(fields: &[SchemaField]) -> serde_json::Value {
24582395
let map = fields
24592396
.iter()
24602397
.map(|(field, ty, doc, default)| {
@@ -2815,7 +2752,7 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
28152752
}
28162753

28172754
#[cfg(test)]
2818-
fn manual(fields: &[(&'static str, &'static str, &[&str], &str)]) -> String {
2755+
fn manual(fields: &[SchemaField]) -> String {
28192756
fields
28202757
.iter()
28212758
.map(|(field, _ty, doc, default)| {

0 commit comments

Comments
 (0)