use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "mode")]
pub enum ElicitRequestParams {
#[serde(rename = "form", rename_all = "camelCase")]
Form {
message: String,
requested_schema: Value,
},
#[serde(rename = "url", rename_all = "camelCase")]
Url {
message: String,
elicitation_id: String,
url: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ElicitResult {
pub action: ElicitAction,
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum ElicitAction {
Accept,
Decline,
Cancel,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ElicitationCompleteNotification {
pub elicitation_id: String,
pub result: ElicitResult,
}
#[deprecated(since = "2.0.0", note = "Use ElicitRequestParams instead")]
pub type ElicitInputRequest = ElicitRequestParams;
#[deprecated(since = "2.0.0", note = "Use ElicitResult instead")]
pub type ElicitInputResponse = ElicitResult;
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn elicit_request_form_mode_serialization() {
let params = ElicitRequestParams::Form {
message: "Enter your name".to_string(),
requested_schema: json!({
"type": "object",
"properties": {
"name": { "type": "string" }
}
}),
};
let json = serde_json::to_value(¶ms).unwrap();
assert_eq!(json["mode"], "form");
assert_eq!(json["message"], "Enter your name");
assert!(json["requestedSchema"]["properties"]["name"].is_object());
let roundtrip: ElicitRequestParams = serde_json::from_value(json).unwrap();
match roundtrip {
ElicitRequestParams::Form { message, .. } => {
assert_eq!(message, "Enter your name");
},
ElicitRequestParams::Url { .. } => panic!("Expected Form variant"),
}
}
#[test]
fn elicit_request_url_mode_serialization() {
let params = ElicitRequestParams::Url {
message: "Please authenticate".to_string(),
elicitation_id: "auth-123".to_string(),
url: "https://example.com/auth".to_string(),
};
let json = serde_json::to_value(¶ms).unwrap();
assert_eq!(json["mode"], "url");
assert_eq!(json["message"], "Please authenticate");
assert_eq!(json["elicitationId"], "auth-123");
assert_eq!(json["url"], "https://example.com/auth");
let roundtrip: ElicitRequestParams = serde_json::from_value(json).unwrap();
match roundtrip {
ElicitRequestParams::Url { elicitation_id, .. } => {
assert_eq!(elicitation_id, "auth-123");
},
ElicitRequestParams::Form { .. } => panic!("Expected Url variant"),
}
}
#[test]
fn elicit_result_accept() {
let mut content = HashMap::new();
content.insert("name".to_string(), json!("Alice"));
let result = ElicitResult {
action: ElicitAction::Accept,
content: Some(content),
};
let json = serde_json::to_value(&result).unwrap();
assert_eq!(json["action"], "accept");
assert_eq!(json["content"]["name"], "Alice");
let roundtrip: ElicitResult = serde_json::from_value(json).unwrap();
assert_eq!(roundtrip.action, ElicitAction::Accept);
assert!(roundtrip.content.is_some());
}
#[test]
fn elicit_result_decline() {
let result = ElicitResult {
action: ElicitAction::Decline,
content: None,
};
let json = serde_json::to_value(&result).unwrap();
assert_eq!(json["action"], "decline");
assert!(json.get("content").is_none());
}
#[test]
fn elicit_action_values() {
assert_eq!(
serde_json::to_value(ElicitAction::Accept).unwrap(),
"accept"
);
assert_eq!(
serde_json::to_value(ElicitAction::Decline).unwrap(),
"decline"
);
assert_eq!(
serde_json::to_value(ElicitAction::Cancel).unwrap(),
"cancel"
);
}
}