use crate::{
ElicitCommunicator, ElicitError, ElicitErrorKind, ElicitIntrospect, ElicitResult, Elicitation,
ElicitationPattern, PatternDetails, Prompt, Select, TypeMetadata, VariantMetadata, mcp,
};
crate::default_style!(reqwest::Method => MethodStyle);
impl Select for reqwest::Method {
fn options() -> Vec<Self> {
vec![
reqwest::Method::GET,
reqwest::Method::POST,
reqwest::Method::PUT,
reqwest::Method::DELETE,
reqwest::Method::PATCH,
reqwest::Method::HEAD,
reqwest::Method::OPTIONS,
reqwest::Method::CONNECT,
reqwest::Method::TRACE,
]
}
fn labels() -> Vec<String> {
vec![
"GET".to_string(),
"POST".to_string(),
"PUT".to_string(),
"DELETE".to_string(),
"PATCH".to_string(),
"HEAD".to_string(),
"OPTIONS".to_string(),
"CONNECT".to_string(),
"TRACE".to_string(),
]
}
fn from_label(label: &str) -> Option<Self> {
match label {
"GET" => Some(reqwest::Method::GET),
"POST" => Some(reqwest::Method::POST),
"PUT" => Some(reqwest::Method::PUT),
"DELETE" => Some(reqwest::Method::DELETE),
"PATCH" => Some(reqwest::Method::PATCH),
"HEAD" => Some(reqwest::Method::HEAD),
"OPTIONS" => Some(reqwest::Method::OPTIONS),
"CONNECT" => Some(reqwest::Method::CONNECT),
"TRACE" => Some(reqwest::Method::TRACE),
_ => None,
}
}
}
impl Prompt for reqwest::Method {
fn prompt() -> Option<&'static str> {
Some("Select HTTP method:")
}
}
impl Elicitation for reqwest::Method {
type Style = MethodStyle;
#[tracing::instrument(skip(communicator))]
async fn elicit<C: ElicitCommunicator>(communicator: &C) -> ElicitResult<Self> {
tracing::debug!("Eliciting reqwest::Method");
let params = mcp::select_params(
Self::prompt().unwrap_or("Select HTTP method:"),
&Self::labels(),
);
let result = communicator
.call_tool(
rmcp::model::CallToolRequestParams::new(mcp::tool_names::elicit_select())
.with_arguments(params),
)
.await?;
let value = mcp::extract_value(result)?;
let label = mcp::parse_string(value)?;
Self::from_label(&label).ok_or_else(|| {
ElicitError::new(ElicitErrorKind::ParseError(format!(
"Invalid HTTP method: {label}"
)))
})
}
fn kani_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::kani_select_wrapper("reqwest::Method", "GET")
}
fn verus_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::verus_select_wrapper("reqwest::Method", "GET")
}
fn creusot_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::creusot_select_wrapper("reqwest::Method", "GET")
}
}
impl ElicitIntrospect for reqwest::Method {
fn pattern() -> ElicitationPattern {
ElicitationPattern::Select
}
fn metadata() -> TypeMetadata {
TypeMetadata {
type_name: "reqwest::Method",
description: Self::prompt(),
details: PatternDetails::Select {
variants: Self::labels()
.into_iter()
.map(|label| VariantMetadata {
label,
fields: vec![],
})
.collect(),
},
}
}
}