codegen_rs/
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        Self {
23            type_def: TypeDef::new(name),
24            fields: Fields::Empty,
25        }
26    }
27
28    /// Returns a reference to the type
29    pub const 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    /// Specify lint attribute to supress a warning or error.
67    pub fn allow(&mut self, allow: &str) -> &mut Self {
68        self.type_def.allow(allow);
69        self
70    }
71
72    /// Specify representation.
73    pub fn repr(&mut self, repr: &str) -> &mut Self {
74        self.type_def.repr(repr);
75        self
76    }
77
78    /// Push a named field to the struct.
79    ///
80    /// A struct can either set named fields with this function or tuple fields
81    /// with `push_tuple_field`, but not both.
82    pub fn push_field(&mut self, field: Field) -> &mut Self {
83        self.fields.push_named(field);
84        self
85    }
86
87    /// Add a named field to the struct.
88    ///
89    /// A struct can either set named fields with this function or tuple fields
90    /// with `tuple_field`, but not both.
91    pub fn field<T>(&mut self, name: &str, ty: T) -> &mut Self
92    where
93        T: Into<Type>,
94    {
95        self.fields.named(name, ty);
96        self
97    }
98
99    /// Add a tuple field to the struct.
100    ///
101    /// A struct can either set tuple fields with this function or named fields
102    /// with `field`, but not both.
103    pub fn tuple_field<T>(&mut self, ty: T) -> &mut Self
104    where
105        T: Into<Type>,
106    {
107        self.fields.tuple(ty);
108        self
109    }
110
111    /// Formats the struct using the given formatter.
112    pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
113        self.type_def.fmt_head("struct", &[], fmt)?;
114        self.fields.fmt(fmt)?;
115
116        match self.fields {
117            Fields::Empty => {
118                writeln!(fmt, ";")?;
119            }
120            Fields::Tuple(..) => {
121                writeln!(fmt, ";")?;
122            }
123            _ => {}
124        }
125
126        Ok(())
127    }
128}