1use serde::{Deserialize, Serialize};
4
5use crate::node::{Common, IntoNode, Node};
6
7#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct Code {
11 #[serde(flatten)]
13 pub common: Common,
14 pub source: String,
16 #[serde(default, skip_serializing_if = "Option::is_none")]
18 pub language: Option<String>,
19 #[serde(default, skip_serializing_if = "Option::is_none")]
21 pub line_numbers: Option<bool>,
22 #[serde(default, skip_serializing_if = "Option::is_none")]
24 pub start_line: Option<u32>,
25 #[serde(default, skip_serializing_if = "Vec::is_empty")]
27 pub highlight_lines: Vec<u32>,
28 #[serde(default, skip_serializing_if = "Option::is_none")]
30 pub wrap: Option<bool>,
31}
32
33impl Code {
34 #[must_use]
36 pub fn new(source: impl Into<String>) -> Self {
37 Self {
38 common: Common::new(),
39 source: source.into(),
40 language: None,
41 line_numbers: None,
42 start_line: None,
43 highlight_lines: Vec::new(),
44 wrap: None,
45 }
46 }
47
48 #[must_use]
50 pub fn language(mut self, language: impl Into<String>) -> Self {
51 self.language = Some(language.into());
52 self
53 }
54
55 #[must_use]
57 pub fn line_numbers(mut self, line_numbers: bool) -> Self {
58 self.line_numbers = Some(line_numbers);
59 self
60 }
61
62 #[must_use]
64 pub fn start_line(mut self, start_line: u32) -> Self {
65 self.start_line = Some(start_line);
66 self
67 }
68
69 #[must_use]
71 pub fn highlight_lines(mut self, lines: impl IntoIterator<Item = u32>) -> Self {
72 self.highlight_lines = lines.into_iter().collect();
73 self
74 }
75
76 #[must_use]
78 pub fn wrap(mut self, wrap: bool) -> Self {
79 self.wrap = Some(wrap);
80 self
81 }
82}
83
84impl IntoNode for Code {}
85impl From<Code> for Node {
86 fn from(c: Code) -> Self {
87 Node::Code(c)
88 }
89}