use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum Reference {
#[serde(rename = "ref/resource")]
Resource {
uri: String,
},
#[serde(rename = "ref/prompt")]
Prompt {
name: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ArgumentInfo {
pub name: String,
pub value: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompletionRequest {
pub ref_: Reference,
pub argument: ArgumentInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompletionResult(pub Vec<CompletionResultItem>);
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompletionResultItem {
pub text: String,
pub finish_reason: Option<String>,
}
pub trait CompletionCallback: Send + Sync {
fn complete(&self, request: CompletionRequest) -> anyhow::Result<CompletionResult>;
}
pub(crate) struct RegisteredCompletion {
#[allow(dead_code)]
pub callback: Box<dyn CompletionCallback>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_resource_reference() {
let reference = Reference::Resource {
uri: "file:///path/to/file".to_string(),
};
let json = serde_json::to_string(&reference).unwrap();
let deserialized: Reference = serde_json::from_str(&json).unwrap();
match deserialized {
Reference::Resource { uri } => {
assert_eq!(uri, "file:///path/to/file");
}
_ => panic!("Wrong reference type"),
}
}
#[test]
fn test_prompt_reference() {
let reference = Reference::Prompt {
name: "test-prompt".to_string(),
};
let json = serde_json::to_string(&reference).unwrap();
let deserialized: Reference = serde_json::from_str(&json).unwrap();
match deserialized {
Reference::Prompt { name } => {
assert_eq!(name, "test-prompt");
}
_ => panic!("Wrong reference type"),
}
}
#[test]
fn test_completion_request() {
let request = CompletionRequest {
ref_: Reference::Resource {
uri: "file:///path/to/file".to_string(),
},
argument: ArgumentInfo {
name: "path".to_string(),
value: "/path/to".to_string(),
},
};
let json = serde_json::to_string(&request).unwrap();
let deserialized: CompletionRequest = serde_json::from_str(&json).unwrap();
assert_eq!(
match deserialized.ref_ {
Reference::Resource { uri } => uri,
_ => panic!("Wrong reference type"),
},
"file:///path/to/file"
);
assert_eq!(deserialized.argument.name, "path");
assert_eq!(deserialized.argument.value, "/path/to");
}
}