Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for -J option group #748

Merged
merged 8 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ num-format = "0.4.4"
wasmparser = "0.215.0"
javy-runner = { path = "../runner/" }
uuid = { workspace = true }
javy-test-macros = { path = "../test-macros/" }

[build-dependencies]
anyhow = "1.0.86"
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/src/codegen/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use javy_config::Config;
use std::path::PathBuf;

/// Options for using WIT in the code generation process.
#[derive(Default, Clone, Debug)]
#[derive(Default, Clone, Debug, PartialEq)]
pub(crate) struct WitOptions {
/// The path of the .wit file to use.
pub path: Option<PathBuf>,
Expand Down
177 changes: 164 additions & 13 deletions crates/cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,14 @@ where
}

/// Code generation option group.
#[derive(Clone, Debug)]
/// This group gets configured from the [`CodegenOption`] enum.
//
// NB: The documentation for each field is ommitted given that it's similar to
// the enum used to configured the group.
#[derive(Clone, Debug, PartialEq)]
pub struct CodegenOptionGroup {
/// Creates a smaller module that requires a dynamically linked QuickJS provider Wasm
/// module to execute (see `emit-provider` command).
pub dynamic: bool,
/// The WIT options.
pub wit: WitOptions,
/// Enable source code compression, which generates smaller WebAssembly files at the cost of increased compile time. Defaults to enabled.
pub source_compression: bool,
}

Expand All @@ -175,16 +175,17 @@ impl Default for CodegenOptionGroup {
option_group! {
#[derive(Clone, Debug)]
pub enum CodegenOption {
/// Creates a smaller module that requires a dynamically linked QuickJS provider Wasm
/// module to execute (see `emit-provider` command).
/// Creates a smaller module that requires a dynamically linked QuickJS
/// provider Wasm module to execute (see `emit-provider` command).
Dynamic(bool),
/// Optional path to WIT file describing exported functions.
/// Only supports function exports with no arguments and no return values.
/// Optional path to WIT file describing exported functions. Only
/// supports function exports with no arguments and no return values.
Wit(PathBuf),
/// Optional path to WIT file describing exported functions.
/// Only supports function exports with no arguments and no return values.
/// Optional path to WIT file describing exported functions. Only
/// supports function exports with no arguments and no return values.
WitWorld(String),
/// Enable source code compression, which generates smaller WebAssembly files at the cost of increased compile time. Defaults to enabled.
/// Enable source code compression, which generates smaller WebAssembly
/// files at the cost of increased compile time.
SourceCompression(bool),
}
}
Expand All @@ -211,10 +212,18 @@ impl TryFrom<Vec<GroupOption<CodegenOption>>> for CodegenOptionGroup {
}
}

/// JavaScript option group.
/// This group gets configured from the [`JsOption`] enum.
//
// NB: The documentation for each field is ommitted given that it's similar to
// the enum used to configured the group.
#[derive(Clone, Debug, PartialEq)]
pub struct JsOptionGroup {
/// Whether to redirect console.log to stderr.
pub redirect_stdout_to_stderr: bool,
pub javy_json: bool,
pub override_json_parse_and_stringify: bool,
pub javy_stream_io: bool,
pub text_encoding: bool,
}

impl Default for JsOptionGroup {
Expand All @@ -228,6 +237,17 @@ option_group! {
pub enum JsOption {
/// Whether to redirect the output of console.log to standard error.
RedirectStdoutToStderr(bool),
/// Whether to enable the `Javy.JSON` builtins.
JavyJson(bool),
/// Whether to enable the `Javy.readSync` and `Javy.writeSync` builtins.
JavyStreamIo(bool),
/// Whether to override the `JSON.parse` and `JSON.stringify`
/// implementations with an alternative, more performant, SIMD based
/// implemetation.
OverrideJsonParseAndStringify(bool),
saulecabrera marked this conversation as resolved.
Show resolved Hide resolved
/// Whether to enable support for the `TextEncoder` and `TextDecoder`
/// APIs.
TextEncoding(bool),
}
}

Expand All @@ -240,6 +260,12 @@ impl From<Vec<GroupOption<JsOption>>> for JsOptionGroup {
JsOption::RedirectStdoutToStderr(enabled) => {
group.redirect_stdout_to_stderr = *enabled;
}
JsOption::JavyJson(enable) => group.javy_json = *enable,
JsOption::OverrideJsonParseAndStringify(enable) => {
group.override_json_parse_and_stringify = *enable
}
JsOption::TextEncoding(enable) => group.text_encoding = *enable,
JsOption::JavyStreamIo(enable) => group.javy_stream_io = *enable,
}
}

