1use std::fmt::{self, Write};
2
3use crate::bound::Bound;
4use crate::docs::Docs;
5use crate::formatter::{fmt_bounds, Formatter};
6
7use crate::r#type::Type;
8
9#[derive(Debug, Clone)]
11pub struct TypeDef {
12 pub ty: Type,
13 vis: Option<String>,
14 docs: Option<Docs>,
15 derive: Vec<String>,
16 allow: Vec<String>,
17 attributes: Vec<String>,
18 repr: Option<String>,
19 bounds: Vec<Bound>,
20 macros: Vec<String>,
21}
22
23impl TypeDef {
24 pub fn new(name: impl Into<String>) -> Self {
26 TypeDef {
27 ty: Type::new(name),
28 vis: None,
29 docs: None,
30 derive: vec![],
31 allow: vec![],
32 attributes: vec![],
33 repr: None,
34 bounds: vec![],
35 macros: vec![],
36 }
37 }
38
39 pub fn vis(&mut self, vis: impl Into<String>) {
40 self.vis = Some(vis.into());
41 }
42
43 pub fn bound<T>(&mut self, name: impl Into<String>, ty: T)
44 where
45 T: Into<Type>,
46 {
47 self.bounds.push(Bound {
48 name: name.into(),
49 bound: vec![ty.into()],
50 });
51 }
52
53 pub fn r#macro(&mut self, r#macro: impl Into<String>) {
54 self.macros.push(r#macro.into());
55 }
56
57 pub fn attr(&mut self, attr: impl Into<String>) {
58 self.attributes.push(attr.into());
59 }
60
61 pub fn doc(&mut self, docs: impl Into<String>) {
62 self.docs = Some(Docs::new(docs.into()));
63 }
64
65 pub fn derive(&mut self, name: impl Into<String>) {
66 self.derive.push(name.into());
67 }
68
69 pub fn allow(&mut self, allow: impl Into<String>) {
70 self.allow.push(allow.into());
71 }
72
73 pub fn repr(&mut self, repr: impl Into<String>) {
74 self.repr = Some(repr.into());
75 }
76
77 pub fn fmt_head(
78 &self,
79 keyword: &str,
80 parents: &[Type],
81 fmt: &mut Formatter<'_>,
82 ) -> fmt::Result {
83 if let Some(ref docs) = self.docs {
84 docs.fmt(fmt)?;
85 }
86
87 self.fmt_allow(fmt)?;
88 self.fmt_derive(fmt)?;
89 self.fmt_repr(fmt)?;
90 self.fmt_attributes(fmt)?;
91 self.fmt_macros(fmt)?;
92
93 if let Some(ref vis) = self.vis {
94 write!(fmt, "{} ", vis)?;
95 }
96
97 write!(fmt, "{} ", keyword)?;
98 self.ty.fmt(fmt)?;
99
100 if !parents.is_empty() {
101 for (i, ty) in parents.iter().enumerate() {
102 if i == 0 {
103 write!(fmt, ": ")?;
104 } else {
105 write!(fmt, " + ")?;
106 }
107
108 ty.fmt(fmt)?;
109 }
110 }
111
112 fmt_bounds(&self.bounds, fmt)?;
113
114 Ok(())
115 }
116
117 fn fmt_attributes(&self, fmt: &mut Formatter) -> fmt::Result {
118 for attr in &self.attributes {
119 write!(fmt, "#[{}]\n", attr)?;
120 }
121
122 Ok(())
123 }
124
125 fn fmt_allow(&self, fmt: &mut Formatter) -> fmt::Result {
126 for allow in &self.allow {
127 write!(fmt, "#[allow({})]\n", allow)?;
128 }
129
130 Ok(())
131 }
132
133 fn fmt_repr(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
134 if let Some(ref repr) = self.repr {
135 write!(fmt, "#[repr({})]\n", repr)?;
136 }
137
138 Ok(())
139 }
140
141 fn fmt_derive(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
142 if !self.derive.is_empty() {
143 write!(fmt, "#[derive(")?;
144
145 for (i, name) in self.derive.iter().enumerate() {
146 if i != 0 {
147 write!(fmt, ", ")?
148 }
149 write!(fmt, "{}", name)?;
150 }
151
152 write!(fmt, ")]\n")?;
153 }
154
155 Ok(())
156 }
157
158 fn fmt_macros(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
159 for m in self.macros.iter() {
160 write!(fmt, "{}\n", m)?;
161 }
162 Ok(())
163 }
164}