mod format_expression;
mod format_spec;
pub use format_expression::*;
pub use format_spec::*;
use microcad_lang_base::{Refer, SrcRef, SrcReferrer};
use microcad_lang_proc_macros::SrcReferrer;
#[derive(Debug, Clone, PartialEq)]
pub enum FormatStringInner {
String(Refer<String>),
FormatExpression(Box<FormatExpression>),
}
impl SrcReferrer for FormatStringInner {
fn src_ref(&self) -> SrcRef {
match self {
FormatStringInner::String(s) => s.src_ref(),
FormatStringInner::FormatExpression(e) => e.src_ref(),
}
}
}
#[derive(Default, Clone, Debug, PartialEq, SrcReferrer)]
pub struct FormatString(pub Refer<Vec<FormatStringInner>>);
impl FormatString {
pub fn push_string(&mut self, s: String, src_ref: SrcRef) {
self.0
.push(FormatStringInner::String(Refer::new(s, src_ref)));
}
pub fn push_format_expr(&mut self, expr: FormatExpression) {
self.0
.push(FormatStringInner::FormatExpression(Box::new(expr)));
}
pub fn section_count(&self) -> usize {
self.0.len()
}
}
impl From<Refer<String>> for FormatString {
fn from(value: Refer<String>) -> Self {
FormatString(Refer {
src_ref: value.src_ref.clone(),
value: vec![FormatStringInner::String(value)],
})
}
}
impl std::fmt::Display for FormatString {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, r#"""#)?;
for elem in &*self.0 {
match elem {
FormatStringInner::String(s) => write!(f, "{}", s.value)?,
FormatStringInner::FormatExpression(expr) => write!(f, "{expr}")?,
}
}
write!(f, r#"""#)?;
Ok(())
}
}