use serde::de::{self, Deserializer};
use serde::ser::Serializer;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use super::request::Tool;
#[derive(Deserialize)]
struct CustomWire {
name: String,
#[serde(default)]
description: Option<String>,
input_schema: Value,
#[serde(default)]
strict: Option<bool>,
}
#[derive(Deserialize)]
struct ProviderWire {
#[serde(rename = "type")]
kind: String,
name: String,
#[serde(flatten)]
config: Map<String, Value>,
}
impl Serialize for Tool {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
#[derive(Serialize)]
struct Custom<'a> {
name: &'a str,
#[serde(skip_serializing_if = "Option::is_none")]
description: &'a Option<String>,
input_schema: &'a Value,
#[serde(skip_serializing_if = "Option::is_none")]
strict: &'a Option<bool>,
}
#[derive(Serialize)]
struct Provider<'a> {
#[serde(rename = "type")]
kind: &'a str,
name: &'a str,
#[serde(flatten)]
config: &'a Map<String, Value>,
}
match self {
Tool::Custom {
name,
description,
input_schema,
strict,
} => Custom {
name,
description,
input_schema,
strict,
}
.serialize(s),
Tool::Provider { kind, name, config } => Provider { kind, name, config }.serialize(s),
}
}
}
impl<'de> Deserialize<'de> for Tool {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let v = Value::deserialize(d)?;
if v.get("type").is_some() {
let w = ProviderWire::deserialize(v).map_err(de::Error::custom)?;
Ok(Tool::Provider {
kind: w.kind,
name: w.name,
config: w.config,
})
} else {
let w = CustomWire::deserialize(v).map_err(de::Error::custom)?;
Ok(Tool::Custom {
name: w.name,
description: w.description,
input_schema: w.input_schema,
strict: w.strict,
})
}
}
}