wit_encoder/
interface.rs

1use std::fmt;
2
3use crate::{Docs, Ident, Render, RenderOpts, StandaloneFunc, TypeDef, Use};
4
5#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
8pub struct Interface {
9    /// Name of this interface.
10    pub(crate) name: Ident,
11
12    // Interface uses
13    pub(crate) uses: Vec<Use>,
14
15    // Interface items
16    pub(crate) items: Vec<InterfaceItem>,
17
18    /// Documentation associated with this interface.
19    pub(crate) docs: Option<Docs>,
20}
21
22impl Interface {
23    /// Create a new instance of `Interface`.
24    pub fn new(name: impl Into<Ident>) -> Self {
25        Self {
26            name: name.into(),
27            uses: vec![],
28            items: vec![],
29            docs: None,
30        }
31    }
32
33    pub fn name(&self) -> &Ident {
34        &self.name
35    }
36
37    pub fn set_name(&mut self, name: impl Into<Ident>) {
38        self.name = name.into();
39    }
40
41    /// Add a `TypeDef` to the interface
42    pub fn type_def(&mut self, type_def: TypeDef) {
43        self.items.push(InterfaceItem::TypeDef(type_def));
44    }
45
46    /// Add an `Function` to the interface
47    pub fn function(&mut self, function: StandaloneFunc) {
48        self.items.push(InterfaceItem::Function(function));
49    }
50
51    pub fn uses(&self) -> &[Use] {
52        &self.uses
53    }
54
55    pub fn uses_mut(&mut self) -> &mut [Use] {
56        &mut self.uses
57    }
58
59    /// Add a `Use` to the interface
60    pub fn use_(&mut self, use_: Use) {
61        self.uses.push(use_);
62    }
63
64    /// Use a type in the interface.
65    pub fn use_type(
66        &mut self,
67        target: impl Into<Ident>,
68        item: impl Into<Ident>,
69        rename: Option<Ident>,
70    ) {
71        let target = target.into();
72        let use_ = self.uses.iter_mut().find(|u| u.target() == &target);
73        match use_ {
74            Some(use_) => use_.item(item, rename),
75            None => {
76                self.use_({
77                    let mut use_ = Use::new(target);
78                    use_.item(item, rename);
79                    use_
80                });
81            }
82        }
83    }
84
85    pub fn item(&mut self, item: impl Into<InterfaceItem>) {
86        self.items.push(item.into());
87    }
88
89    pub fn items(&self) -> &[InterfaceItem] {
90        &self.items
91    }
92
93    pub fn items_mut(&mut self) -> &mut Vec<InterfaceItem> {
94        &mut self.items
95    }
96
97    /// Set the documentation of this interface.
98    pub fn set_docs(&mut self, docs: Option<impl Into<Docs>>) {
99        self.docs = docs.map(|d| d.into());
100    }
101
102    pub fn docs(&self) -> &Option<Docs> {
103        &self.docs
104    }
105}
106
107#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
108#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
109#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
110pub enum InterfaceItem {
111    TypeDef(TypeDef),
112    Function(StandaloneFunc),
113}
114
115pub type InterfaceItems = Vec<InterfaceItem>;
116
117impl Render for InterfaceItems {
118    fn render(&self, f: &mut fmt::Formatter<'_>, opts: &RenderOpts) -> fmt::Result {
119        for item in self {
120            match item {
121                InterfaceItem::TypeDef(type_def) => {
122                    type_def.render(f, opts)?;
123                }
124                InterfaceItem::Function(func) => {
125                    if let Some(docs) = &func.docs {
126                        docs.render(f, opts)?;
127                    }
128                    let opt_async = if func.async_ { "async " } else { "" };
129                    write!(
130                        f,
131                        "{}{}: {opt_async}func({})",
132                        opts.spaces(),
133                        func.name,
134                        func.params,
135                    )?;
136                    if let Some(ty) = &func.result {
137                        write!(f, " -> {ty}")?;
138                    }
139                    write!(f, ";\n")?;
140                }
141            }
142        }
143        Ok(())
144    }
145}
146
147pub type InterfaceUses = Vec<Use>;
148
149impl Render for InterfaceUses {
150    fn render(&self, f: &mut fmt::Formatter<'_>, opts: &RenderOpts) -> fmt::Result {
151        for use_ in self {
152            use_.render(f, opts)?;
153        }
154        Ok(())
155    }
156}