use serde::Serialize;
use std::fmt;
const ESCAPE_MARKDOWN: [char; 4] = ['_', '*', '`', '['];
const ESCAPE_MARKDOWNV2: [char; 18] = [
'_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!',
];
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub enum ParseMode {
#[serde(rename = "HTML")]
Html,
Markdown,
MarkdownV2,
}
impl ParseMode {
pub fn escape<T>(self, input: T) -> String
where
T: Into<String>,
{
let input = input.into();
let mut result = String::new();
match self {
ParseMode::Html => {
for i in input.chars() {
match i {
'<' => result += "<",
'>' => result += ">",
'&' => result += "&",
_ => result.push(i),
}
}
}
ParseMode::Markdown => {
for i in input.chars() {
if ESCAPE_MARKDOWN.contains(&i) {
result.push('\\');
}
result.push(i);
}
}
ParseMode::MarkdownV2 => {
for i in input.chars() {
if ESCAPE_MARKDOWNV2.contains(&i) {
result.push('\\');
}
result.push(i);
}
}
}
result
}
}
impl fmt::Display for ParseMode {
fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
write!(
out,
"{}",
match self {
ParseMode::Html => "HTML",
ParseMode::Markdown => "Markdown",
ParseMode::MarkdownV2 => "MarkdownV2",
}
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_mode() {
assert_eq!(serde_json::to_string(&ParseMode::Html).unwrap(), r#""HTML""#);
assert_eq!(serde_json::to_string(&ParseMode::Markdown).unwrap(), r#""Markdown""#);
assert_eq!(
serde_json::to_string(&ParseMode::MarkdownV2).unwrap(),
r#""MarkdownV2""#
);
assert_eq!(ParseMode::Html.to_string(), "HTML");
assert_eq!(ParseMode::Markdown.to_string(), "Markdown");
assert_eq!(ParseMode::MarkdownV2.to_string(), "MarkdownV2");
}
#[test]
fn parse_mode_escape() {
assert_eq!(ParseMode::Html.escape("<>&"), "<>&");
assert_eq!(ParseMode::Markdown.escape(r#"_*`["#), r#"\_\*\`\["#);
assert_eq!(
ParseMode::MarkdownV2.escape(r#"_*[]()~`>#+-=|{}.!"#),
r#"\_\*\[\]\(\)\~\`\>\#\+\-\=\|\{\}\.\!"#
);
}
}