use super::types::RecoverableError;
pub fn require_param<'a>(
input: &'a serde_json::Value,
name: &str,
) -> anyhow::Result<&'a serde_json::Value> {
input.get(name).ok_or_else(|| {
RecoverableError::with_hint(
format!("missing '{}' parameter", name),
format!("Add the required '{}' parameter to the tool call.", name),
)
.into()
})
}
pub fn require_param_or<'a>(
input: &'a serde_json::Value,
name: &str,
aliases: &[&str],
) -> anyhow::Result<&'a serde_json::Value> {
if let Some(v) = input.get(name) {
return Ok(v);
}
for alias in aliases {
if let Some(v) = input.get(*alias) {
return Ok(v);
}
}
Err(RecoverableError::with_hint(
format!("missing '{}' parameter", name),
format!("Add the required '{}' parameter to the tool call.", name),
)
.into())
}
pub fn require_str_param_or<'a>(
input: &'a serde_json::Value,
name: &str,
aliases: &[&str],
) -> anyhow::Result<&'a str> {
require_param_or(input, name, aliases)?
.as_str()
.ok_or_else(|| {
RecoverableError::with_hint(
format!("'{}' must be a string", name),
format!("Provide '{}' as a string value.", name),
)
.into()
})
}
pub fn require_str_param<'a>(input: &'a serde_json::Value, name: &str) -> anyhow::Result<&'a str> {
require_param(input, name)?.as_str().ok_or_else(|| {
RecoverableError::with_hint(
format!("'{}' must be a string", name),
format!("Provide '{}' as a string value.", name),
)
.into()
})
}
pub fn require_u64_param(input: &serde_json::Value, name: &str) -> anyhow::Result<u64> {
let val = require_param(input, name)?;
if let Some(n) = val.as_u64() {
return Ok(n);
}
if let Some(s) = val.as_str() {
if let Ok(n) = s.trim().parse::<u64>() {
return Ok(n);
}
}
Err(RecoverableError::with_hint(
format!("'{}' must be a non-negative integer", name),
format!("Provide '{}' as a non-negative integer.", name),
)
.into())
}
pub fn parse_bool_param(val: &serde_json::Value) -> bool {
val.as_bool()
.or_else(|| val.as_str().and_then(|s| s.parse::<bool>().ok()))
.unwrap_or(false)
}
pub fn optional_bool_param(input: &serde_json::Value, name: &str) -> Option<bool> {
let val = input.get(name)?;
if val.is_null() {
return None;
}
val.as_bool()
.or_else(|| val.as_str().and_then(|s| s.parse::<bool>().ok()))
}
pub fn optional_u64_param(input: &serde_json::Value, name: &str) -> Option<u64> {
let val = input.get(name)?;
if val.is_null() {
return None;
}
val.as_u64()
.or_else(|| val.as_str().and_then(|s| s.trim().parse::<u64>().ok()))
}
pub fn optional_i64_param(input: &serde_json::Value, name: &str) -> Option<i64> {
let val = input.get(name)?;
if val.is_null() {
return None;
}
val.as_i64()
.or_else(|| val.as_str().and_then(|s| s.trim().parse::<i64>().ok()))
}
pub fn optional_f64_param(input: &serde_json::Value, name: &str) -> Option<f64> {
let val = input.get(name)?;
if val.is_null() {
return None;
}
val.as_f64()
.or_else(|| val.as_str().and_then(|s| s.trim().parse::<f64>().ok()))
}
pub fn optional_array_param(
input: &serde_json::Value,
name: &str,
) -> Option<Vec<serde_json::Value>> {
let val = input.get(name)?;
if val.is_null() {
return None;
}
if let Some(arr) = val.as_array() {
return Some(arr.clone());
}
if let Some(s) = val.as_str() {
if let Ok(serde_json::Value::Array(arr)) = serde_json::from_str(s) {
return Some(arr);
}
}
None
}