wit_walrus/
implements.rs

1use crate::{FuncId, WasmInterfaceTypes, WitIdsToIndices, WitIndicesToIds};
2use anyhow::Result;
3use id_arena::{Arena, Id};
4use walrus::IndicesToIds;
5
6#[derive(Debug, Default)]
7pub struct Implements {
8    arena: Arena<Implement>,
9}
10
11#[derive(Debug)]
12pub struct Implement {
13    id: ImplementId,
14    pub adapter_func: FuncId,
15    pub core_func: walrus::FunctionId,
16}
17
18pub type ImplementId = Id<Implement>;
19
20impl WasmInterfaceTypes {
21    pub(crate) fn parse_implements(
22        &mut self,
23        implements: wit_parser::Implements,
24        ids: &IndicesToIds,
25        wids: &mut WitIndicesToIds,
26    ) -> Result<()> {
27        for implement in implements {
28            let implement = implement?;
29            self.implements.add(
30                wids.func(implement.adapter_func)?,
31                ids.get_func(implement.core_func)?,
32            );
33        }
34
35        Ok(())
36    }
37
38    pub(crate) fn encode_implements(
39        &self,
40        writer: &mut wit_writer::Writer,
41        wids: &WitIdsToIndices,
42        ids: &walrus::IdsToIndices,
43    ) {
44        let mut w = writer.implements(self.implements.arena.len() as u32);
45        for implement in self.implements.iter() {
46            w.add(
47                ids.get_func_index(implement.core_func),
48                wids.func(implement.adapter_func),
49            );
50        }
51    }
52}
53
54impl Implements {
55    /// Gets a reference to an implement given its id
56    pub fn get(&self, id: ImplementId) -> &Implement {
57        &self.arena[id]
58    }
59
60    /// Gets a reference to an implement given its id
61    pub fn get_mut(&mut self, id: ImplementId) -> &mut Implement {
62        &mut self.arena[id]
63    }
64
65    // /// Removes an implement from this module.
66    // ///
67    // /// It is up to you to ensure that any potential references to the deleted
68    // /// implement are also removed, eg `get_global` expressions.
69    // pub fn delete(&mut self, id: ImplementId) {
70    //     self.arena.delete(id);
71    // }
72
73    /// Get a shared reference to this section's implements.
74    pub fn iter(&self) -> impl Iterator<Item = &Implement> {
75        self.arena.iter().map(|(_, f)| f)
76    }
77
78    /// Get mutable references to this section's implements.
79    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Implement> {
80        self.arena.iter_mut().map(|(_, f)| f)
81    }
82
83    /// Adds a new implement to this section
84    pub fn add(&mut self, adapter_func: FuncId, core_func: walrus::FunctionId) -> ImplementId {
85        self.arena.alloc_with_id(|id| Implement {
86            id,
87            core_func,
88            adapter_func,
89        })
90    }
91}
92
93impl Implement {
94    /// Returns the identifier for this `Implement`
95    pub fn id(&self) -> ImplementId {
96        self.id
97    }
98}