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 if formatter_array.is_empty() {
41 return Ok(());
42 }
43 let mut code_action_formatters = Vec::new();
44 for formatter in formatter_array {
45 let Some(code_action) = formatter.get("code_action") else {
46 return Ok(());
47 };
48 let Some(code_action_name) = code_action.as_str() else {
49 anyhow::bail!(
50 r#"The `code_action` is in an invalid state and cannot be migrated at {}. Please ensure the code_action setting is a String"#,
51 fmt_path(path, "formatter"),
52 );
53 };
54 code_action_formatters.push(code_action_name.to_string());
55 }
56
57 code_actions_map.extend(
58 code_action_formatters
59 .into_iter()
60 .rev()
61 .map(|code_action| (code_action, Value::Bool(true))),
62 );
63
64 obj.insert("formatter".to_string(), Value::Array(vec![]));
65 obj.insert(
66 "code_actions_on_format".into(),
67 Value::Object(code_actions_map),
68 );
69
70 Ok(())
71}