1use super::{generate_item::FnParent, FnBuilder, GenConst, Generator, Parent, StreamBuilder};
2use crate::{
3 parse::{GenericConstraints, Generics},
4 prelude::{Delimiter, Result},
5};
6
7#[must_use]
8pub struct Impl<'a, P: Parent> {
10 parent: &'a mut P,
11 outer_attr: Vec<StreamBuilder>,
12 inner_attr: Vec<StreamBuilder>,
13 name: String,
14 consts: Vec<StreamBuilder>,
16 custom_generic_constraints: Option<GenericConstraints>,
17 fns: Vec<(StreamBuilder, StreamBuilder)>,
18}
19
20impl<'a, P: Parent> Impl<'a, P> {
21 pub(super) fn with_parent_name(parent: &'a mut P) -> Self {
22 Self {
23 outer_attr: Vec::new(),
24 inner_attr: Vec::new(),
25 name: parent.name().to_string(),
26 parent,
27 consts: Vec::new(),
28 custom_generic_constraints: None,
29 fns: Vec::new(),
30 }
31 }
32
33 pub(super) fn new(parent: &'a mut P, name: impl Into<String>) -> Self {
34 Self {
35 outer_attr: Vec::new(),
36 inner_attr: Vec::new(),
37 parent,
38 name: name.into(),
39 consts: Vec::new(),
40 custom_generic_constraints: None,
41 fns: Vec::new(),
42 }
43 }
44
45 pub fn impl_outer_attr(&mut self, attr: impl AsRef<str>) -> Result {
47 let mut builder = StreamBuilder::new();
48 builder.punct('#').group(Delimiter::Bracket, |builder| {
49 builder.push_parsed(attr)?;
50 Ok(())
51 })?;
52 self.outer_attr.push(builder);
53 Ok(())
54 }
55
56 pub fn impl_inner_attr(&mut self, attr: impl AsRef<str>) -> Result {
58 let mut builder = StreamBuilder::new();
59 builder
60 .punct('#')
61 .punct('!')
62 .group(Delimiter::Brace, |builder| {
63 builder.push_parsed(attr)?;
64 Ok(())
65 })?;
66 self.inner_attr.push(builder);
67 Ok(())
68 }
69
70 pub fn generate_fn(&mut self, name: impl Into<String>) -> FnBuilder<Self> {
82 FnBuilder::new(self, name)
83 }
84
85 pub fn generate_const(&mut self, name: impl Into<String>, ty: impl Into<String>) -> GenConst {
105 GenConst::new(&mut self.consts, name, ty)
106 }
107}
108
109impl<'a> Impl<'a, Generator> {
110 pub fn modify_generic_constraints<CB>(&mut self, cb: CB) -> &mut Self
138 where
139 CB: FnOnce(&Generics, &mut GenericConstraints),
140 {
141 if let Some(generics) = self.parent.generics() {
142 let constraints = self.custom_generic_constraints.get_or_insert_with(|| {
143 self.parent
144 .generic_constraints()
145 .cloned()
146 .unwrap_or_default()
147 });
148 cb(generics, constraints);
149 }
150 self
151 }
152}
153
154impl<'a, P: Parent> FnParent for Impl<'a, P> {
155 fn append(&mut self, fn_definition: StreamBuilder, fn_body: StreamBuilder) -> Result {
156 self.fns.push((fn_definition, fn_body));
157 Ok(())
158 }
159}
160
161impl<'a, P: Parent> Drop for Impl<'a, P> {
162 fn drop(&mut self) {
163 if std::thread::panicking() {
164 return;
165 }
166 let mut builder = StreamBuilder::new();
167 for attr in std::mem::take(&mut self.outer_attr) {
168 builder.append(attr);
169 }
170 builder.ident_str("impl");
171
172 if let Some(generics) = self.parent.generics() {
173 builder.append(generics.impl_generics());
174 }
175 builder.push_parsed(&self.name).unwrap();
176
177 if let Some(generics) = self.parent.generics() {
178 builder.append(generics.type_generics());
179 }
180 if let Some(generic_constraints) = self.custom_generic_constraints.take() {
181 builder.append(generic_constraints.where_clause());
182 } else if let Some(generic_constraints) = self.parent.generic_constraints() {
183 builder.append(generic_constraints.where_clause());
184 }
185
186 builder
187 .group(Delimiter::Brace, |builder| {
188 for attr in std::mem::take(&mut self.inner_attr) {
189 builder.append(attr);
190 }
191 for r#const in std::mem::take(&mut self.consts) {
192 builder.append(r#const);
193 }
194 for (fn_def, fn_body) in std::mem::take(&mut self.fns) {
195 builder.append(fn_def);
196 builder
197 .group(Delimiter::Brace, |body| {
198 *body = fn_body;
199 Ok(())
200 })
201 .unwrap();
202 }
203 Ok(())
204 })
205 .unwrap();
206
207 self.parent.append(builder);
208 }
209}