phoebe/src/message_ast/convert_discord.rs

76 lines
3.0 KiB
Rust

use super::{MessageContent, Styled};
use discord_message_format::DiscordComponent;
impl<'a> From<&DiscordComponent<'a>> for Styled {
fn from(discord: &DiscordComponent<'a>) -> Self {
match discord {
DiscordComponent::Plain(text) => Self::Plain(text.to_string()),
DiscordComponent::Literal(char) => Self::Plain(char.to_string()),
DiscordComponent::Link(link) => Self::Link {
target: link.to_string(),
text: vec![Self::Plain(link.to_string())],
},
DiscordComponent::Bold(content) => Self::Bold(convert_discord(content)),
DiscordComponent::Italic(content) => Self::Italic(convert_discord(content)),
DiscordComponent::Strikethrough(content) => {
Self::Strikethrough(convert_discord(content))
}
DiscordComponent::Underline(content) => Self::Underline(convert_discord(content)),
DiscordComponent::Code(code) => Self::Code(code.to_string()),
DiscordComponent::CodeBlock { lang, source } => Self::CodeBlock {
lang: lang.map(|s| s.to_string()),
source: source.to_string(),
},
DiscordComponent::Spoiler(content) => Self::Spoiler {
reason: None,
content: convert_discord(content),
},
DiscordComponent::LineBreak => Self::HardBreak,
DiscordComponent::Quote(content) => Self::BlockQuote(convert_discord(content)),
}
}
}
pub fn convert_discord(discord_message: &[DiscordComponent<'_>]) -> MessageContent {
discord_message
.iter()
.map(Styled::from)
.collect::<MessageContent>()
}
pub fn format_discord(message_content: &MessageContent) -> String {
message_content
.iter()
.map(|component| match component {
Styled::Plain(text) => text.to_string(), // TODO: Escape
Styled::Link { target, .. } => target.to_string(), // TODO: Link text
Styled::Italic(inner) => format!("*{}*", format_discord(inner)),
Styled::Bold(inner) => format!("**{}**", format_discord(inner)),
Styled::Strikethrough(inner) => format!("~~{}~~", format_discord(inner)),
Styled::Underline(inner) => format!("__{}__", format_discord(inner)),
Styled::Code(code) => format!("`{}`", code), // TODO: Double-grave delimiting when code contains '`'
Styled::CodeBlock { lang, source } => {
format!(
"```{}\n{}\n```",
lang.as_ref()
.map(|s| s.to_string())
.unwrap_or("".to_string()),
source.to_string()
)
}
Styled::Spoiler { content, .. } => format!("||{}||", format_discord(content)), // TODO: Spoiler reason
Styled::HardBreak => "\n".to_string(),
Styled::BlockQuote(inner) => format!("> {}", format_discord(inner)),
})
.collect()
}