facet_core/types/shape/
shape_builder.rs1use alloc::alloc::Layout;
2
3use crate::{
4 Attr, ConstTypeId, Def, MarkerTraits, ProxyDef, Shape, ShapeFlags, ShapeLayout, Type,
5 TypeNameFn, TypeOps, TypeOpsDirect, TypeOpsIndirect, TypeParam, VTableDirect, VTableErased,
6 VTableIndirect, Variance,
7};
8
9pub struct ShapeBuilder {
21 shape: Shape,
22}
23
24const EMPTY_VESSEL: Shape = Shape {
25 id: ConstTypeId::of::<()>(),
26 layout: ShapeLayout::Sized(Layout::new::<()>()),
27 vtable: VTableErased::Direct(&VTableDirect::empty()),
28 type_ops: None,
29 marker_traits: MarkerTraits::empty(),
30 ty: Type::Undefined,
31 def: Def::Undefined,
32 type_identifier: "‹undefined›",
33 type_params: &[],
34 doc: &[],
35 attributes: &[],
36 type_tag: None,
37 inner: None,
38 type_name: None,
39 proxy: None,
40 variance: Variance::COVARIANT,
41 flags: ShapeFlags::empty(),
42 tag: None,
43 content: None,
44};
45
46impl Shape {
47 #[inline]
51 pub const fn builder_for_sized<T>(type_identifier: &'static str) -> ShapeBuilder {
52 ShapeBuilder::for_sized::<T>(type_identifier)
53 }
54
55 #[inline]
57 pub const fn builder_for_unsized<T: ?Sized>(type_identifier: &'static str) -> ShapeBuilder {
58 ShapeBuilder::for_unsized::<T>(type_identifier)
59 }
60}
61
62impl ShapeBuilder {
63 #[inline]
67 pub const fn for_sized<T>(type_identifier: &'static str) -> Self {
68 Self {
69 shape: Shape {
70 id: ConstTypeId::of::<T>(),
71 layout: ShapeLayout::Sized(Layout::new::<T>()),
72 type_identifier,
73 ..EMPTY_VESSEL
74 },
75 }
76 }
77
78 #[inline]
80 pub const fn for_unsized<T: ?Sized>(type_identifier: &'static str) -> Self {
81 Self {
82 shape: Shape {
83 id: ConstTypeId::of::<T>(),
84 layout: ShapeLayout::Unsized,
85 type_identifier,
86 ..EMPTY_VESSEL
87 },
88 }
89 }
90
91 #[inline]
93 pub const fn vtable(mut self, vtable: VTableErased) -> Self {
94 self.shape.vtable = vtable;
95 self
96 }
97
98 #[inline]
100 pub const fn vtable_direct(mut self, vtable: &'static VTableDirect) -> Self {
101 self.shape.vtable = VTableErased::Direct(vtable);
102 self
103 }
104
105 #[inline]
107 pub const fn vtable_indirect(mut self, vtable: &'static VTableIndirect) -> Self {
108 self.shape.vtable = VTableErased::Indirect(vtable);
109 self
110 }
111
112 #[inline]
117 pub const fn type_ops(mut self, type_ops: TypeOps) -> Self {
118 self.shape.type_ops = Some(type_ops);
119 self
120 }
121
122 #[inline]
126 pub const fn type_ops_direct(mut self, type_ops: &'static TypeOpsDirect) -> Self {
127 self.shape.type_ops = Some(TypeOps::Direct(type_ops));
128 self
129 }
130
131 #[inline]
135 pub const fn type_ops_indirect(mut self, type_ops: &'static TypeOpsIndirect) -> Self {
136 self.shape.type_ops = Some(TypeOps::Indirect(type_ops));
137 self
138 }
139
140 #[inline]
142 pub const fn add_marker_trait(mut self, trait_flag: MarkerTraits) -> Self {
143 self.shape.marker_traits = self.shape.marker_traits.union(trait_flag);
144 self
145 }
146
147 #[inline]
149 pub const fn marker_traits(mut self, traits: MarkerTraits) -> Self {
150 self.shape.marker_traits = traits;
151 self
152 }
153
154 #[inline]
156 pub const fn eq(self) -> Self {
157 self.add_marker_trait(MarkerTraits::EQ)
158 }
159
160 #[inline]
162 pub const fn copy(self) -> Self {
163 self.add_marker_trait(MarkerTraits::COPY)
164 }
165
166 #[inline]
168 pub const fn send(self) -> Self {
169 self.add_marker_trait(MarkerTraits::SEND)
170 }
171
172 #[inline]
174 pub const fn sync(self) -> Self {
175 self.add_marker_trait(MarkerTraits::SYNC)
176 }
177
178 #[inline]
180 pub const fn unpin(self) -> Self {
181 self.add_marker_trait(MarkerTraits::UNPIN)
182 }
183
184 #[inline]
186 pub const fn unwind_safe(self) -> Self {
187 self.add_marker_trait(MarkerTraits::UNWIND_SAFE)
188 }
189
190 #[inline]
192 pub const fn ref_unwind_safe(self) -> Self {
193 self.add_marker_trait(MarkerTraits::REF_UNWIND_SAFE)
194 }
195
196 #[inline]
198 pub const fn ty(mut self, ty: Type) -> Self {
199 self.shape.ty = ty;
200 self
201 }
202
203 #[inline]
205 pub const fn def(mut self, def: Def) -> Self {
206 self.shape.def = def;
207 self
208 }
209
210 #[inline]
212 pub const fn type_params(mut self, type_params: &'static [TypeParam]) -> Self {
213 self.shape.type_params = type_params;
214 self
215 }
216
217 #[inline]
219 pub const fn doc(mut self, doc: &'static [&'static str]) -> Self {
220 self.shape.doc = doc;
221 self
222 }
223
224 #[inline]
226 pub const fn attributes(mut self, attributes: &'static [Attr]) -> Self {
227 self.shape.attributes = attributes;
228 self
229 }
230
231 #[inline]
233 pub const fn type_tag(mut self, type_tag: &'static str) -> Self {
234 self.shape.type_tag = Some(type_tag);
235 self
236 }
237
238 #[inline]
240 pub const fn inner(mut self, inner: &'static Shape) -> Self {
241 self.shape.inner = Some(inner);
242 self
243 }
244
245 #[inline]
250 pub const fn type_name(mut self, type_name: TypeNameFn) -> Self {
251 self.shape.type_name = Some(type_name);
252 self
253 }
254
255 #[inline]
260 pub const fn proxy(mut self, proxy: &'static ProxyDef) -> Self {
261 self.shape.proxy = Some(proxy);
262 self
263 }
264
265 #[inline]
270 pub const fn variance(mut self, variance: fn(&'static Shape) -> Variance) -> Self {
271 self.shape.variance = variance;
272 self
273 }
274
275 #[inline]
277 pub const fn flags(mut self, flags: ShapeFlags) -> Self {
278 self.shape.flags = flags;
279 self
280 }
281
282 #[inline]
286 pub const fn untagged(mut self) -> Self {
287 self.shape.flags = self.shape.flags.union(ShapeFlags::UNTAGGED);
288 self
289 }
290
291 #[inline]
293 pub const fn tag(mut self, tag: &'static str) -> Self {
294 self.shape.tag = Some(tag);
295 self
296 }
297
298 #[inline]
300 pub const fn content(mut self, content: &'static str) -> Self {
301 self.shape.content = Some(content);
302 self
303 }
304
305 #[inline]
310 pub const fn build(self) -> Shape {
311 let ty = match self.shape.ty {
312 Type::Undefined => self.shape.def.default_type(),
313 ty => ty,
314 };
315
316 Shape { ty, ..self.shape }
317 }
318}