use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompletionRef {
#[serde(rename = "type")]
pub ref_type: String,
pub uri: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompletionArgument {
pub name: String,
pub value: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompletionRequest {
pub reference: CompletionRef,
pub argument: CompletionArgument,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompletionValue {
pub label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompletionResult {
pub values: Vec<CompletionValue>,
#[serde(default)]
pub total: Option<usize>,
#[serde(rename = "hasMore", default)]
pub has_more: bool,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_completion_ref_serialization() {
let ref_val = CompletionRef {
ref_type: "ref/prompt".to_string(),
uri: "prompt://code_review".to_string(),
};
let json = serde_json::to_string(&ref_val).unwrap();
assert!(json.contains("\"type\":\"ref/prompt\""));
assert!(json.contains("\"uri\":\"prompt://code_review\""));
}
#[test]
fn test_completion_argument_serialization() {
let arg = CompletionArgument {
name: "language".to_string(),
value: "ru".to_string(),
};
let json = serde_json::to_string(&arg).unwrap();
assert!(json.contains("\"name\":\"language\""));
assert!(json.contains("\"value\":\"ru\""));
}
#[test]
fn test_completion_request_serialization() {
let req = CompletionRequest {
reference: CompletionRef {
ref_type: "ref/prompt".to_string(),
uri: "prompt://code_review".to_string(),
},
argument: CompletionArgument {
name: "language".to_string(),
value: "ru".to_string(),
},
};
let json = serde_json::to_string(&req).unwrap();
assert!(json.contains("\"reference\""));
assert!(json.contains("\"argument\""));
}
#[test]
fn test_completion_value_with_description() {
let val = CompletionValue {
label: "rust".to_string(),
description: Some("Rust programming language".to_string()),
};
let json = serde_json::to_string(&val).unwrap();
assert!(json.contains("\"label\":\"rust\""));
assert!(json.contains("\"description\""));
}
#[test]
fn test_completion_value_without_description() {
let val = CompletionValue {
label: "python".to_string(),
description: None,
};
let json = serde_json::to_string(&val).unwrap();
assert!(!json.contains("description"));
}
#[test]
fn test_completion_result_deserialization() {
let json = r#"{"values":[{"label":"rust"},{"label":"ruby"}],"total":2,"hasMore":false}"#;
let result: CompletionResult = serde_json::from_str(json).unwrap();
assert_eq!(result.values.len(), 2);
assert_eq!(result.values[0].label, "rust");
assert_eq!(result.total, Some(2));
assert!(!result.has_more);
}
#[test]
fn test_completion_result_defaults() {
let json = r#"{"values":[{"label":"rust"}]}"#;
let result: CompletionResult = serde_json::from_str(json).unwrap();
assert!(result.total.is_none());
assert!(!result.has_more);
}
}