fluence_it_types/
types.rs

1//! This module defines the WIT types.
2
3use crate::ne_vec::NEVec;
4
5use serde::Deserialize;
6use serde::Serialize;
7use variant_count::VariantCount;
8/// Represents the types supported by WIT.
9#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize, VariantCount)]
10pub enum IType {
11    /// Boolean.
12    Boolean,
13
14    /// A 8-bits signed integer.
15    S8,
16
17    /// A 16-bits signed integer.
18    S16,
19
20    /// A 32-bits signed integer.
21    S32,
22
23    /// A 64-bits signed integer.
24    S64,
25
26    /// A 8-bits unsigned integer.
27    U8,
28
29    /// A 16-bits unsigned integer.
30    U16,
31
32    /// A 32-bits unsigned integer.
33    U32,
34
35    /// A 64-bits unsigned integer.
36    U64,
37
38    /// A 32-bits float.
39    F32,
40
41    /// A 64-bits float.
42    F64,
43
44    /// A string.
45    String,
46
47    /// Specialization of arrays for byte vector.
48    ByteArray,
49
50    /// An array of values of the same type.
51    Array(Box<IType>),
52
53    /// A 32-bits integer (as defined in WebAssembly core).
54    I32,
55
56    /// A 64-bits integer (as defined in WebAssembly core).
57    I64,
58
59    /// A record contains record index from interfaces AST.
60    Record(u64),
61}
62
63/// Represents a record field type.
64#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
65pub struct RecordFieldType {
66    // TODO: make name optional to support structures with anonymous fields in Rust
67    /// A field name.
68    pub name: String,
69
70    /// A field type.
71    pub ty: IType,
72}
73
74/// Represents a record type.
75#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
76pub struct RecordType {
77    /// A record name.
78    pub name: String,
79
80    /// Types and names representing the fields.
81    /// A record must have at least one field, hence the
82    /// [`Vec1`][crate::vec1::Vec1].
83    pub fields: NEVec<RecordFieldType>,
84}
85
86impl Default for RecordType {
87    fn default() -> Self {
88        Self {
89            name: String::new(),
90            fields: NEVec::new(vec![RecordFieldType {
91                name: String::new(),
92                ty: IType::S8,
93            }])
94            .unwrap(),
95        }
96    }
97}
98
99/// Encode an `IType` into a string.
100// TODO: consider change to impl Display
101impl ToString for &IType {
102    fn to_string(&self) -> String {
103        match &self {
104            IType::Boolean => "bool".to_string(),
105            IType::S8 => "s8".to_string(),
106            IType::S16 => "s16".to_string(),
107            IType::S32 => "s32".to_string(),
108            IType::S64 => "s64".to_string(),
109            IType::U8 => "u8".to_string(),
110            IType::U16 => "u16".to_string(),
111            IType::U32 => "u32".to_string(),
112            IType::U64 => "u64".to_string(),
113            IType::F32 => "f32".to_string(),
114            IType::F64 => "f64".to_string(),
115            IType::String => "string".to_string(),
116            IType::ByteArray => "array (u8)".to_string(),
117            IType::Array(ty) => format!("array ({})", ty.as_ref().to_string()),
118            IType::I32 => "i32".to_string(),
119            IType::I64 => "i64".to_string(),
120            IType::Record(record_type_id) => format!("record {}", record_type_id),
121        }
122    }
123}
124
125impl ToString for &RecordType {
126    fn to_string(&self) -> String {
127        format!(
128            "record ${} (\n{fields})",
129            self.name,
130            fields = self
131                .fields
132                .iter()
133                .fold(String::new(), |mut accumulator, field_type| {
134                    accumulator.push(' ');
135                    accumulator.push_str(&format!(
136                        "field ${}: {}\n",
137                        field_type.name,
138                        (&field_type.ty).to_string()
139                    ));
140                    accumulator
141                }),
142        )
143    }
144}