Skip to main content

codegen_rs/
type_def.rs

1use std::fmt::{self, Write};
2
3use crate::bound::Bound;
4use crate::docs::Docs;
5use crate::formatter::{fmt_bounds, Formatter};
6
7use crate::r#type::Type;
8
9/// Defines a type definition.
10#[derive(Debug, Clone)]
11pub struct TypeDef {
12    pub ty: Type,
13    vis: Option<String>,
14    docs: Option<Docs>,
15    derive: Vec<String>,
16    allow: Vec<String>,
17    repr: Option<String>,
18    bounds: Vec<Bound>,
19    macros: Vec<String>,
20}
21
22impl TypeDef {
23    /// Return a structure definition with the provided name
24    pub fn new(name: &str) -> Self {
25        Self {
26            ty: Type::new(name),
27            vis: None,
28            docs: None,
29            derive: vec![],
30            allow: vec![],
31            repr: None,
32            bounds: vec![],
33            macros: vec![],
34        }
35    }
36
37    pub fn vis(&mut self, vis: &str) {
38        self.vis = Some(vis.to_string());
39    }
40
41    pub fn bound<T>(&mut self, name: &str, ty: T)
42    where
43        T: Into<Type>,
44    {
45        self.bounds.push(Bound {
46            name: name.to_string(),
47            bound: vec![ty.into()],
48        });
49    }
50
51    pub fn r#macro(&mut self, r#macro: &str) {
52        self.macros.push(r#macro.to_string());
53    }
54
55    pub fn doc(&mut self, docs: &str) {
56        self.docs = Some(Docs::new(docs));
57    }
58
59    pub fn derive(&mut self, name: &str) {
60        self.derive.push(name.to_string());
61    }
62
63    pub fn allow(&mut self, allow: &str) {
64        self.allow.push(allow.to_string());
65    }
66
67    pub fn repr(&mut self, repr: &str) {
68        self.repr = Some(repr.to_string());
69    }
70
71    pub fn fmt_head(
72        &self,
73        keyword: &str,
74        parents: &[Type],
75        fmt: &mut Formatter<'_>,
76    ) -> fmt::Result {
77        if let Some(ref docs) = self.docs {
78            docs.fmt(fmt)?;
79        }
80
81        self.fmt_allow(fmt)?;
82        self.fmt_derive(fmt)?;
83        self.fmt_repr(fmt)?;
84        self.fmt_macros(fmt)?;
85
86        if let Some(ref vis) = self.vis {
87            write!(fmt, "{} ", vis)?;
88        }
89
90        write!(fmt, "{} ", keyword)?;
91        self.ty.fmt(fmt)?;
92
93        if !parents.is_empty() {
94            for (i, ty) in parents.iter().enumerate() {
95                if i == 0 {
96                    write!(fmt, ": ")?;
97                } else {
98                    write!(fmt, " + ")?;
99                }
100
101                ty.fmt(fmt)?;
102            }
103        }
104
105        fmt_bounds(&self.bounds, fmt)?;
106
107        Ok(())
108    }
109
110    fn fmt_allow(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
111        for allow in &self.allow {
112            write!(fmt, "#[allow({})]\n", allow)?;
113        }
114
115        Ok(())
116    }
117
118    fn fmt_repr(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
119        if let Some(ref repr) = self.repr {
120            writeln!(fmt, "#[repr({})]", repr)?;
121        }
122
123        Ok(())
124    }
125
126    fn fmt_derive(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
127        if !self.derive.is_empty() {
128            write!(fmt, "#[derive(")?;
129
130            for (i, name) in self.derive.iter().enumerate() {
131                if i != 0 {
132                    write!(fmt, ", ")?
133                }
134                write!(fmt, "{}", name)?;
135            }
136
137            writeln!(fmt, ")]")?;
138        }
139
140        Ok(())
141    }
142
143    fn fmt_macros(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
144        for m in self.macros.iter() {
145            writeln!(fmt, "{}", m)?;
146        }
147        Ok(())
148    }
149}