1use std::fmt::{self, Write};
2
3use crate::bound::Bound;
4use crate::field::Field;
5use crate::formatter::{fmt_bounds, fmt_generics, Formatter};
6use crate::function::Function;
7
8use crate::r#type::Type;
9
10#[derive(Debug, Clone)]
12pub struct Impl {
13 target: Type,
15
16 generics: Vec<String>,
18
19 impl_trait: Option<Type>,
21
22 assoc_tys: Vec<Field>,
24
25 bounds: Vec<Bound>,
27
28 fns: Vec<Function>,
29
30 macros: Vec<String>,
31}
32
33impl Impl {
34 pub fn new<T>(target: T) -> Self
36 where
37 T: Into<Type>,
38 {
39 Self {
40 target: target.into(),
41 generics: vec![],
42 impl_trait: None,
43 assoc_tys: vec![],
44 bounds: vec![],
45 fns: vec![],
46 macros: vec![],
47 }
48 }
49
50 pub fn generic(&mut self, name: &str) -> &mut Self {
54 self.generics.push(name.to_string());
55 self
56 }
57
58 pub fn target_generic<T>(&mut self, ty: T) -> &mut Self
60 where
61 T: Into<Type>,
62 {
63 self.target.generic(ty);
64 self
65 }
66
67 pub fn impl_trait<T>(&mut self, ty: T) -> &mut Self
69 where
70 T: Into<Type>,
71 {
72 self.impl_trait = Some(ty.into());
73 self
74 }
75
76 pub fn r#macro(&mut self, r#macro: &str) -> &mut Self {
78 self.macros.push(r#macro.to_string());
79 self
80 }
81
82 pub fn associate_type<T>(&mut self, name: &str, ty: T) -> &mut Self
84 where
85 T: Into<Type>,
86 {
87 self.assoc_tys.push(Field {
88 name: name.to_string(),
89 ty: ty.into(),
90 documentation: Vec::new(),
91 annotation: Vec::new(),
92 });
93
94 self
95 }
96
97 pub fn bound<T>(&mut self, name: &str, ty: T) -> &mut Self
99 where
100 T: Into<Type>,
101 {
102 self.bounds.push(Bound {
103 name: name.to_string(),
104 bound: vec![ty.into()],
105 });
106 self
107 }
108
109 pub fn new_fn(&mut self, name: &str) -> &mut Function {
111 self.push_fn(Function::new(name));
112 self.fns.last_mut().unwrap()
113 }
114
115 pub fn push_fn(&mut self, item: Function) -> &mut Self {
117 self.fns.push(item);
118 self
119 }
120
121 pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
123 for m in self.macros.iter() {
124 writeln!(fmt, "{}", m)?;
125 }
126 write!(fmt, "impl")?;
127 fmt_generics(&self.generics[..], fmt)?;
128
129 if let Some(ref t) = self.impl_trait {
130 write!(fmt, " ")?;
131 t.fmt(fmt)?;
132 write!(fmt, " for")?;
133 }
134
135 write!(fmt, " ")?;
136 self.target.fmt(fmt)?;
137
138 fmt_bounds(&self.bounds, fmt)?;
139
140 fmt.block(|fmt| {
141 if !self.assoc_tys.is_empty() {
143 for ty in &self.assoc_tys {
144 write!(fmt, "type {} = ", ty.name)?;
145 ty.ty.fmt(fmt)?;
146 writeln!(fmt, ";")?;
147 }
148 }
149
150 for (i, func) in self.fns.iter().enumerate() {
151 if i != 0 || !self.assoc_tys.is_empty() {
152 writeln!(fmt)?;
153 }
154
155 func.fmt(false, fmt)?;
156 }
157
158 Ok(())
159 })
160 }
161}