1use crate::patterns::migrate_language_setting;
2use anyhow::Result;
3use serde_json::Value;
4
5pub fn flatten_code_actions_formatters(value: &mut Value) -> Result<()> {
6 migrate_language_setting(value, |value, _path| {
7 let Some(obj) = value.as_object_mut() else {
8 return Ok(());
9 };
10 for key in ["formatter", "format_on_save"] {
11 let Some(formatter) = obj.get_mut(key) else {
12 continue;
13 };
14 let new_formatter = match formatter {
15 Value::Array(arr) => {
16 let mut new_arr = Vec::new();
17 let mut found_code_actions = false;
18 for item in arr {
19 let Some(obj) = item.as_object() else {
20 new_arr.push(item.clone());
21 continue;
22 };
23 let code_actions_obj = obj
24 .get("code_actions")
25 .and_then(|code_actions| code_actions.as_object());
26 let Some(code_actions) = code_actions_obj else {
27 new_arr.push(item.clone());
28 continue;
29 };
30 found_code_actions = true;
31 for (name, enabled) in code_actions {
32 if !enabled.as_bool().unwrap_or(true) {
33 continue;
34 }
35 new_arr.push(serde_json::json!({
36 "code_action": name
37 }));
38 }
39 }
40 if !found_code_actions {
41 continue;
42 }
43 Value::Array(new_arr)
44 }
45 Value::Object(obj) => {
46 let mut new_arr = Vec::new();
47 let code_actions_obj = obj
48 .get("code_actions")
49 .and_then(|code_actions| code_actions.as_object());
50 let Some(code_actions) = code_actions_obj else {
51 continue;
52 };
53 for (name, enabled) in code_actions {
54 if !enabled.as_bool().unwrap_or(true) {
55 continue;
56 }
57 new_arr.push(serde_json::json!({
58 "code_action": name
59 }));
60 }
61 if new_arr.len() == 1 {
62 new_arr.pop().unwrap()
63 } else {
64 Value::Array(new_arr)
65 }
66 }
67 _ => continue,
68 };
69
70 obj.insert(key.to_string(), new_formatter);
71 }
72 return Ok(());
73 })
74}