openai_tools/common/
parameters.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::collections::HashMap;
4
5pub type Name = String;
6
7#[derive(Debug, Clone, Default, Deserialize, Serialize)]
8pub struct ParameterProp {
9    #[serde(rename = "type")]
10    pub type_name: String,
11    #[serde(skip_serializing_if = "Option::is_none")]
12    pub description: Option<String>,
13    #[serde(rename = "enum", skip_serializing_if = "Option::is_none")]
14    pub enum_values: Option<Vec<String>>,
15}
16
17impl ParameterProp {
18    pub fn string<U: AsRef<str>>(description: U) -> Self {
19        Self { type_name: "string".to_string(), description: Some(description.as_ref().to_string()), ..Default::default() }
20    }
21    pub fn number<U: AsRef<str>>(description: U) -> Self {
22        Self { type_name: "number".to_string(), description: Some(description.as_ref().to_string()), ..Default::default() }
23    }
24    pub fn boolean<U: AsRef<str>>(description: U) -> Self {
25        Self { type_name: "boolean".to_string(), description: Some(description.as_ref().to_string()), ..Default::default() }
26    }
27    pub fn integer<U: AsRef<str>>(description: U) -> Self {
28        Self { type_name: "integer".to_string(), description: Some(description.as_ref().to_string()), ..Default::default() }
29    }
30}
31
32impl From<Value> for ParameterProp {
33    fn from(value: Value) -> Self {
34        let props = value.as_object().unwrap();
35        Self {
36            type_name: props.get("type").and_then(Value::as_str).unwrap_or_default().to_string(),
37            description: props.get("description").and_then(Value::as_str).map(|s| s.to_string()),
38            enum_values: props.get("enum").and_then(Value::as_array).map(|arr| arr.iter().filter_map(Value::as_str).map(|s| s.to_string()).collect()),
39        }
40    }
41}
42
43impl From<ParameterProp> for Value {
44    fn from(prop: ParameterProp) -> Self {
45        let mut map = serde_json::Map::new();
46        map.insert("type".to_string(), Value::String(prop.type_name));
47        if let Some(desc) = prop.description {
48            map.insert("description".to_string(), Value::String(desc));
49        }
50        if let Some(enum_values) = prop.enum_values {
51            map.insert("enum".to_string(), Value::Array(enum_values.into_iter().map(Value::String).collect()));
52        }
53        Value::Object(map)
54    }
55}
56
57#[derive(Debug, Clone, Default, Deserialize, Serialize)]
58pub struct Parameters {
59    #[serde(rename = "type")]
60    pub type_name: String,
61    pub properties: HashMap<Name, ParameterProp>,
62    #[serde(skip_serializing_if = "Option::is_none")]
63    pub required: Option<Vec<Name>>,
64    #[serde(rename = "additionalProperties", skip_serializing_if = "Option::is_none")]
65    pub additional_properties: Option<bool>,
66}
67
68impl Parameters {
69    pub fn new<T: AsRef<str>>(properties: Vec<(T, ParameterProp)>, additional_properties: Option<bool>) -> Self {
70        let props = properties.iter().map(|(k, v)| (k.as_ref().to_string(), v.clone())).collect::<HashMap<String, ParameterProp>>();
71        let required = properties.iter().map(|(k, _)| k.as_ref().to_string()).collect::<Vec<_>>();
72        Self { type_name: "object".into(), properties: props, required: Some(required), additional_properties }
73    }
74}