pub mod cache;
pub mod content;
pub mod message;
pub mod output;
pub mod thinking;
pub mod tool;
pub use cache::{CacheControl, CacheTtl};
pub use content::{
Base64Source, CitationsConfig, ContentBlock, ContentBlockParam, ContentSource,
DocumentBlockParam, DocumentSource, FallbackBlock, FallbackRef, FileSource, ImageBlockParam,
ImageSource, PlainTextSource, RedactedThinkingBlock, TextBlock, TextBlockParam, ThinkingBlock,
ToolResultBlockParam, ToolUseBlock, UrlSource, WebSearchToolResultBlock,
};
pub use message::{
Container, Message, MessageContent, MessageParam, Metadata, Role, StopDetails, StopReason,
SystemPrompt, Usage,
};
pub use output::{Effort, OutputConfig, OutputFormat};
pub use thinking::{ThinkingConfig, ThinkingDisplay};
pub use tool::{Tool, ToolChoice, ToolResultContent, ToolUnion};
pub(crate) fn serialize_tagged<T, S>(inner: &T, tag: &str, serializer: S) -> Result<S::Ok, S::Error>
where
T: serde::Serialize,
S: serde::Serializer,
{
let mut value = serde_json::to_value(inner).map_err(serde::ser::Error::custom)?;
match &mut value {
serde_json::Value::Object(map) => {
map.insert(
"type".to_string(),
serde_json::Value::String(tag.to_string()),
);
}
_ => {
return Err(serde::ser::Error::custom(
"tagged enum variant did not serialize to a JSON object",
));
}
}
serde::Serialize::serialize(&value, serializer)
}
macro_rules! tagged_enum {
(
$(#[$enum_meta:meta])*
$vis:vis enum $name:ident {
$(
$(#[$var_meta:meta])*
$variant:ident($inner:ty) = $tag:literal
),* $(,)?
}
) => {
$(#[$enum_meta])*
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
$vis enum $name {
$(
$(#[$var_meta])*
$variant($inner),
)*
Unknown(::serde_json::Value),
}
impl ::serde::Serialize for $name {
fn serialize<S>(&self, serializer: S) -> ::core::result::Result<S::Ok, S::Error>
where
S: ::serde::Serializer,
{
match self {
$(
$name::$variant(inner) => {
$crate::types::serialize_tagged(inner, $tag, serializer)
}
)*
$name::Unknown(value) => ::serde::Serialize::serialize(value, serializer),
}
}
}
impl<'de> ::serde::Deserialize<'de> for $name {
fn deserialize<D>(deserializer: D) -> ::core::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
let value = ::serde_json::Value::deserialize(deserializer)?;
let tag = value
.get("type")
.and_then(|t| t.as_str())
.map(|s| s.to_owned());
match tag.as_deref() {
$(
::core::option::Option::Some($tag) => ::serde_json::from_value(value)
.map($name::$variant)
.map_err(::serde::de::Error::custom),
)*
_ => ::core::result::Result::Ok($name::Unknown(value)),
}
}
}
};
}
macro_rules! string_enum {
(
$(#[$enum_meta:meta])*
$vis:vis enum $name:ident {
$(
$(#[$var_meta:meta])*
$variant:ident = $s:literal
),* $(,)?
}
) => {
$(#[$enum_meta])*
#[derive(Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
$vis enum $name {
$(
$(#[$var_meta])*
$variant,
)*
Unknown(::std::string::String),
}
impl $name {
$vis fn as_str(&self) -> &str {
match self {
$( $name::$variant => $s, )*
$name::Unknown(s) => s.as_str(),
}
}
}
impl ::core::fmt::Display for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_str(self.as_str())
}
}
impl ::serde::Serialize for $name {
fn serialize<S>(&self, serializer: S) -> ::core::result::Result<S::Ok, S::Error>
where
S: ::serde::Serializer,
{
serializer.serialize_str(self.as_str())
}
}
impl<'de> ::serde::Deserialize<'de> for $name {
fn deserialize<D>(deserializer: D) -> ::core::result::Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
let s = ::std::string::String::deserialize(deserializer)?;
::core::result::Result::Ok(match s.as_str() {
$( $s => $name::$variant, )*
_ => $name::Unknown(s),
})
}
}
};
}
pub(crate) use string_enum;
pub(crate) use tagged_enum;