mod args;
mod async_stream;
mod client_registry;
mod codec;
mod error;
mod ffi;
mod known_types;
pub mod platform;
mod raw_objects;
mod runtime;
mod stream;
mod types;
mod proto {
#![allow(clippy::empty_structs_with_brackets)]
pub(crate) mod baml_cffi_v1 {
include!(concat!(env!("OUT_DIR"), "/baml.cffi.v1.rs"));
}
}
use std::ffi::CString;
pub use args::{CancellationToken, FunctionArgs};
pub use async_stream::AsyncStreamingCall;
pub use baml_macros::{BamlDecode, BamlEncode, BamlSerde};
pub use client_registry::ClientRegistry;
pub use codec::{
decode_enum, decode_field, encode_class, encode_class_dynamic, encode_enum, BamlClass,
BamlDecode, BamlEncode, BamlEnum, BamlSerializeMapKey, BamlValue, DynamicClass, DynamicEnum,
DynamicUnion, FromBamlValue, FromBamlValueRef, KnownTypes,
};
pub use error::BamlError;
pub use ffi::callbacks::OnTickCallback;
pub use raw_objects::{
Audio,
ClassBuilder,
ClassPropertyBuilder,
Collector,
EnumBuilder,
EnumValueBuilder,
FunctionLog,
HTTPBody,
HTTPRequest,
HTTPResponse,
Image,
LLMCall,
LLMCallKind,
LLMStreamCall,
LogType,
Pdf,
SSEResponse,
StreamTiming,
Timing,
TypeBuilder,
TypeDef,
Usage,
Video,
};
pub use runtime::{BamlRuntime, StaticRuntimeType};
pub use stream::{StreamEvent, StreamingCall};
pub use types::{Check, CheckStatus, Checked, StreamState, StreamingState};
#[doc(hidden)]
pub mod __internal {
pub use serde;
use crate::{codec::traits::BamlClass, error::BamlError};
pub use crate::{
ffi::callbacks,
proto::baml_cffi_v1::*,
raw_objects::{BamlMediaRepr, BamlMediaReprContent},
};
pub fn decode_class<T: BamlClass>(holder: &CffiValueHolder) -> Result<T, BamlError> {
match &holder.value {
Some(cffi_value_holder::Value::ClassValue(class)) => T::from_class_value(class),
other => Err(BamlError::internal(format!(
"expected class {}, got {:?}",
T::TYPE_NAME,
other.as_ref().map(variant_name)
))),
}
}
pub fn extract_union_variant_with_name<'a>(
type_name: &str,
holder: &'a CffiValueHolder,
) -> Result<(&'a str, &'a CffiValueHolder), BamlError> {
match &holder.value {
Some(cffi_value_holder::Value::UnionVariantValue(union)) => {
let inner = union
.value
.as_ref()
.map(std::convert::AsRef::as_ref)
.ok_or_else(|| BamlError::internal("union variant missing inner value"))?;
Ok((union.value_option_name.as_str(), inner))
}
_ => Err(BamlError::internal(format!(
"expected union variant of type {type_name}, got {holder:?}"
))),
}
}
fn variant_name(v: &cffi_value_holder::Value) -> &'static str {
match v {
cffi_value_holder::Value::NullValue(_) => "null",
cffi_value_holder::Value::StringValue(_) => "string",
cffi_value_holder::Value::IntValue(_) => "int",
cffi_value_holder::Value::FloatValue(_) => "float",
cffi_value_holder::Value::BoolValue(_) => "bool",
cffi_value_holder::Value::ClassValue(_) => "class",
cffi_value_holder::Value::EnumValue(_) => "enum",
cffi_value_holder::Value::LiteralValue(_) => "literal",
cffi_value_holder::Value::ObjectValue(_) => "object",
cffi_value_holder::Value::ListValue(_) => "list",
cffi_value_holder::Value::MapValue(_) => "map",
cffi_value_holder::Value::UnionVariantValue(_) => "union",
cffi_value_holder::Value::CheckedValue(_) => "checked",
cffi_value_holder::Value::StreamingStateValue(_) => "streaming_state",
}
}
}
pub fn invoke_cli(args: &[&str]) -> i32 {
let c_args: Vec<CString> = args
.iter()
.map(|s| CString::new(*s).expect("invalid arg"))
.collect();
let c_arg_ptrs: Vec<*const libc::c_char> = c_args
.iter()
.map(|s| s.as_ptr())
.chain(std::iter::once(std::ptr::null())) .collect();
#[allow(unsafe_code, clippy::print_stderr)]
unsafe {
match ffi::invoke_runtime_cli(c_arg_ptrs.as_ptr()) {
Ok(code) => code,
Err(e) => {
eprintln!("Failed to load BAML library: {e}");
1
}
}
}
}
pub fn version() -> String {
match ffi::version() {
Ok(v) => v,
Err(_) => "unknown".to_string(),
}
}