diff --git a/.cirrus.yml b/.cirrus.yml
index 6352157..5dfed6c 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -1,6 +1,7 @@
env:
PATH: "$HOME/.cargo/bin:$PATH"
RUST_VERSION: '1.70.0' # Needs to be <= FreeBSD version
+ WASM_VERSION: '1.73.0'
AWS_ACCESS_KEY_ID: ENCRYPTED[5c3f77d4196c6b47340a4f07f6dec015753bf26df6f7323467217282d614988db7568c67785129a46a6de7fe8117c2af]
AWS_SECRET_ACCESS_KEY: ENCRYPTED[4c49da1c017860dd66710621efb3edb855c7da0dcad438a7bf9a3dbf41adfd15905cbe14df679ba2a83cff5a9ec2afdc]
@@ -48,6 +49,22 @@ task:
fi
before_cache_script: rm -rf $HOME/.cargo/registry/index
+task:
+ name: Build (Web Assembly)
+ container:
+ image: debian:12-slim
+ cpu: 4
+ cargo_cache:
+ folder: $HOME/.cargo/registry
+ fingerprint_script: cat Cargo.lock
+ install_script:
+ - apt-get update && apt-get install -y --no-install-recommends git ca-certificates curl gcc libc6-dev
+ - curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal --default-toolchain ${WASM_VERSION}
+ - rustup target add wasm32-unknown-unknown
+ build_script:
+ - cargo build --lib --target wasm32-unknown-unknown
+ before_cache_script: rm -rf $HOME/.cargo/registry/index
+
task:
name: Build (FreeBSD)
freebsd_instance:
diff --git a/.gitignore b/.gitignore
index 324c57f..0f8826d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
target/
+/wasm
**/*.rs.bk
diff --git a/Cargo.lock b/Cargo.lock
index 99b643e..a06b00d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -11,12 +11,54 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "bumpalo"
+version = "3.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "log"
+version = "0.4.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
+
[[package]]
name = "memchr"
version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
+[[package]]
+name = "once_cell"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.81"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+dependencies = [
+ "proc-macro2",
+]
+
[[package]]
name = "regex"
version = "1.10.4"
@@ -46,9 +88,81 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
+[[package]]
+name = "syn"
+version = "2.0.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
[[package]]
name = "titlecase"
version = "3.0.0"
dependencies = [
"regex",
+ "wasm-bindgen",
]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
diff --git a/Cargo.toml b/Cargo.toml
index d3f5feb..4606b75 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,5 +15,12 @@ license = "MIT"
keywords = ["title", "case", "capitalization", "capitalisation", "capitalize"]
categories = ["text-processing"]
+[lib]
+# cdylib is for WASM
+crate-type = ["cdylib", "rlib"]
+
[dependencies]
regex = { version = "1.10", default-features = false, features = ["std", "perf", "unicode-perl"]}
+
+[target.'cfg(target_family = "wasm")'.dependencies]
+wasm-bindgen = "0.2.92"
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..41e063e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+all: wasm/titlecase.js
+
+wasm/titlecase.js: target/wasm32-unknown-unknown/release/titlecase.wasm
+ wasm-bindgen target/wasm32-unknown-unknown/release/titlecase.wasm --target web --out-dir wasm
+
+target/wasm32-unknown-unknown/release/titlecase.wasm:
+ cargo build --lib --target wasm32-unknown-unknown --release
+
+.PHONY: target/wasm32-unknown-unknown/release/titlecase.wasm
diff --git a/README.md b/README.md
index 0b93b51..276998a 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,10 @@ by Rust including Linux, macOS, FreeBSD, NetBSD, OpenBSD, and Windows.
[][crate-docs]
[][MIT]
+## Try Online
+
+
+
## Command Line Usage
`titlecase` reads lines of text from **stdin** and prints title cased versions
@@ -56,6 +60,27 @@ install the most recently released `titlecase` with cargo:
See the [crate documentation][crate-docs].
+## Building for WebAssembly
+
+### Pre-requisites
+
+- Rust 1.73.0+
+- Rust `wasm32-unknown-unknown` target
+ (`rustup target add wasm32-unknown-unknown` or `rust-wasm` package on Chimera Linux)
+- [wasm-bindgen]
+ (`wasm-bindgen` package on Arch, or `cargo install wasm-bindgen-cli --version 0.2.92`)
+- `make` (GNU or BSD should work)
+
+### Building
+
+There is a `Makefile` that automates building for WebAssembly.
+
+ make
+
+The output is put into a `wasm` directory. See
+ for an
+example that uses the wasm build.
+
## Style
Instead of simply capitalizing each word `titlecase` does the following
@@ -81,3 +106,4 @@ Pagaltzis], and [David Gouch].
[MIT]: https://github.com/wezm/titlecase/blob/master/LICENSE
[rustup]: https://www.rust-lang.org/tools/install
[style]: https://daringfireball.net/2008/05/title_case
+[wasm-bindgen]: https://github.com/rustwasm/wasm-bindgen
diff --git a/src/lib.rs b/src/lib.rs
index fa05fd6..7df40e9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -31,6 +31,9 @@ use std::sync::OnceLock;
use regex::{Captures, Regex};
+#[cfg(target_family = "wasm")]
+mod wasm;
+
#[rustfmt::skip]
const SMALL_WORDS: &[&str] = &[
"a",
diff --git a/src/wasm.rs b/src/wasm.rs
new file mode 100644
index 0000000..180f3a8
--- /dev/null
+++ b/src/wasm.rs
@@ -0,0 +1,6 @@
+use wasm_bindgen::prelude::*;
+
+#[wasm_bindgen]
+pub fn titlecase(text: &str) -> String {
+ crate::titlecase(text)
+}