systemprompt-ai 0.1.21

Core AI module for systemprompt.io
Documentation
use serde_json::Value;
use std::collections::HashMap;

#[derive(Debug, Clone)]
pub struct DiscriminatedUnion {
    pub discriminator_field: String,
    pub discriminator_values: Vec<String>,
    pub variants: HashMap<String, Value>,
    pub base_properties: Value,
}

impl DiscriminatedUnion {
    pub fn detect(schema: &Value) -> Option<Self> {
        let obj = schema.as_object()?;
        let all_of = obj.get("allOf")?.as_array()?;

        let mut discriminator_field: Option<String> = None;
        let mut variants = HashMap::new();
        let mut discriminator_values = Vec::new();

        for variant_schema in all_of {
            let variant_obj = variant_schema.as_object()?;
            let if_clause = variant_obj.get("if")?;
            let then_clause = variant_obj.get("then")?;

            let if_obj = if_clause.as_object()?;
            let if_props = if_obj.get("properties")?.as_object()?;

            let (field_name, field_value) = if_props.iter().next()?;

            if discriminator_field.is_none() {
                discriminator_field = Some(field_name.clone());
            } else if discriminator_field.as_ref() != Some(field_name) {
                return None;
            }

            let const_value = field_value.get("const")?.as_str()?;
            discriminator_values.push(const_value.to_string());
            variants.insert(const_value.to_string(), then_clause.clone());
        }

        let base_properties = obj
            .get("properties")
            .cloned()
            .unwrap_or(serde_json::json!({}));

        Some(Self {
            discriminator_field: discriminator_field?,
            discriminator_values,
            variants,
            base_properties,
        })
    }
}