Giter Club home page Giter Club logo

witgen's Introduction

witgen

Rust Rust Version Docs.rs

witgen is a library and a CLI that helps you generate wit definitions in a wit file for WebAssembly. Using this lib in addition to wit-bindgen will help you to import/export types and functions from/to wasm module. This project currently supports the wit parser at version 0.2.0 see here.

Getting started

Goal: Generate a .wit file writing only Rust.

You will need both the library and the CLI.

Preliminaries

  • Create a new library project and move to it.
$ cargo new my_wit
$ cd my_wit
  • Add witgen as a dependency in your Cargo.toml. Note: must have cargo-edit installed to add dependencies from CLI, e.g. cargo install cargo-edit.
$ cargo add witgen
  • Install cargo witgen CLI.
$ cargo install cargo-witgen

Writing code

  • Replace the content of your lib.rs by:
use witgen::witgen;

#[witgen]
use other_crate::*;

/// Doc strings are supported!
#[witgen]
struct TestStruct {
    /// Even for fields!
    inner: String,
}

#[witgen]
enum TestEnum {
    Unit,
    Number(u64),
    StringVariant(String),
}

#[witgen]
fn test(other: Vec<u8>, test_struct: TestStruct, other_enum: TestEnum) -> Result<(String, i64), String> {
    // The following code is not part of the generated `.wit` file.
    // You may add an example implementation or just satisfy the compiler with a `todo!()`.
    Ok((String::from("test"), 0i64))
}

#[witgen]
impl AResource {
  /// Can convert custom attributes to doc strings
  #[custom_attribute]
  pub fn foo(&self) {}
  /// Have special mutable attribute
  pub fn faa(&mut self) {}

  pub fn fee() {}
}
  • Then you can launch the CLI (at the root of your package):
cargo witgen generate
  • It will generate a index.wit file at the root of your package:
use * from other-crate

/// Doc strings are supported!
record test-struct {
  /// Even for fields!
  inner: string
}

variant test-enum {
  unit,
  number(u64),
  string-variant(string),
}

test : func(other: list <u8>, test-struct: test-struct, other-enum: test-enum) -> expected<tuple<string, s64>>

resource a-resource {
  /// Can convert custom attributes to doc strings
  /// @custom_attribute
  foo: func()
  /// Have special mutable attribute
  /// @mutable
  faa: func()
  static fee: func()
}
  • You can find more complete examples here

Limitations

For now using #[witgen] have some limitations:

  • You can use the proc macro #[witgen] only on struct, enum, type alias, function, impl, and use
  • Generic parameters or lifetime annotations are not supported, except for HashMap, which is interpreted as list<tuple<key, value>>.
  • Type &str is not supported (but you can use String)
  • References, Box, Rc, Arc and all types of smart pointers are not supported
  • There is no semantic analysis, which means if your function, struct or enum uses a non scalar type, you have to add #[witgen] where this type is declared (it won't fail at the compile time)

Development

It's a very minimal version, it doesn't already support all kinds of types but the main ones are supported. I made it to easily generate .wit files for my need. Feel free to create issues or pull-requests if you need something. I will be happy to help you!

witgen's People

Contributors

bnjjj avatar saona-raimundo avatar willemneal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

witgen's Issues

Improvement for witgen's documentation

Hi there!

First of all, thank you for the crate! I found it in the comments of wit-bindgen crate and it got me started with using .wit files, so thanks a lot!

After using it, I wanted to come back with some comments to improve the user experience :) Let me know if you would prefer a PR on any of these comments.

Documentation improvement

On the main example of the crate, it states "Into your Rust code:". The first thing I wondered was should I use lib.rs or main.rs?
It turns out that it "does not matter" as you can then pass the corresponding path to cargo witgen generate...
I propose to make the example fixed in lib.rs and at the end add a note that this can be also done by putting the Rust code in a binary and changing the call to cargo witgen.

Examples directory

The documentation you have put in the README and libr.rs is nice, but the curious user might also look for the examples directory. You could add the same example as a new crate (called my my-wit for example) located in the examples directory of this crate.

Limitations?

When using the cli, I wondered what features were supported and what kind of Rust code could I mark with #[witgen].
I know that the .wit specification is changing, but do you think it would be good to keep track of what is possible and what is not?

Say, in .wit there are no methods, only functions. This is correctly marked when you use #[witgen] in an impl block. The same with the use of references, as interface types are meant to be consumed by design (hope I got this right).

Since the actual Rust code that can be converted to wit is few, I would just mention it somewhere.

Body functions

While using the cli, I wondered what the functions bodies are used for. They are skipped, as they are not part of the .wit file. They are there so that the Rust compiler does not complain and serve as an "example of implementing the function".

