use std::fmt;
use std::fmt::Write;
use crate::{Doc, Formatter, Type, Variant};
#[derive(Debug, Clone)]
pub struct Enum {
name: String,
variants: Vec<Variant>,
doc: Option<Doc>,
}
impl Enum {
pub fn new(name: &str) -> Self {
Self {
name: String::from(name),
variants: Vec::new(),
doc: None,
}
}
pub fn with_variants(name: &str, variants: Vec<Variant>) -> Self {
Self {
name: String::from(name),
variants,
doc: None,
}
}
pub fn to_type(&self) -> Type {
Type::new_enum(&self.name)
}
pub fn doc(&mut self, doc: Doc) -> &mut Self {
self.doc = Some(doc);
self
}
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 new_variant(&mut self, name: &str) -> &mut Variant {
self.variants.push(Variant::new(name));
self.variants.last_mut().unwrap()
}
pub fn push_variant(&mut self, item: Variant) -> &mut Self {
self.variants.push(item);
self
}
pub fn variant_by_name(&self, name: &str) -> Option<&Variant> {
self.variants.iter().find(|f| f.name() == name)
}
pub fn variant_by_name_mut(&mut self, name: &str) -> Option<&mut Variant> {
self.variants.iter_mut().find(|f| f.name() == name)
}
pub fn variant_by_idx(&self, idx: usize) -> Option<&Variant> {
self.variants.get(idx)
}
pub fn variant_by_idx_mut(&mut self, idx: usize) -> Option<&mut Variant> {
self.variants.get_mut(idx)
}
pub fn fmt_decl(&self, fmt: &mut Formatter) -> fmt::Result {
write!(fmt, "enum {}; // forward declaration", self.name)
}
pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
if let Some(ref docs) = self.doc {
docs.fmt(fmt)?;
}
write!(fmt, "enum {}", self.name)?;
fmt.block(|fmt| {
let mut first = true;
for variant in &self.variants {
if first {
first = false;
} else {
writeln!(fmt, ",")?;
}
variant.fmt(fmt)?;
}
Ok(())
})?;
writeln!(fmt, ";")
}
}