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