wac_types/
component.rs

1use crate::ModuleType;
2use id_arena::{Arena, Id};
3use indexmap::{IndexMap, IndexSet};
4use std::{
5    fmt,
6    ops::{Index, IndexMut},
7};
8
9/// An identifier for defined value types.
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11pub struct DefinedTypeId(Id<DefinedType>);
12
13#[cfg(feature = "serde")]
14impl serde::Serialize for DefinedTypeId {
15    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
16        self.0.index().serialize(serializer)
17    }
18}
19
20impl fmt::Display for DefinedTypeId {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        write!(f, "{}", self.0.index())
23    }
24}
25
26/// An identifier for resource types.
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28pub struct ResourceId(Id<Resource>);
29
30#[cfg(feature = "serde")]
31impl serde::Serialize for ResourceId {
32    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
33        self.0.index().serialize(serializer)
34    }
35}
36
37impl fmt::Display for ResourceId {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        write!(f, "{}", self.0.index())
40    }
41}
42
43/// An identifier for function types.
44#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
45pub struct FuncTypeId(Id<FuncType>);
46
47#[cfg(feature = "serde")]
48impl serde::Serialize for FuncTypeId {
49    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
50        self.0.index().serialize(serializer)
51    }
52}
53
54impl fmt::Display for FuncTypeId {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        write!(f, "{}", self.0.index())
57    }
58}
59
60/// An identifier for interfaces.
61///
62/// An interface is analogous to an instance type in the component model.
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
64pub struct InterfaceId(Id<Interface>);
65
66#[cfg(feature = "serde")]
67impl serde::Serialize for InterfaceId {
68    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
69        self.0.index().serialize(serializer)
70    }
71}
72
73impl fmt::Display for InterfaceId {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        write!(f, "{}", self.0.index())
76    }
77}
78
79/// An identifier for worlds.
80///
81/// A world is analogous to a component type in the component model.
82#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
83pub struct WorldId(Id<World>);
84
85#[cfg(feature = "serde")]
86impl serde::Serialize for WorldId {
87    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
88        self.0.index().serialize(serializer)
89    }
90}
91
92impl fmt::Display for WorldId {
93    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94        write!(f, "{}", self.0.index())
95    }
96}
97
98/// An identifier for module types.
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
100pub struct ModuleTypeId(Id<ModuleType>);
101
102#[cfg(feature = "serde")]
103impl serde::Serialize for ModuleTypeId {
104    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
105        self.0.index().serialize(serializer)
106    }
107}
108
109impl fmt::Display for ModuleTypeId {
110    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111        write!(f, "{}", self.0.index())
112    }
113}
114
115#[cfg(feature = "serde")]
116fn serialize_arena<T, S>(arena: &Arena<T>, serializer: S) -> Result<S::Ok, S::Error>
117where
118    S: serde::Serializer,
119    T: serde::Serialize,
120{
121    use serde::ser::SerializeSeq;
122
123    let mut s = serializer.serialize_seq(Some(arena.len()))?;
124    for (_, e) in arena.iter() {
125        s.serialize_element(e)?;
126    }
127
128    s.end()
129}
130
131/// Represents a component model types collection.
132#[derive(Default, Clone, Debug)]
133#[cfg_attr(feature = "serde", derive(serde::Serialize))]
134#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
135pub struct Types {
136    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
137    defined: Arena<DefinedType>,
138    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
139    resources: Arena<Resource>,
140    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
141    funcs: Arena<FuncType>,
142    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
143    interfaces: Arena<Interface>,
144    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
145    worlds: Arena<World>,
146    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
147    modules: Arena<ModuleType>,
148}
149
150impl Types {
151    /// Creates a new types collection.
152    pub fn new() -> Self {
153        Self::default()
154    }
155
156    /// Iterates the defined types in the collection.
157    pub fn defined_types(&self) -> impl Iterator<Item = &DefinedType> {
158        self.defined.iter().map(|(_, t)| t)
159    }
160
161    /// Iterates the resources in the collection.
162    pub fn resources(&self) -> impl Iterator<Item = &Resource> {
163        self.resources.iter().map(|(_, t)| t)
164    }
165
166    /// Iterates the function types in the collection.
167    pub fn func_types(&self) -> impl Iterator<Item = &FuncType> {
168        self.funcs.iter().map(|(_, t)| t)
169    }
170
171    /// Iterates the interfaces in the collection.
172    pub fn interfaces(&self) -> impl Iterator<Item = &Interface> {
173        self.interfaces.iter().map(|(_, t)| t)
174    }
175
176    /// Iterates the worlds in the collection.
177    pub fn worlds(&self) -> impl Iterator<Item = &World> {
178        self.worlds.iter().map(|(_, t)| t)
179    }
180
181    /// Iterates the modules in the collection.
182    pub fn modules(&self) -> impl Iterator<Item = &ModuleType> {
183        self.modules.iter().map(|(_, t)| t)
184    }
185
186    /// Adds a defined value type to the collection.
187    pub fn add_defined_type(&mut self, ty: DefinedType) -> DefinedTypeId {
188        DefinedTypeId(self.defined.alloc(ty))
189    }
190
191    /// Adds a resource to the collection.
192    pub fn add_resource(&mut self, resource: Resource) -> ResourceId {
193        ResourceId(self.resources.alloc(resource))
194    }
195
196    /// Adds a function type to the collection.
197    pub fn add_func_type(&mut self, func: FuncType) -> FuncTypeId {
198        FuncTypeId(self.funcs.alloc(func))
199    }
200
201    /// Adds an interface (i.e. instance type) to the collection.
202    pub fn add_interface(&mut self, interface: Interface) -> InterfaceId {
203        InterfaceId(self.interfaces.alloc(interface))
204    }
205
206    /// Adds a world (i.e. component type) to the collection.
207    pub fn add_world(&mut self, world: World) -> WorldId {
208        WorldId(self.worlds.alloc(world))
209    }
210
211    /// Adds a module type to the collection.
212    pub fn add_module_type(&mut self, module: ModuleType) -> ModuleTypeId {
213        ModuleTypeId(self.modules.alloc(module))
214    }
215
216    /// Determines if the given type is defined in this collection.
217    ///
218    /// Note that primitive types are always considered part of a collection.
219    pub fn contains(&self, ty: Type) -> bool {
220        match ty {
221            Type::Resource(id)
222            | Type::Value(ValueType::Borrow(id))
223            | Type::Value(ValueType::Own(id)) => self.resources.get(id.0).is_some(),
224            Type::Func(id) => self.funcs.get(id.0).is_some(),
225            Type::Value(ValueType::Primitive(_)) => true,
226            Type::Value(ValueType::Defined(id)) => self.defined.get(id.0).is_some(),
227            Type::Interface(id) => self.interfaces.get(id.0).is_some(),
228            Type::World(id) => self.worlds.get(id.0).is_some(),
229            Type::Module(id) => self.modules.get(id.0).is_some(),
230        }
231    }
232
233    /// Resolves a value type to a un-aliased value type.
234    pub fn resolve_value_type(&self, mut ty: ValueType) -> ValueType {
235        loop {
236            match ty {
237                ValueType::Defined(id) => match self[id] {
238                    DefinedType::Alias(aliased) => ty = aliased,
239                    _ => return ty,
240                },
241                _ => return ty,
242            }
243        }
244    }
245
246    /// Resolves any aliased resource id to the underlying defined resource id.
247    pub fn resolve_resource(&self, mut id: ResourceId) -> ResourceId {
248        while let Some(alias) = &self[id].alias {
249            id = alias.source;
250        }
251
252        id
253    }
254}
255
256impl Index<DefinedTypeId> for Types {
257    type Output = DefinedType;
258
259    fn index(&self, id: DefinedTypeId) -> &Self::Output {
260        &self.defined[id.0]
261    }
262}
263
264impl Index<ResourceId> for Types {
265    type Output = Resource;
266
267    fn index(&self, id: ResourceId) -> &Self::Output {
268        &self.resources[id.0]
269    }
270}
271
272impl Index<FuncTypeId> for Types {
273    type Output = FuncType;
274
275    fn index(&self, id: FuncTypeId) -> &Self::Output {
276        &self.funcs[id.0]
277    }
278}
279
280impl Index<InterfaceId> for Types {
281    type Output = Interface;
282
283    fn index(&self, id: InterfaceId) -> &Self::Output {
284        &self.interfaces[id.0]
285    }
286}
287
288impl Index<WorldId> for Types {
289    type Output = World;
290
291    fn index(&self, id: WorldId) -> &Self::Output {
292        &self.worlds[id.0]
293    }
294}
295
296impl Index<ModuleTypeId> for Types {
297    type Output = ModuleType;
298
299    fn index(&self, id: ModuleTypeId) -> &Self::Output {
300        &self.modules[id.0]
301    }
302}
303
304impl IndexMut<DefinedTypeId> for Types {
305    fn index_mut(&mut self, id: DefinedTypeId) -> &mut Self::Output {
306        &mut self.defined[id.0]
307    }
308}
309
310impl IndexMut<ResourceId> for Types {
311    fn index_mut(&mut self, id: ResourceId) -> &mut Self::Output {
312        &mut self.resources[id.0]
313    }
314}
315
316impl IndexMut<FuncTypeId> for Types {
317    fn index_mut(&mut self, id: FuncTypeId) -> &mut Self::Output {
318        &mut self.funcs[id.0]
319    }
320}
321
322impl IndexMut<InterfaceId> for Types {
323    fn index_mut(&mut self, id: InterfaceId) -> &mut Self::Output {
324        &mut self.interfaces[id.0]
325    }
326}
327
328impl IndexMut<WorldId> for Types {
329    fn index_mut(&mut self, id: WorldId) -> &mut Self::Output {
330        &mut self.worlds[id.0]
331    }
332}
333
334impl IndexMut<ModuleTypeId> for Types {
335    fn index_mut(&mut self, id: ModuleTypeId) -> &mut Self::Output {
336        &mut self.modules[id.0]
337    }
338}
339
340/// Represents the kind of a component model item.
341///
342/// Note that an item kind is associated with a particular `Types` collection.
343#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
344#[cfg_attr(feature = "serde", derive(serde::Serialize))]
345#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
346pub enum ItemKind {
347    /// The item is a type.
348    Type(Type),
349    /// The item is a function.
350    Func(FuncTypeId),
351    /// The item is a component instance.
352    Instance(InterfaceId),
353    /// The item is a component.
354    Component(WorldId),
355    /// The item is a core module.
356    Module(ModuleTypeId),
357    /// The item is a value.
358    Value(ValueType),
359}
360
361impl ItemKind {
362    /// Gets the type of the item.
363    ///
364    /// Returns `None` for resource items.
365    pub fn ty(&self) -> Type {
366        match self {
367            ItemKind::Type(ty) => *ty,
368            ItemKind::Func(id) => Type::Func(*id),
369            ItemKind::Instance(id) => Type::Interface(*id),
370            ItemKind::Component(id) => Type::World(*id),
371            ItemKind::Module(id) => Type::Module(*id),
372            ItemKind::Value(ty) => Type::Value(*ty),
373        }
374    }
375
376    /// Gets a description of the item kind.
377    pub fn desc(&self, types: &Types) -> &'static str {
378        match self {
379            ItemKind::Func(_) => "function",
380            ItemKind::Type(ty) => ty.desc(types),
381            ItemKind::Instance(_) => "instance",
382            ItemKind::Component(_) => "component",
383            ItemKind::Module(_) => "module",
384            ItemKind::Value(_) => "value",
385        }
386    }
387
388    /// Promote function types, instance types, and component types
389    /// to functions, instances, and components.
390    pub fn promote(&self) -> Self {
391        match *self {
392            ItemKind::Type(Type::Func(id)) => ItemKind::Func(id),
393            ItemKind::Type(Type::Interface(id)) => ItemKind::Instance(id),
394            ItemKind::Type(Type::World(id)) => ItemKind::Component(id),
395            kind => kind,
396        }
397    }
398
399    fn _visit_defined_types<'a, E>(
400        &self,
401        types: &'a Types,
402        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
403    ) -> Result<(), E> {
404        match self {
405            ItemKind::Type(ty) => ty._visit_defined_types(types, visitor, false),
406            ItemKind::Func(id) => types[*id]._visit_defined_types(types, visitor),
407            ItemKind::Instance(id) => types[*id]._visit_defined_types(types, visitor),
408            ItemKind::Component(id) => types[*id]._visit_defined_types(types, visitor),
409            ItemKind::Module(_) => Ok(()),
410            ItemKind::Value(ty) => ty._visit_defined_types(types, visitor, false),
411        }
412    }
413}
414
415impl From<ItemKind> for wasm_encoder::ComponentExportKind {
416    fn from(value: ItemKind) -> Self {
417        match value {
418            ItemKind::Type(_) => Self::Type,
419            ItemKind::Func(_) => Self::Func,
420            ItemKind::Instance(_) => Self::Instance,
421            ItemKind::Component(_) => Self::Component,
422            ItemKind::Module(_) => Self::Module,
423            ItemKind::Value(_) => Self::Value,
424        }
425    }
426}
427
428/// Represent a component model type.
429#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
430#[cfg_attr(feature = "serde", derive(serde::Serialize))]
431#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
432pub enum Type {
433    /// The type is a resource.
434    Resource(ResourceId),
435    /// The type is a function type.
436    Func(FuncTypeId),
437    /// The type is a value type.
438    Value(ValueType),
439    /// The type is an interface (i.e. instance type).
440    Interface(InterfaceId),
441    /// The type is a world (i.e. component type).
442    World(WorldId),
443    /// The type is a core module type.
444    Module(ModuleTypeId),
445}
446
447impl Type {
448    /// Gets a description of the type.
449    pub fn desc(&self, types: &Types) -> &'static str {
450        match self {
451            Type::Resource(_) => "resource",
452            Type::Func(_) => "function type",
453            Type::Value(ty) => ty.desc(types),
454            Type::Interface(_) => "interface",
455            Type::World(_) => "world",
456            Type::Module(_) => "module type",
457        }
458    }
459
460    /// Visits each defined type referenced by this type.
461    ///
462    /// If the visitor returns `Err`, the visiting stops and the error is returned.
463    pub fn visit_defined_types<'a, E>(
464        &self,
465        types: &'a Types,
466        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
467    ) -> Result<(), E> {
468        self._visit_defined_types(types, visitor, true)
469    }
470
471    fn _visit_defined_types<'a, E>(
472        &self,
473        types: &'a Types,
474        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
475        recurse: bool,
476    ) -> Result<(), E> {
477        match self {
478            Type::Module(_) | Type::Resource(_) => Ok(()),
479            Type::Func(id) => types[*id]._visit_defined_types(types, visitor),
480            Type::Value(ty) => ty._visit_defined_types(types, visitor, recurse),
481            Type::Interface(id) => types[*id]._visit_defined_types(types, visitor),
482            Type::World(id) => types[*id]._visit_defined_types(types, visitor),
483        }
484    }
485}
486
487/// Represents a primitive type.
488#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
489#[cfg_attr(feature = "serde", derive(serde::Serialize))]
490#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
491pub enum PrimitiveType {
492    /// A `u8` type.
493    U8,
494    /// A `s8` type.
495    S8,
496    /// A `u16` type.
497    U16,
498    /// A `s16` type.
499    S16,
500    /// A `u32` type.
501    U32,
502    /// A `s32` type.
503    S32,
504    /// A `u64` type.
505    U64,
506    /// A `s64` type.
507    S64,
508    /// A `f32` type.
509    F32,
510    /// A `f64` type.
511    F64,
512    /// A `char` type.
513    Char,
514    /// A `bool` type.
515    Bool,
516    /// A `string` type.
517    String,
518    /// An `error-context` type.
519    ErrorContext,
520}
521
522impl PrimitiveType {
523    /// Gets a description of the primitive type.
524    pub fn desc(&self) -> &'static str {
525        match self {
526            Self::U8 => "u8",
527            Self::S8 => "s8",
528            Self::U16 => "u16",
529            Self::S16 => "s16",
530            Self::U32 => "u32",
531            Self::S32 => "s32",
532            Self::U64 => "u64",
533            Self::S64 => "s64",
534            Self::F32 => "f32",
535            Self::F64 => "f64",
536            Self::Char => "char",
537            Self::Bool => "bool",
538            Self::String => "string",
539            Self::ErrorContext => "error-context",
540        }
541    }
542}
543
544impl From<wasmparser::PrimitiveValType> for PrimitiveType {
545    fn from(value: wasmparser::PrimitiveValType) -> Self {
546        match value {
547            wasmparser::PrimitiveValType::Bool => Self::Bool,
548            wasmparser::PrimitiveValType::S8 => Self::S8,
549            wasmparser::PrimitiveValType::U8 => Self::U8,
550            wasmparser::PrimitiveValType::S16 => Self::S16,
551            wasmparser::PrimitiveValType::U16 => Self::U16,
552            wasmparser::PrimitiveValType::S32 => Self::S32,
553            wasmparser::PrimitiveValType::U32 => Self::U32,
554            wasmparser::PrimitiveValType::S64 => Self::S64,
555            wasmparser::PrimitiveValType::U64 => Self::U64,
556            wasmparser::PrimitiveValType::F32 => Self::F32,
557            wasmparser::PrimitiveValType::F64 => Self::F64,
558            wasmparser::PrimitiveValType::Char => Self::Char,
559            wasmparser::PrimitiveValType::String => Self::String,
560            wasmparser::PrimitiveValType::ErrorContext => Self::ErrorContext,
561        }
562    }
563}
564
565impl From<PrimitiveType> for wasm_encoder::PrimitiveValType {
566    fn from(value: PrimitiveType) -> Self {
567        match value {
568            PrimitiveType::U8 => Self::U8,
569            PrimitiveType::S8 => Self::S8,
570            PrimitiveType::U16 => Self::U16,
571            PrimitiveType::S16 => Self::S16,
572            PrimitiveType::U32 => Self::U32,
573            PrimitiveType::S32 => Self::S32,
574            PrimitiveType::U64 => Self::U64,
575            PrimitiveType::S64 => Self::S64,
576            PrimitiveType::F32 => Self::F32,
577            PrimitiveType::F64 => Self::F64,
578            PrimitiveType::Char => Self::Char,
579            PrimitiveType::Bool => Self::Bool,
580            PrimitiveType::String => Self::String,
581            PrimitiveType::ErrorContext => Self::ErrorContext,
582        }
583    }
584}
585
586/// Represents a value type.
587#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
588pub enum ValueType {
589    /// A primitive value type.
590    Primitive(PrimitiveType),
591    /// The type is a borrow of a resource type.
592    Borrow(ResourceId),
593    /// The type is an owned resource type.
594    Own(ResourceId),
595    /// A defined value type.
596    Defined(DefinedTypeId),
597}
598
599impl ValueType {
600    /// Checks if the type contains a borrow.
601    ///
602    /// Function results may not return a type containing a borrow.
603    pub fn contains_borrow(&self, types: &Types) -> bool {
604        match self {
605            ValueType::Primitive(_) | ValueType::Own(_) => false,
606            ValueType::Borrow(_) => true,
607            ValueType::Defined(id) => types[*id].contains_borrow(types),
608        }
609    }
610
611    fn _visit_defined_types<'a, E>(
612        &self,
613        types: &'a Types,
614        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
615        recurse: bool,
616    ) -> Result<(), E> {
617        match self {
618            ValueType::Primitive(_) | ValueType::Borrow(_) | ValueType::Own(_) => Ok(()),
619            ValueType::Defined(id) => {
620                visitor(types, *id)?;
621                if recurse {
622                    types[*id]._visit_defined_types(types, visitor)?;
623                }
624
625                Ok(())
626            }
627        }
628    }
629
630    /// Gets a description of the value type.
631    pub fn desc(&self, types: &Types) -> &'static str {
632        match self {
633            Self::Primitive(ty) => ty.desc(),
634            Self::Borrow(_) => "borrow",
635            Self::Own(_) => "own",
636            Self::Defined(id) => types[*id].desc(types),
637        }
638    }
639}
640
641#[cfg(feature = "serde")]
642impl serde::Serialize for ValueType {
643    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
644        match self {
645            Self::Primitive(ty) => ty.serialize(serializer),
646            Self::Borrow(id) => format!("borrow<{id}>", id = id.0.index()).serialize(serializer),
647            Self::Own(id) => format!("own<{id}>", id = id.0.index()).serialize(serializer),
648            Self::Defined(id) => id.serialize(serializer),
649        }
650    }
651}
652
653/// Represents a defined value type.
654#[derive(Debug, Clone)]
655#[cfg_attr(feature = "serde", derive(serde::Serialize))]
656#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
657pub enum DefinedType {
658    /// A tuple type.
659    Tuple(Vec<ValueType>),
660    /// A list type.
661    List(ValueType),
662    /// A fixed size array
663    FixedSizeList(ValueType, u32),
664    /// An option type.
665    Option(ValueType),
666    /// A result type.
667    Result {
668        /// The result's `ok` type.
669        ok: Option<ValueType>,
670        /// The result's `err` type.
671        err: Option<ValueType>,
672    },
673    /// The type is a variant type.
674    Variant(Variant),
675    /// The type is a record type.
676    Record(Record),
677    /// The type is a flags type.
678    Flags(Flags),
679    /// The type is an enum.
680    Enum(Enum),
681    /// The type is an alias to another value type.
682    Alias(ValueType),
683    /// A stream type.
684    Stream(Option<ValueType>),
685    /// A futures type.
686    Future(Option<ValueType>),
687}
688
689impl DefinedType {
690    /// Determines if the defined type recursively contains a borrow.
691    pub fn contains_borrow(&self, types: &Types) -> bool {
692        match self {
693            Self::Tuple(tys) => tys.iter().any(|ty| ty.contains_borrow(types)),
694            Self::List(ty) | Self::FixedSizeList(ty, _) => ty.contains_borrow(types),
695            Self::Option(ty) => ty.contains_borrow(types),
696            Self::Result { ok, err } => {
697                ok.map(|ty| ty.contains_borrow(types)).unwrap_or(false)
698                    || err.map(|ty| ty.contains_borrow(types)).unwrap_or(false)
699            }
700            Self::Variant(v) => v
701                .cases
702                .values()
703                .any(|ty| ty.map(|ty| ty.contains_borrow(types)).unwrap_or(false)),
704            Self::Record(r) => r.fields.iter().any(|(_, ty)| ty.contains_borrow(types)),
705            Self::Flags(_) => false,
706            Self::Enum(_) => false,
707            Self::Alias(ty) => ty.contains_borrow(types),
708            Self::Stream(ty) => ty.map(|ty| ty.contains_borrow(types)).unwrap_or(false),
709            Self::Future(ty) => ty.map(|ty| ty.contains_borrow(types)).unwrap_or(false),
710        }
711    }
712
713    fn _visit_defined_types<'a, E>(
714        &self,
715        types: &'a Types,
716        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
717    ) -> Result<(), E> {
718        match self {
719            DefinedType::Tuple(tys) => {
720                for ty in tys {
721                    ty._visit_defined_types(types, visitor, false)?;
722                }
723
724                Ok(())
725            }
726            DefinedType::List(ty) | DefinedType::Option(ty) | DefinedType::FixedSizeList(ty, _) => {
727                ty._visit_defined_types(types, visitor, false)
728            }
729            DefinedType::Result { ok, err } => {
730                if let Some(ty) = ok.as_ref() {
731                    ty._visit_defined_types(types, visitor, false)?;
732                }
733
734                if let Some(ty) = err.as_ref() {
735                    ty._visit_defined_types(types, visitor, false)?;
736                }
737
738                Ok(())
739            }
740            DefinedType::Variant(v) => {
741                for ty in v.cases.values().filter_map(Option::as_ref) {
742                    ty._visit_defined_types(types, visitor, false)?;
743                }
744
745                Ok(())
746            }
747            DefinedType::Record(r) => {
748                for (_, ty) in &r.fields {
749                    ty._visit_defined_types(types, visitor, false)?
750                }
751
752                Ok(())
753            }
754            DefinedType::Flags(_) | DefinedType::Enum(_) | DefinedType::Alias(_) => Ok(()),
755            DefinedType::Stream(ty) | DefinedType::Future(ty) => {
756                if let Some(ty) = ty {
757                    ty._visit_defined_types(types, visitor, false)?;
758                }
759
760                Ok(())
761            }
762        }
763    }
764
765    /// Gets atyd | DefinedType::Future(t)escription of the defined type.
766    pub fn desc(&self, types: &Types) -> &'static str {
767        match self {
768            Self::Tuple(_) => "tuple",
769            Self::List(_) => "list",
770            Self::FixedSizeList(_, _) => "list<,N>",
771            Self::Option(_) => "option",
772            Self::Result { .. } => "result",
773            Self::Variant(_) => "variant",
774            Self::Record(_) => "record",
775            Self::Flags(_) => "flags",
776            Self::Enum(_) => "enum",
777            Self::Alias(ty) => ty.desc(types),
778            Self::Stream(_) => "stream",
779            Self::Future(_) => "future",
780        }
781    }
782}
783
784/// Represents a kind of function in the component model.
785#[derive(Debug, Clone, Copy, PartialEq, Eq)]
786#[cfg_attr(feature = "serde", derive(serde::Serialize))]
787#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
788pub enum FuncKind {
789    /// The function is a "free" function (i.e. not associated with a resource).
790    Free,
791    /// The function is a method on a resource.
792    Method,
793    /// The function is a static method on a resource.
794    Static,
795    /// The function is a resource constructor.
796    Constructor,
797}
798
799impl fmt::Display for FuncKind {
800    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
801        match self {
802            FuncKind::Free => write!(f, "function"),
803            FuncKind::Method => write!(f, "method"),
804            FuncKind::Static => write!(f, "static method"),
805            FuncKind::Constructor => write!(f, "constructor"),
806        }
807    }
808}
809
810/// Represents information about an aliased resource.
811#[derive(Debug, Clone, Copy)]
812#[cfg_attr(feature = "serde", derive(serde::Serialize))]
813#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
814pub struct ResourceAlias {
815    /// The foreign owning interface for the resource.
816    ///
817    /// This may be `None` if the resource does not have a foreign interface owner
818    /// such as in a world or when aliasing within the same interface.
819    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
820    pub owner: Option<InterfaceId>,
821    /// The id of the resource that was aliased.
822    pub source: ResourceId,
823}
824
825/// Represents a resource type.
826#[derive(Debug, Clone)]
827#[cfg_attr(feature = "serde", derive(serde::Serialize))]
828#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
829pub struct Resource {
830    /// The name of the resource.
831    pub name: String,
832    /// Information if the resource has been aliased.
833    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
834    pub alias: Option<ResourceAlias>,
835}
836
837/// Represents a variant.
838#[derive(Debug, Clone)]
839#[cfg_attr(feature = "serde", derive(serde::Serialize))]
840#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
841pub struct Variant {
842    /// The variant cases.
843    pub cases: IndexMap<String, Option<ValueType>>,
844}
845
846/// Represents a record type.
847#[derive(Debug, Clone)]
848#[cfg_attr(feature = "serde", derive(serde::Serialize))]
849#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
850pub struct Record {
851    /// The record fields.
852    pub fields: IndexMap<String, ValueType>,
853}
854
855/// Represents a flags type.
856#[derive(Debug, Clone)]
857#[cfg_attr(feature = "serde", derive(serde::Serialize))]
858#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
859pub struct Flags(pub IndexSet<String>);
860
861/// Represents an enum type.
862#[derive(Debug, Clone)]
863#[cfg_attr(feature = "serde", derive(serde::Serialize))]
864#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
865pub struct Enum(pub IndexSet<String>);
866
867/// Represents a function type.
868#[derive(Debug, Clone, Default)]
869#[cfg_attr(feature = "serde", derive(serde::Serialize))]
870#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
871pub struct FuncType {
872    /// The parameters of the function.
873    pub params: IndexMap<String, ValueType>,
874    /// The result of the function.
875    pub result: Option<ValueType>,
876}
877
878impl FuncType {
879    fn _visit_defined_types<'a, E>(
880        &self,
881        types: &'a Types,
882        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
883    ) -> Result<(), E> {
884        for ty in self.params.values() {
885            ty._visit_defined_types(types, visitor, false)?;
886        }
887
888        if let Some(ty) = &self.result {
889            ty._visit_defined_types(types, visitor, false)?;
890        }
891
892        Ok(())
893    }
894}
895
896/// Represents a used type.
897#[derive(Debug, Clone)]
898#[cfg_attr(feature = "serde", derive(serde::Serialize))]
899#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
900pub struct UsedType {
901    /// The interface the type was used from.
902    pub interface: InterfaceId,
903    /// The original export name.
904    ///
905    /// This is `None` when the type was not renamed with an `as` clause.
906    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
907    pub name: Option<String>,
908}
909
910/// Represents an interface (i.e. instance type).
911#[derive(Debug, Clone, Default)]
912#[cfg_attr(feature = "serde", derive(serde::Serialize))]
913#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
914pub struct Interface {
915    /// The identifier of the interface.
916    ///
917    /// This may be `None` for inline interfaces.
918    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
919    pub id: Option<String>,
920    /// A map of exported name to information about the used type.
921    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "IndexMap::is_empty"))]
922    pub uses: IndexMap<String, UsedType>,
923    /// The exported items of the interface.
924    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "IndexMap::is_empty"))]
925    pub exports: IndexMap<String, ItemKind>,
926}
927
928impl Interface {
929    fn _visit_defined_types<'a, E>(
930        &self,
931        types: &'a Types,
932        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
933    ) -> Result<(), E> {
934        for kind in self.exports.values() {
935            kind._visit_defined_types(types, visitor)?;
936        }
937
938        Ok(())
939    }
940}
941
942/// Represents a world.
943#[derive(Debug, Clone, Default)]
944#[cfg_attr(feature = "serde", derive(serde::Serialize))]
945#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
946pub struct World {
947    /// The identifier of the world.
948    ///
949    /// This may be `None` for worlds representing component types.
950    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
951    pub id: Option<String>,
952    /// A map of imported name to information about the used type.
953    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "IndexMap::is_empty"))]
954    pub uses: IndexMap<String, UsedType>,
955    /// The imported items of the world.
956    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "IndexMap::is_empty"))]
957    pub imports: IndexMap<String, ItemKind>,
958    /// The exported items of the world.
959    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "IndexMap::is_empty"))]
960    pub exports: IndexMap<String, ItemKind>,
961}
962
963impl World {
964    fn _visit_defined_types<'a, E>(
965        &self,
966        types: &'a Types,
967        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
968    ) -> Result<(), E> {
969        for kind in self.imports.values() {
970            kind._visit_defined_types(types, visitor)?;
971        }
972
973        for kind in self.exports.values() {
974            kind._visit_defined_types(types, visitor)?;
975        }
976
977        Ok(())
978    }
979
980    /// The interfaces imported implicitly through uses.
981    pub fn implicit_imported_interfaces<'a>(
982        &'a self,
983        types: &'a Types,
984    ) -> IndexMap<&'a str, ItemKind> {
985        let mut interfaces = IndexMap::new();
986        let mut add_interface_for_used_type = |used_item: &UsedType| {
987            let used_interface_id = used_item.interface;
988            // The id must be set since used interfaces are always named.
989            let used_interface_name = types[used_interface_id].id.as_deref().unwrap();
990            interfaces.insert(used_interface_name, ItemKind::Instance(used_interface_id));
991        };
992
993        for (_, used_type) in self.uses.iter() {
994            add_interface_for_used_type(used_type);
995        }
996
997        for (_, import) in self.imports.iter() {
998            if let ItemKind::Instance(interface_id) = import {
999                let import = &types[*interface_id];
1000                for (_, used_item) in &import.uses {
1001                    add_interface_for_used_type(used_item);
1002                }
1003            }
1004        }
1005        interfaces
1006    }
1007}
1008
1009/// Represents a kind of an extern item.
1010#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
1011pub enum ExternKind {
1012    /// The item is an import.
1013    Import,
1014    /// The item is an export.
1015    Export,
1016}
1017
1018impl fmt::Display for ExternKind {
1019    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1020        match self {
1021            Self::Import => write!(f, "import"),
1022            Self::Export => write!(f, "export"),
1023        }
1024    }
1025}