///|
/// Rich content embedded in a Discord message.
///
/// Use `Embed(...)` to construct outgoing embeds from fields Discord accepts
/// when sending. Embed models remain public records so received metadata can
/// be inspected. Pass outgoing values to
/// `Client::create_message(embeds=[...])`, `CommandReply::message(embeds=[...])`,
/// `ctx.respond`, or a followup method. Discord applies its documented embed
/// count and text-length limits.
///
/// ```mbt check
/// test "construct an outgoing embed" {
/// let embed = @model.Embed(
/// title="Build complete",
/// description="All checks passed.",
/// timestamp=Timestamp("2026-07-15T00:00:00Z"),
/// color=0x57F287,
/// footer=EmbedFooter("build 42"),
/// fields=[
/// EmbedField("Target", "native", inline=true),
/// EmbedField("Tests", "325 passed", inline=true),
/// ],
/// )
/// json_inspect(embed, content={
/// "title": "Build complete",
/// "description": "All checks passed.",
/// "timestamp": "2026-07-15T00:00:00Z",
/// "color": 5763719,
/// "footer": { "text": "build 42" },
/// "fields": [
/// { "name": "Target", "value": "native", "inline": true },
/// { "name": "Tests", "value": "325 passed", "inline": true },
/// ],
/// })
/// }
/// ```
pub(all) struct Embed {
title : String?
typ : EmbedType?
url : String?
description : String?
timestamp : Timestamp?
color : Int?
footer : EmbedFooter?
image : EmbedImage?
thumbnail : EmbedThumbnail?
video : EmbedVideo?
provider : EmbedProvider?
author : EmbedAuthor?
fields : Array[EmbedField]?
flags : EmbedFlags?
// Not modeled: embed components appear in OpenAPI but not in the public documentation.
} derive (
ToJson(fields(typ(rename="type"))),
FromJson(fields(typ(rename="type"))),
Debug,
)
///|
/// Construct an embed containing only fields accepted in outgoing payloads.
/// Receive-only fields are left unset. The `fields` array is copied so later
/// mutations of the caller's array do not affect the embed.
pub fn Embed::Embed(
title? : String,
description? : String,
url? : String,
timestamp? : Timestamp,
color? : Int,
footer? : EmbedFooter,
image? : EmbedImage,
thumbnail? : EmbedThumbnail,
author? : EmbedAuthor,
fields? : Array[EmbedField],
) -> Embed {
{
title,
typ: None,
url,
description,
timestamp,
color,
footer,
image,
thumbnail,
video: None,
provider: None,
author,
fields: fields.map(values => values.copy()),
flags: None,
}
}
///|
/// Bit flags describing special rendering behavior of an embed.
pub(all) struct EmbedFlags(UInt64) derive(Eq)
///|
pub fn EmbedFlags::from_bits(bits : UInt64) -> EmbedFlags {
EmbedFlags(bits)
}
///|
pub fn EmbedFlags::bits(self : EmbedFlags) -> UInt64 {
self.0
}
///|
pub impl Debug for EmbedFlags with fn to_repr(self) {
Repr(self.0)
}
///|
pub impl ToJson for EmbedFlags with fn to_json(self) {
Json::number(self.0.to_double(), repr=self.0.to_string())
}
///|
pub impl @json.FromJson for EmbedFlags with fn from_json(json, path) {
match json {
Number(_, repr=Some(repr)) =>
EmbedFlags(
@string.parse_uint64(repr.to_string()) catch {
_ => raise JsonDecodeError((path, "expected embed flags (number)"))
},
)
Number(value, repr=None) => EmbedFlags(value.to_uint64())
_ => raise JsonDecodeError((path, "expected embed flags (number)"))
}
}
///|
pub fn EmbedFlags::is_content_inventory_entry() -> EmbedFlags {
EmbedFlags(1UL << 5)
}
///|
/// The string discriminator describing an embed's rendering category.
pub(all) enum EmbedType {
Rich
Image
Video
Gifv
Article
Link
AutoModerationMessage
PollResult
Unknown(String)
} derive(Eq, Debug)
///|
pub fn EmbedType::to_string(self : EmbedType) -> String {
match self {
Rich => "rich"
Image => "image"
Video => "video"
Gifv => "gifv"
Article => "article"
Link => "link"
AutoModerationMessage => "auto_moderation_message"
PollResult => "poll_result"
Unknown(value) => value
}
}
///|
pub fn EmbedType::from_string(value : String) -> EmbedType {
match value {
"rich" => Rich
"image" => Image
"video" => Video
"gifv" => Gifv
"article" => Article
"link" => Link
"auto_moderation_message" => AutoModerationMessage
"poll_result" => PollResult
value => Unknown(value)
}
}
///|
pub impl ToJson for EmbedType with fn to_json(self) {
Json::string(self.to_string())
}
///|
pub impl @json.FromJson for EmbedType with fn from_json(json, path) {
match json {
String(value) => EmbedType::from_string(value)
_ => raise JsonDecodeError((path, "expected an embed type (string)"))
}
}
///|
/// Footer text and optional icon URLs for an embed.
pub(all) struct EmbedFooter {
text : String
icon_url : String?
proxy_icon_url : String?
} derive(ToJson, FromJson, Debug)
///|
/// Construct footer content for an outgoing embed.
pub fn EmbedFooter::EmbedFooter(
text : String,
icon_url? : String,
) -> EmbedFooter {
{ text, icon_url, proxy_icon_url: None, }
}
///|
/// Image media displayed within an embed.
pub(all) struct EmbedImage {
url : String
proxy_url : String?
height : Int?
width : Int?
} derive(ToJson, FromJson, Debug)
///|
/// Construct image media for an outgoing embed.
pub fn EmbedImage::EmbedImage(url : String) -> EmbedImage {
{ url, proxy_url: None, height: None, width: None, }
}
///|
/// Thumbnail media displayed beside an embed.
pub(all) struct EmbedThumbnail {
url : String
proxy_url : String?
height : Int?
width : Int?
} derive(ToJson, FromJson, Debug)
///|
/// Construct thumbnail media for an outgoing embed.
pub fn EmbedThumbnail::EmbedThumbnail(url : String) -> EmbedThumbnail {
{ url, proxy_url: None, height: None, width: None, }
}
///|
/// Video media attached to an embed.
pub(all) struct EmbedVideo {
url : String?
proxy_url : String?
height : Int?
width : Int?
} derive(ToJson, FromJson, Debug)
///|
/// Attribution information for the provider of an embed.
pub(all) struct EmbedProvider {
name : String?
url : String?
} derive(ToJson, FromJson, Debug)
///|
/// Author information displayed at the top of an embed.
pub(all) struct EmbedAuthor {
name : String
url : String?
icon_url : String?
proxy_icon_url : String?
} derive(ToJson, FromJson, Debug)
///|
/// Construct author information for an outgoing embed.
pub fn EmbedAuthor::EmbedAuthor(
name : String,
url? : String,
icon_url? : String,
) -> EmbedAuthor {
{ name, url, icon_url, proxy_icon_url: None, }
}
///|
/// A named value displayed in an embed's field grid.
pub(all) struct EmbedField {
name : String
value : String
inline : Bool?
} derive(ToJson, FromJson, Debug)
///|
/// Construct a field for an outgoing embed.
pub fn EmbedField::EmbedField(
name : String,
value : String,
inline? : Bool,
) -> EmbedField {
{ name, value, inline, }
}