use std::fmt::{self, Write};
use crate::bound::Bound;
use crate::docs::Docs;
use crate::formatter::{fmt_bounds, Formatter};
use crate::r#type::Type;
#[derive(Debug, Clone)]
pub struct TypeDef {
pub ty: Type,
vis: Option<String>,
docs: Option<Docs>,
derive: Vec<String>,
allow: Vec<String>,
attributes: Vec<String>,
repr: Option<String>,
bounds: Vec<Bound>,
macros: Vec<String>,
}
impl TypeDef {
pub fn new(name: impl Into<String>) -> Self {
TypeDef {
ty: Type::new(name),
vis: None,
docs: None,
derive: vec![],
allow: vec![],
attributes: vec![],
repr: None,
bounds: vec![],
macros: vec![],
}
}
pub fn vis(&mut self, vis: impl Into<String>) {
self.vis = Some(vis.into());
}
pub fn bound<T>(&mut self, name: impl Into<String>, ty: T)
where
T: Into<Type>,
{
self.bounds.push(Bound {
name: name.into(),
bound: vec![ty.into()],
});
}
pub fn r#macro(&mut self, r#macro: impl Into<String>) {
self.macros.push(r#macro.into());
}
pub fn attr(&mut self, attr: impl Into<String>) {
self.attributes.push(attr.into());
}
pub fn doc(&mut self, docs: impl Into<String>) {
self.docs = Some(Docs::new(docs.into()));
}
pub fn derive(&mut self, name: impl Into<String>) {
self.derive.push(name.into());
}
pub fn allow(&mut self, allow: impl Into<String>) {
self.allow.push(allow.into());
}
pub fn repr(&mut self, repr: impl Into<String>) {
self.repr = Some(repr.into());
}
pub fn fmt_head(
&self,
keyword: &str,
parents: &[Type],
fmt: &mut Formatter<'_>,
) -> fmt::Result {
if let Some(ref docs) = self.docs {
docs.fmt(fmt)?;
}
self.fmt_allow(fmt)?;
self.fmt_derive(fmt)?;
self.fmt_repr(fmt)?;
self.fmt_attributes(fmt)?;
self.fmt_macros(fmt)?;
if let Some(ref vis) = self.vis {
write!(fmt, "{} ", vis)?;
}
write!(fmt, "{} ", keyword)?;
self.ty.fmt(fmt)?;
if !parents.is_empty() {
for (i, ty) in parents.iter().enumerate() {
if i == 0 {
write!(fmt, ": ")?;
} else {
write!(fmt, " + ")?;
}
ty.fmt(fmt)?;
}
}
fmt_bounds(&self.bounds, fmt)?;
Ok(())
}
fn fmt_attributes(&self, fmt: &mut Formatter) -> fmt::Result {
for attr in &self.attributes {
write!(fmt, "#[{}]\n", attr)?;
}
Ok(())
}
fn fmt_allow(&self, fmt: &mut Formatter) -> fmt::Result {
for allow in &self.allow {
write!(fmt, "#[allow({})]\n", allow)?;
}
Ok(())
}
fn fmt_repr(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
if let Some(ref repr) = self.repr {
write!(fmt, "#[repr({})]\n", repr)?;
}
Ok(())
}
fn fmt_derive(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
if !self.derive.is_empty() {
write!(fmt, "#[derive(")?;
for (i, name) in self.derive.iter().enumerate() {
if i != 0 {
write!(fmt, ", ")?
}
write!(fmt, "{}", name)?;
}
write!(fmt, ")]\n")?;
}
Ok(())
}
fn fmt_macros(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
for m in self.macros.iter() {
write!(fmt, "{}\n", m)?;
}
Ok(())
}
}