use std::fmt::{self, Write};
use crate::doc::Doc;
use crate::formatter::Formatter;
#[derive(Debug, Clone)]
pub struct Macro {
name: String,
args: Vec<String>,
value: Option<String>,
doc: Option<Doc>,
}
impl Macro {
pub fn new(name: &str) -> Self {
Self::with_name(String::from(name))
}
pub fn with_name(name: String) -> Self {
Macro {
name,
args: Vec::new(),
value: None,
doc: None,
}
}
pub fn doc_str(&mut self, doc: &str) -> &mut Self {
if let Some(d) = &mut self.doc {
d.add_text(doc);
} else {
self.doc = Some(Doc::with_str(doc));
}
self
}
pub fn doc(&mut self, doc: Doc) -> &mut Self {
self.doc = Some(doc);
self
}
pub fn new_arg(&mut self, arg: &str) -> &mut Self {
self.args.push(String::from(arg));
self
}
pub fn set_value(&mut self, value: &str) -> &mut Self {
self.value = Some(String::from(value));
self
}
pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
if let Some(ref docs) = self.doc {
docs.fmt(fmt)?;
}
write!(fmt, "#define {} ", self.name)?;
if !self.args.is_empty() {
let args = self.args.join(", ");
write!(fmt, "({args})")?;
}
if let Some(v) = &self.value {
fmt.indent(|f| {
for (i, l) in v.lines().enumerate() {
if i != 0 {
writeln!(f, "\\")?;
}
write!(f, "{l}")?;
}
writeln!(f)?;
Ok(())
})
} else {
writeln!(fmt)
}
}
}