//! Embed CRUD operations on `MessageRepo`. use uuid::Uuid; use crate::ImksResult; use crate::models::message_embed::{EmbedDetail, MessageEmbed, MessageEmbedField}; use super::message_repo::MessageRepo; impl MessageRepo { /// Create an embed with its fields. Returns the embed (fields fetched separately). #[allow(clippy::too_many_arguments)] pub async fn create_embed( &self, message_id: Uuid, embed_type: &str, title: Option<&str>, description: Option<&str>, url: Option<&str>, color: Option, image_url: Option<&str>, author_name: Option<&str>, author_url: Option<&str>, footer_text: Option<&str>, provider_name: Option<&str>, fields: &[(String, String, bool)], ) -> ImksResult { let embed_id = Uuid::now_v7(); let embed = sqlx::query_as::<_, MessageEmbed>( r#" INSERT INTO message_embed ( id, message_id, embed_type, title, description, url, color, image_url, author_name, author_url, footer_text, provider_name ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING * "#, ) .bind(embed_id) .bind(message_id) .bind(embed_type) .bind(title) .bind(description) .bind(url) .bind(color) .bind(image_url) .bind(author_name) .bind(author_url) .bind(footer_text) .bind(provider_name) .fetch_one(self.pool()) .await?; for (i, (name, value, inline)) in fields.iter().enumerate() { sqlx::query( r#" INSERT INTO message_embed_field (id, embed_id, name, value, inline, position) VALUES ($1, $2, $3, $4, $5, $6) "#, ) .bind(Uuid::now_v7()) .bind(embed_id) .bind(name) .bind(value) .bind(inline) .bind(i as i32) .execute(self.pool()) .await?; } Ok(embed) } /// Get all embeds for a message, including their fields. pub async fn get_embeds(&self, message_id: Uuid) -> ImksResult> { let embeds: Vec = sqlx::query_as("SELECT * FROM message_embed WHERE message_id = $1 ORDER BY created_at") .bind(message_id) .fetch_all(self.pool()) .await?; let mut result = Vec::with_capacity(embeds.len()); for embed in embeds { let fields: Vec = sqlx::query_as( "SELECT * FROM message_embed_field WHERE embed_id = $1 ORDER BY position", ) .bind(embed.id) .fetch_all(self.pool()) .await?; result.push(EmbedDetail { embed, fields }); } Ok(result) } /// Delete an embed (fields cascade via FK). pub async fn delete_embed(&self, embed_id: Uuid) -> ImksResult { let result = sqlx::query("DELETE FROM message_embed WHERE id = $1") .bind(embed_id) .execute(self.pool()) .await?; Ok(result.rows_affected() > 0) } }