markdown_composer/types/
header.rs1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3use std::fmt;
4use tousize::ToUsize;
5
6#[derive(Clone, Debug, Eq, PartialEq)]
8#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
9pub struct HeaderLevel(usize);
10
11impl Default for HeaderLevel {
12 fn default() -> Self {
14 HeaderLevel(1)
15 }
16}
17
18impl HeaderLevel {
19 pub fn new() -> Self {
21 Self::default()
22 }
23
24 pub fn from(level: impl ToUsize) -> Self {
30 let level = level.to_usize();
31 assert!(1 <= level && level <= 6);
32 Self(level)
33 }
34}
35
36impl<T> From<T> for HeaderLevel
37where
38 T: ToUsize,
39{
40 fn from(value: T) -> Self {
41 Self::from(value)
42 }
43}
44
45#[derive(Clone, Debug, Default, Eq, PartialEq)]
47#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
48pub struct Header {
49 pub text: String,
51 pub level: HeaderLevel,
53}
54
55impl Header {
56 pub fn new() -> Self {
58 Self::default()
59 }
60
61 pub fn from(text: impl Into<String>, level: impl Into<HeaderLevel>) -> Self {
67 Self {
68 text: text.into(),
69 level: level.into(),
70 }
71 }
72}
73
74impl fmt::Display for Header {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 writeln!(f, "{} {}", "#".repeat(self.level.0), self.text)
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::{Header, HeaderLevel};
83
84 #[test]
85 fn test_header_level() {
86 let level = 5usize;
87 assert_eq!(HeaderLevel::from(5usize), level.into());
88 }
89
90 #[test]
91 #[should_panic]
92 fn test_header_level_panic() {
93 let _: HeaderLevel = 0usize.into();
94 }
95
96 #[test]
97 fn test_header() {
98 let content = "Some header content";
99 let level = 5usize;
100 let header = Header::from(content, level);
101 assert_eq!(header.text, content);
102 assert_eq!(header.level, level.into());
103 }
104}