1use std::fmt::Display;
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6#[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}