Skip to content

Commit

Permalink
Add a wit-encoder tool (#1580)
Browse files Browse the repository at this point in the history
* init wit-encoder

* implement base types for `wit-encoder`

* fix warnings

* tidy up

* tidy world

* Mostly interface updates

* Interface updates

* Function accessors

* Result accessors

* Some type updates

* impl Display for inline types

* Some type additions

* Added render trait

* TypeDef flags, enums, and variants

* params construct from iterator

* Added resource

* Standalone functions

* Removed some unused types

* Added some tests

* Docs

* Handle intensifiers with keywords

* Cleaned up some comments

* Clean up render a bit

* Made some things more private

* Some smaller usability changes

* Added serde dependency

* Same derives everywhere

* interface and package items should be a single Vec, to keep global order

* Cargo.lock

* Fix up world

* Fix type

* Renamed StandaloneFunction to StandaloneFunc

* Revert formatting of items outside of wit-encoder

* Removed serde

* Not all types can be borrowed

* Some small result related improvements

* Added wit-encoder to workspace properly

* Updated Cargo.lock

* Added wit-encoder to publish list

---------

Co-authored-by: Yosh <github@yosh.is>
  • Loading branch information
MendyBerger and yoshuawuyts authored Jun 14, 2024
1 parent 0ef50ac commit 999fc16
Show file tree
Hide file tree
Showing 23 changed files with 1,981 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ members = [
'crates/fuzz-stats',
'crates/wasm-mutate-stats',
'fuzz',
'crates/wit-encoder',
'crates/wit-parser/fuzz',
'crates/wit-component/dl',
'playground/component',
Expand Down Expand Up @@ -94,6 +95,7 @@ wasmprinter = { version = "0.210.0", path = "crates/wasmprinter" }
wast = { version = "210.0.0", path = "crates/wast" }
wat = { version = "1.210.0", path = "crates/wat" }
wit-component = { version = "0.210.0", path = "crates/wit-component" }
wit-encoder = { version = "0.210.0", path = "crates/wit-encoder" }
wit-parser = { version = "0.210.0", path = "crates/wit-parser" }
wit-smith = { version = "0.210.0", path = "crates/wit-smith" }

Expand Down Expand Up @@ -140,6 +142,7 @@ cpp_demangle = { version = "0.4.0", optional = true }

# Dependencies of `component`
wit-component = { workspace = true, optional = true, features = ['dummy-module', 'wat', 'semver-check'] }
wit-encoder = { workspace = true, optional = true }
wit-parser = { workspace = true, optional = true, features = ['decoding', 'wat', 'serde'] }
wast = { workspace = true, optional = true }

Expand Down Expand Up @@ -208,6 +211,7 @@ compose = ['wasm-compose', 'dep:wasmparser']
demangle = ['rustc-demangle', 'cpp_demangle', 'dep:wasmparser', 'wasm-encoder']
component = [
'wit-component',
'wit-encoder',
'wit-parser',
'dep:wast',
'wasm-encoder',
Expand Down
1 change: 1 addition & 0 deletions ci/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const CRATES_TO_PUBLISH: &[&str] = &[
"wit-parser",
"wasm-metadata",
"wit-component",
"wit-encoder",
"wasm-compose",
"wit-smith",
"wasm-tools",
Expand Down
15 changes: 15 additions & 0 deletions crates/wit-encoder/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
description = "A WIT encoder for Rust"
documentation = "https://docs.rs/wit-encoder"
edition.workspace = true
license = "Apache-2.0 WITH LLVM-exception"
name = "wit-encoder"
repository = "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wit-encoder"
version.workspace = true

[lints]
workspace = true

[dependencies]
semver = { workspace = true }
pretty_assertions = { workspace = true }
37 changes: 37 additions & 0 deletions crates/wit-encoder/src/docs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use std::fmt;

use crate::{Render, RenderOpts};

/// Documentation
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct Docs {
contents: String,
}

impl Docs {
pub fn new(contents: impl Into<String>) -> Self {
Self {
contents: contents.into(),
}
}
}

impl<S> From<S> for Docs
where
S: Into<String>,
{
fn from(value: S) -> Self {
Self {
contents: value.into(),
}
}
}

impl Render for Docs {
fn render(&self, f: &mut fmt::Formatter<'_>, opts: &RenderOpts) -> fmt::Result {
for line in self.contents.lines() {
write!(f, "{}/// {}\n", opts.spaces(), line)?;
}
Ok(())
}
}
59 changes: 59 additions & 0 deletions crates/wit-encoder/src/enum_.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use crate::{Docs, Ident};

/// A variant without a payload
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct Enum {
pub(crate) cases: Vec<EnumCase>,
}

impl<C> FromIterator<C> for Enum
where
C: Into<EnumCase>,
{
fn from_iter<T: IntoIterator<Item = C>>(iter: T) -> Self {
Self {
cases: iter.into_iter().map(|c| c.into()).collect(),
}
}
}

impl Enum {
pub fn cases(&self) -> &[EnumCase] {
&self.cases
}

pub fn cases_mut(&mut self) -> &mut Vec<EnumCase> {
&mut self.cases
}
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct EnumCase {
pub(crate) name: Ident,
pub(crate) docs: Option<Docs>,
}

impl<N> From<N> for EnumCase
where
N: Into<Ident>,
{
fn from(value: N) -> Self {
Self {
name: value.into(),
docs: None,
}
}
}

impl EnumCase {
pub fn new(name: impl Into<Ident>) -> Self {
Self {
name: name.into(),
docs: None,
}
}

pub fn docs(&mut self, docs: Option<impl Into<Docs>>) {
self.docs = docs.map(|d| d.into());
}
}
62 changes: 62 additions & 0 deletions crates/wit-encoder/src/flags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use crate::{ident::Ident, Docs};

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Flags {
pub(crate) flags: Vec<Flag>,
}

impl Flags {
pub fn new(flags: impl IntoIterator<Item = impl Into<Flag>>) -> Self {
Self {
flags: flags.into_iter().map(|f| f.into()).collect(),
}
}

pub fn flags(&self) -> &[Flag] {
&self.flags
}

pub fn flags_mut(&mut self) -> &mut Vec<Flag> {
&mut self.flags
}
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Flag {
pub(crate) name: Ident,
pub(crate) docs: Option<Docs>,
}

impl Flag {
pub fn new(name: impl Into<Ident>) -> Self {
Flag {
name: name.into(),
docs: None,
}
}

pub fn docs(&mut self, docs: Option<impl Into<Docs>>) {
self.docs = docs.map(|d| d.into());
}
}

impl<T> Into<Flag> for (T,)
where
T: Into<Ident>,
{
fn into(self) -> Flag {
Flag::new(self.0)
}
}

impl<T, D> Into<Flag> for (T, D)
where
T: Into<Ident>,
D: Into<Docs>,
{
fn into(self) -> Flag {
let mut flag = Flag::new(self.0);
flag.docs(Some(self.1));
flag
}
}
Loading

0 comments on commit 999fc16

Please sign in to comment.