baml/raw_objects/
media.rs

1//! Media types (Image, Audio, Pdf, Video)
2//!
3//! These wrap FFI pointers to media objects managed by the BAML runtime.
4
5use std::ffi::c_void;
6
7use super::{RawObject, RawObjectTrait};
8use crate::{baml_unreachable, proto::baml_cffi_v1::BamlObjectType};
9
10// =============================================================================
11// Media type macro - generates Image, Audio, Pdf, Video
12// Uses define_raw_object_wrapper for base struct + from_raw + RawObjectTrait
13// =============================================================================
14
15macro_rules! define_media_type {
16    (
17        $(#[$meta:meta])*
18        $name:ident => $object_type:ident
19    ) => {
20        // Use the base wrapper for struct, from_raw, and RawObjectTrait
21        define_raw_object_wrapper! {
22            $(#[$meta])*
23            $name => $object_type
24        }
25
26        // Add media-specific constructors and methods
27        impl $name {
28            /// Create from a URL
29            pub fn from_url(runtime: *const c_void, url: &str, mime_type: Option<&str>) -> Self {
30                let raw = RawObject::new(
31                    runtime,
32                    BamlObjectType::$object_type,
33                    (("url", url), ("mime_type", mime_type)),
34                )
35                .unwrap_or_else(|e| baml_unreachable!("Failed to create {} from URL: {}", stringify!($name), e));
36                Self { raw }
37            }
38
39            /// Create from base64-encoded data
40            pub fn from_base64(runtime: *const c_void, base64: &str, mime_type: Option<&str>) -> Self {
41                let raw = RawObject::new(
42                    runtime,
43                    BamlObjectType::$object_type,
44                    (("base64", base64), ("mime_type", mime_type)),
45                )
46                .unwrap_or_else(|e| baml_unreachable!("Failed to create {} from base64: {}", stringify!($name), e));
47                Self { raw }
48            }
49
50            /// Get the MIME type (if known)
51            pub fn mime_type(&self) -> Option<String> {
52                self.raw.call_method("mime_type", ())
53            }
54
55            /// Check if this is a URL reference
56            pub fn is_url(&self) -> bool {
57                self.raw.call_method("is_url", ())
58            }
59
60            /// Check if this is base64 encoded
61            pub fn is_base64(&self) -> bool {
62                self.raw.call_method("is_base64", ())
63            }
64
65            /// Get as URL (if applicable)
66            pub fn as_url(&self) -> Option<String> {
67                self.raw.call_method("as_url", ())
68            }
69
70            /// Get as base64 (if applicable)
71            pub fn as_base64(&self) -> Option<String> {
72                self.raw.call_method("as_base64", ())
73            }
74        }
75
76        impl std::fmt::Debug for $name {
77            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78                f.debug_struct(stringify!($name)).finish_non_exhaustive()
79            }
80        }
81
82        impl Default for $name {
83            fn default() -> Self {
84                unreachable!("Media types cannot be default-constructed; they require a runtime")
85            }
86        }
87
88        impl $crate::BamlDecode for $name {
89            fn baml_decode(
90                _holder: &$crate::__internal::CffiValueHolder
91            ) -> ::core::result::Result<Self, $crate::BamlError> {
92                // Media types come as ObjectValue which requires runtime context to decode.
93                // This path shouldn't be hit in normal usage - media decoding goes through
94                // the runtime's object handle mechanism instead.
95                Err($crate::BamlError::internal(
96                    concat!("Cannot decode ", stringify!($name), " without runtime context")
97                ))
98            }
99        }
100    };
101}
102
103// =============================================================================
104// Media type definitions
105// =============================================================================
106
107define_media_type! {
108    /// Image media type
109    Image => ObjectMediaImage
110}
111
112define_media_type! {
113    /// Audio media type
114    Audio => ObjectMediaAudio
115}
116
117define_media_type! {
118    /// PDF media type
119    Pdf => ObjectMediaPdf
120}
121
122define_media_type! {
123    /// Video media type
124    Video => ObjectMediaVideo
125}