markdown_builder/types/
header.rs1use std::fmt;
2use tousize::ToUsize;
3
4#[derive(Clone, Debug, Eq, PartialEq)]
6pub struct HeaderLevel(usize);
7
8impl Default for HeaderLevel {
9 fn default() -> Self {
11 HeaderLevel(1)
12 }
13}
14
15impl HeaderLevel {
16 pub fn new() -> Self {
18 Self::default()
19 }
20
21 pub fn from(level: impl ToUsize) -> Self {
25 let level = level.to_usize();
26 assert!((1..=6).contains(&level));
27 Self(level)
28 }
29}
30
31impl<T> From<T> for HeaderLevel
32where
33 T: ToUsize,
34{
35 fn from(value: T) -> Self {
36 Self::from(value)
37 }
38}
39
40#[derive(Clone, Debug, Default, Eq, PartialEq)]
42pub struct Header {
43 pub text: String,
45 pub level: HeaderLevel,
47}
48
49impl Header {
50 pub fn new() -> Self {
52 Self::default()
53 }
54
55 pub fn from(text: impl Into<String>, level: impl Into<HeaderLevel>) -> Self {
60 Self {
61 text: text.into(),
62 level: level.into(),
63 }
64 }
65}
66
67impl fmt::Display for Header {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 writeln!(f, "{} {}", "#".repeat(self.level.0), self.text)
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::{Header, HeaderLevel};
76 use crate::MarkdownElement;
77
78 #[test]
79 fn test_header_level() {
80 assert_eq!(HeaderLevel::from(5usize), 5usize.into());
81 }
82
83 #[test]
84 #[should_panic]
85 fn test_header_level_panic_lowball() {
86 HeaderLevel::from(0usize);
87 }
88
89 #[test]
90 #[should_panic]
91 fn test_header_level_panic_highball() {
92 HeaderLevel::from(7usize);
93 }
94
95 #[test]
96 fn test_header_of_all_sizes() {
97 assert_eq!(Header::from("A header", 1usize).render(), "# A header\n");
98 assert_eq!(Header::from("A header", 2usize).render(), "## A header\n");
99 assert_eq!(Header::from("A header", 3usize).render(), "### A header\n");
100 assert_eq!(Header::from("A header", 4usize).render(), "#### A header\n");
101 assert_eq!(
102 Header::from("A header", 5usize).render(),
103 "##### A header\n"
104 );
105 assert_eq!(
106 Header::from("A header", 6usize).render(),
107 "###### A header\n"
108 );
109 }
110
111 #[test]
112 fn test_header_default() {
113 assert_eq!(Header::new().level, 1usize.into());
114 assert_eq!(Header::new().text, "");
115 }
116}