1use anyhow::Result;
2use serde_json::Value;
3
4use crate::patterns::migrate_language_setting;
5
6pub fn restore_code_actions_on_format(value: &mut Value) -> Result<()> {
7 migrate_language_setting(value, restore_code_actions_on_format_inner)
8}
9
10fn restore_code_actions_on_format_inner(value: &mut Value, path: &[&str]) -> Result<()> {
11 let Some(obj) = value.as_object_mut() else {
12 return Ok(());
13 };
14 let code_actions_on_format = obj
15 .get("code_actions_on_format")
16 .cloned()
17 .unwrap_or_else(|| Value::Object(Default::default()));
18
19 fn fmt_path(path: &[&str], key: &str) -> String {
20 let mut path = path.to_vec();
21 path.push(key);
22 path.join(".")
23 }
24
25 let Some(mut code_actions_map) = code_actions_on_format.as_object().cloned() else {
26 anyhow::bail!(
27 r#"The `code_actions_on_format` is in an invalid state and cannot be migrated at {}. Please ensure the code_actions_on_format setting is a Map<String, bool>"#,
28 fmt_path(path, "code_actions_on_format"),
29 );
30 };
31
32 let Some(formatter) = obj.get("formatter") else {
33 return Ok(());
34 };
35 let formatter_array = if let Some(array) = formatter.as_array() {
36 array.clone()
37 } else {
38 vec![formatter.clone()]
39 };
40 let mut code_action_formatters = Vec::new();
41 for formatter in formatter_array {
42 let Some(code_action) = formatter.get("code_action") else {
43 return Ok(());
44 };
45 let Some(code_action_name) = code_action.as_str() else {
46 anyhow::bail!(
47 r#"The `code_action` is in an invalid state and cannot be migrated at {}. Please ensure the code_action setting is a String"#,
48 fmt_path(path, "formatter"),
49 );
50 };
51 code_action_formatters.push(code_action_name.to_string());
52 }
53
54 code_actions_map.extend(
55 code_action_formatters
56 .into_iter()
57 .rev()
58 .map(|code_action| (code_action, Value::Bool(true))),
59 );
60
61 obj.remove("formatter");
62 obj.insert(
63 "code_actions_on_format".into(),
64 Value::Object(code_actions_map),
65 );
66
67 Ok(())
68}