miden_assembly/ast/
docstring.rs1use alloc::string::String;
2
3use crate::{Span, Spanned, prettier::PrettyPrint};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct DocString(Span<String>);
8
9impl DocString {
10 pub fn new(content: Span<String>) -> Self {
12 Self(content)
13 }
14
15 pub fn set(&mut self, content: String) {
17 *self.0 = content;
18 }
19
20 #[inline]
22 pub fn as_str(&self) -> &str {
23 self.as_ref()
24 }
25
26 #[inline]
28 pub fn as_spanned_str(&self) -> Span<&str> {
29 self.0.as_deref()
30 }
31
32 pub fn is_empty(&self) -> bool {
34 self.0.is_empty()
35 }
36}
37
38impl Spanned for DocString {
39 fn span(&self) -> crate::SourceSpan {
40 self.0.span()
41 }
42}
43
44impl AsRef<str> for DocString {
45 #[inline]
46 fn as_ref(&self) -> &str {
47 self.0.as_str()
48 }
49}
50
51impl core::fmt::Display for DocString {
52 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
53 use crate::prettier::PrettyPrint;
54
55 self.pretty_print(f)
56 }
57}
58
59impl PrettyPrint for DocString {
60 fn render(&self) -> crate::prettier::Document {
61 use crate::prettier::*;
62
63 if self.is_empty() {
64 return Document::Empty;
65 }
66
67 let content = self.as_str();
68
69 let fragment = content.lines().map(text).reduce(|acc, line| {
70 if line.is_empty() {
71 acc + nl() + text("#!")
72 } else {
73 acc + nl() + text("#! ") + line
74 }
75 });
76
77 fragment.map(|doc| const_text("#! ") + doc + nl()).unwrap_or(Document::Empty)
78 }
79}