I would add a comment somewhere that the body functions are not translated and Rust programmer could use the opportunity to write examples of functions (instead of satisfying the compiler with a todo!()).

Feature request: Documentation support

Thanks for the crate!

I wanted to ask if there could be documentation support.

Wit supports only comments and does not differentiate between documentation and code comments. But, when using wit-bindgen to transform to markdown, comments are part of the generated .md and correctly located.

Proposal

I propose to make use of this to pass over documentation comments in Rust as comments (using \\) to the generated .wit file.
Code comments in the Rust file would be ignored.

Use case

At the end of the day, the objective is to generate the .wit file that people possibly outside of the Rust world can use, therefore it makes sense to me to generate the documentation also outside of the Rust world.

I do not have experience in this type of macros, but I could do the research if needed.

Can not find the witgen subcommand

run cargo install cargo-witgen In MacOS:

➜  my_wit git:(main) ✗ cargo witgen
error: no such subcommand: `witgen`

I rename ~/.cargo/bin/cargo_witgen to ~/.cargo/bin/cargo-witgen, and then ok.

[Feature] Add version of witgen to generated comment

Currently this comment is at the top of the final generated wit file. This line could also indicate which version of witgen was used to produce the file.

// This is a generated file by witgen (https://github.com/bnjjj/witgen), please do not edit yourself, you can generate a new one thanks to cargo witgen generate command

[Bug] version mismatch

In the last update cargo_witgen, didn't update the dependency to the newest version.

witgen_macro_helper = { path= "../witgen_macro_helper", version = "0.13" }

I think perhaps it's finally time to invest in a GH action to handle the versioning and publishing.

Generating wit from dependencies

First off, fantastic work! Worked out of the box and am excited to help with the project.

One issue I ran into is trying to generate wit from a dependencies. Within the project worked wonders, but I'm guessing the the cli is only checking the source files of the current project.

Without this, I'm wondering if there is a way to publish the wit with cargo?

Again great work and look forward to getting this in the hands of devs working with NEAR smart contracts!

[BREAKING] Upgrade to wit-parser 0.1.0 and incorporate it into wit generation

This issue outlines the current work in wit-bindgen: bytecodealliance/wit-bindgen#201

They also recently created a 0.1.0 tag for the project. I took this as an opportunity to publish aha-wit-parser, which has the same version just different name. It can be added like so:

wit-parser = { version = "0.1.0", package = "aha-wit-parser" }

feat: use cargo to get all source files used in project

Currently the runtime of the tooling can be slow because it requires compiling the project. So while once the project is stable it's quick, any edit can add some time to the rerun.

The current approach has the limitation that dependencies aren't caught by the macro. Instead the cargo crate could be used to generate a list of all source files used in the project.

This would allow using syn to analyze each file for a witgen macro. Or alternatively witgen could be inserted to any type that is part of the root crate's public API.

Structs and functions with parameters/fields named "handle" are quietly not exported

Hi, I think I caught a bug in witgen. When I run cargo witgen generate on this code:

use witgen::witgen;

#[witgen]
fn works() {}

#[witgen]
fn doesnt_work(handle: i32) -> i32 { handle }

#[witgen]
struct Works { test: i32 }

#[witgen]
struct DoesntWork { handle: i32 }

Then it creates this WIT file:

// auto-generated file by witgen (https://github.com/bnjjj/witgen), please do not edit yourself, you can generate a new one thanks to cargo witgen generate command. (cargo-witgen v0.15.0) 

works: func()


record works {
  test: s32
}

The function doesnt_work and the struct DoesntWork are missing.

There is no error being reported from the cargo witgen generate command.

I am using cargo-witgen v0.15.0, the witgen crate is also v0.15.0.

Change license field to `MIT`

Because license in Cargo.toml is currently specified as license-file = ..., it shows up as "non-standard" on crates.io and makes automated license checks harder, too.

image

When a license is standard, it's better to use the standard SPDX identifier via license = ... field instead.

Add default, world or interface block around wit definitions

The generated wit files result in an error when trying to use them with (some!?) other tools. Especially those coming from the bytecode alliance (wasmtime, wit-bindgen, etc.). I guess current generated wit files would work with wai-bindgen and others.

I'm not quite sure why. My guess is that declaring one of default, world or interface as a top-level declaration was not mandatory before.

Do you want to change the implementation so that one of these top level declarations will be present in the generated output?

If so how would the implementation actually look? Would all Rust declarations that are annotated with only the witgen macro automatically be added to the "default" interface + the ability to pass in a world and / or interface the declaration should belong to?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.