codegen2/
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
15    /// Struct fields
16    fields: Fields,
17
18    /// The attributes for this struct.
19    attributes: Vec<String>,
20}
21
22impl Struct {
23    /// Return a structure definition with the provided name
24    pub fn new(name: &str) -> Self {
25        Struct {
26            type_def: TypeDef::new(name),
27            fields: Fields::Empty,
28            attributes: vec![],
29        }
30    }
31
32    /// Returns a reference to the type
33    pub fn ty(&self) -> &Type {
34        &self.type_def.ty
35    }
36
37    /// Set the structure visibility.
38    pub fn vis(&mut self, vis: &str) -> &mut Self {
39        self.type_def.vis(vis);
40        self
41    }
42
43    /// Add a generic to the struct.
44    pub fn generic(&mut self, name: &str) -> &mut Self {
45        self.type_def.ty.generic(name);
46        self
47    }
48
49    /// Add a `where` bound to the struct.
50    pub fn bound<T>(&mut self, name: &str, ty: T) -> &mut Self
51    where
52        T: Into<Type>,
53    {
54        self.type_def.bound(name, ty);
55        self
56    }
57
58    /// Set the structure documentation.
59    pub fn doc(&mut self, docs: &str) -> &mut Self {
60        self.type_def.doc(docs);
61        self
62    }
63
64    /// Add a new type that the struct should derive.
65    pub fn derive(&mut self, name: &str) -> &mut Self {
66        self.type_def.derive(name);
67        self
68    }
69
70    /// Adds an attribute to the struct (e.g. `"#[some_attribute]"`)
71    pub fn attribute(&mut self, attribute: &str) -> &mut Self {
72        self.attributes.push(attribute.to_string());
73        self
74    }
75
76    /// Specify lint attribute to supress a warning or error.
77    pub fn allow(&mut self, allow: &str) -> &mut Self {
78        self.type_def.allow(allow);
79        self
80    }
81
82    /// Specify representation.
83    pub fn repr(&mut self, repr: &str) -> &mut Self {
84        self.type_def.repr(repr);
85        self
86    }
87
88    /// Add an arbitrary macro.
89    pub fn r#macro(&mut self, r#macro: &str) -> &mut Self {
90        self.type_def.r#macro(r#macro);
91        self
92    }
93
94    /// Push a named field to the struct.
95    ///
96    /// A struct can either set named fields with this function or tuple fields
97    /// with `push_tuple_field`, but not both.
98    pub fn push_field(&mut self, field: Field) -> &mut Self {
99        self.fields.push_named(field);
100        self
101    }
102
103    /// Add a named field to the struct.
104    ///
105    /// A struct can either set named fields with this function or tuple fields
106    /// with `tuple_field`, but not both.
107    pub fn field<T>(&mut self, name: &str, ty: T) -> &mut Self
108    where
109        T: Into<Type>,
110    {
111        self.fields.named(name, ty);
112        self
113    }
114
115    /// Add a tuple field to the struct.
116    ///
117    /// A struct can either set tuple fields with this function or named fields
118    /// with `field`, but not both.
119    pub fn tuple_field<T>(&mut self, ty: T) -> &mut Self
120    where
121        T: Into<Type>,
122    {
123        self.fields.tuple(ty);
124        self
125    }
126
127    /// Formats the struct using the given formatter.
128    pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
129        for m in self.attributes.iter() {
130            write!(fmt, "{}\n", m)?;
131        }
132        self.type_def.fmt_head("struct", &[], fmt)?;
133        self.fields.fmt(fmt)?;
134
135        match self.fields {
136            Fields::Empty => {
137                write!(fmt, ";\n")?;
138            }
139            Fields::Tuple(..) => {
140                write!(fmt, ";\n")?;
141            }
142            _ => {}
143        }
144
145        Ok(())
146    }
147}