Expand All @@ -254,6 +280,13 @@ impl From<JsOptionGroup> for Config {
Config::REDIRECT_STDOUT_TO_STDERR,
value.redirect_stdout_to_stderr,
);
config.set(Config::JAVY_JSON, value.javy_json);
config.set(
Config::OVERRIDE_JSON_PARSE_AND_STRINGIFY,
value.override_json_parse_and_stringify,
);
config.set(Config::JAVY_STREAM_IO, value.javy_stream_io);
config.set(Config::TEXT_ENCODING, value.text_encoding);
config
}
}
Expand All @@ -262,6 +295,124 @@ impl From<Config> for JsOptionGroup {
fn from(value: Config) -> Self {
Self {
redirect_stdout_to_stderr: value.contains(Config::REDIRECT_STDOUT_TO_STDERR),
javy_json: value.contains(Config::JAVY_JSON),
override_json_parse_and_stringify: value
.contains(Config::OVERRIDE_JSON_PARSE_AND_STRINGIFY),
javy_stream_io: value.contains(Config::JAVY_STREAM_IO),
text_encoding: value.contains(Config::TEXT_ENCODING),
}
}
}

#[cfg(test)]
mod tests {
use super::{CodegenOption, CodegenOptionGroup, GroupOption, JsOption, JsOptionGroup};
use anyhow::Result;
use javy_config::Config;

#[test]
fn js_group_conversion_between_vector_of_options_and_group() -> Result<()> {
let group: JsOptionGroup = vec![].into();

assert_eq!(group, JsOptionGroup::default());

let raw = vec![GroupOption(vec![JsOption::RedirectStdoutToStderr(false)])];
let group: JsOptionGroup = raw.into();
let expected = JsOptionGroup {
redirect_stdout_to_stderr: false,
..Default::default()
};

assert_eq!(group, expected);

let raw = vec![GroupOption(vec![JsOption::JavyJson(false)])];
let group: JsOptionGroup = raw.into();
let expected = JsOptionGroup {
javy_json: false,
..Default::default()
};
assert_eq!(group, expected);

let raw = vec![GroupOption(vec![JsOption::JavyStreamIo(false)])];
let group: JsOptionGroup = raw.into();
let expected = JsOptionGroup {
javy_stream_io: false,
..Default::default()
};
assert_eq!(group, expected);

let raw = vec![GroupOption(vec![JsOption::OverrideJsonParseAndStringify(
false,
)])];
let group: JsOptionGroup = raw.into();

let expected = JsOptionGroup {
override_json_parse_and_stringify: false,
..Default::default()
};
assert_eq!(group, expected);

let raw = vec![GroupOption(vec![JsOption::TextEncoding(false)])];
let group: JsOptionGroup = raw.into();

let expected = JsOptionGroup {
text_encoding: false,
..Default::default()
};
assert_eq!(group, expected);

let raw = vec![GroupOption(vec![
JsOption::JavyStreamIo(false),
JsOption::JavyJson(false),
JsOption::RedirectStdoutToStderr(false),
JsOption::TextEncoding(false),
JsOption::OverrideJsonParseAndStringify(false),
])];
let group: JsOptionGroup = raw.into();
let expected = JsOptionGroup {
javy_stream_io: false,
javy_json: false,
redirect_stdout_to_stderr: false,
text_encoding: false,
override_json_parse_and_stringify: false,
};
assert_eq!(group, expected);

Ok(())
}

#[test]
fn codegen_group_conversion_between_vector_of_options_and_group() -> Result<()> {
let group: CodegenOptionGroup = vec![].try_into()?;
assert_eq!(group, CodegenOptionGroup::default());

let raw = vec![GroupOption(vec![CodegenOption::Dynamic(true)])];
let group: CodegenOptionGroup = raw.try_into()?;
let expected = CodegenOptionGroup {
dynamic: true,
..Default::default()
};

assert_eq!(group, expected);

let raw = vec![GroupOption(vec![CodegenOption::SourceCompression(false)])];
let group: CodegenOptionGroup = raw.try_into()?;
let expected = CodegenOptionGroup {
source_compression: false,
..Default::default()
};

assert_eq!(group, expected);

Ok(())
}

#[test]
fn js_conversion_between_group_and_config() -> Result<()> {
assert_eq!(JsOptionGroup::default(), Config::default().into());

let cfg: Config = JsOptionGroup::default().into();
assert_eq!(cfg, Config::default());
Ok(())
}
}
2 changes: 1 addition & 1 deletion crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ fn main() -> Result<()> {
builder
.wit_opts(codegen.wit)
.source_compression(codegen.source_compression)
.provider_version("2");
.provider_version("3");

let js_opts: JsOptionGroup = opts.js.clone().into();
let mut gen = if codegen.dynamic {
Expand Down
11 changes: 0 additions & 11 deletions crates/cli/tests/common/mod.rs

This file was deleted.

Loading
Loading