Skip to main content

yamd/nodes/
code.rs

1use std::fmt::Display;
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6/// # Code
7///
8/// Starts with [Backtick](type@crate::lexer::TokenKind::Backtick) of length 3.
9///
10/// [Lang](Code::lang) is every token except [Terminator](type@crate::lexer::TokenKind::Terminator)
11/// between [Backtick](type@crate::lexer::TokenKind::Backtick) of length 3 and
12/// [EOL](type@crate::lexer::TokenKind::Eol).
13///
14/// [Code](Code::code) is every token until [Backtick](type@crate::lexer::TokenKind::Backtick) of
15/// length 3.
16///
17/// Example:
18///
19/// ~~~text
20/// ```rust
21/// let a = 42;
22/// ```
23/// ~~~
24///
25/// HTML equivalent:
26///
27/// ```html
28/// <pre><code class="rust">let a = 42;</code></pre>
29/// ```
30
31#[derive(Debug, PartialEq, Clone, Eq)]
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33pub struct Code {
34    pub lang: String,
35    pub code: String,
36}
37
38impl Code {
39    pub fn new<S: Into<String>>(lang: S, code: S) -> Self {
40        Self {
41            lang: lang.into(),
42            code: code.into(),
43        }
44    }
45}
46
47impl Display for Code {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        write!(
50            f,
51            "```{}\n{}\n```",
52            self.lang.replace("```", "\\```").replace("\n", "\\\n"),
53            self.code.replace("```", "\\```")
54        )
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn code() {
64        let code = Code::new("rust", "let a = 42;");
65        assert_eq!(code.to_string(), "```rust\nlet a = 42;\n```");
66    }
67
68    #[test]
69    fn code_with_backtick() {
70        let code = Code::new("rust", "let a = 42;\nlet ```b` = 43;");
71        assert_eq!(
72            code.to_string(),
73            "```rust\nlet a = 42;\nlet \\```b` = 43;\n```"
74        );
75    }
76
77    #[test]
78    fn language_with_eol() {
79        let code = Code::new("rust\n\n", "let a = 42;");
80        assert_eq!(code.to_string(), "```rust\\\n\\\n\nlet a = 42;\n```");
81    }
82}