rust_codegen/struct.rs
1use std::fmt::{self, Write};
2
3use crate::field::Field;
4use crate::fields::Fields;
5use crate::formatter::Formatter;
6use crate::type_def::TypeDef;
7
8use crate::r#type::Type;
9
10/// Defines a struct.
11#[derive(Debug, Clone)]
12pub struct Struct {
13 type_def: TypeDef,
14 /// Struct fields
15 fields: Fields,
16 /// The attributes for this struct.
17 attributes: Vec<String>,
18}
19
20impl Struct {
21 /// Return a structure definition with the provided name.
22 ///
23 /// # Arguments
24 ///
25 /// * `name` - The name of the struct.
26 ///
27 /// # Examples
28 ///
29 /// ```
30 /// use rust_codegen::Struct;
31 ///
32 /// let foo_struct = Struct::new("Foo");
33 /// ```
34 pub fn new(name: &str) -> Self {
35 Struct {
36 type_def: TypeDef::new(name),
37 fields: Fields::Empty,
38 attributes: vec![],
39 }
40 }
41
42 /// Returns a reference to the type.
43 ///
44 /// # Examples
45 ///
46 /// ```
47 /// use rust_codegen::Struct;
48 ///
49 /// let foo_struct = Struct::new("Foo");
50 /// println!("{:?}", foo_struct.ty());
51 /// ```
52 pub fn ty(&self) -> &Type {
53 &self.type_def.ty
54 }
55
56 /// Set the structure visibility.
57 ///
58 /// # Arguments
59 ///
60 /// * `vis` - The visibility of the struct.
61 ///
62 /// # Examples
63 ///
64 /// ```
65 /// use rust_codegen::Struct;
66 ///
67 /// let mut foo_struct = Struct::new("Foo");
68 /// foo_struct.vis("pub");
69 /// ```
70 pub fn vis(&mut self, vis: &str) -> &mut Self {
71 self.type_def.vis(vis);
72 self
73 }
74
75 /// Add a generic to the struct.
76 ///
77 /// # Arguments
78 ///
79 /// * `name` - The name of the generic.
80 ///
81 /// # Examples
82 ///
83 /// ```
84 /// use rust_codegen::Struct;
85 ///
86 /// let mut foo_struct = Struct::new("Foo");
87 /// foo_struct.generic("T");
88 /// ```
89 pub fn generic(&mut self, name: &str) -> &mut Self {
90 self.type_def.ty.generic(name);
91 self
92 }
93
94 /// Add a `where` bound to the struct.
95 ///
96 /// # Arguments
97 ///
98 /// * `name` - The name of the bound.
99 /// * `ty` - The type of the bound.
100 ///
101 /// # Examples
102 ///
103 /// ```
104 /// use rust_codegen::Struct;
105 ///
106 /// let mut foo_struct = Struct::new("Foo");
107 /// foo_struct.bound("A", "TraitA");
108 /// ```
109 pub fn bound<T>(&mut self, name: &str, ty: T) -> &mut Self
110 where
111 T: Into<Type>,
112 {
113 self.type_def.bound(name, ty);
114 self
115 }
116
117 /// Set the structure documentation.
118 ///
119 /// # Arguments
120 ///
121 /// * `docs` - The documentation to set for the struct.
122 ///
123 /// # Examples
124 ///
125 /// ```
126 /// use rust_codegen::Struct;
127 ///
128 /// let mut foo_struct = Struct::new("Foo");
129 /// foo_struct.doc("Sample struct documentation.");
130 /// ```
131 pub fn doc(&mut self, docs: &str) -> &mut Self {
132 self.type_def.doc(docs);
133 self
134 }
135
136 /// Add a new type that the struct should derive.
137 ///
138 /// # Arguments
139 ///
140 /// * `name` - The name of the type to derive.
141 ///
142 /// # Examples
143 ///
144 /// ```
145 /// use rust_codegen::Struct;
146 ///
147 /// let mut foo_struct = Struct::new("Foo");
148 /// foo_struct.derive("Debug");
149 /// ```
150 pub fn derive(&mut self, name: &str) -> &mut Self {
151 self.type_def.derive(name);
152 self
153 }
154
155 /// Specify lint attribute to supress a warning or error.
156 ///
157 /// # Arguments
158 ///
159 /// * `allow` - The lint attribute to add.
160 ///
161 /// # Examples
162 ///
163 /// ```
164 /// use rust_codegen::Struct;
165 ///
166 /// let mut foo_struct = Struct::new("Foo");
167 /// foo_struct.allow("dead_code");
168 /// ```
169 pub fn allow(&mut self, allow: &str) -> &mut Self {
170 self.type_def.allow(allow);
171 self
172 }
173
174 /// Specify representation.
175 ///
176 /// * `repr` - The representation to specify.
177 ///
178 /// # Examples
179 ///
180 /// ```
181 /// use rust_codegen::Struct;
182 ///
183 /// let mut foo_struct = Struct::new("Foo");
184 /// foo_struct.repr("C");
185 /// ```
186 pub fn repr(&mut self, repr: &str) -> &mut Self {
187 self.type_def.repr(repr);
188 self
189 }
190
191 /// Push a named field to the struct.
192 ///
193 /// A struct can either set named fields with this function or tuple fields
194 /// with `push_tuple_field`, but not both.
195 ///
196 /// # Arguments
197 ///
198 /// * `field` - The named field to push.
199 ///
200 /// # Examples
201 ///
202 /// ```
203 /// use rust_codegen::{Field,Struct};
204 ///
205 /// let mut foo_struct = Struct::new("Foo");
206 /// let mut bar_field = Field::new("bar", "i32");
207 ///
208 /// foo_struct.push_field(bar_field);
209 /// ```
210 pub fn push_field(&mut self, field: Field) -> &mut Self {
211 self.fields.push_named(field);
212 self
213 }
214
215 /// Add a named field to the struct.
216 ///
217 /// A struct can either set named fields with this function or tuple fields
218 /// with `tuple_field`, but not both.
219 ///
220 /// # Arguments
221 ///
222 /// * `name` - The name of the field.
223 /// * `ty` - The type of the field.
224 ///
225 /// # Examples
226 ///
227 /// ```
228 /// use rust_codegen::Struct;
229 ///
230 /// let mut foo_struct = Struct::new("Foo");
231 /// foo_struct.field("bar", "i32");
232 /// ```
233 pub fn field<T>(&mut self, name: &str, ty: T) -> &mut Self
234 where
235 T: Into<Type>,
236 {
237 self.fields.named(name, ty);
238 self
239 }
240
241 /// Add a tuple field to the struct.
242 ///
243 /// A struct can either set tuple fields with this function or named fields
244 /// with `field`, but not both.
245 ///
246 /// # Arguments
247 ///
248 /// * `ty` - The type of the tuple field to add.
249 ///
250 /// # Examples
251 ///
252 /// ```
253 /// use rust_codegen::{Struct,Type};
254 ///
255 /// let mut foo_struct = Struct::new("Foo");
256 /// let mut bar_type = Type::new("bar");
257 ///
258 /// foo_struct.tuple_field(bar_type);
259 /// ```
260 pub fn tuple_field<T>(&mut self, ty: T) -> &mut Self
261 where
262 T: Into<Type>,
263 {
264 self.fields.tuple(ty);
265 self
266 }
267
268 /// Adds an attribute to the struct (e.g. `"#[some_attribute]"`)
269 ///
270 /// # Arguments
271 ///
272 /// * `attribute` - The attribute to add.
273 ///
274 /// # Examples
275 ///
276 /// ```
277 /// use rust_codegen::Struct;
278 ///
279 /// let mut foo_struct = Struct::new("Foo");
280 /// foo_struct.attr("some_attribute");
281 /// ```
282 pub fn attr(&mut self, attribute: &str) -> &mut Self {
283 self.attributes.push(attribute.to_string());
284 self
285 }
286
287 /// Formats the struct using the given formatter.
288 ///
289 /// # Arguments
290 ///
291 /// * `fmt` - The formatter to use.
292 ///
293 /// # Examples
294 ///
295 /// ```
296 /// use rust_codegen::*;
297 ///
298 /// let mut dest = String::new();
299 /// let mut fmt = Formatter::new(&mut dest);
300 ///
301 /// let mut foo_struct = Struct::new("Foo");
302 /// foo_struct.fmt(&mut fmt);
303 pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
304 for m in self.attributes.iter() {
305 write!(fmt, "{}\n", m)?;
306 }
307
308 self.type_def.fmt_head("struct", &[], fmt)?;
309 self.fields.fmt(fmt)?;
310
311 match self.fields {
312 Fields::Empty => {
313 write!(fmt, ";\n")?;
314 }
315 Fields::Tuple(..) => {
316 write!(fmt, ";\n")?;
317 }
318 _ => {}
319 }
320
321 Ok(())
322 }
323}