use serde::{Deserialize, Serialize}; use uuid::Uuid; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RichTextBlock { pub block_type: BlockType, pub content: String, pub attributes: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum BlockType { Text, Code, Quote, Link, Mention, Emoji, Image, } pub struct RichTextRenderer {} impl RichTextRenderer { pub fn new() -> Self { Self {} } pub fn parse_markdown(&self, content: &str) -> Vec { let mut blocks = Vec::new(); blocks.push(RichTextBlock { block_type: BlockType::Text, content: content.to_string(), attributes: None, }); blocks } pub fn parse_mentions(&self, content: &str) -> Vec { let mut mentions = Vec::new(); for word in content.split_whitespace() { if word.starts_with('@') { if let Ok(uuid) = Uuid::parse_str(&word[1..]) { mentions.push(uuid); } } } mentions } pub fn highlight_code(&self, code: &str, language: &str) -> String { format!("```{}\n{}\n```", language, code) } pub fn render_to_html(&self, blocks: &[RichTextBlock]) -> String { blocks .iter() .map(|block| match block.block_type { BlockType::Text => format!("

{}

", html_escape(&block.content)), BlockType::Code => { format!("
{}
", html_escape(&block.content)) } BlockType::Quote => { format!("
{}
", html_escape(&block.content)) } BlockType::Link => format!( "{}", html_escape(&block.content), html_escape(&block.content) ), BlockType::Mention => format!( "@{}", html_escape(&block.content) ), BlockType::Emoji => format!( "{}", html_escape(&block.content) ), BlockType::Image => format!("", html_escape(&block.content)), }) .collect::>() .join("\n") } } fn html_escape(s: &str) -> String { s.replace('&', "&") .replace('<', "<") .replace('>', ">") .replace('"', """) .replace('\'', "'") }