skiff_cli/session/
protocol.rs1use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum SessionMethod {
9 ListTools,
10 ListToolsLight,
11 GetTool,
12 CallTool,
13 ListResources,
14 ReadResource,
15 ListResourceTemplates,
16 ListPrompts,
17 GetPrompt,
18}
19
20impl SessionMethod {
21 pub fn as_str(self) -> &'static str {
22 match self {
23 Self::ListTools => "list_tools",
24 Self::ListToolsLight => "list_tools_light",
25 Self::GetTool => "get_tool",
26 Self::CallTool => "call_tool",
27 Self::ListResources => "list_resources",
28 Self::ReadResource => "read_resource",
29 Self::ListResourceTemplates => "list_resource_templates",
30 Self::ListPrompts => "list_prompts",
31 Self::GetPrompt => "get_prompt",
32 }
33 }
34
35 pub fn parse(s: &str) -> Option<Self> {
36 Some(match s {
37 "list_tools" => Self::ListTools,
38 "list_tools_light" => Self::ListToolsLight,
39 "get_tool" => Self::GetTool,
40 "call_tool" => Self::CallTool,
41 "list_resources" => Self::ListResources,
42 "read_resource" => Self::ReadResource,
43 "list_resource_templates" => Self::ListResourceTemplates,
44 "list_prompts" => Self::ListPrompts,
45 "get_prompt" => Self::GetPrompt,
46 _ => return None,
47 })
48 }
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct SessionRequest {
53 pub id: u64,
54 pub method: String,
55 #[serde(default)]
56 pub params: Value,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct SessionResponse {
61 pub id: u64,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub result: Option<Value>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 pub error: Option<String>,
66}
67
68impl SessionResponse {
69 pub fn ok(id: u64, result: Value) -> Self {
70 Self {
71 id,
72 result: Some(result),
73 error: None,
74 }
75 }
76
77 pub fn err(id: u64, error: impl Into<String>) -> Self {
78 Self {
79 id,
80 result: None,
81 error: Some(error.into()),
82 }
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use serde_json::json;
90
91 #[test]
92 fn roundtrip() {
93 let req = SessionRequest {
94 id: 1,
95 method: "list_tools".into(),
96 params: json!({"refresh": true}),
97 };
98 let line = serde_json::to_string(&req).unwrap();
99 let back: SessionRequest = serde_json::from_str(&line).unwrap();
100 assert_eq!(back.method, "list_tools");
101 assert_eq!(
102 SessionMethod::parse(&back.method),
103 Some(SessionMethod::ListTools)
104 );
105 }
106}