mirror of
https://github.com/fluencelabs/interface-types
synced 2024-12-04 15:20:20 +00:00
add version to interfaces
This commit is contained in:
parent
f6fdc50e75
commit
5758fa66c6
38
Cargo.lock
generated
38
Cargo.lock
generated
@ -1,5 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
@ -83,6 +85,15 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
dependencies = [
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
@ -113,6 +124,24 @@ version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50b8b2cd387f744f69469aaed197954ba4c0ecdb31e02edf99b023e0df11178a"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
|
||||
dependencies = [
|
||||
"pest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.118"
|
||||
@ -161,6 +190,12 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
@ -175,13 +210,14 @@ checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-interface-types-fl"
|
||||
version = "0.17.24"
|
||||
version = "0.17.25"
|
||||
dependencies = [
|
||||
"fluence-it-types",
|
||||
"it-to-bytes",
|
||||
"log",
|
||||
"nom",
|
||||
"safe-transmute",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wast",
|
||||
|
@ -72,13 +72,7 @@ where
|
||||
W: Write,
|
||||
{
|
||||
fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
|
||||
// Size first.
|
||||
writer.write_all(&[self.len() as u8])?;
|
||||
|
||||
// Then the string.
|
||||
writer.write_all(self.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
self.as_str().to_bytes(writer)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-interface-types-fl"
|
||||
version = "0.17.24"
|
||||
version = "0.17.25"
|
||||
description = "WebAssembly Interface Types library for Wasmer"
|
||||
license = "MIT"
|
||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
@ -22,5 +22,7 @@ serde_json = "1.0"
|
||||
safe-transmute = "0.11.0"
|
||||
log = "0.4.11"
|
||||
|
||||
semver = "0.11.0"
|
||||
|
||||
[features]
|
||||
default = ["serde"]
|
||||
|
@ -98,6 +98,9 @@ pub struct Implementation {
|
||||
/// Represents the kind of interface.
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
|
||||
pub enum InterfaceKind {
|
||||
/// A version.
|
||||
Version,
|
||||
|
||||
/// A type.
|
||||
Type,
|
||||
|
||||
@ -116,8 +119,11 @@ pub enum InterfaceKind {
|
||||
|
||||
/// Represents a set of interfaces, i.e. it entirely describes a WIT
|
||||
/// definition.
|
||||
#[derive(PartialEq, Eq, Debug, Default, Clone, Hash)]
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Hash)]
|
||||
pub struct Interfaces<'input> {
|
||||
/// Version of IT.
|
||||
pub version: semver::Version,
|
||||
|
||||
/// All the types.
|
||||
pub types: Vec<Type>,
|
||||
|
||||
|
@ -35,6 +35,7 @@ impl TryFrom<u8> for InterfaceKind {
|
||||
0x02 => Self::Adapter,
|
||||
0x03 => Self::Export,
|
||||
0x04 => Self::Implementation,
|
||||
0x05 => Self::Version,
|
||||
_ => return Err("Unknown interface kind code."),
|
||||
})
|
||||
}
|
||||
@ -487,6 +488,7 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
|
||||
) -> IResult<&'input [u8], Interfaces, E> {
|
||||
let mut input = bytes;
|
||||
|
||||
let mut all_versions = vec![];
|
||||
let mut all_types = vec![];
|
||||
let mut all_imports = vec![];
|
||||
let mut all_adapters = vec![];
|
||||
@ -500,6 +502,10 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
|
||||
.map_err(|_| Err::Error(make_error(input, ErrorKind::ParseTo)))?;
|
||||
|
||||
match interface_kind {
|
||||
InterfaceKind::Version => {
|
||||
consume!((input, new_version) = string(input)?);
|
||||
all_versions.push(new_version);
|
||||
}
|
||||
InterfaceKind::Type => {
|
||||
consume!((input, mut new_types) = types(input)?);
|
||||
all_types.append(&mut new_types);
|
||||
@ -527,9 +533,12 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
|
||||
}
|
||||
}
|
||||
|
||||
let version = try_into_version(all_versions).map_err(|e| Err::Error(make_error(input, e)))?;
|
||||
|
||||
Ok((
|
||||
input,
|
||||
Interfaces {
|
||||
version,
|
||||
types: all_types,
|
||||
imports: all_imports,
|
||||
adapters: all_adapters,
|
||||
@ -539,6 +548,22 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
|
||||
))
|
||||
}
|
||||
|
||||
fn try_into_version(versions: Vec<&str>) -> Result<semver::Version, ErrorKind> {
|
||||
use std::str::FromStr;
|
||||
|
||||
if versions.is_empty() {
|
||||
return Err(ErrorKind::NoneOf);
|
||||
}
|
||||
|
||||
if versions.len() != 1 {
|
||||
return Err(ErrorKind::Many0);
|
||||
}
|
||||
|
||||
let version = semver::Version::from_str(&versions[0]).map_err(|_| ErrorKind::IsNot)?;
|
||||
|
||||
Ok(version)
|
||||
}
|
||||
|
||||
/// Parse a sequence of bytes, expecting it to be a valid WIT binary
|
||||
/// representation, into an [`Interfaces`](crate::ast::Interfaces)
|
||||
/// structure.
|
||||
|
@ -18,6 +18,7 @@ mod keyword {
|
||||
custom_keyword!(r#type = "type");
|
||||
custom_keyword!(record);
|
||||
custom_keyword!(field);
|
||||
custom_keyword!(version);
|
||||
|
||||
// Special symbols
|
||||
custom_keyword!(comma = ",");
|
||||
@ -380,6 +381,7 @@ impl Parse<'_> for FunctionType {
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
enum Interface<'a> {
|
||||
Version(String),
|
||||
Type(Type),
|
||||
Import(Import<'a>),
|
||||
Adapter(Adapter),
|
||||
@ -397,7 +399,9 @@ impl<'a> Parse<'a> for Interface<'a> {
|
||||
|
||||
let mut lookahead = parser.lookahead1();
|
||||
|
||||
if lookahead.peek::<keyword::r#type>() {
|
||||
if lookahead.peek::<keyword::version>() {
|
||||
Ok(Interface::Version(parser.parse()?))
|
||||
} else if lookahead.peek::<keyword::r#type>() {
|
||||
Ok(Interface::Type(parser.parse()?))
|
||||
} else if lookahead.peek::<keyword::import>() {
|
||||
Ok(Interface::Import(parser.parse()?))
|
||||
@ -548,26 +552,66 @@ impl<'a> Parse<'a> for Adapter {
|
||||
|
||||
impl<'a> Parse<'a> for Interfaces<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut interfaces: Interfaces = Default::default();
|
||||
let mut version: Option<semver::Version> = None;
|
||||
let mut types = vec![];
|
||||
let mut imports = vec![];
|
||||
let mut adapters = vec![];
|
||||
let mut exports = vec![];
|
||||
let mut implementations = vec![];
|
||||
|
||||
while !parser.is_empty() {
|
||||
let interface = parser.parse::<Interface>()?;
|
||||
|
||||
match interface {
|
||||
Interface::Type(ty) => interfaces.types.push(ty),
|
||||
Interface::Import(import) => interfaces.imports.push(import),
|
||||
Interface::Adapter(adapter) => interfaces.adapters.push(adapter),
|
||||
Interface::Export(export) => interfaces.exports.push(export),
|
||||
Interface::Implementation(implementation) => {
|
||||
interfaces.implementations.push(implementation)
|
||||
Interface::Version(version_str) => {
|
||||
try_handle_version(&version_str, &mut version, &parser)?
|
||||
}
|
||||
Interface::Type(ty) => types.push(ty),
|
||||
Interface::Import(import) => imports.push(import),
|
||||
Interface::Adapter(adapter) => adapters.push(adapter),
|
||||
Interface::Export(export) => exports.push(export),
|
||||
Interface::Implementation(implementation) => implementations.push(implementation),
|
||||
}
|
||||
}
|
||||
|
||||
let version = version.ok_or_else(|| {
|
||||
wast::Error::new(parser.cur_span(), String::from("version must be specified"))
|
||||
})?;
|
||||
|
||||
let interfaces = Interfaces {
|
||||
version,
|
||||
types,
|
||||
imports,
|
||||
adapters,
|
||||
exports,
|
||||
implementations,
|
||||
};
|
||||
|
||||
Ok(interfaces)
|
||||
}
|
||||
}
|
||||
|
||||
fn try_handle_version(
|
||||
version_str: &str,
|
||||
version: &mut Option<semver::Version>,
|
||||
parser: &Parser<'_>,
|
||||
) -> Result<()> {
|
||||
use std::str::FromStr;
|
||||
|
||||
if version.is_some() {
|
||||
return Err(wast::Error::new(
|
||||
parser.cur_span(),
|
||||
String::from("only one version directive is possible"),
|
||||
));
|
||||
}
|
||||
|
||||
let parsed_version = semver::Version::from_str(version_str)
|
||||
.map_err(|e| wast::Error::new(parser.cur_span(), format!("version is corrupted: {}", e)))?;
|
||||
*version = Some(parsed_version);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parse a WIT definition in its textual format, and produces an
|
||||
/// [AST](crate::ast) with the [`Interfaces`](crate::ast::Interfaces)
|
||||
/// structure upon succesful.
|
||||
|
@ -33,6 +33,7 @@ where
|
||||
Self::Adapter => 0x02_u8.to_bytes(writer),
|
||||
Self::Export => 0x03_u8.to_bytes(writer),
|
||||
Self::Implementation => 0x04_u8.to_bytes(writer),
|
||||
Self::Version => 0x05_u8.to_bytes(writer),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -144,6 +145,9 @@ where
|
||||
W: Write,
|
||||
{
|
||||
fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
|
||||
InterfaceKind::Version.to_bytes(writer)?;
|
||||
self.version.to_string().to_bytes(writer)?;
|
||||
|
||||
if !self.types.is_empty() {
|
||||
InterfaceKind::Type.to_bytes(writer)?;
|
||||
self.types.to_bytes(writer)?;
|
||||
|
@ -296,6 +296,10 @@ impl<'input> ToString for &Interfaces<'input> {
|
||||
}
|
||||
};
|
||||
|
||||
output.push_str("Version: ");
|
||||
output.push_str(&self.version.to_string());
|
||||
separator(&mut output);
|
||||
|
||||
if !types.is_empty() {
|
||||
output.push_str(";; Types");
|
||||
output.push_str(&types);
|
||||
|
Loading…
Reference in New Issue
Block a user