prompty 2.0.0-beta.1

Prompty is an asset class and format for LLM prompts
Documentation
// Code generated by Prompty emitter; DO NOT EDIT.

#![allow(
    unused_imports,
    dead_code,
    non_camel_case_types,
    unused_variables,
    clippy::all
)]

use super::super::context::{LoadContext, SaveContext};

/// Variant-specific data for [`ContentPart`], discriminated by `kind`.
#[derive(Debug, Clone)]
pub enum ContentPartKind {
    /// `kind` = `"text"`
    TextPart {
        /// The text content
        value: String,
    },
    /// `kind` = `"image"`
    ImagePart {
        /// URL or base64-encoded image data
        source: String,
        /// Detail level hint for the model (e.g., 'auto', 'low', 'high')
        detail: Option<String>,
        /// MIME type of the image (e.g., 'image/png')
        media_type: Option<String>,
    },
    /// `kind` = `"file"`
    FilePart {
        /// URL or base64-encoded file data
        source: String,
        /// MIME type of the file (e.g., 'application/pdf')
        media_type: Option<String>,
    },
    /// `kind` = `"audio"`
    AudioPart {
        /// URL or base64-encoded audio data
        source: String,
        /// MIME type of the audio (e.g., 'audio/wav')
        media_type: Option<String>,
    },
}

impl Default for ContentPartKind {
    fn default() -> Self {
        ContentPartKind::TextPart {
            value: String::from(""),
        }
    }
}
/// A part of a message's content. Content parts are discriminated on the `kind` field and represent the different modalities that can appear in a message.
#[derive(Debug, Clone, Default)]
pub struct ContentPart {
    /// Variant-specific data, discriminated by `kind`.
    pub kind: ContentPartKind,
}

impl ContentPart {
    /// Create a new ContentPart with default values.
    pub fn new() -> Self {
        Self::default()
    }

    /// Load ContentPart from a JSON string.
    pub fn from_json(json: &str, ctx: &LoadContext) -> Result<Self, serde_json::Error> {
        let value: serde_json::Value = serde_json::from_str(json)?;
        Ok(Self::load_from_value(&value, ctx))
    }

    /// Load ContentPart from a YAML string.
    pub fn from_yaml(yaml: &str, ctx: &LoadContext) -> Result<Self, serde_yaml::Error> {
        let value: serde_json::Value = serde_yaml::from_str(yaml)?;
        Ok(Self::load_from_value(&value, ctx))
    }

    /// Load ContentPart from a `serde_json::Value`.
    ///
    /// Calls `ctx.process_input` before field extraction.
    pub fn load_from_value(value: &serde_json::Value, ctx: &LoadContext) -> Self {
        let value = ctx.process_input(value.clone());
        let kind_str = value.get("kind").and_then(|v| v.as_str()).unwrap_or("");
        let kind = match kind_str {
            "text" => ContentPartKind::TextPart {
                value: value
                    .get("value")
                    .and_then(|v| v.as_str())
                    .unwrap_or_default()
                    .to_string(),
            },
            "image" => ContentPartKind::ImagePart {
                source: value
                    .get("source")
                    .and_then(|v| v.as_str())
                    .unwrap_or_default()
                    .to_string(),
                detail: value
                    .get("detail")
                    .and_then(|v| v.as_str())
                    .map(|s| s.to_string()),
                media_type: value
                    .get("mediaType")
                    .and_then(|v| v.as_str())
                    .map(|s| s.to_string()),
            },
            "file" => ContentPartKind::FilePart {
                source: value
                    .get("source")
                    .and_then(|v| v.as_str())
                    .unwrap_or_default()
                    .to_string(),
                media_type: value
                    .get("mediaType")
                    .and_then(|v| v.as_str())
                    .map(|s| s.to_string()),
            },
            "audio" => ContentPartKind::AudioPart {
                source: value
                    .get("source")
                    .and_then(|v| v.as_str())
                    .unwrap_or_default()
                    .to_string(),
                media_type: value
                    .get("mediaType")
                    .and_then(|v| v.as_str())
                    .map(|s| s.to_string()),
            },
            _ => ContentPartKind::default(),
        };
        Self { kind: kind }
    }

    /// Returns the `kind` discriminator string for this instance.
    pub fn kind_str(&self) -> &str {
        match &self.kind {
            ContentPartKind::TextPart { .. } => "text",
            ContentPartKind::ImagePart { .. } => "image",
            ContentPartKind::FilePart { .. } => "file",
            ContentPartKind::AudioPart { .. } => "audio",
        }
    }

    /// Serialize ContentPart to a `serde_json::Value`.
    ///
    /// Calls `ctx.process_dict` after serialization.
    pub fn to_value(&self, ctx: &SaveContext) -> serde_json::Value {
        let mut result = serde_json::Map::new();
        // Write the discriminator
        result.insert(
            "kind".to_string(),
            serde_json::Value::String(self.kind_str().to_string()),
        );
        // Write base fields
        // Write variant-specific fields
        match &self.kind {
            ContentPartKind::TextPart { value, .. } => {
                if !value.is_empty() {
                    result.insert(
                        "value".to_string(),
                        serde_json::Value::String(value.clone()),
                    );
                }
            }
            ContentPartKind::ImagePart {
                source,
                detail,
                media_type,
                ..
            } => {
                if !source.is_empty() {
                    result.insert(
                        "source".to_string(),
                        serde_json::Value::String(source.clone()),
                    );
                }
                if let Some(val) = detail {
                    result.insert("detail".to_string(), serde_json::Value::String(val.clone()));
                }
                if let Some(val) = media_type {
                    result.insert(
                        "mediaType".to_string(),
                        serde_json::Value::String(val.clone()),
                    );
                }
            }
            ContentPartKind::FilePart {
                source, media_type, ..
            } => {
                if !source.is_empty() {
                    result.insert(
                        "source".to_string(),
                        serde_json::Value::String(source.clone()),
                    );
                }
                if let Some(val) = media_type {
                    result.insert(
                        "mediaType".to_string(),
                        serde_json::Value::String(val.clone()),
                    );
                }
            }
            ContentPartKind::AudioPart {
                source, media_type, ..
            } => {
                if !source.is_empty() {
                    result.insert(
                        "source".to_string(),
                        serde_json::Value::String(source.clone()),
                    );
                }
                if let Some(val) = media_type {
                    result.insert(
                        "mediaType".to_string(),
                        serde_json::Value::String(val.clone()),
                    );
                }
            }
        }
        ctx.process_dict(serde_json::Value::Object(result))
    }

    /// Serialize ContentPart to a JSON string.
    pub fn to_json(&self, ctx: &SaveContext) -> Result<String, serde_json::Error> {
        serde_json::to_string_pretty(&self.to_value(ctx))
    }

    /// Serialize ContentPart to a YAML string.
    pub fn to_yaml(&self, ctx: &SaveContext) -> Result<String, serde_yaml::Error> {
        serde_yaml::to_string(&self.to_value(ctx))
    }
}