diff --git a/Cargo.lock b/Cargo.lock index 3a67285..a313527 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,46 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "addr2line" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + +[[package]] +name = "assert_approx_eq" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c07dab4369547dbe5114677b33fbbf724971019f3818172d59a97a61c774ffd" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backtrace" +version = "0.3.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2baad346b2d4e94a24347adeee9c7a93f412ee94b9cc26e5b59dea23848e9f28" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bumpalo" version = "3.4.0" @@ -12,21 +53,79 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi", +] + [[package]] name = "console_error_panic_hook" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "wasm-bindgen", ] +[[package]] +name = "error-chain" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" +dependencies = [ + "backtrace", +] + +[[package]] +name = "geo-types" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "866e8f6dbd2218b05ea8a25daa1bfac32b0515fe7e0a37cb6a7b9ed0ed82a07e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "gimli" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" + +[[package]] +name = "gpx" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96f48f1635cee5d19d368d8142fb38b3ca5a6ae8b805f0cf42590751f3b33be" +dependencies = [ + "assert_approx_eq", + "chrono", + "error-chain", + "geo-types", + "xml-rs", +] + [[package]] name = "gpx-web-utils" version = "0.0.1" dependencies = [ "console_error_panic_hook", + "gpx", + "js-sys", "wasm-bindgen", "wasm-bindgen-test", ] @@ -46,20 +145,61 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "libc" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" + [[package]] name = "log" version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] -name = "proc-macro2" -version = "1.0.21" +name = "miniz_oxide" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" +checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ "unicode-xid", ] @@ -73,6 +213,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rustc-demangle" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" + [[package]] name = "scoped-tls" version = "1.0.0" @@ -81,28 +227,45 @@ checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" [[package]] name = "syn" -version = "1.0.41" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" +checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac" dependencies = [ "proc-macro2", "quote", "unicode-xid", ] +[[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi", + "winapi", +] + [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasm-bindgen" version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "wasm-bindgen-macro", ] @@ -127,7 +290,7 @@ version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "js-sys", "wasm-bindgen", "web-sys", @@ -195,3 +358,31 @@ dependencies = [ "js-sys", "wasm-bindgen", ] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xml-rs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" diff --git a/Cargo.toml b/Cargo.toml index 675a95c..e16062d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,8 @@ default = ["console_error_panic_hook"] [dependencies] wasm-bindgen = "0.2.63" +js-sys = "0.3.45" +gpx = "0.8.1" console_error_panic_hook = { version = "0.1.6", optional = true } @@ -22,5 +24,5 @@ console_error_panic_hook = { version = "0.1.6", optional = true } wasm-bindgen-test = "0.3.13" [profile.release] -# Tell `rustc` to optimize for small code size. -opt-level = "s" +opt-level = 3 +lto = true diff --git a/src/lib.rs b/src/lib.rs index 77a676f..78ea0c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,14 +2,16 @@ mod utils; use wasm_bindgen::prelude::*; -#[wasm_bindgen] -extern "C" { - fn alert(s: &str); -} +#[cfg(feature = "wee_alloc")] +#[global_allocator] +static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; #[wasm_bindgen] -pub fn greet() { +pub fn merge(files: js_sys::Array) -> wasm_bindgen::JsValue { utils::set_panic_hook(); + let files: Vec = utils::translate_js_to_rust(files); + let merged: gpx::Gpx = utils::join_gpx_files(files); + let out_vec: Vec = utils::write_gpx_to_buffer(merged); - alert("Hello, gpx-web-utils!"); + JsValue::from_str(&String::from_utf8(out_vec).unwrap()) } diff --git a/src/utils.rs b/src/utils.rs index b1d7929..c8cd025 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,10 +1,46 @@ pub fn set_panic_hook() { - // When the `console_error_panic_hook` feature is enabled, we can call the - // `set_panic_hook` function at least once during initialization, and then - // we will get better error messages if our code ever panics. - // - // For more details see - // https://github.com/rustwasm/console_error_panic_hook#readme #[cfg(feature = "console_error_panic_hook")] console_error_panic_hook::set_once(); } + +pub fn translate_js_to_rust(files: js_sys::Array) -> Vec { + // https://github.com/rustwasm/wasm-bindgen/issues/111 + files.iter().map(|f| f.as_string().unwrap()).collect() +} + +pub fn join_gpx_files(files: Vec) -> gpx::Gpx { + let mut merged: gpx::Gpx = Default::default(); + + for file in files.iter() { + let buffer = std::io::BufReader::new(file.as_bytes()); + let mut parsed_gpx: gpx::Gpx = gpx::read(buffer).expect("invalid gpx"); + + merged.tracks.append(&mut parsed_gpx.tracks); + merged.waypoints.append(&mut parsed_gpx.waypoints); + } + + let link = gpx::Link { + href: String::from("https://gpx.thermokar.st"), + ..Default::default() + }; + let author = gpx::Person { + link: Some(link), + ..Default::default() + }; + let metadata = gpx::Metadata { + name: Some(String::from("merged")), + author: Some(author), + ..Default::default() + }; + merged.metadata = Some(metadata); + merged.version = gpx::GpxVersion::Gpx11; + + merged +} + +pub fn write_gpx_to_buffer(gpx: gpx::Gpx) -> Vec { + let mut buffer = Vec::new(); + gpx::write(&gpx, &mut buffer).unwrap(); + + buffer +} diff --git a/www/index.html b/www/index.html index 9f40409..1951cd3 100644 --- a/www/index.html +++ b/www/index.html @@ -6,6 +6,7 @@ + diff --git a/www/index.js b/www/index.js index 53c5ada..9a40654 100644 --- a/www/index.js +++ b/www/index.js @@ -1,3 +1,27 @@ -import * as wasm from "gpx-web-utils"; +import * as gpx from "gpx-web-utils"; -wasm.greet(); +const inputElement = document.getElementById("input"); + +inputElement.addEventListener("change", readFiles, false); + +function readFiles() { + if (inputElement.files.length < 2) { alert("open two or more files"); return; } + + const files = Array.from(inputElement.files); + const promises = files.map(f => f.text()); + + Promise.all(promises).then(gpxes => { + const merged = gpx.merge(gpxes); + writeOutput(merged); + inputElement.value = ""; + }); +} + +function writeOutput(file) { + const blob = new Blob([file], {type: "text/gpx"}); + const a = document.createElement("a"); + a.href = URL.createObjectURL(blob); + a.download = "merged.gpx"; + a.click(); + URL.revokeObjectURL(a.href); +}