From dbb25c07cbe421ad5bab951246dc13a154c10ed9 Mon Sep 17 00:00:00 2001 From: Douglas Machado Date: Thu, 11 May 2023 11:36:51 -0300 Subject: [PATCH 1/7] add initial support for wasm target --- Cargo.toml | 1 + rrule-wasm/Cargo.toml | 20 ++++++++++++++++++++ rrule-wasm/Makefile | 11 +++++++++++ rrule-wasm/src/lib.rs | 19 +++++++++++++++++++ rrule-wasm/tests/wasm.rs | 11 +++++++++++ rrule-wasm/wasm-example.html | 23 +++++++++++++++++++++++ 6 files changed, 85 insertions(+) create mode 100644 rrule-wasm/Cargo.toml create mode 100644 rrule-wasm/Makefile create mode 100644 rrule-wasm/src/lib.rs create mode 100644 rrule-wasm/tests/wasm.rs create mode 100644 rrule-wasm/wasm-example.html diff --git a/Cargo.toml b/Cargo.toml index d7a69c6..2479d0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ rust-version = "1.64.0" members = [ "rrule", "rrule-debugger", + "rrule-wasm" ] # These are the 2 packages to mainly work on. diff --git a/rrule-wasm/Cargo.toml b/rrule-wasm/Cargo.toml new file mode 100644 index 0000000..3fa7e58 --- /dev/null +++ b/rrule-wasm/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "rrule-wasm" +version = "0.1.0" +authors = ["Ralph Bisschops "] +publish = false +license.workspace = true +edition.workspace = true +rust-version.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rrule = { path = "../rrule" } +wasm-bindgen = "0.2.63" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dev-dependencies] +wasm-bindgen-test = "0.3.13" diff --git a/rrule-wasm/Makefile b/rrule-wasm/Makefile new file mode 100644 index 0000000..eca6dd7 --- /dev/null +++ b/rrule-wasm/Makefile @@ -0,0 +1,11 @@ +install-wasm-pack: + curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + +build-web-wasm: + wasm-pack build --target web + +test-web-wasm-on-browser: + npx http-server + +run-tests: + wasm-pack test --node \ No newline at end of file diff --git a/rrule-wasm/src/lib.rs b/rrule-wasm/src/lib.rs new file mode 100644 index 0000000..0090836 --- /dev/null +++ b/rrule-wasm/src/lib.rs @@ -0,0 +1,19 @@ +use rrule::RRuleSet; +use wasm_bindgen::prelude::*; + +/** + Get all recurrences of the rrule! + rule_set_string: List of rrules + limit: Limit must be set in order to prevent infinite loops +*/ +#[wasm_bindgen] +pub fn get_all_date_recurrences(rule_set_string: &str, limit: Option) -> Vec { + let rrule: RRuleSet = rule_set_string.parse().unwrap(); + // Set hard limit in case of infinitely recurring rules + let rule_set = rrule.all(limit.unwrap_or(100)); + let result: Vec = rule_set.dates + .into_iter() + .map(|s| JsValue::from_str(&Some(s).unwrap().to_string())) + .collect(); + return result; +} diff --git a/rrule-wasm/tests/wasm.rs b/rrule-wasm/tests/wasm.rs new file mode 100644 index 0000000..f5e91da --- /dev/null +++ b/rrule-wasm/tests/wasm.rs @@ -0,0 +1,11 @@ +use wasm_bindgen_test::*; +use rrule_wasm::get_all_date_recurrences; + +#[wasm_bindgen_test] +fn test_date_recurrences() { + let dates: Vec = get_all_date_recurrences("DTSTART:20120201T093000Z\nRRULE:FREQ=DAILY;COUNT=3", Some(100)); + assert_eq!(dates.len(), 3); + assert_eq!(dates.get(0).unwrap().as_string().unwrap(), "2012-02-01 09:30:00 UTC"); + assert_eq!(dates.get(1).unwrap().as_string().unwrap(), "2012-02-02 09:30:00 UTC"); + assert_eq!(dates.get(2).unwrap().as_string().unwrap(), "2012-02-03 09:30:00 UTC"); +} diff --git a/rrule-wasm/wasm-example.html b/rrule-wasm/wasm-example.html new file mode 100644 index 0000000..43bc866 --- /dev/null +++ b/rrule-wasm/wasm-example.html @@ -0,0 +1,23 @@ + + + + + + + + + + + + \ No newline at end of file From f6b499cdd105796dfa92141ad75eb966b9f96271 Mon Sep 17 00:00:00 2001 From: Douglas Machado Date: Sat, 13 May 2023 07:07:15 -0300 Subject: [PATCH 2/7] add nodejs wasm example --- rrule-wasm/Makefile | 14 +++++++++---- rrule-wasm/example/nodejs/app.js | 20 +++++++++++++++++++ .../web/index.html} | 2 +- 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 rrule-wasm/example/nodejs/app.js rename rrule-wasm/{wasm-example.html => example/web/index.html} (86%) diff --git a/rrule-wasm/Makefile b/rrule-wasm/Makefile index eca6dd7..5755697 100644 --- a/rrule-wasm/Makefile +++ b/rrule-wasm/Makefile @@ -1,11 +1,17 @@ install-wasm-pack: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -build-web-wasm: +build-wasm-nodejs: + wasm-pack build --target nodejs + +test-wasm-on-nodejs: + node example/nodejs/app.js + +build-wasm-web: wasm-pack build --target web -test-web-wasm-on-browser: - npx http-server +test-wasm-on-web-browser: + cd example/web && npx http-server -run-tests: +run-unit-tests: wasm-pack test --node \ No newline at end of file diff --git a/rrule-wasm/example/nodejs/app.js b/rrule-wasm/example/nodejs/app.js new file mode 100644 index 0000000..b9e1a62 --- /dev/null +++ b/rrule-wasm/example/nodejs/app.js @@ -0,0 +1,20 @@ +const { get_all_date_recurrences } = require('../../pkg/rrule_wasm.js'); + +const http = require('http'); +const url = require('url'); +const hostname = '127.0.0.1'; +const port = 3000; + +const server = http.createServer((req, res) => { + const queryObject = url.parse(req.url,true).query; + res.statusCode = 200; + res.setHeader('Content-Type', 'text/plain'); + + var data = get_all_date_recurrences("DTSTART:20120201T093000Z\nRRULE:FREQ=DAILY;COUNT=3", 100); + console.log(data); + res.end(data.toString()); +}); + +server.listen(port, hostname, () => { + console.log(`Server running at http://${hostname}:${port}/`); +}); \ No newline at end of file diff --git a/rrule-wasm/wasm-example.html b/rrule-wasm/example/web/index.html similarity index 86% rename from rrule-wasm/wasm-example.html rename to rrule-wasm/example/web/index.html index 43bc866..53916b2 100644 --- a/rrule-wasm/wasm-example.html +++ b/rrule-wasm/example/web/index.html @@ -8,7 +8,7 @@ diff --git a/rrule/src/lib.rs b/rrule/src/lib.rs index 1fbdc91..057b17b 100644 --- a/rrule/src/lib.rs +++ b/rrule/src/lib.rs @@ -99,6 +99,8 @@ mod iter; mod parser; mod tests; mod validator; +#[cfg(feature = "wasm")] +mod wasm; pub use crate::core::{Frequency, NWeekday, RRule, RRuleResult, RRuleSet, Tz}; pub use crate::core::{Unvalidated, Validated}; diff --git a/rrule-wasm/src/lib.rs b/rrule/src/wasm/mod.rs similarity index 89% rename from rrule-wasm/src/lib.rs rename to rrule/src/wasm/mod.rs index 74898de..a4547e6 100644 --- a/rrule-wasm/src/lib.rs +++ b/rrule/src/wasm/mod.rs @@ -4,9 +4,10 @@ clippy::unwrap_used )] -use rrule::RRuleSet; use wasm_bindgen::prelude::*; +use crate::{RRuleSet, RRuleError}; + /** Get all recurrences of the rrule! rule_set_string: List of rrules @@ -14,7 +15,7 @@ use wasm_bindgen::prelude::*; */ #[wasm_bindgen] pub fn get_all_date_recurrences(rule_set: &str, limit: Option) -> Result, JsError> { - let rrule_result: Result = rule_set.parse(); + let rrule_result: Result = rule_set.parse(); match rrule_result { Ok(rrule) => { // Set hard limit in case of infinitely recurring rules From 1a6e951d9aa5328a25796c641430552025de3274 Mon Sep 17 00:00:00 2001 From: Douglas Machado Date: Fri, 19 May 2023 23:40:21 -0300 Subject: [PATCH 6/7] code review fixes --- rrule/Cargo.toml | 7 ++----- rrule/examples/wasm/web/index.html | 4 ++-- rrule/src/wasm/mod.rs | 6 ------ 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/rrule/Cargo.toml b/rrule/Cargo.toml index 860e601..a5fb982 100644 --- a/rrule/Cargo.toml +++ b/rrule/Cargo.toml @@ -21,13 +21,11 @@ regex = { version = "1.5.5", default-features = false, features = ["perf", "std" clap = { version = "4.1.9", optional = true, features = ["derive"] } thiserror = "1.0.30" serde_with = { version = "2.3.1", optional = true } -#[cfg(feature = "wasm")] -wasm-bindgen = { version="0.2.85" } +wasm-bindgen = { version="0.2.85", optional = true } [dev-dependencies] serde_json = "1.0.80" orig_serde = { package = "serde", version = "1.0.137", default-features = false } -#[cfg(feature = "wasm")] wasm-bindgen-test = "0.3.13" [[bin]] @@ -50,8 +48,7 @@ serde = ["serde_with", "chrono/serde", "chrono-tz/serde"] exrule = [] # Allows to use WASM -wasm = [] +wasm = ["dep:wasm-bindgen"] [lib] -#[cfg(feature = "wasm")] crate-type = ["cdylib", "rlib"] diff --git a/rrule/examples/wasm/web/index.html b/rrule/examples/wasm/web/index.html index 8cca838..ea857bf 100644 --- a/rrule/examples/wasm/web/index.html +++ b/rrule/examples/wasm/web/index.html @@ -12,8 +12,8 @@ async function run_wasm() { await init(); - const rule_set = "DTSTART:20120201T093000Z\nRRULE:FREQ=DAILY;COUNT=3"; - const data = get_all_date_recurrences(rule_set, 100); + const ruleSet = "DTSTART:20120201T093000Z\nRRULE:FREQ=DAILY;COUNT=3"; + const data = get_all_date_recurrences(ruleSet, 100); console.log(data); alert(data); } diff --git a/rrule/src/wasm/mod.rs b/rrule/src/wasm/mod.rs index a4547e6..ad992c5 100644 --- a/rrule/src/wasm/mod.rs +++ b/rrule/src/wasm/mod.rs @@ -1,9 +1,3 @@ -#![allow( - clippy::cast_possible_truncation, - clippy::doc_markdown, - clippy::unwrap_used -)] - use wasm_bindgen::prelude::*; use crate::{RRuleSet, RRuleError}; From 391b3f2c1f3622565ccebf48a8388a7f676dba36 Mon Sep 17 00:00:00 2001 From: Douglas Machado Date: Fri, 19 May 2023 23:46:26 -0300 Subject: [PATCH 7/7] code review fixes --- rrule/src/wasm/mod.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/rrule/src/wasm/mod.rs b/rrule/src/wasm/mod.rs index ad992c5..385c358 100644 --- a/rrule/src/wasm/mod.rs +++ b/rrule/src/wasm/mod.rs @@ -2,17 +2,19 @@ use wasm_bindgen::prelude::*; use crate::{RRuleSet, RRuleError}; -/** - Get all recurrences of the rrule! - rule_set_string: List of rrules - limit: Limit must be set in order to prevent infinite loops -*/ +/// Get all recurrences of the rrule +/// +/// # Arguments +/// +/// * `rule_set` - List of rrules +/// +/// * `limit` - Limit must be set in order to prevent infinite loops #[wasm_bindgen] pub fn get_all_date_recurrences(rule_set: &str, limit: Option) -> Result, JsError> { let rrule_result: Result = rule_set.parse(); match rrule_result { Ok(rrule) => { - // Set hard limit in case of infinitely recurring rules + /// Set hard limit in case of infinitely recurring rules let rule_set_collection = rrule.all(limit.unwrap_or(100)); let result: Vec = rule_set_collection.dates .into_iter()