microcad_lang/syntax/format_string/
mod.rs

1// Copyright © 2024-2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! µcad format expression syntax elements
5
6mod format_expression;
7mod format_spec;
8
9pub use format_expression::*;
10pub use format_spec::*;
11
12use crate::{src_ref::*, syntax::*};
13
14/// Format string item.
15#[derive(Clone, Debug)]
16pub enum FormatStringInner {
17    /// String literal.
18    String(Refer<String>),
19    /// Format expression.
20    FormatExpression(FormatExpression),
21}
22
23impl SrcReferrer for FormatStringInner {
24    fn src_ref(&self) -> crate::src_ref::SrcRef {
25        match self {
26            FormatStringInner::String(s) => s.src_ref(),
27            FormatStringInner::FormatExpression(e) => e.src_ref(),
28        }
29    }
30}
31
32/// Format string.
33#[derive(Default, Clone, Debug)]
34pub struct FormatString(pub Refer<Vec<FormatStringInner>>);
35
36impl FormatString {
37    /// Insert a string.
38    pub fn push_string(&mut self, s: String, src_ref: SrcRef) {
39        self.0
40            .push(FormatStringInner::String(Refer::new(s, src_ref)));
41    }
42
43    /// Insert a format expression
44    pub fn push_format_expr(&mut self, expr: FormatExpression) {
45        self.0.push(FormatStringInner::FormatExpression(expr));
46    }
47
48    /// Return the number of sections (inserted elements)
49    pub fn section_count(&self) -> usize {
50        self.0.len()
51    }
52}
53
54impl SrcReferrer for FormatString {
55    fn src_ref(&self) -> crate::src_ref::SrcRef {
56        self.0.src_ref.clone()
57    }
58}
59
60impl std::fmt::Display for FormatString {
61    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
62        write!(f, r#"""#)?;
63        for elem in &*self.0 {
64            match elem {
65                FormatStringInner::String(s) => write!(f, "{}", s.value)?,
66                FormatStringInner::FormatExpression(expr) => write!(f, "{expr}")?,
67            }
68        }
69        write!(f, r#"""#)?;
70        Ok(())
71    }
72}
73
74impl TreeDisplay for FormatString {
75    fn tree_print(&self, f: &mut std::fmt::Formatter, mut depth: TreeState) -> std::fmt::Result {
76        writeln!(f, "{:depth$}FormatString:", "")?;
77        depth.indent();
78        self.0.iter().try_for_each(|fs| match fs {
79            FormatStringInner::String(s) => writeln!(f, "{:depth$}String: \"{}\"", "", s.value),
80            FormatStringInner::FormatExpression(e) => e.tree_print(f, depth),
81        })
82    }
83}