rust_codegen/
enum.rs

1use std::fmt;
2
3use crate::formatter::Formatter;
4use crate::type_def::TypeDef;
5use crate::variant::Variant;
6
7use crate::r#type::Type;
8
9/// Defines an enumeration.
10#[derive(Debug, Clone)]
11pub struct Enum {
12    type_def: TypeDef,
13    variants: Vec<Variant>,
14}
15
16impl Enum {
17    /// Returns a enum definition with the provided name.
18    /// 
19    /// # Arguments
20    /// 
21    /// * `name` - The name of the enum.
22    /// 
23    /// # Examples
24    /// 
25    /// ```
26    /// use rust_codegen::Enum;
27    /// 
28    /// let foo_enum = Enum::new("Foo");
29    /// ```
30    pub fn new(name: &str) -> Self {
31        Enum {
32            type_def: TypeDef::new(name),
33            variants: vec![],
34        }
35    }
36
37    /// Returns a reference to the enum's type.
38    /// 
39    /// # Examples
40    /// 
41    /// ```
42    /// use rust_codegen::Enum;
43    /// 
44    /// let foo_enum = Enum::new("Foo");
45    /// println!("{:?}", foo_enum.ty());
46    /// ```
47    pub fn ty(&self) -> &Type {
48        &self.type_def.ty
49    }
50
51    /// Set the enum's visibility.
52    /// 
53    /// # Arguments
54    /// 
55    /// * `vis` - The visibility of the enum.
56    /// 
57    /// # Examples
58    /// 
59    /// ```
60    /// use rust_codegen::Enum;
61    /// 
62    /// let mut foo_enum = Enum::new("Foo");
63    /// foo_enum.vis("pub");
64    /// ```
65    pub fn vis(&mut self, vis: &str) -> &mut Self {
66        self.type_def.vis(vis);
67        self
68    }
69
70    /// Add a generic to the enum.
71    /// 
72    /// # Arguments
73    /// 
74    /// * `name` - The name of the generic.
75    /// 
76    /// # Examples
77    /// 
78    /// ```
79    /// use rust_codegen::Enum;
80    /// 
81    /// let mut foo_enum = Enum::new("Foo");
82    /// foo_enum.generic("T");
83    /// ```
84    pub fn generic(&mut self, name: &str) -> &mut Self {
85        self.type_def.ty.generic(name);
86        self
87    }
88
89    /// Add a `where` bound to the enum.
90    /// 
91    /// # Arguments
92    /// 
93    /// * `name` - The name of the bound.
94    /// * `ty` - The type of the bound.
95    /// 
96    /// # Examples
97    /// 
98    /// ```
99    /// use rust_codegen::Enum;
100    /// 
101    /// let mut foo_enum = Enum::new("Foo");
102    /// foo_enum.bound("T", "Default");
103    /// ```
104    pub fn bound<T>(&mut self, name: &str, ty: T) -> &mut Self
105    where
106        T: Into<Type>,
107    {
108        self.type_def.bound(name, ty);
109        self
110    }
111
112    /// Set the enum's documentation.
113    /// 
114    /// # Arguments
115    /// 
116    /// * `docs` - The docs to set for the enum.
117    /// 
118    /// # Examples
119    /// 
120    /// ```
121    /// use rust_codegen::Enum;
122    /// 
123    /// let mut foo_enum = Enum::new("Foo");
124    /// foo_enum.doc("Sample Foo enum documentation");
125    /// ```
126    pub fn doc(&mut self, docs: &str) -> &mut Self {
127        self.type_def.doc(docs);
128        self
129    }
130
131    /// Add a new type that the enum should derive.
132    /// 
133    /// # Arguments
134    /// 
135    /// * `name` - The name of the derive.
136    /// 
137    /// # Examples
138    /// 
139    /// ```
140    /// use rust_codegen::Enum;
141    /// 
142    /// let mut foo_enum = Enum::new("Foo");
143    /// foo_enum.derive("Debug");
144    /// ```
145    pub fn derive(&mut self, name: &str) -> &mut Self {
146        self.type_def.derive(name);
147        self
148    }
149
150    /// Specify lint attribute to supress a warning or error.
151    /// 
152    /// # Arguments
153    /// 
154    /// * `allow` - The lint attribute to apply.
155    /// 
156    /// # Examples
157    /// 
158    /// ```
159    /// use rust_codegen::Enum;
160    /// 
161    /// let mut foo_enum = Enum::new("Foo");
162    /// foo_enum.allow("dead_code");
163    /// ```
164    pub fn allow(&mut self, allow: &str) -> &mut Self {
165        self.type_def.allow(allow);
166        self
167    }
168
169    /// Specify representation.
170    /// 
171    /// # Arguments
172    /// 
173    /// * `repr` - The representation to specify.
174    /// 
175    /// # Examples
176    /// 
177    /// ```
178    /// use rust_codegen::Enum;
179    /// 
180    /// let mut foo_enum = Enum::new("Foo");
181    /// foo_enum.repr("C");
182    /// ```
183    pub fn repr(&mut self, repr: &str) -> &mut Self {
184        self.type_def.repr(repr);
185        self
186    }
187
188    /// Push a variant to the enum, returning a mutable reference to it.
189    /// 
190    /// # Arguments
191    /// 
192    /// * `name` - The name of the variant.
193    /// 
194    /// # Examples
195    /// 
196    /// ```
197    /// use rust_codegen::Enum;
198    /// 
199    /// let mut foo_enum = Enum::new("Foo");
200    /// foo_enum.new_variant("FirstVariant");
201    /// ```
202    pub fn new_variant(&mut self, name: &str) -> &mut Variant {
203        self.push_variant(Variant::new(name));
204        self.variants.last_mut().unwrap()
205    }
206
207    /// Push a variant to the enum.
208    /// 
209    /// # Arguments
210    /// 
211    /// * `item` - The variant to push to the enum.
212    /// 
213    /// # Examples
214    /// 
215    /// ```
216    /// use rust_codegen::*;
217    /// 
218    /// let mut foo_enum = Enum::new("Foo");
219    /// 
220    /// let foo_enum_first_variant = Variant::new("FirstVariant");
221    /// foo_enum.push_variant(foo_enum_first_variant);
222    /// ```
223    pub fn push_variant(&mut self, item: Variant) -> &mut Self {
224        self.variants.push(item);
225        self
226    }
227
228    /// Formats the enum using the given formatter.
229    /// 
230    /// # Arguments
231    /// 
232    /// * `fmt` - The formatter to use.
233    /// 
234    /// # Examples
235    /// 
236    /// ```
237    /// use rust_codegen::*;
238    /// 
239    /// let mut dest = String::new();
240    /// let mut fmt = Formatter::new(&mut dest);
241    /// 
242    /// let foo_enum = Enum::new("Foo");
243    /// foo_enum.fmt(&mut fmt);
244    /// ```
245    pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
246        self.type_def.fmt_head("enum", &[], fmt)?;
247
248        fmt.block(|fmt| {
249            for variant in &self.variants {
250                variant.fmt(fmt)?;
251            }
252
253            Ok(())
254        })
255    }
256}