use std::fmt::Display;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use super::{Paragraph, paragraph::escape_leading_block_marker};
#[derive(Debug, PartialEq, Clone, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Highlight {
pub title: Option<String>,
pub icon: Option<String>,
pub body: Vec<Paragraph>,
}
impl Highlight {
pub fn new<T: Into<String>, I: Into<String>>(
title: Option<T>,
icon: Option<I>,
body: Vec<Paragraph>,
) -> Self {
Self {
title: title.map(|title| title.into()),
icon: icon.map(|icon| icon.into()),
body,
}
}
}
impl Display for Highlight {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let title = self
.title
.as_ref()
.map_or("".to_string(), |t| format!(" {}", t.replace("\\", "\\\\")));
let icon = self.icon.as_ref().map_or("".to_string(), |i| {
format!("! {}\n", i.replace("\\", "\\\\"))
});
write!(
f,
"!!{}\n{}{}\n!!",
title,
icon,
self.body
.iter()
.map(|p| escape_leading_block_marker(p.to_string().replace("!!", "\\!!")))
.collect::<Vec<_>>()
.join("\n\n")
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::nodes::Paragraph;
#[test]
fn highlight() {
let highlight = Highlight::new(
Some("title"),
Some("icon"),
vec![Paragraph::new(vec!["body".to_string().into()])],
);
assert_eq!(highlight.to_string(), "!! title\n! icon\nbody\n!!");
}
#[test]
fn highlight_without_title() {
let highlight = Highlight::new::<&str, &str>(
None,
Some("icon"),
vec![Paragraph::new(vec!["body".to_string().into()])],
);
assert_eq!(highlight.to_string(), "!!\n! icon\nbody\n!!");
}
#[test]
fn highlight_without_icon() {
let highlight = Highlight::new::<&str, &str>(
Some("title"),
None,
vec![Paragraph::new(vec!["body".to_string().into()])],
);
assert_eq!(highlight.to_string(), "!! title\nbody\n!!");
}
#[test]
fn highlight_with_double_bang_in_the_middle() {
let highlight = Highlight::new::<&str, &str>(
Some("title"),
Some("icon"),
vec![
Paragraph::new(vec!["body".to_string().into()]),
Paragraph::new(vec!["a\n!!".to_string().into()]),
],
);
assert_eq!(
highlight.to_string(),
"!! title\n! icon\nbody\n\na\n\\!!\n!!"
);
}
}