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 ModuleId {
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}
519
520impl PrimitiveType {
521    /// Gets a description of the primitive type.
522    pub fn desc(&self) -> &'static str {
523        match self {
524            Self::U8 => "u8",
525            Self::S8 => "s8",
526            Self::U16 => "u16",
527            Self::S16 => "s16",
528            Self::U32 => "u32",
529            Self::S32 => "s32",
530            Self::U64 => "u64",
531            Self::S64 => "s64",
532            Self::F32 => "f32",
533            Self::F64 => "f64",
534            Self::Char => "char",
535            Self::Bool => "bool",
536            Self::String => "string",
537        }
538    }
539}
540
541impl From<wasmparser::PrimitiveValType> for PrimitiveType {
542    fn from(value: wasmparser::PrimitiveValType) -> Self {
543        match value {
544            wasmparser::PrimitiveValType::Bool => Self::Bool,
545            wasmparser::PrimitiveValType::S8 => Self::S8,
546            wasmparser::PrimitiveValType::U8 => Self::U8,
547            wasmparser::PrimitiveValType::S16 => Self::S16,
548            wasmparser::PrimitiveValType::U16 => Self::U16,
549            wasmparser::PrimitiveValType::S32 => Self::S32,
550            wasmparser::PrimitiveValType::U32 => Self::U32,
551            wasmparser::PrimitiveValType::S64 => Self::S64,
552            wasmparser::PrimitiveValType::U64 => Self::U64,
553            wasmparser::PrimitiveValType::F32 => Self::F32,
554            wasmparser::PrimitiveValType::F64 => Self::F64,
555            wasmparser::PrimitiveValType::Char => Self::Char,
556            wasmparser::PrimitiveValType::String => Self::String,
557        }
558    }
559}
560
561impl From<PrimitiveType> for wasm_encoder::PrimitiveValType {
562    fn from(value: PrimitiveType) -> Self {
563        match value {
564            PrimitiveType::U8 => Self::U8,
565            PrimitiveType::S8 => Self::S8,
566            PrimitiveType::U16 => Self::U16,
567            PrimitiveType::S16 => Self::S16,
568            PrimitiveType::U32 => Self::U32,
569            PrimitiveType::S32 => Self::S32,
570            PrimitiveType::U64 => Self::U64,
571            PrimitiveType::S64 => Self::S64,
572            PrimitiveType::F32 => Self::F32,
573            PrimitiveType::F64 => Self::F64,
574            PrimitiveType::Char => Self::Char,
575            PrimitiveType::Bool => Self::Bool,
576            PrimitiveType::String => Self::String,
577        }
578    }
579}
580
581/// Represents a value type.
582#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
583pub enum ValueType {
584    /// A primitive value type.
585    Primitive(PrimitiveType),
586    /// The type is a borrow of a resource type.
587    Borrow(ResourceId),
588    /// The type is an owned resource type.
589    Own(ResourceId),
590    /// A defined value type.
591    Defined(DefinedTypeId),
592}
593
594impl ValueType {
595    /// Checks if the type contains a borrow.
596    ///
597    /// Function results may not return a type containing a borrow.
598    pub fn contains_borrow(&self, types: &Types) -> bool {
599        match self {
600            ValueType::Primitive(_) | ValueType::Own(_) => false,
601            ValueType::Borrow(_) => true,
602            ValueType::Defined(id) => types[*id].contains_borrow(types),
603        }
604    }
605
606    fn _visit_defined_types<'a, E>(
607        &self,
608        types: &'a Types,
609        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
610        recurse: bool,
611    ) -> Result<(), E> {
612        match self {
613            ValueType::Primitive(_) | ValueType::Borrow(_) | ValueType::Own(_) => Ok(()),
614            ValueType::Defined(id) => {
615                visitor(types, *id)?;
616                if recurse {
617                    types[*id]._visit_defined_types(types, visitor)?;
618                }
619
620                Ok(())
621            }
622        }
623    }
624
625    /// Gets a description of the value type.
626    pub fn desc(&self, types: &Types) -> &'static str {
627        match self {
628            Self::Primitive(ty) => ty.desc(),
629            Self::Borrow(_) => "borrow",
630            Self::Own(_) => "own",
631            Self::Defined(id) => types[*id].desc(types),
632        }
633    }
634}
635
636#[cfg(feature = "serde")]
637impl serde::Serialize for ValueType {
638    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
639        match self {
640            Self::Primitive(ty) => ty.serialize(serializer),
641            Self::Borrow(id) => format!("borrow<{id}>", id = id.0.index()).serialize(serializer),
642            Self::Own(id) => format!("own<{id}>", id = id.0.index()).serialize(serializer),
643            Self::Defined { id, .. } => id.serialize(serializer),
644        }
645    }
646}
647
648/// Represents a defined value type.
649#[derive(Debug, Clone)]
650#[cfg_attr(feature = "serde", derive(serde::Serialize))]
651#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
652pub enum DefinedType {
653    /// A tuple type.
654    Tuple(Vec<ValueType>),
655    /// A list type.
656    List(ValueType),
657    /// An option type.
658    Option(ValueType),
659    /// A result type.
660    Result {
661        /// The result's `ok` type.
662        ok: Option<ValueType>,
663        /// The result's `err` type.
664        err: Option<ValueType>,
665    },
666    /// The type is a variant type.
667    Variant(Variant),
668    /// The type is a record type.
669    Record(Record),
670    /// The type is a flags type.
671    Flags(Flags),
672    /// The type is an enum.
673    Enum(Enum),
674    /// The type is an alias to another value type.
675    Alias(ValueType),
676}
677
678impl DefinedType {
679    /// Determines if the defined type recursively contains a borrow.
680    pub fn contains_borrow(&self, types: &Types) -> bool {
681        match self {
682            Self::Tuple(tys) => tys.iter().any(|ty| ty.contains_borrow(types)),
683            Self::List(ty) => ty.contains_borrow(types),
684            Self::Option(ty) => ty.contains_borrow(types),
685            Self::Result { ok, err } => {
686                ok.map(|ty| ty.contains_borrow(types)).unwrap_or(false)
687                    || err.map(|ty| ty.contains_borrow(types)).unwrap_or(false)
688            }
689            Self::Variant(v) => v
690                .cases
691                .values()
692                .any(|ty| ty.map(|ty| ty.contains_borrow(types)).unwrap_or(false)),
693            Self::Record(r) => r.fields.iter().any(|(_, ty)| ty.contains_borrow(types)),
694            Self::Flags(_) => false,
695            Self::Enum(_) => false,
696            Self::Alias(ty) => ty.contains_borrow(types),
697        }
698    }
699
700    fn _visit_defined_types<'a, E>(
701        &self,
702        types: &'a Types,
703        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
704    ) -> Result<(), E> {
705        match self {
706            DefinedType::Tuple(tys) => {
707                for ty in tys {
708                    ty._visit_defined_types(types, visitor, false)?;
709                }
710
711                Ok(())
712            }
713            DefinedType::List(ty) | DefinedType::Option(ty) => {
714                ty._visit_defined_types(types, visitor, false)
715            }
716            DefinedType::Result { ok, err } => {
717                if let Some(ty) = ok.as_ref() {
718                    ty._visit_defined_types(types, visitor, false)?;
719                }
720
721                if let Some(ty) = err.as_ref() {
722                    ty._visit_defined_types(types, visitor, false)?;
723                }
724
725                Ok(())
726            }
727            DefinedType::Variant(v) => {
728                for ty in v.cases.values().filter_map(Option::as_ref) {
729                    ty._visit_defined_types(types, visitor, false)?;
730                }
731
732                Ok(())
733            }
734            DefinedType::Record(r) => {
735                for (_, ty) in &r.fields {
736                    ty._visit_defined_types(types, visitor, false)?
737                }
738
739                Ok(())
740            }
741            DefinedType::Flags(_) | DefinedType::Enum(_) | DefinedType::Alias(_) => Ok(()),
742        }
743    }
744
745    /// Gets a description of the defined type.
746    pub fn desc(&self, types: &Types) -> &'static str {
747        match self {
748            Self::Tuple(_) => "tuple",
749            Self::List(_) => "list",
750            Self::Option(_) => "option",
751            Self::Result { .. } => "result",
752            Self::Variant(_) => "variant",
753            Self::Record(_) => "record",
754            Self::Flags(_) => "flags",
755            Self::Enum(_) => "enum",
756            Self::Alias(ty) => ty.desc(types),
757        }
758    }
759}
760
761/// Represents a kind of function in the component model.
762#[derive(Debug, Clone, Copy, PartialEq, Eq)]
763#[cfg_attr(feature = "serde", derive(serde::Serialize))]
764#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
765pub enum FuncKind {
766    /// The function is a "free" function (i.e. not associated with a resource).
767    Free,
768    /// The function is a method on a resource.
769    Method,
770    /// The function is a static method on a resource.
771    Static,
772    /// The function is a resource constructor.
773    Constructor,
774}
775
776impl fmt::Display for FuncKind {
777    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
778        match self {
779            FuncKind::Free => write!(f, "function"),
780            FuncKind::Method => write!(f, "method"),
781            FuncKind::Static => write!(f, "static method"),
782            FuncKind::Constructor => write!(f, "constructor"),
783        }
784    }
785}
786
787/// Represents information about an aliased resource.
788#[derive(Debug, Clone, Copy)]
789#[cfg_attr(feature = "serde", derive(serde::Serialize))]
790#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
791pub struct ResourceAlias {
792    /// The foreign owning interface for the resource.
793    ///
794    /// This may be `None` if the resource does not have a foreign interface owner
795    /// such as in a world or when aliasing within the same interface.
796    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
797    pub owner: Option<InterfaceId>,
798    /// The id of the resource that was aliased.
799    pub source: ResourceId,
800}
801
802/// Represents a resource type.
803#[derive(Debug, Clone)]
804#[cfg_attr(feature = "serde", derive(serde::Serialize))]
805#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
806pub struct Resource {
807    /// The name of the resource.
808    pub name: String,
809    /// Information if the resource has been aliased.
810    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
811    pub alias: Option<ResourceAlias>,
812}
813
814/// Represents a variant.
815#[derive(Debug, Clone)]
816#[cfg_attr(feature = "serde", derive(serde::Serialize))]
817#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
818pub struct Variant {
819    /// The variant cases.
820    pub cases: IndexMap<String, Option<ValueType>>,
821}
822
823/// Represents a record type.
824#[derive(Debug, Clone)]
825#[cfg_attr(feature = "serde", derive(serde::Serialize))]
826#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
827pub struct Record {
828    /// The record fields.
829    pub fields: IndexMap<String, ValueType>,
830}
831
832/// Represents a flags type.
833#[derive(Debug, Clone)]
834#[cfg_attr(feature = "serde", derive(serde::Serialize))]
835#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
836pub struct Flags(pub IndexSet<String>);
837
838/// Represents an enum type.
839#[derive(Debug, Clone)]
840#[cfg_attr(feature = "serde", derive(serde::Serialize))]
841#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
842pub struct Enum(pub IndexSet<String>);
843
844/// Represents a function type.
845#[derive(Debug, Clone, Default)]
846#[cfg_attr(feature = "serde", derive(serde::Serialize))]
847#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
848pub struct FuncType {
849    /// The parameters of the function.
850    pub params: IndexMap<String, ValueType>,
851    /// The results of the function.
852    pub results: Option<FuncResult>,
853}
854
855impl FuncType {
856    fn _visit_defined_types<'a, E>(
857        &self,
858        types: &'a Types,
859        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
860    ) -> Result<(), E> {
861        for ty in self.params.values() {
862            ty._visit_defined_types(types, visitor, false)?;
863        }
864
865        if let Some(results) = self.results.as_ref() {
866            results._visit_defined_types(types, visitor)?;
867        }
868
869        Ok(())
870    }
871}
872
873/// Represents a function result.
874#[derive(Debug, Clone)]
875#[cfg_attr(feature = "serde", derive(serde::Serialize))]
876#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
877pub enum FuncResult {
878    /// A scalar result.
879    Scalar(ValueType),
880    /// A list of named results.
881    List(IndexMap<String, ValueType>),
882}
883
884impl FuncResult {
885    fn _visit_defined_types<'a, E>(
886        &self,
887        types: &'a Types,
888        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
889    ) -> Result<(), E> {
890        match self {
891            FuncResult::Scalar(ty) => ty._visit_defined_types(types, visitor, false),
892            FuncResult::List(tys) => {
893                for ty in tys.values() {
894                    ty._visit_defined_types(types, visitor, false)?;
895                }
896
897                Ok(())
898            }
899        }
900    }
901}
902
903/// Represents a used type.
904#[derive(Debug, Clone)]
905#[cfg_attr(feature = "serde", derive(serde::Serialize))]
906#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
907pub struct UsedType {
908    /// The interface the type was used from.
909    pub interface: InterfaceId,
910    /// The original export name.
911    ///
912    /// This is `None` when the type was not renamed with an `as` clause.
913    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
914    pub name: Option<String>,
915}
916
917/// Represents an interface (i.e. instance type).
918#[derive(Debug, Clone, Default)]
919#[cfg_attr(feature = "serde", derive(serde::Serialize))]
920#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
921pub struct Interface {
922    /// The identifier of the interface.
923    ///
924    /// This may be `None` for inline interfaces.
925    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
926    pub id: Option<String>,
927    /// A map of exported name to information about the used type.
928    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "IndexMap::is_empty"))]
929    pub uses: IndexMap<String, UsedType>,
930    /// The exported items of the interface.
931    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "IndexMap::is_empty"))]
932    pub exports: IndexMap<String, ItemKind>,
933}
934
935impl Interface {
936    fn _visit_defined_types<'a, E>(
937        &self,
938        types: &'a Types,
939        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
940    ) -> Result<(), E> {
941        for kind in self.exports.values() {
942            kind._visit_defined_types(types, visitor)?;
943        }
944
945        Ok(())
946    }
947}
948
949/// Represents a world.
950#[derive(Debug, Clone, Default)]
951#[cfg_attr(feature = "serde", derive(serde::Serialize))]
952#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
953pub struct World {
954    /// The identifier of the world.
955    ///
956    /// This may be `None` for worlds representing component types.
957    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
958    pub id: Option<String>,
959    /// A map of imported name to information about the used type.
960    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "IndexMap::is_empty"))]
961    pub uses: IndexMap<String, UsedType>,
962    /// The imported items of the world.
963    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "IndexMap::is_empty"))]
964    pub imports: IndexMap<String, ItemKind>,
965    /// The exported items of the world.
966    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "IndexMap::is_empty"))]
967    pub exports: IndexMap<String, ItemKind>,
968}
969
970impl World {
971    fn _visit_defined_types<'a, E>(
972        &self,
973        types: &'a Types,
974        visitor: &mut impl FnMut(&'a Types, DefinedTypeId) -> Result<(), E>,
975    ) -> Result<(), E> {
976        for kind in self.imports.values() {
977            kind._visit_defined_types(types, visitor)?;
978        }
979
980        for kind in self.exports.values() {
981            kind._visit_defined_types(types, visitor)?;
982        }
983
984        Ok(())
985    }
986
987    /// The interfaces imported implicitly through uses.
988    pub fn implicit_imported_interfaces<'a>(
989        &'a self,
990        types: &'a Types,
991    ) -> IndexMap<&str, ItemKind> {
992        let mut interfaces = IndexMap::new();
993        let mut add_interface_for_used_type = |used_item: &UsedType| {
994            let used_interface_id = used_item.interface;
995            // The id must be set since used interfaces are always named.
996            let used_interface_name = types[used_interface_id].id.as_deref().unwrap();
997            interfaces.insert(used_interface_name, ItemKind::Instance(used_interface_id));
998        };
999
1000        for (_, used_type) in self.uses.iter() {
1001            add_interface_for_used_type(used_type);
1002        }
1003
1004        for (_, import) in self.imports.iter() {
1005            if let ItemKind::Instance(interface_id) = import {
1006                let import = &types[*interface_id];
1007                for (_, used_item) in &import.uses {
1008                    add_interface_for_used_type(used_item);
1009                }
1010            }
1011        }
1012        interfaces
1013    }
1014}
1015
1016/// Represents a kind of an extern item.
1017#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
1018pub enum ExternKind {
1019    /// The item is an import.
1020    Import,
1021    /// The item is an export.
1022    Export,
1023}
1024
1025impl fmt::Display for ExternKind {
1026    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1027        match self {
1028            Self::Import => write!(f, "import"),
1029            Self::Export => write!(f, "export"),
1030        }
1031    }
1032}