|
16 | 16 | // Copyright (C) 2022-2022 Fuwn <contact@fuwn.me> |
17 | 17 | // SPDX-License-Identifier: GPL-3.0-only |
18 | 18 |
|
19 | | -use super::Node; |
| 19 | +use {super::Node, std::fmt::Write}; |
20 | 20 |
|
21 | 21 | /// An AST structure which contains an AST tree |
22 | 22 | /// |
@@ -52,7 +52,7 @@ impl Ast { |
52 | 52 | /// ``` |
53 | 53 | #[must_use] |
54 | 54 | #[allow(clippy::needless_pass_by_value)] |
55 | | - pub fn from_string(value: (impl Into<String> + ?Sized)) -> Self { |
| 55 | + pub fn from_string(value: impl Into<String>) -> Self { |
56 | 56 | Self::from_value(&value.into()) |
57 | 57 | } |
58 | 58 |
|
@@ -82,7 +82,7 @@ impl Ast { |
82 | 82 | )); |
83 | 83 | } |
84 | 84 |
|
85 | | - if source.chars().last().map_or(false, |c| c == '\n') { |
| 85 | + if source.ends_with('\n') { |
86 | 86 | if let Some(last) = ast.last() { |
87 | 87 | if !matches!(last, Node::Whitespace) { |
88 | 88 | ast.push(Node::Whitespace); |
@@ -110,37 +110,50 @@ impl Ast { |
110 | 110 | /// ); |
111 | 111 | /// ``` |
112 | 112 | #[must_use] |
113 | | - pub fn from_nodes(nodes: Vec<Node>) -> Self { Self { inner: nodes } } |
| 113 | + pub const fn from_nodes(nodes: Vec<Node>) -> Self { Self { inner: nodes } } |
114 | 114 |
|
115 | 115 | #[must_use] |
116 | 116 | pub fn to_gemtext(&self) -> String { |
117 | 117 | let mut gemtext = String::new(); |
118 | 118 |
|
119 | 119 | for node in &self.inner { |
120 | 120 | match node { |
121 | | - Node::Text(text) => gemtext.push_str(&format!("{text}\n")), |
122 | | - Node::Link { to, text } => gemtext.push_str(&format!( |
123 | | - "=> {}{}\n", |
124 | | - to, |
125 | | - text.clone().map_or_else(String::new, |text| format!(" {text}")), |
126 | | - )), |
127 | | - Node::Heading { level, text } => |
128 | | - gemtext.push_str(&format!("{} {}\n", "#".repeat(*level), text)), |
129 | | - Node::List(items) => gemtext.push_str(&format!( |
130 | | - "{}\n", |
131 | | - items |
132 | | - .iter() |
133 | | - .map(|i| format!("* {i}")) |
134 | | - .collect::<Vec<String>>() |
135 | | - .join("\n"), |
136 | | - )), |
137 | | - Node::Blockquote(text) => gemtext.push_str(&format!("> {text}\n")), |
138 | | - Node::PreformattedText { alt_text, text } => |
139 | | - gemtext.push_str(&format!( |
140 | | - "```{}\n{}```\n", |
| 121 | + Node::Text(text) => { |
| 122 | + let _ = writeln!(&mut gemtext, "{text}"); |
| 123 | + } |
| 124 | + Node::Link { to, text } => { |
| 125 | + let _ = writeln!( |
| 126 | + &mut gemtext, |
| 127 | + "=> {}{}", |
| 128 | + to, |
| 129 | + text.clone().map_or_else(String::new, |text| format!(" {text}")), |
| 130 | + ); |
| 131 | + } |
| 132 | + Node::Heading { level, text } => { |
| 133 | + let _ = writeln!(&mut gemtext, "{} {}", "#".repeat(*level), text); |
| 134 | + } |
| 135 | + Node::List(items) => { |
| 136 | + let _ = writeln!( |
| 137 | + &mut gemtext, |
| 138 | + "{}", |
| 139 | + items |
| 140 | + .iter() |
| 141 | + .map(|i| format!("* {i}")) |
| 142 | + .collect::<Vec<String>>() |
| 143 | + .join("\n"), |
| 144 | + ); |
| 145 | + } |
| 146 | + Node::Blockquote(text) => { |
| 147 | + let _ = writeln!(&mut gemtext, "> {text}"); |
| 148 | + } |
| 149 | + Node::PreformattedText { alt_text, text } => { |
| 150 | + let _ = writeln!( |
| 151 | + &mut gemtext, |
| 152 | + "```{}\n{}```", |
141 | 153 | alt_text.clone().unwrap_or_default(), |
142 | 154 | text |
143 | | - )), |
| 155 | + ); |
| 156 | + } |
144 | 157 | Node::Whitespace => gemtext.push('\n'), |
145 | 158 | } |
146 | 159 | } |
@@ -281,7 +294,7 @@ impl Ast { |
281 | 294 | if *in_preformatted { |
282 | 295 | // If we are in a preformatted line context, add the line to the |
283 | 296 | // preformatted blocks content and increment the line. |
284 | | - preformatted.push_str(&format!("{line}\n")); |
| 297 | + let _ = writeln!(&mut preformatted, "{line}"); |
285 | 298 |
|
286 | 299 | if let Some(next_line) = lines.next() { |
287 | 300 | line = next_line; |
|
0 commit comments