Skip to content

tsoniclang/tsonic-rust

Repository files navigation

tsonic-rust

Rust target pack for Tsonic (@tsonic/target-rust).

This package owns the TypeScript-side Rust target implementation: target descriptor, Rust target options, target-semantics extension (carrier, operator, ownership, and provider facts), generic provider-package infrastructure, backend planning/printing, Cargo project generation, and Cargo toolchain integration. The backend is fail-closed: constructs without finalized lowering facts produce deterministic diagnostics, never guessed Rust source.

Runtime crates are intentionally split into sibling repositories, matching the C# package layout:

  • rust-runtime / tsonic_rust_runtime
  • rust-js / tsonic_rust_js
  • rust-nodejs / tsonic_rust_node

This repository must not own JS/Node runtime surface implementations.

Supported lanes

Static-native spine: source-core primitive carriers, functions, locals, constants (UPPER_SNAKE), returns, blocks, if/else, while and classic for loops, fact-backed arithmetic/comparison/boolean/string-concat operators, compound assignments, module imports/exports.

Native semantics: classes to struct + impl (constructor lane, methods with fact-selected &self/&mut self, static methods as associated functions), enums with TSTS-evaluated discriminants, interfaces as record structs with contextual object literals, closed string-literal union aliases as unit-variant enums, tuples with constant indexing, readonly T[] as &[T] and mutable array parameters as &mut [T], null-only unions as Option<T> with ?? coalescing, passthrough generic functions, source-core borrow/borrowMut/move flow markers validated against finalized argument modes, async/await with await-only future discipline, a naming policy that preserves every user-authored identifier verbatim with scoped lint allowances (snake_case exists only for compiler-generated temporaries; provider and library identity is always row metadata emitted verbatim), and the error model: throwing functions lower to TsonicResult with transitive fallibility, throw new Error(message) becomes an Err return, try/catch lowers to a Result closure boundary, and fallible calls propagate with ? (closures are fallibility boundaries). The string ABI: parameters whose every use is a ref-mode provider argument or member-access receiver take &str (literal call sites pass bare &str literals); ownership-requiring uses keep owned String. Homogeneous primitive tuple annotations carry compile-time-proven length and lower to [T; N] with literal construction and constant in-range indexing; dynamic indexing fails closed.

JS surface (selected surface or compat mode): dense Vec<T> and sparse JsArray<T> lanes with callback iteration (map/filter/reduce/some/every as Rust closures), string operations, Map/Set with SameValueZero runtime semantics, Date (UTC carrier), JSON parse/stringify through fallible rows, and T | undefined Option lanes.

Provider packages: identity-keyed operation rows over virtual declarations (calls, constructors, properties, indexers, operators via std::ops metadata, async and fallible rows), cargo dependency contribution, and fail-closed diagnostics for unsupported members. Node.js support is not part of this package: it ships as the separately installed @tsonic/rust-nodejs capability plugin, which owns node:* module declarations, operation rows, and the tsonic_rust_node runtime crate contribution. This target package exposes the standard createTsonicPlugin() entrypoint and the generic capability authoring helpers (createRustProviderPackage with creation-time identity validation, alias-import and carrier-path contribution, and composeRustCapabilities for fail-closed local composition). Capability crates enter the generated Cargo manifest only on activation: an installed but unused capability contributes no dependencies. The @acme/rust-superbunapi fixture proves the mechanism is name-blind — no code in this package names any capability.

Explicitly unsupported (fail-closed, classified)

Each unsupported lane requires a contract that does not exist: discriminated object unions (narrowing facts — see the exact repro pinned in test/r8-completion.test.mjs), and RegExp constructs outside the oracle-proven subset (constant patterns with classes, quantifiers, anchors, alternation, and groups under flags i/g/m, proven against 217 committed Node oracle vectors plus a 157-entry engine-generated acceptance corpus that pins compile-time validation to the runtime parser contract — see the rust-js JS parity inventory (docs/js-parity.md); lazy quantifiers, backreferences, lookaround, named groups, word boundaries, and dynamic patterns reject deterministically). Every unsupported lane diagnoses deterministically; see test/capability-ledger.test.mjs.

Build and test

npm install
npm test

The build requires the sibling tsonic repository's packages to be prebuilt (@tsonic/target-api, @tsonic/tsts, @tsonic/source-core); it never builds or writes into the tsonic repository itself. Tests include generated Cargo projects under .temp/generated/ validated with cargo fmt --check, check --locked, clippy -D warnings, test, and run for binaries.

Runtime artifact rule

Each runtime npm package owns one canonical Cargo source tree: @tsonic/rust-runtime/crates/tsonic_rust_runtime, @tsonic/rust-js/crates/tsonic_rust_js, and capability-owned crate paths such as @tsonic/rust-nodejs/rust/crates/tsonic_rust_node. Target packages never copy runtime sources. Runtime contributions carry absolute installed crate paths, so npm packages may be hoisted or nested independently. A crate that intentionally replaces the same exact crate from crates.io declares that registry-source relationship explicitly; generated Cargo manifests patch only those declared crates and never infer replacements from package or crate names.

Authoring provider packages

Use createRustProviderPackage: declare virtual modules (ProviderExportDeclaration models), identity-keyed operation rows (exportId/memberId/signatureId plus a Rust operation form), and cargo crate contributions. Concrete names live only in row data; the generic matcher contains no per-name branching. See src/source/provider-packages/index.ts and the @acme/* fixtures under test/helpers/rust-session.mjs.

About

Rust backend for Tsonic

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors