Skip to content

Library API: portable core crate with CLI and WASM adapters - #18

Merged
hypnagonia merged 4 commits into
mainfrom
library-api
Sep 30, 2026
Merged

hypnagonia merged 4 commits into
mainfrom
library-api

Conversation

@hypnagonia

Copy link
Copy Markdown
Owner

Turns the project into a proper Rust library, with the CLI and the WebAssembly bindings as thin adapters over it.

Layout

A Cargo workspace, so the dependency direction is enforced by crate boundaries:

Crate Path Role
eigentrust src/ the library: plain rlib, builds on every target, no wasm gating
eigentrust-cli cli/ the eigentrust binary; uses only the public API
eigentrust-wasm wasm/ JS bindings, the only cdylib, publish = false

Public API

Everything is re-exported from lib.rs, and all modules are private.

use eigentrust::{eigentrust, eigentrust_with_options, EigenTrustOptions, PreTrust, TrustEdge};

let result = eigentrust([TrustEdge::new(0, 1, 2.0), TrustEdge::new(1, 0, 1.0)], [PreTrust::new(0, 1.0)])?;
result.scores(); result.ranking(); result.iterations(); result.residual();
  • EigenTrustOptions: alpha, epsilon, max_iterations. Private fields with a builder, validated before any work.
  • EigenTrustError is #[non_exhaustive], covering invalid options, non-finite, negative or overflowing weights, invalid peers, an empty network and non-convergence.
  • Feature csv: csv::Network::from_csv, with its own error type (line numbers and kinds).
  • Feature parallel: rayon. There are no default features.
  • The input rules (weights, normalization, duplicates, α = 0, convergence) are documented in the crate docs.

Verification

  • CLI output is byte-identical to main on 10 reference inputs (up to 5M lines), and the CLI is about 15% faster.
  • WASM output is byte-identical, at the same speed in Node and in the browser with threads.
  • 44 tests: unit, public-API integration tests (tests/api.rs, tests/csv.rs), and doc tests including the README example.
  • Clippy is clean natively (all and no features) and on wasm32. Rustdoc builds with -D warnings as docs.rs does. cargo machete is clean.
  • cargo package -p eigentrust -p eigentrust-cli builds from the tarballs. The library package is 26 KB of sources, tests, examples, test data and licenses.
  • cargo-semver-checks runs against the base branch. It's informational until the first crates.io release, and I checked that it catches a removed method.

Removed

  • The unused sparse helpers (CSC, merge, sorting utils).
  • The distrust functions that were never wired in. Negative weights stay rejected.

Cargo workspace:
- eigentrust (root): the library, rlib, builds on every target, no wasm gating
- eigentrust-cli (cli/): the `eigentrust` binary, uses only the public API
- eigentrust-wasm (wasm/): JS bindings, the only cdylib, publish = false

Public API, all re-exported from lib.rs, every module private:
- eigentrust(local_trust, pre_trust) and eigentrust_with_options(.., &options)
- TrustEdge { from, to, weight }, PreTrust { peer, weight }, From tuple impls
- EigenTrustOptions: alpha, epsilon, max_iterations; private fields, builder,
  validated before any work
- TrustScores: scores, get, ranking, iterations, residual
- EigenTrustError (#[non_exhaustive]) and Input; no String errors
- csv feature: csv::Network::from_csv with its own Error / ErrorKind
- parallel feature: rayon; default features: none

Behavior and numbers are unchanged: CLI output is byte-identical to the
previous version on 10 reference inputs (up to 5M lines), WASM output is
byte-identical, CLI is ~15% faster, WASM the same.

- crate docs with input rules, convergence and examples; missing_docs on
- examples/basic.rs, examples/csv.rs
- tests/api.rs and tests/csv.rs use the crate like an external consumer
- README Rust example runs as a doc test
- crates.io metadata, include list, docs.rs config; Cargo.lock committed
- removed the unused sparse helpers (CSC, merge, sorting utils) and the
  unwired distrust functions; their history stays in git
@hypnagonia
hypnagonia merged commit 2462b98 into main Sep 30, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant