1 | use super::CORE_TYPE_SORT; |
2 | use crate::{ |
3 | encode_section, Alias, ComponentExportKind, ComponentOuterAliasKind, ComponentSection, |
4 | ComponentSectionId, ComponentTypeRef, CoreTypeEncoder, Encode, EntityType, ValType, |
5 | }; |
6 | |
7 | /// Represents the type of a core module. |
8 | #[derive (Debug, Clone, Default)] |
9 | pub struct ModuleType { |
10 | bytes: Vec<u8>, |
11 | num_added: u32, |
12 | types_added: u32, |
13 | } |
14 | |
15 | impl ModuleType { |
16 | /// Creates a new core module type. |
17 | pub fn new() -> Self { |
18 | Self::default() |
19 | } |
20 | |
21 | /// Defines an import in this module type. |
22 | pub fn import(&mut self, module: &str, name: &str, ty: EntityType) -> &mut Self { |
23 | self.bytes.push(0x00); |
24 | module.encode(&mut self.bytes); |
25 | name.encode(&mut self.bytes); |
26 | ty.encode(&mut self.bytes); |
27 | self.num_added += 1; |
28 | self |
29 | } |
30 | |
31 | /// Define a type in this module type. |
32 | /// |
33 | /// The returned encoder must be used before adding another definition. |
34 | #[must_use = "the encoder must be used to encode the type" ] |
35 | pub fn ty(&mut self) -> CoreTypeEncoder { |
36 | self.bytes.push(0x01); |
37 | self.num_added += 1; |
38 | self.types_added += 1; |
39 | CoreTypeEncoder { |
40 | push_prefix_if_component_core_type: false, |
41 | bytes: &mut self.bytes, |
42 | } |
43 | } |
44 | |
45 | /// Defines an outer core type alias in this module type. |
46 | pub fn alias_outer_core_type(&mut self, count: u32, index: u32) -> &mut Self { |
47 | self.bytes.push(0x02); |
48 | self.bytes.push(CORE_TYPE_SORT); |
49 | self.bytes.push(0x01); // outer |
50 | count.encode(&mut self.bytes); |
51 | index.encode(&mut self.bytes); |
52 | self.num_added += 1; |
53 | self.types_added += 1; |
54 | self |
55 | } |
56 | |
57 | /// Defines an export in this module type. |
58 | pub fn export(&mut self, name: &str, ty: EntityType) -> &mut Self { |
59 | self.bytes.push(0x03); |
60 | name.encode(&mut self.bytes); |
61 | ty.encode(&mut self.bytes); |
62 | self.num_added += 1; |
63 | self |
64 | } |
65 | |
66 | /// Gets the number of types that have been added to this module type. |
67 | pub fn type_count(&self) -> u32 { |
68 | self.types_added |
69 | } |
70 | } |
71 | |
72 | impl Encode for ModuleType { |
73 | fn encode(&self, sink: &mut Vec<u8>) { |
74 | sink.push(0x50); |
75 | self.num_added.encode(sink); |
76 | sink.extend(&self.bytes); |
77 | } |
78 | } |
79 | |
80 | /// Used to encode core types. |
81 | #[derive (Debug)] |
82 | pub struct ComponentCoreTypeEncoder<'a>(pub(crate) &'a mut Vec<u8>); |
83 | |
84 | impl<'a> ComponentCoreTypeEncoder<'a> { |
85 | /// Define a module type. |
86 | pub fn module(self, ty: &ModuleType) { |
87 | ty.encode(self.0); |
88 | } |
89 | |
90 | /// Define any core type other than a module type. |
91 | #[must_use = "the encoder must be used to encode the type" ] |
92 | pub fn core(self) -> CoreTypeEncoder<'a> { |
93 | CoreTypeEncoder { |
94 | bytes: self.0, |
95 | push_prefix_if_component_core_type: true, |
96 | } |
97 | } |
98 | } |
99 | |
100 | /// An encoder for the core type section of WebAssembly components. |
101 | /// |
102 | /// # Example |
103 | /// |
104 | /// ```rust |
105 | /// use wasm_encoder::{Component, CoreTypeSection, ModuleType}; |
106 | /// |
107 | /// let mut types = CoreTypeSection::new(); |
108 | /// |
109 | /// types.ty().module(&ModuleType::new()); |
110 | /// |
111 | /// let mut component = Component::new(); |
112 | /// component.section(&types); |
113 | /// |
114 | /// let bytes = component.finish(); |
115 | /// ``` |
116 | #[derive (Clone, Debug, Default)] |
117 | pub struct CoreTypeSection { |
118 | bytes: Vec<u8>, |
119 | num_added: u32, |
120 | } |
121 | |
122 | impl CoreTypeSection { |
123 | /// Create a new core type section encoder. |
124 | pub fn new() -> Self { |
125 | Self::default() |
126 | } |
127 | |
128 | /// The number of types in the section. |
129 | pub fn len(&self) -> u32 { |
130 | self.num_added |
131 | } |
132 | |
133 | /// Determines if the section is empty. |
134 | pub fn is_empty(&self) -> bool { |
135 | self.num_added == 0 |
136 | } |
137 | |
138 | /// Encode a type into this section. |
139 | /// |
140 | /// The returned encoder must be finished before adding another type. |
141 | #[must_use = "the encoder must be used to encode the type" ] |
142 | pub fn ty(&mut self) -> ComponentCoreTypeEncoder<'_> { |
143 | self.num_added += 1; |
144 | ComponentCoreTypeEncoder(&mut self.bytes) |
145 | } |
146 | } |
147 | |
148 | impl Encode for CoreTypeSection { |
149 | fn encode(&self, sink: &mut Vec<u8>) { |
150 | encode_section(sink, self.num_added, &self.bytes); |
151 | } |
152 | } |
153 | |
154 | impl ComponentSection for CoreTypeSection { |
155 | fn id(&self) -> u8 { |
156 | ComponentSectionId::CoreType.into() |
157 | } |
158 | } |
159 | |
160 | /// Represents a component type. |
161 | #[derive (Debug, Clone, Default)] |
162 | pub struct ComponentType { |
163 | bytes: Vec<u8>, |
164 | num_added: u32, |
165 | core_types_added: u32, |
166 | types_added: u32, |
167 | instances_added: u32, |
168 | } |
169 | |
170 | impl ComponentType { |
171 | /// Creates a new component type. |
172 | pub fn new() -> Self { |
173 | Self::default() |
174 | } |
175 | |
176 | /// Define a core type in this component type. |
177 | /// |
178 | /// The returned encoder must be used before adding another definition. |
179 | #[must_use = "the encoder must be used to encode the type" ] |
180 | pub fn core_type(&mut self) -> ComponentCoreTypeEncoder { |
181 | self.bytes.push(0x00); |
182 | self.num_added += 1; |
183 | self.core_types_added += 1; |
184 | ComponentCoreTypeEncoder(&mut self.bytes) |
185 | } |
186 | |
187 | /// Define a type in this component type. |
188 | /// |
189 | /// The returned encoder must be used before adding another definition. |
190 | #[must_use = "the encoder must be used to encode the type" ] |
191 | pub fn ty(&mut self) -> ComponentTypeEncoder { |
192 | self.bytes.push(0x01); |
193 | self.num_added += 1; |
194 | self.types_added += 1; |
195 | ComponentTypeEncoder(&mut self.bytes) |
196 | } |
197 | |
198 | /// Defines an alias for an exported item of a prior instance or an |
199 | /// outer type. |
200 | pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self { |
201 | self.bytes.push(0x02); |
202 | alias.encode(&mut self.bytes); |
203 | self.num_added += 1; |
204 | match &alias { |
205 | Alias::InstanceExport { |
206 | kind: ComponentExportKind::Type, |
207 | .. |
208 | } |
209 | | Alias::Outer { |
210 | kind: ComponentOuterAliasKind::Type, |
211 | .. |
212 | } => self.types_added += 1, |
213 | Alias::Outer { |
214 | kind: ComponentOuterAliasKind::CoreType, |
215 | .. |
216 | } => self.core_types_added += 1, |
217 | Alias::InstanceExport { |
218 | kind: ComponentExportKind::Instance, |
219 | .. |
220 | } => self.instances_added += 1, |
221 | _ => {} |
222 | } |
223 | self |
224 | } |
225 | |
226 | /// Defines an import in this component type. |
227 | pub fn import(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self { |
228 | self.bytes.push(0x03); |
229 | crate::encode_component_import_name(&mut self.bytes, name); |
230 | ty.encode(&mut self.bytes); |
231 | self.num_added += 1; |
232 | match ty { |
233 | ComponentTypeRef::Type(..) => self.types_added += 1, |
234 | ComponentTypeRef::Instance(..) => self.instances_added += 1, |
235 | _ => {} |
236 | } |
237 | self |
238 | } |
239 | |
240 | /// Defines an export in this component type. |
241 | pub fn export(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self { |
242 | self.bytes.push(0x04); |
243 | crate::encode_component_export_name(&mut self.bytes, name); |
244 | ty.encode(&mut self.bytes); |
245 | self.num_added += 1; |
246 | match ty { |
247 | ComponentTypeRef::Type(..) => self.types_added += 1, |
248 | ComponentTypeRef::Instance(..) => self.instances_added += 1, |
249 | _ => {} |
250 | } |
251 | self |
252 | } |
253 | |
254 | /// Gets the number of core types that have been added to this component type. |
255 | pub fn core_type_count(&self) -> u32 { |
256 | self.core_types_added |
257 | } |
258 | |
259 | /// Gets the number of types that have been added or aliased in this component type. |
260 | pub fn type_count(&self) -> u32 { |
261 | self.types_added |
262 | } |
263 | |
264 | /// Gets the number of instances that have been defined in this component |
265 | /// type through imports, exports, or aliases. |
266 | pub fn instance_count(&self) -> u32 { |
267 | self.instances_added |
268 | } |
269 | } |
270 | |
271 | impl Encode for ComponentType { |
272 | fn encode(&self, sink: &mut Vec<u8>) { |
273 | sink.push(0x41); |
274 | self.num_added.encode(sink); |
275 | sink.extend(&self.bytes); |
276 | } |
277 | } |
278 | |
279 | /// Represents an instance type. |
280 | #[derive (Debug, Clone, Default)] |
281 | pub struct InstanceType(ComponentType); |
282 | |
283 | impl InstanceType { |
284 | /// Creates a new instance type. |
285 | pub fn new() -> Self { |
286 | Self::default() |
287 | } |
288 | |
289 | /// Define a core type in this instance type. |
290 | /// |
291 | /// The returned encoder must be used before adding another definition. |
292 | #[must_use = "the encoder must be used to encode the type" ] |
293 | pub fn core_type(&mut self) -> ComponentCoreTypeEncoder { |
294 | self.0.core_type() |
295 | } |
296 | |
297 | /// Define a type in this instance type. |
298 | /// |
299 | /// The returned encoder must be used before adding another definition. |
300 | #[must_use = "the encoder must be used to encode the type" ] |
301 | pub fn ty(&mut self) -> ComponentTypeEncoder { |
302 | self.0.ty() |
303 | } |
304 | |
305 | /// Defines an outer core type alias in this component type. |
306 | pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self { |
307 | self.0.alias(alias); |
308 | self |
309 | } |
310 | |
311 | /// Defines an export in this instance type. |
312 | pub fn export(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self { |
313 | self.0.export(name, ty); |
314 | self |
315 | } |
316 | |
317 | /// Gets the number of core types that have been added to this instance type. |
318 | pub fn core_type_count(&self) -> u32 { |
319 | self.0.core_types_added |
320 | } |
321 | |
322 | /// Gets the number of types that have been added or aliased in this instance type. |
323 | pub fn type_count(&self) -> u32 { |
324 | self.0.types_added |
325 | } |
326 | |
327 | /// Gets the number of instances that have been imported or exported or |
328 | /// aliased in this instance type. |
329 | pub fn instance_count(&self) -> u32 { |
330 | self.0.instances_added |
331 | } |
332 | |
333 | /// Returns whether or not this instance type is empty. |
334 | pub fn is_empty(&self) -> bool { |
335 | self.0.num_added == 0 |
336 | } |
337 | |
338 | /// Returns the number of entries added to this instance types. |
339 | pub fn len(&self) -> u32 { |
340 | self.0.num_added |
341 | } |
342 | } |
343 | |
344 | impl Encode for InstanceType { |
345 | fn encode(&self, sink: &mut Vec<u8>) { |
346 | sink.push(0x42); |
347 | self.0.num_added.encode(sink); |
348 | sink.extend(&self.0.bytes); |
349 | } |
350 | } |
351 | |
352 | /// Used to encode component function types. |
353 | #[derive (Debug)] |
354 | pub struct ComponentFuncTypeEncoder<'a> { |
355 | params_encoded: bool, |
356 | results_encoded: bool, |
357 | sink: &'a mut Vec<u8>, |
358 | } |
359 | |
360 | impl<'a> ComponentFuncTypeEncoder<'a> { |
361 | fn new(sink: &'a mut Vec<u8>) -> Self { |
362 | sink.push(0x40); |
363 | Self { |
364 | params_encoded: false, |
365 | results_encoded: false, |
366 | sink, |
367 | } |
368 | } |
369 | |
370 | /// Defines named parameters. |
371 | /// |
372 | /// Parameters must be defined before defining results. |
373 | /// |
374 | /// # Panics |
375 | /// |
376 | /// This method will panic if the function is called twice since parameters |
377 | /// can only be encoded once. |
378 | pub fn params<'b, P, T>(&mut self, params: P) -> &mut Self |
379 | where |
380 | P: IntoIterator<Item = (&'b str, T)>, |
381 | P::IntoIter: ExactSizeIterator, |
382 | T: Into<ComponentValType>, |
383 | { |
384 | assert!(!self.params_encoded); |
385 | self.params_encoded = true; |
386 | let params = params.into_iter(); |
387 | params.len().encode(self.sink); |
388 | for (name, ty) in params { |
389 | name.encode(self.sink); |
390 | ty.into().encode(self.sink); |
391 | } |
392 | self |
393 | } |
394 | |
395 | /// Defines a single unnamed result. |
396 | /// |
397 | /// This method cannot be used with `results`. |
398 | /// |
399 | /// # Panics |
400 | /// |
401 | /// This method will panic if the function is called twice, called before |
402 | /// the `params` method, or called in addition to the `results` method. |
403 | pub fn result(&mut self, ty: impl Into<ComponentValType>) -> &mut Self { |
404 | assert!(self.params_encoded); |
405 | assert!(!self.results_encoded); |
406 | self.results_encoded = true; |
407 | self.sink.push(0x00); |
408 | ty.into().encode(self.sink); |
409 | self |
410 | } |
411 | |
412 | /// Defines named results. |
413 | /// |
414 | /// This method cannot be used with `result`. |
415 | /// |
416 | /// # Panics |
417 | /// |
418 | /// This method will panic if the function is called twice, called before |
419 | /// the `params` method, or called in addition to the `result` method. |
420 | pub fn results<'b, R, T>(&mut self, results: R) -> &mut Self |
421 | where |
422 | R: IntoIterator<Item = (&'b str, T)>, |
423 | R::IntoIter: ExactSizeIterator, |
424 | T: Into<ComponentValType>, |
425 | { |
426 | assert!(self.params_encoded); |
427 | assert!(!self.results_encoded); |
428 | self.results_encoded = true; |
429 | self.sink.push(0x01); |
430 | let results = results.into_iter(); |
431 | results.len().encode(self.sink); |
432 | for (name, ty) in results { |
433 | name.encode(self.sink); |
434 | ty.into().encode(self.sink); |
435 | } |
436 | self |
437 | } |
438 | } |
439 | |
440 | /// Used to encode component and instance types. |
441 | #[derive (Debug)] |
442 | pub struct ComponentTypeEncoder<'a>(&'a mut Vec<u8>); |
443 | |
444 | impl<'a> ComponentTypeEncoder<'a> { |
445 | /// Define a component type. |
446 | pub fn component(self, ty: &ComponentType) { |
447 | ty.encode(self.0); |
448 | } |
449 | |
450 | /// Define an instance type. |
451 | pub fn instance(self, ty: &InstanceType) { |
452 | ty.encode(self.0); |
453 | } |
454 | |
455 | /// Define a function type. |
456 | pub fn function(self) -> ComponentFuncTypeEncoder<'a> { |
457 | ComponentFuncTypeEncoder::new(self.0) |
458 | } |
459 | |
460 | /// Define a defined component type. |
461 | /// |
462 | /// The returned encoder must be used before adding another type. |
463 | #[must_use = "the encoder must be used to encode the type" ] |
464 | pub fn defined_type(self) -> ComponentDefinedTypeEncoder<'a> { |
465 | ComponentDefinedTypeEncoder(self.0) |
466 | } |
467 | |
468 | /// Define a resource type. |
469 | pub fn resource(self, rep: ValType, dtor: Option<u32>) { |
470 | self.0.push(0x3f); |
471 | rep.encode(self.0); |
472 | match dtor { |
473 | Some(i) => { |
474 | self.0.push(0x01); |
475 | i.encode(self.0); |
476 | } |
477 | None => self.0.push(0x00), |
478 | } |
479 | } |
480 | } |
481 | |
482 | /// Represents a primitive component value type. |
483 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
484 | pub enum PrimitiveValType { |
485 | /// The type is a boolean. |
486 | Bool, |
487 | /// The type is a signed 8-bit integer. |
488 | S8, |
489 | /// The type is an unsigned 8-bit integer. |
490 | U8, |
491 | /// The type is a signed 16-bit integer. |
492 | S16, |
493 | /// The type is an unsigned 16-bit integer. |
494 | U16, |
495 | /// The type is a signed 32-bit integer. |
496 | S32, |
497 | /// The type is an unsigned 32-bit integer. |
498 | U32, |
499 | /// The type is a signed 64-bit integer. |
500 | S64, |
501 | /// The type is an unsigned 64-bit integer. |
502 | U64, |
503 | /// The type is a 32-bit floating point number with only one NaN. |
504 | F32, |
505 | /// The type is a 64-bit floating point number with only one NaN. |
506 | F64, |
507 | /// The type is a Unicode character. |
508 | Char, |
509 | /// The type is a string. |
510 | String, |
511 | } |
512 | |
513 | impl Encode for PrimitiveValType { |
514 | fn encode(&self, sink: &mut Vec<u8>) { |
515 | sink.push(match self { |
516 | Self::Bool => 0x7f, |
517 | Self::S8 => 0x7e, |
518 | Self::U8 => 0x7d, |
519 | Self::S16 => 0x7c, |
520 | Self::U16 => 0x7b, |
521 | Self::S32 => 0x7a, |
522 | Self::U32 => 0x79, |
523 | Self::S64 => 0x78, |
524 | Self::U64 => 0x77, |
525 | Self::F32 => 0x76, |
526 | Self::F64 => 0x75, |
527 | Self::Char => 0x74, |
528 | Self::String => 0x73, |
529 | }); |
530 | } |
531 | } |
532 | |
533 | /// Represents a component value type. |
534 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
535 | pub enum ComponentValType { |
536 | /// The value is a primitive type. |
537 | Primitive(PrimitiveValType), |
538 | /// The value is to a defined value type. |
539 | /// |
540 | /// The type index must be to a value type. |
541 | Type(u32), |
542 | } |
543 | |
544 | impl Encode for ComponentValType { |
545 | fn encode(&self, sink: &mut Vec<u8>) { |
546 | match self { |
547 | Self::Primitive(ty: &PrimitiveValType) => ty.encode(sink), |
548 | Self::Type(index: &u32) => (*index as i64).encode(sink), |
549 | } |
550 | } |
551 | } |
552 | |
553 | impl From<PrimitiveValType> for ComponentValType { |
554 | fn from(ty: PrimitiveValType) -> Self { |
555 | Self::Primitive(ty) |
556 | } |
557 | } |
558 | |
559 | /// Used for encoding component defined types. |
560 | #[derive (Debug)] |
561 | pub struct ComponentDefinedTypeEncoder<'a>(&'a mut Vec<u8>); |
562 | |
563 | impl ComponentDefinedTypeEncoder<'_> { |
564 | /// Define a primitive value type. |
565 | pub fn primitive(self, ty: PrimitiveValType) { |
566 | ty.encode(self.0); |
567 | } |
568 | |
569 | /// Define a record type. |
570 | pub fn record<'a, F, T>(self, fields: F) |
571 | where |
572 | F: IntoIterator<Item = (&'a str, T)>, |
573 | F::IntoIter: ExactSizeIterator, |
574 | T: Into<ComponentValType>, |
575 | { |
576 | let fields = fields.into_iter(); |
577 | self.0.push(0x72); |
578 | fields.len().encode(self.0); |
579 | for (name, ty) in fields { |
580 | name.encode(self.0); |
581 | ty.into().encode(self.0); |
582 | } |
583 | } |
584 | |
585 | /// Define a variant type. |
586 | pub fn variant<'a, C>(self, cases: C) |
587 | where |
588 | C: IntoIterator<Item = (&'a str, Option<ComponentValType>, Option<u32>)>, |
589 | C::IntoIter: ExactSizeIterator, |
590 | { |
591 | let cases = cases.into_iter(); |
592 | self.0.push(0x71); |
593 | cases.len().encode(self.0); |
594 | for (name, ty, refines) in cases { |
595 | name.encode(self.0); |
596 | ty.encode(self.0); |
597 | refines.encode(self.0); |
598 | } |
599 | } |
600 | |
601 | /// Define a list type. |
602 | pub fn list(self, ty: impl Into<ComponentValType>) { |
603 | self.0.push(0x70); |
604 | ty.into().encode(self.0); |
605 | } |
606 | |
607 | /// Define a tuple type. |
608 | pub fn tuple<I, T>(self, types: I) |
609 | where |
610 | I: IntoIterator<Item = T>, |
611 | I::IntoIter: ExactSizeIterator, |
612 | T: Into<ComponentValType>, |
613 | { |
614 | let types = types.into_iter(); |
615 | self.0.push(0x6F); |
616 | types.len().encode(self.0); |
617 | for ty in types { |
618 | ty.into().encode(self.0); |
619 | } |
620 | } |
621 | |
622 | /// Define a flags type. |
623 | pub fn flags<'a, I>(self, names: I) |
624 | where |
625 | I: IntoIterator<Item = &'a str>, |
626 | I::IntoIter: ExactSizeIterator, |
627 | { |
628 | let names = names.into_iter(); |
629 | self.0.push(0x6E); |
630 | names.len().encode(self.0); |
631 | for name in names { |
632 | name.encode(self.0); |
633 | } |
634 | } |
635 | |
636 | /// Define an enum type. |
637 | pub fn enum_type<'a, I>(self, tags: I) |
638 | where |
639 | I: IntoIterator<Item = &'a str>, |
640 | I::IntoIter: ExactSizeIterator, |
641 | { |
642 | let tags = tags.into_iter(); |
643 | self.0.push(0x6D); |
644 | tags.len().encode(self.0); |
645 | for tag in tags { |
646 | tag.encode(self.0); |
647 | } |
648 | } |
649 | |
650 | /// Define an option type. |
651 | pub fn option(self, ty: impl Into<ComponentValType>) { |
652 | self.0.push(0x6B); |
653 | ty.into().encode(self.0); |
654 | } |
655 | |
656 | /// Define a result type. |
657 | pub fn result(self, ok: Option<ComponentValType>, err: Option<ComponentValType>) { |
658 | self.0.push(0x6A); |
659 | ok.encode(self.0); |
660 | err.encode(self.0); |
661 | } |
662 | |
663 | /// Define a `own` handle type |
664 | pub fn own(self, idx: u32) { |
665 | self.0.push(0x69); |
666 | idx.encode(self.0); |
667 | } |
668 | |
669 | /// Define a `borrow` handle type |
670 | pub fn borrow(self, idx: u32) { |
671 | self.0.push(0x68); |
672 | idx.encode(self.0); |
673 | } |
674 | } |
675 | |
676 | /// An encoder for the type section of WebAssembly components. |
677 | /// |
678 | /// # Example |
679 | /// |
680 | /// ```rust |
681 | /// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType}; |
682 | /// |
683 | /// let mut types = ComponentTypeSection::new(); |
684 | /// |
685 | /// // Define a function type of `[string, string] -> string`. |
686 | /// types |
687 | /// .function() |
688 | /// .params( |
689 | /// [ |
690 | /// ("a" , PrimitiveValType::String), |
691 | /// ("b" , PrimitiveValType::String) |
692 | /// ] |
693 | /// ) |
694 | /// .result(PrimitiveValType::String); |
695 | /// |
696 | /// let mut component = Component::new(); |
697 | /// component.section(&types); |
698 | /// |
699 | /// let bytes = component.finish(); |
700 | /// ``` |
701 | #[derive (Clone, Debug, Default)] |
702 | pub struct ComponentTypeSection { |
703 | bytes: Vec<u8>, |
704 | num_added: u32, |
705 | } |
706 | |
707 | impl ComponentTypeSection { |
708 | /// Create a new component type section encoder. |
709 | pub fn new() -> Self { |
710 | Self::default() |
711 | } |
712 | |
713 | /// The number of types in the section. |
714 | pub fn len(&self) -> u32 { |
715 | self.num_added |
716 | } |
717 | |
718 | /// Determines if the section is empty. |
719 | pub fn is_empty(&self) -> bool { |
720 | self.num_added == 0 |
721 | } |
722 | |
723 | /// Encode a type into this section. |
724 | /// |
725 | /// The returned encoder must be finished before adding another type. |
726 | #[must_use = "the encoder must be used to encode the type" ] |
727 | pub fn ty(&mut self) -> ComponentTypeEncoder<'_> { |
728 | self.num_added += 1; |
729 | ComponentTypeEncoder(&mut self.bytes) |
730 | } |
731 | |
732 | /// Define a component type in this type section. |
733 | pub fn component(&mut self, ty: &ComponentType) -> &mut Self { |
734 | self.ty().component(ty); |
735 | self |
736 | } |
737 | |
738 | /// Define an instance type in this type section. |
739 | pub fn instance(&mut self, ty: &InstanceType) -> &mut Self { |
740 | self.ty().instance(ty); |
741 | self |
742 | } |
743 | |
744 | /// Define a function type in this type section. |
745 | pub fn function(&mut self) -> ComponentFuncTypeEncoder<'_> { |
746 | self.ty().function() |
747 | } |
748 | |
749 | /// Add a component defined type to this type section. |
750 | /// |
751 | /// The returned encoder must be used before adding another type. |
752 | #[must_use = "the encoder must be used to encode the type" ] |
753 | pub fn defined_type(&mut self) -> ComponentDefinedTypeEncoder<'_> { |
754 | self.ty().defined_type() |
755 | } |
756 | |
757 | /// Defines a new resource type. |
758 | pub fn resource(&mut self, rep: ValType, dtor: Option<u32>) -> &mut Self { |
759 | self.ty().resource(rep, dtor); |
760 | self |
761 | } |
762 | } |
763 | |
764 | impl Encode for ComponentTypeSection { |
765 | fn encode(&self, sink: &mut Vec<u8>) { |
766 | encode_section(sink, self.num_added, &self.bytes); |
767 | } |
768 | } |
769 | |
770 | impl ComponentSection for ComponentTypeSection { |
771 | fn id(&self) -> u8 { |
772 | ComponentSectionId::Type.into() |
773 | } |
774 | } |
775 | |