use serde::{Deserialize, Serialize};
use crate::envelope::Envelope;
use crate::io::ToolSchema;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "lowercase")]
#[non_exhaustive]
pub enum ExecutionHint {
#[default]
Backend,
Ui,
Hybrid,
#[serde(other)]
Unknown,
}
impl Serialize for ExecutionHint {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self.effective() {
Self::Backend | Self::Unknown => serializer.serialize_str("backend"),
Self::Ui => serializer.serialize_str("ui"),
Self::Hybrid => serializer.serialize_str("hybrid"),
}
}
}
impl ExecutionHint {
#[must_use]
pub const fn effective(self) -> Self {
match self {
Self::Unknown => Self::Backend,
other => other,
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Annotations {
#[serde(skip_serializing_if = "String::is_empty", default)]
pub title: String,
#[serde(skip_serializing_if = "String::is_empty", default)]
pub category: String,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub tags: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub idempotent_hint: Option<bool>,
#[serde(default)]
pub execution_hint: ExecutionHint,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Definition {
pub name: String,
pub description: String,
pub input_schema: ToolSchema,
#[serde(skip_serializing_if = "Option::is_none")]
pub output_schema: Option<ToolSchema>,
#[serde(default)]
pub annotations: Annotations,
#[serde(default)]
pub envelope: Envelope,
}