miden_assembly_syntax/ast/
docstring.rs

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