1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//! Represents the WIT language as a tree. This is the central
//! representation of the language.

use crate::{interpreter::Instruction, IRecordType, IType};

use serde::Deserialize;
use serde::Serialize;
use std::rc::Rc;
use std::str;

/// Represents the kind of type.
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
pub enum TypeKind {
    /// A function type.
    Function,

    /// A record type.
    Record,
}

/// Represents the function argument type.
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
pub struct FunctionArg {
    /// A function argument name.
    pub name: String,

    /// A function argument type.
    pub ty: IType,
}

/// Represents a type.
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
pub enum Type {
    /// A function type, like:
    ///
    /// ```wasm,ignore
    /// (@interface type (func (param i32 i32) (result string)))
    /// ```
    Function {
        /// Types for the parameters (`(param (name i32))`).
        arguments: Rc<Vec<FunctionArg>>,

        /// Types for the results (`(result …)`).
        output_types: Rc<Vec<IType>>,
    },

    /// A record type, like:
    ///
    /// ```wasm,ignore
    /// (@interface type (record string i32))
    /// ```
    Record(Rc<IRecordType>),
}

/// Represents an imported function.
#[derive(PartialEq, Eq, Debug, Default, Clone, Hash)]
pub struct Import<'input> {
    /// The function namespace.
    pub namespace: &'input str,

    /// The function name.
    pub name: &'input str,

    /// The type signature.
    pub function_type: u32,
}

/// Represents an exported function signature.
#[derive(PartialEq, Eq, Debug, Default, Clone, Hash)]
pub struct Export<'input> {
    /// The export name.
    pub name: &'input str,

    /// The WIT function type being exported.
    pub function_type: u32,
}

/// Represents an adapter.
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
pub struct Adapter {
    /// The adapter function type.
    pub function_type: u32,

    /// The instructions.
    pub instructions: Vec<Instruction>,
}

/// Represents an implementation.
#[derive(PartialEq, Eq, Debug, Default, Clone, Hash, Serialize, Deserialize)]
pub struct Implementation {
    /// The core function type.
    pub core_function_type: u32,

    /// The adapter function type.
    pub adapter_function_type: u32,
}

/// Represents the kind of interface.
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
pub enum InterfaceKind {
    /// A version.
    Version,

    /// A type.
    Type,

    /// An imported function.
    Import,

    /// An adapter.
    Adapter,

    /// An exported function.
    Export,

    /// An implementation.
    Implementation,
}

/// Represents a set of interfaces, i.e. it entirely describes a WIT
/// definition.
#[derive(PartialEq, Eq, Debug, Clone, Hash)]
pub struct Interfaces<'input> {
    /// Version of IT.
    pub version: semver::Version,

    /// All the types.
    pub types: Vec<Type>,

    /// All the imported functions.
    pub imports: Vec<Import<'input>>,

    /// All the adapters.
    pub adapters: Vec<Adapter>,

    /// All the exported functions.
    pub exports: Vec<Export<'input>>,

    /// All the implementations.
    pub implementations: Vec<Implementation>,
}

impl Interfaces<'_> {
    /// Creates a new Interfaces where version comes from this package version.
    pub fn new() -> Self {
        use std::str::FromStr;

        // it's safe because otherwise it won't compile
        let version = semver::Version::from_str(env!("CARGO_PKG_VERSION")).unwrap();

        Self {
            version,
            types: Vec::new(),
            imports: Vec::new(),
            adapters: Vec::new(),
            exports: Vec::new(),
            implementations: Vec::new(),
        }
    }

    /// Creates a new Interfaces from the provided version.
    pub fn from_version(version: semver::Version) -> Self {
        Self {
            version,
            types: Vec::new(),
            imports: Vec::new(),
            adapters: Vec::new(),
            exports: Vec::new(),
            implementations: Vec::new(),
        }
    }
}

impl Default for Interfaces<'_> {
    fn default() -> Self {
        Self::new()
    }
}