use std::collections::HashMap;
use serde_json::Value;
use super::parse_text_edit;
use crate::lsp::types::{CodeAction, TextEdit, WorkspaceEdit};
pub fn parse_workspace_edit(v: &Value) -> Option<WorkspaceEdit> {
if v.is_null() {
return None;
}
let mut out: HashMap<String, Vec<TextEdit>> = HashMap::new();
if let Some(changes) = v.get("changes").and_then(|c| c.as_object()) {
for (uri, edits) in changes {
if let Some(arr) = edits.as_array() {
let edits = arr.iter().filter_map(parse_text_edit).collect();
out.insert(uri.clone(), edits);
}
}
}
if let Some(doc_changes) = v.get("documentChanges").and_then(|c| c.as_array()) {
for dc in doc_changes {
if dc.get("kind").is_some() {
continue;
}
let Some(uri) = dc
.get("textDocument")
.and_then(|td| td.get("uri"))
.and_then(|v| v.as_str())
else {
continue;
};
let Some(edits) = dc.get("edits").and_then(|e| e.as_array()) else {
continue;
};
let edits: Vec<TextEdit> = edits.iter().filter_map(parse_text_edit).collect();
out.entry(uri.to_string()).or_default().extend(edits);
}
}
if out.is_empty() {
return None;
}
Some(WorkspaceEdit { changes: out })
}
pub fn parse_code_actions(v: &Value) -> Vec<CodeAction> {
let mut out = Vec::new();
let push = |out: &mut Vec<CodeAction>, item: &Value| {
let Some(title) = item.get("title").and_then(|t| t.as_str()) else {
return;
};
let edit = item.get("edit").and_then(parse_workspace_edit);
out.push(CodeAction {
title: title.to_string(),
edit,
raw: item.clone(),
source: String::new(),
});
};
if let Some(arr) = v.as_array() {
for item in arr {
push(&mut out, item);
}
} else if v.is_object() {
push(&mut out, v);
}
out
}
pub fn parse_code_action(v: &Value) -> Option<CodeAction> {
let title = v.get("title").and_then(|t| t.as_str())?.to_string();
let edit = v.get("edit").and_then(parse_workspace_edit);
Some(CodeAction {
title,
edit,
raw: v.clone(),
source: String::new(),
})
}
pub fn parse_text_edits(v: &Value) -> Vec<TextEdit> {
if v.is_null() {
return Vec::new();
}
let Some(arr) = v.as_array() else {
return Vec::new();
};
arr.iter().filter_map(parse_text_edit).collect()
}