use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MainContext {
pub server_name: String,
pub server_version: String,
pub generation_date: String,
pub frontend_type: String,
pub backend_type: String,
pub has_http: bool,
pub has_stdio: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProxyContext {
pub server_name: String,
pub frontend_type: String,
pub backend_type: String,
pub tools: Vec<ToolDefinition>,
pub resources: Vec<ResourceDefinition>,
pub prompts: Vec<PromptDefinition>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolDefinition {
pub name: String,
pub description: Option<String>,
pub input_type: Option<String>,
pub output_type: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceDefinition {
pub name: String,
pub uri: String,
pub description: Option<String>,
pub mime_type: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PromptDefinition {
pub name: String,
pub description: Option<String>,
pub arguments: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TypesContext {
pub server_name: String,
pub type_definitions: Vec<TypeDefinition>,
pub tool_enums: Vec<ToolEnumVariant>,
pub resource_enums: Vec<ResourceEnumVariant>,
pub prompt_enums: Vec<PromptEnumVariant>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TypeDefinition {
pub name: String,
pub description: Option<String>,
pub rename: Option<String>,
pub fields: Vec<FieldDefinition>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FieldDefinition {
pub name: String,
pub rust_type: String,
pub optional: bool,
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolEnumVariant {
pub name: String,
pub params: Vec<ParamDefinition>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ParamDefinition {
pub name: String,
pub rust_type: String,
pub optional: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceEnumVariant {
pub name: String,
pub uri: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PromptEnumVariant {
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CargoContext {
pub package_name: String,
pub version: String,
pub server_name: String,
pub turbomcp_version: String,
pub frontend_type: String,
pub transport_features: Vec<String>,
pub additional_dependencies: Vec<Dependency>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Dependency {
pub name: String,
pub version: Option<String>,
pub spec: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_main_context_serialization() {
let context = MainContext {
server_name: "test-server".to_string(),
server_version: "1.0.0".to_string(),
generation_date: "2025-01-01".to_string(),
frontend_type: "HTTP".to_string(),
backend_type: "STDIO".to_string(),
has_http: true,
has_stdio: true,
};
let json = serde_json::to_string(&context);
assert!(json.is_ok(), "MainContext should serialize to JSON");
}
#[test]
fn test_tool_definition() {
let tool = ToolDefinition {
name: "search".to_string(),
description: Some("Search for items".to_string()),
input_type: Some("SearchInput".to_string()),
output_type: Some("SearchOutput".to_string()),
};
assert_eq!(tool.name, "search");
assert!(tool.description.is_some());
}
#[test]
fn test_type_definition() {
let type_def = TypeDefinition {
name: "SearchInput".to_string(),
description: Some("Search input parameters".to_string()),
rename: None,
fields: vec![
FieldDefinition {
name: "query".to_string(),
rust_type: "String".to_string(),
optional: false,
description: Some("Search query".to_string()),
},
FieldDefinition {
name: "limit".to_string(),
rust_type: "i64".to_string(),
optional: true,
description: Some("Result limit".to_string()),
},
],
};
assert_eq!(type_def.fields.len(), 2);
assert!(!type_def.fields[0].optional);
assert!(type_def.fields[1].optional);
}
#[test]
fn test_cargo_context() {
let context = CargoContext {
package_name: "test-proxy".to_string(),
version: "0.1.0".to_string(),
server_name: "test-server".to_string(),
turbomcp_version: "2.1.1".to_string(),
frontend_type: "HTTP".to_string(),
transport_features: vec!["http".to_string(), "stdio".to_string()],
additional_dependencies: vec![],
};
assert_eq!(context.package_name, "test-proxy");
assert_eq!(context.transport_features.len(), 2);
}
}