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}