use serde::Deserialize;
use serde::Serialize;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PromptResponse {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub status: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub message_id: Option<String>,
#[serde(flatten)]
pub extra: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CommandResponse {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub status: Option<String>,
#[serde(flatten)]
pub extra: serde_json::Value,
}
pub type ShellResponse = CommandResponse;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FindResponse {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub results: Option<serde_json::Value>,
#[serde(flatten)]
pub extra: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpActionResponse {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ok: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub connected: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(flatten)]
pub extra: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LspServerStatus {
pub id: String,
pub name: String,
pub root: String,
pub status: LspConnectionStatus,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum LspConnectionStatus {
Connected,
Error,
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FormatterInfo {
pub name: String,
#[serde(default)]
pub extensions: Vec<String>,
#[serde(default)]
pub enabled: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenApiDoc {
#[serde(flatten)]
pub spec: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UpdatePartResponse {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub part: Option<crate::types::message::Part>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub delta: Option<String>,
#[serde(flatten)]
pub extra: serde_json::Value,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_prompt_response_deserialize() {
let json = r#"{"status":"ok","messageId":"msg-123"}"#;
let resp: PromptResponse = serde_json::from_str(json).unwrap();
assert_eq!(resp.status, Some("ok".to_string()));
assert_eq!(resp.message_id, Some("msg-123".to_string()));
}
#[test]
fn test_prompt_response_with_extra() {
let json = r#"{"status":"ok","messageId":"msg-123","futureField":"value"}"#;
let resp: PromptResponse = serde_json::from_str(json).unwrap();
assert_eq!(resp.extra.get("futureField").unwrap(), "value");
}
#[test]
fn test_command_response_deserialize() {
let json = r#"{"status":"executed"}"#;
let resp: CommandResponse = serde_json::from_str(json).unwrap();
assert_eq!(resp.status, Some("executed".to_string()));
}
#[test]
fn test_find_response_deserialize() {
let json = r#"{"results":[{"file":"test.rs","line":10}]}"#;
let resp: FindResponse = serde_json::from_str(json).unwrap();
assert!(resp.results.is_some());
}
#[test]
fn test_mcp_action_response_deserialize() {
let json = r#"{"ok":true,"connected":true,"name":"my-server"}"#;
let resp: McpActionResponse = serde_json::from_str(json).unwrap();
assert_eq!(resp.ok, Some(true));
assert_eq!(resp.connected, Some(true));
assert_eq!(resp.name, Some("my-server".to_string()));
}
#[test]
fn test_lsp_server_status_deserialize() {
let json = r#"{"id":"ra-1","name":"rust-analyzer","root":"./","status":"connected"}"#;
let resp: LspServerStatus = serde_json::from_str(json).unwrap();
assert_eq!(resp.id, "ra-1");
assert_eq!(resp.name, "rust-analyzer");
assert_eq!(resp.status, LspConnectionStatus::Connected);
}
#[test]
fn test_lsp_server_status_array_deserialize() {
let json = r#"[{"id":"ra-1","name":"rust-analyzer","root":"./","status":"connected"}]"#;
let resp: Vec<LspServerStatus> = serde_json::from_str(json).unwrap();
assert_eq!(resp.len(), 1);
assert_eq!(resp[0].name, "rust-analyzer");
}
#[test]
fn test_formatter_info_deserialize() {
let json = r#"{"name":"rustfmt","extensions":[".rs"],"enabled":true}"#;
let resp: FormatterInfo = serde_json::from_str(json).unwrap();
assert_eq!(resp.name, "rustfmt");
assert!(resp.enabled);
assert_eq!(resp.extensions, vec![".rs"]);
}
#[test]
fn test_formatter_info_array_deserialize() {
let json = r#"[{"name":"rustfmt","extensions":[".rs"],"enabled":true}]"#;
let resp: Vec<FormatterInfo> = serde_json::from_str(json).unwrap();
assert_eq!(resp.len(), 1);
assert_eq!(resp[0].name, "rustfmt");
}
#[test]
fn test_update_part_response_deserialize() {
let json = r#"{"delta":"Hello"}"#;
let resp: UpdatePartResponse = serde_json::from_str(json).unwrap();
assert_eq!(resp.delta, Some("Hello".to_string()));
}
}