diff --git a/.gitignore b/.gitignore index de8b06d..634d1c9 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,8 @@ luacov.stats.out # Python tests/__pycache__ + +# Node +lib/ +node_module/ +package-lock.json diff --git a/Cargo.lock b/Cargo.lock index ebb84d0..49f26e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -271,6 +271,7 @@ dependencies = [ "clap_complete", "clap_mangen", "mlua", + "neon", "predicates", "pyo3", "regex", @@ -925,6 +926,16 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libloading" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -1016,6 +1027,31 @@ dependencies = [ "syn", ] +[[package]] +name = "neon" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d75440242411c87dc39847b0e33e961ec1f10326a9d8ecf9c1ea64a3b3c13dc" +dependencies = [ + "libloading", + "neon-macros", + "once_cell", + "semver", + "send_wrapper", + "smallvec", +] + +[[package]] +name = "neon-macros" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6813fde79b646e47e7ad75f480aa80ef76a5d9599e2717407961531169ee38b" +dependencies = [ + "quote", + "syn", + "syn-mid", +] + [[package]] name = "normalize-line-endings" version = "0.3.0" @@ -1324,6 +1360,12 @@ dependencies = [ "serde", ] +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + [[package]] name = "serde" version = "1.0.204" @@ -1422,6 +1464,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-mid" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5dc35bb08dd1ca3dfb09dce91fd2d13294d6711c88897d9a9d60acf39bce049" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "target-lexicon" version = "0.12.14" diff --git a/Cargo.toml b/Cargo.toml index baccb4c..166949c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ lua52 = ["luamodule", "mlua/lua52"] lua51 = ["luamodule", "mlua/lua51"] luajit = ["luamodule", "mlua/luajit"] pythonmodule = ["pyo3"] +nodemodule = ["neon"] [profile.release] lto = true @@ -58,6 +59,12 @@ unicode_titlecase = "2.3" optional = true features = ["module"] + [dependencies.neon] + version = "1.0" + optional = true + default-features = false + # features = ["napi-8"] + [dependencies.pyo3] version = "0.22" optional = true diff --git a/Makefile.am b/Makefile.am index 3de80ac..cbd8fc2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,9 +10,9 @@ docdir = $(datarootdir)/doc/$(TRANSFORMED_PACKAGE_NAME) licensedir = $(datarootdir)/licenses/$(TRANSFORMED_PACKAGE_NAME) bin_PROGRAMS = decasify -decasify_SOURCES = src/bin/decasify.rs src/cli.rs src/lib.rs src/lua.rs src/python.rs src/types.rs +decasify_SOURCES = src/bin/decasify.rs src/cli.rs src/lib.rs src/lua.rs src/node.rs src/python.rs src/types.rs EXTRA_decasify_SOURCES = tests/cli.rs -EXTRA_DIST = pyproject.toml spec/decasify_spec.lua tests/test_all.py +EXTRA_DIST = package.json pyproject.toml spec/decasify_spec.lua tests/test_all.py dist_doc_DATA = README.md CHANGELOG.md dist_license_DATA = LICENSE.md nodist_man_MANS = diff --git a/configure.ac b/configure.ac index 625ff3f..248c51d 100644 --- a/configure.ac +++ b/configure.ac @@ -23,6 +23,9 @@ AM_COND_IF([DEVELOPER_MODE], [ QUE_PROGVAR([maturin]) QUE_PROGVAR([pytest]) QUE_PROGVAR([uv]) + # Node build and testing dependencies + QUE_PROGVAR([node]) + QUE_PROGVAR([tsc]) # Release tooling QUE_PROGVAR([gitcliff], [git-cliff]) ]) diff --git a/package.json b/package.json new file mode 100644 index 0000000..4ab3010 --- /dev/null +++ b/package.json @@ -0,0 +1,42 @@ +{ + "name": "decasify", + "version": "0.5.5", + "description": "A CLI utility and library to cast strings to title-case according to locale specific style guides including Turkish support", + "main": "./lib/index.cjs", + "scripts": { + "build": "tsc && cargo build --features nodemodule --release --message-format=json > cargo.log" + }, + "author": "Caleb Maclennan ", + "license": "GPL-3.0-only", + "exports": { + ".": { + "import": { + "types": "./lib/index.d.mts", + "default": "./lib/index.mjs" + }, + "require": { + "types": "./lib/index.d.cts", + "default": "./lib/index.cjs" + } + } + }, + "types": "./lib/index.d.cts", + "files": [ + "lib/**/*.?({c,m}){t,j}s" + ], + "neon": { + "type": "library", + "org": "@nus", + "platforms": "common", + "load": "./src/load.cts" + }, + "devDependencies": { + "neon-cli": "^0.4", + "@tsconfig/node20": "^20.1", + "@types/node": "^20.14", + "typescript": "^5.5" + }, + "dependencies": { + "@neon-rs/load": "^0.1" + } +} diff --git a/src/index.cts b/src/index.cts new file mode 100644 index 0000000..001e420 --- /dev/null +++ b/src/index.cts @@ -0,0 +1,19 @@ +// This module is the CJS entry point for the library. + +// The Rust addon. +import * as addon from './load.cjs'; + +// Use this declaration to assign types to the addon's exports, +// which otherwise by default are `any`. +declare module "./load.cjs" { + function hello(): string; +} + +export type Greeting = { + message: string +}; + +export function greeting(): Greeting { + const message = addon.hello(); + return { message }; +} diff --git a/src/index.mts b/src/index.mts new file mode 100644 index 0000000..5e1ab26 --- /dev/null +++ b/src/index.mts @@ -0,0 +1,3 @@ +// This module is the ESM entry point for the library. + +export * from './index.cjs'; diff --git a/src/lib.rs b/src/lib.rs index c00119c..4c7718f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,9 @@ pub use types::{InputLocale, Result, StyleGuide, TargetCase}; #[cfg(feature = "cli")] pub mod cli; +#[cfg(feature = "nodemodule")] +pub mod node; + #[cfg(feature = "luamodule")] pub mod lua; diff --git a/src/load.cts b/src/load.cts new file mode 100644 index 0000000..901553e --- /dev/null +++ b/src/load.cts @@ -0,0 +1,16 @@ +// This module loads the platform-specific build of the addon on +// the current system. The supported platforms are registered in +// the `platforms` object below, whose entries can be managed by +// by the Neon CLI: +// +// https://www.npmjs.com/package/@neon-rs/cli + +module.exports = require('@neon-rs/load').proxy({ + platforms: { + 'win32-x64-msvc': () => require('@nus/win32-x64-msvc'), + 'darwin-x64': () => require('@nus/darwin-x64'), + 'darwin-arm64': () => require('@nus/darwin-arm64'), + 'linux-x64-gnu': () => require('@nus/linux-x64-gnu') + }, + debug: () => require('../index.node') +}); diff --git a/src/node.rs b/src/node.rs new file mode 100644 index 0000000..d9e7e35 --- /dev/null +++ b/src/node.rs @@ -0,0 +1,12 @@ +use crate::*; +use neon::prelude::*; + +#[neon::main] +fn main(mut cx: ModuleContext) -> NeonResult<()> { + cx.export_function("titlecase", titlecase)?; + Ok(()) +} + +fn titlecase(mut cx: FunctionContext) -> JsResult { + Ok(cx.string("foo")) +}