88 lines
3.5 KiB
Rust
88 lines
3.5 KiB
Rust
use super::{MessageComponent, MessageContent};
|
|
use discord_message_format::DiscordComponent;
|
|
|
|
impl<'a> From<&DiscordComponent<'a>> for MessageComponent {
|
|
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(MessageComponent::from)
|
|
.collect::<MessageContent>()
|
|
}
|
|
|
|
pub fn format_discord(message_content: &[MessageComponent]) -> String {
|
|
message_content
|
|
.iter()
|
|
.map(|component| match component {
|
|
MessageComponent::Plain(text) => text.to_string(), // TODO: Escape
|
|
|
|
MessageComponent::Link { target, text } => {
|
|
let formatted_text = format_discord(text);
|
|
|
|
// TODO: Maybe tolerate a missing http(s) URL scheme?
|
|
if &formatted_text == target {
|
|
formatted_text
|
|
} else {
|
|
format!("{} ({})", formatted_text, target)
|
|
}
|
|
}
|
|
|
|
MessageComponent::Italic(inner) => format!("*{}*", format_discord(inner)),
|
|
MessageComponent::Bold(inner) => format!("**{}**", format_discord(inner)),
|
|
MessageComponent::Strikethrough(inner) => format!("~~{}~~", format_discord(inner)),
|
|
MessageComponent::Underline(inner) => format!("__{}__", format_discord(inner)),
|
|
|
|
MessageComponent::Code(code) => format!("`{}`", code), // TODO: Double-grave delimiting when code contains '`'
|
|
MessageComponent::CodeBlock { lang, source } => {
|
|
format!(
|
|
"```{}\n{}\n```",
|
|
lang.as_ref()
|
|
.map(|s| s.to_string())
|
|
.unwrap_or_else(|| "".to_string()),
|
|
source.to_string()
|
|
)
|
|
}
|
|
|
|
MessageComponent::Spoiler { content, .. } => format!("||{}||", format_discord(content)), // TODO: Spoiler reason
|
|
|
|
MessageComponent::HardBreak => "\n".to_string(),
|
|
MessageComponent::BlockQuote(inner) => format_discord(inner)
|
|
.lines()
|
|
.map(|l| format!("> {}\n", l))
|
|
.collect(),
|
|
})
|
|
.collect()
|
|
}
|