rust_codegen/module.rs
1use std::fmt::{self, Write};
2
3use crate::docs::Docs;
4use crate::formatter::Formatter;
5use crate::function::Function;
6use crate::scope::Scope;
7
8use crate::r#enum::Enum;
9use crate::r#impl::Impl;
10use crate::r#struct::Struct;
11use crate::r#trait::Trait;
12
13/// Defines a module.
14#[derive(Debug, Clone)]
15#[allow(dead_code)]
16pub struct Module {
17 /// The module's name.
18 pub name: String,
19 /// The module's visibility.
20 vis: Option<String>,
21 /// Module documentation.
22 docs: Option<Docs>,
23 /// Contents of the module.
24 scope: Scope,
25}
26
27impl Module {
28 /// Return a new, blank module.
29 ///
30 /// # Arguments
31 ///
32 /// * `name` - The name of the module.
33 ///
34 /// # Examples
35 ///
36 /// ```
37 /// use rust_codegen::Module;
38 ///
39 /// let foo_module = Module::new("Foo");
40 /// ```
41 pub fn new(name: &str) -> Self {
42 Module {
43 name: name.to_string(),
44 vis: None,
45 docs: None,
46 scope: Scope::new(),
47 }
48 }
49
50 /// Returns a mutable reference to the module's scope.
51 ///
52 /// # Examples
53 ///
54 /// ```
55 /// use rust_codegen::Module;
56 ///
57 /// let mut foo_module = Module::new("Foo");
58 /// println!("{:?}", foo_module.scope());
59 /// ```
60 pub fn scope(&mut self) -> &mut Scope {
61 &mut self.scope
62 }
63
64 /// Set the module visibility.
65 ///
66 /// # Arguments
67 ///
68 /// * `vis` - The visibility of the module.
69 ///
70 /// # Examples
71 ///
72 /// ```
73 /// use rust_codegen::Module;
74 ///
75 /// let mut foo_module = Module::new("Foo");
76 /// foo_module.vis("pub");
77 /// ```
78 pub fn vis(&mut self, vis: &str) -> &mut Self {
79 self.vis = Some(vis.to_string());
80 self
81 }
82
83 /// Import a type into the module's scope.
84 ///
85 /// This results in a new `use` statement bein added to the beginning of
86 /// the module.
87 ///
88 /// # Arguments
89 ///
90 /// * `path` - The path to the type to import.
91 /// * `ty` - The type to import.
92 ///
93 /// # Examples
94 ///
95 /// ```
96 /// use rust_codegen::Module;
97 ///
98 /// let mut foo_module = Module::new("Foo");
99 /// foo_module.import("rust_codegen", "Module");
100 /// ```
101 pub fn import(&mut self, path: &str, ty: &str) -> &mut Self {
102 self.scope.import(path, ty);
103 self
104 }
105
106 /// Push a new module definition, returning a mutable reference to it.
107 ///
108 /// # Panics
109 ///
110 /// Since a module's name must uniquely identify it within the scope in
111 /// which it is defined, pushing a module whose name is already defined
112 /// in this scope will cause this function to panic.
113 ///
114 /// In many cases, the [`get_or_new_module`] function is preferrable, as it
115 /// will return the existing definition instead.
116 ///
117 /// [`get_or_new_module`]: #method.get_or_new_module
118 ///
119 /// # Arguments
120 ///
121 /// * `name` - The name of the module.
122 ///
123 /// # Examples
124 ///
125 /// ```
126 /// use rust_codegen::Module;
127 ///
128 /// let mut foo_module = Module::new("Foo");
129 /// foo_module.new_module("Bar");
130 /// ```
131 pub fn new_module(&mut self, name: &str) -> &mut Module {
132 self.scope.new_module(name)
133 }
134
135 /// Returns a reference to a module if it is exists in this scope.
136 ///
137 /// # Arguments
138 ///
139 /// * `name` - The name of the module to get.
140 ///
141 /// # Examples
142 ///
143 /// ```
144 /// use rust_codegen::Module;
145 ///
146 /// let mut foo_module = Module::new("Foo");
147 /// foo_module.new_module("Bar");
148 ///
149 /// foo_module.get_module("Bar");
150 /// ```
151 pub fn get_module<Q: ?Sized>(&self, name: &Q) -> Option<&Module>
152 where
153 String: PartialEq<Q>,
154 {
155 self.scope.get_module(name)
156 }
157
158 /// Returns a mutable reference to a module if it is exists in this scope.
159 ///
160 /// # Arguments
161 ///
162 /// * `name` - The name of the module to get.
163 ///
164 /// # Examples
165 ///
166 /// ```
167 /// use rust_codegen::Module;
168 ///
169 /// let mut foo_module = Module::new("Foo");
170 /// foo_module.new_module("Bar");
171 ///
172 /// foo_module.get_module("Bar");
173 /// ```
174 pub fn get_module_mut<Q: ?Sized>(&mut self, name: &Q) -> Option<&mut Module>
175 where
176 String: PartialEq<Q>,
177 {
178 self.scope.get_module_mut(name)
179 }
180
181 /// Returns a mutable reference to a module, creating it if it does
182 /// not exist.
183 ///
184 /// # Arguments
185 ///
186 /// * `name` - The name of the module to get or create if it doesn't exist.
187 ///
188 /// # Examples
189 ///
190 /// ```
191 /// use rust_codegen::Module;
192 ///
193 /// let mut foo_module = Module::new("Foo");
194 /// foo_module.get_or_new_module("Bar");
195 /// ```
196 pub fn get_or_new_module(&mut self, name: &str) -> &mut Module {
197 self.scope.get_or_new_module(name)
198 }
199
200 /// Push a module definition.
201 ///
202 /// # Panics
203 ///
204 /// Since a module's name must uniquely identify it within the scope in
205 /// which it is defined, pushing a module whose name is already defined
206 /// in this scope will cause this function to panic.
207 ///
208 /// In many cases, the [`get_or_new_module`] function is preferrable, as it will
209 /// return the existing definition instead.
210 ///
211 /// [`get_or_new_module`]: #method.get_or_new_module
212 ///
213 /// # Arguments
214 ///
215 /// * `item` - The module to push.
216 ///
217 /// # Examples
218 ///
219 /// ```
220 /// use rust_codegen::Module;
221 ///
222 /// let mut foo_module = Module::new("Foo");
223 /// let mut bar_module = Module::new("Bar");
224 ///
225 /// foo_module.push_module(bar_module);
226 /// ```
227 pub fn push_module(&mut self, item: Module) -> &mut Self {
228 self.scope.push_module(item);
229 self
230 }
231
232 /// Push a new struct definition, returning a mutable reference to it.
233 ///
234 /// # Arguments
235 ///
236 /// * `name` - The name of the struct to push.
237 ///
238 /// # Examples
239 ///
240 /// ```
241 /// use rust_codegen::Module;
242 ///
243 /// let mut foo_module = Module::new("Foo");
244 /// foo_module.new_struct("Bar");
245 /// ```
246 pub fn new_struct(&mut self, name: &str) -> &mut Struct {
247 self.scope.new_struct(name)
248 }
249
250 /// Push a structure definition.
251 ///
252 /// # Arguments
253 ///
254 /// * `item` - The struct definition to push.
255 ///
256 /// # Examples
257 ///
258 /// ```
259 /// use rust_codegen::{Module,Struct};
260 ///
261 /// let mut foo_module = Module::new("Foo");
262 /// let mut bar_struct = Struct::new("Bar");
263 ///
264 /// foo_module.push_struct(bar_struct);
265 /// ```
266 pub fn push_struct(&mut self, item: Struct) -> &mut Self {
267 self.scope.push_struct(item);
268 self
269 }
270
271 /// Push a new function definition, returning a mutable reference to it.
272 ///
273 /// # Arguments
274 ///
275 /// * `name` - The name of the function to push.
276 ///
277 /// # Examples
278 ///
279 /// ```
280 /// use rust_codegen::Module;
281 ///
282 /// let mut foo_module = Module::new("Foo");
283 /// foo_module.new_fn("bar_fn");
284 /// ```
285 pub fn new_fn(&mut self, name: &str) -> &mut Function {
286 self.scope.new_fn(name)
287 }
288
289 /// Push a function definition.
290 ///
291 /// # Arguments
292 ///
293 /// * `item` - The function definition to push.
294 ///
295 /// # Examples
296 ///
297 /// ```
298 /// use rust_codegen::{Function,Module};
299 ///
300 /// let mut foo_module = Module::new("Foo");
301 /// let mut bar_fn = Function::new("bar_fn");
302 ///
303 /// foo_module.push_fn(bar_fn);
304 /// ```
305 pub fn push_fn(&mut self, item: Function) -> &mut Self {
306 self.scope.push_fn(item);
307 self
308 }
309
310 /// Push a new enum definition, returning a mutable reference to it.
311 ///
312 /// # Arguments
313 ///
314 /// * `name` - The name of the enum.
315 ///
316 /// # Examples
317 ///
318 /// ```
319 /// use rust_codegen::Module;
320 ///
321 /// let mut foo_module = Module::new("Foo");
322 /// foo_module.new_enum("Bar");
323 /// ```
324 pub fn new_enum(&mut self, name: &str) -> &mut Enum {
325 self.scope.new_enum(name)
326 }
327
328 /// Push an enum definition.
329 ///
330 /// # Arguments
331 ///
332 /// * `item` - The enum definition to push.
333 ///
334 /// # Examples
335 ///
336 /// ```
337 /// use rust_codegen::{Enum,Module};
338 ///
339 /// let mut foo_module = Module::new("Foo");
340 /// let mut bar_enum = Enum::new("Bar");
341 ///
342 /// foo_module.push_enum(bar_enum);
343 /// ```
344 pub fn push_enum(&mut self, item: Enum) -> &mut Self {
345 self.scope.push_enum(item);
346 self
347 }
348
349 /// Push a new `impl` block, returning a mutable reference to it.
350 ///
351 /// # Arguments
352 ///
353 /// * `target` - The impl block to push.
354 ///
355 /// # Examples
356 ///
357 /// ```
358 /// use rust_codegen::Module;
359 ///
360 /// let mut foo_module = Module::new("Foo");
361 /// foo_module.new_impl("Bar");
362 /// ```
363 pub fn new_impl(&mut self, target: &str) -> &mut Impl {
364 self.scope.new_impl(target)
365 }
366
367 /// Push an `impl` block.
368 ///
369 /// # Arguments
370 ///
371 /// * `item` - The impl definition to push.
372 ///
373 /// # Examples
374 ///
375 /// ```
376 /// use rust_codegen::{Impl,Module};
377 ///
378 /// let mut foo_module = Module::new("Foo");
379 /// let mut bar_impl = Impl::new("Bar");
380 ///
381 /// foo_module.push_impl(bar_impl);
382 /// ```
383 pub fn push_impl(&mut self, item: Impl) -> &mut Self {
384 self.scope.push_impl(item);
385 self
386 }
387
388 /// Push a trait definition.
389 ///
390 /// # Arguments
391 ///
392 /// * `item` - The trait to push.
393 ///
394 /// # Examples
395 ///
396 /// ```
397 /// use rust_codegen::{Module,Trait};
398 ///
399 /// let mut foo_module = Module::new("Foo");
400 /// let mut bar_trait = Trait::new("Bar");
401 ///
402 /// foo_module.push_trait(bar_trait);
403 /// ```
404 pub fn push_trait(&mut self, item: Trait) -> &mut Self {
405 self.scope.push_trait(item);
406 self
407 }
408
409 /// Formats the module using the given formatter.
410 ///
411 /// # Arguments
412 ///
413 /// * `fmt` - The formatter to use.
414 ///
415 /// # Examples
416 ///
417 /// ```
418 /// use rust_codegen::*;
419 ///
420 /// let mut dest = String::new();
421 /// let mut fmt = Formatter::new(&mut dest);
422 ///
423 /// let mut foo_module = Module::new("Foo");
424 /// foo_module.fmt(&mut fmt);
425 /// ```
426 pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
427 if let Some(ref vis) = self.vis {
428 write!(fmt, "{} ", vis)?;
429 }
430
431 write!(fmt, "mod {}", self.name)?;
432 fmt.block(|fmt| self.scope.fmt(fmt))
433 }
434}