Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
 
root / crates / npro-test / transcripts / ws-server-close-when-flushed.json
Author[]Andy Green <andy@warmcat.com> 2026-10-03 09:24 UTC
Committer[]Andy Green <andy@warmcat.com> 2026-10-03 09:24 UTC
Tree4361df462d2a7923f98c68ca3f877e56abccb11e   Raw Patch
 
meta: npro workspace, its lints and the CI gates
meta: npro workspace, its lints and the CI gates

The placeholder lws crate becomes the npro workspace: members under
crates/, starting with the npro facade, which re-exports the protocol
crates as they arrive.  A crate is added by the phase that gives it
content.

[workspace.lints] carries AGENTS.md's rules for every crate:
- unsafe_code forbidden, missing_docs and unexpected_cfgs denied;
- clippy denies unwrap / expect / panic / unreachable, slice indexing,
  arithmetic side effects and lossy casts.

These are the C bug classes a panic or a wrapped length turns into a
remote abort or worse.  clippy.toml lets only tests assert by panicking.
Cargo.lock is committed so every gate runs on the same tree.

scripts/ci.sh runs the gates every commit passes:
- fmt;
- clippy with warnings denied;
- tests;
- docs with warnings denied;
- a check at rust-version 1.85, the edition 2024 floor;
- cargo deny, against deny.toml: MIT only, one version of anything, no
  unknown registries or git sources;
- cargo audit.

The README says what npro is, that it is written by AI agents working
with the author of libwebsockets, and how it is held to the C library:
transcripts, the state tables, fuzzing, differential and conformance
tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019kg5Eemy68ZaqDBcUJQG6J
diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..852c0a8 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "npro" +version = "0.0.2" diff --git a/Cargo.toml b/Cargo.toml index 0d76fbe..e802236 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,36 @@ -[package] -name = "lws" -version = "0.0.1" -license = "MIT" -homepage = "https://libwebsockets.org" -description = "Modern all-safe networking library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls" -edition = "2024" -readme = "README.md" -repository = "https://libwebsockets.org/git/lws-rs" -keywords = ["websocket", "http2", "http3", "sans-io", "networking"] -categories = ["network-programming", "web-programming::websocket"] +[workspace] +resolver = "3" +members = ["crates/*"] + +[workspace.package] +version = "0.0.2" +edition = "2024" rust-version = "1.85" -[dependencies] +license = "MIT" +homepage = "https://npro.rs" +repository = "https://libwebsockets.org/git/npro" + +[workspace.lints.rust] +unsafe_code = "forbid" +missing_docs = "deny" +unexpected_cfgs = "deny" + +# What AGENTS.md asks of every crate: nothing that can panic on input, no +# unchecked arithmetic on lengths, no lossy integer casts. A lint is +# silenced only by an #[allow] on the one item, with a reason. + +[workspace.lints.clippy] +unwrap_used = "deny" +expect_used = "deny" +panic = "deny" +unreachable = "deny" +todo = "deny" +unimplemented = "deny" +indexing_slicing = "deny" +arithmetic_side_effects = "deny" +as_conversions = "deny" +cast_possible_truncation = "deny" +cast_sign_loss = "deny" +cast_possible_wrap = "deny" +missing_errors_doc = "deny" +must_use_candidate = "deny" diff --git a/README.md b/README.md index 7c2f156..628e315 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,49 @@ -# Placeholder +# npro -This is a placeholder for lws by Andy Green <andy@warmcat.com> +![npro network protocols logo](docs/npro.png) +npro is the Rust port of the sansIO half of +[libwebsockets](https://libwebsockets.org): h1, h2, h3, ws and wt as +entirely `safe`, `no_std` state machines that take bytes and time in, +and give bytes and events out; with an IO crate for sockets, tls +and the event loop along side it. It's all rust. + +[npro Home](https://npro.rs) - [npro Git](https://npro.rs/git/npro) - [npro CI](https://npro.rs/sai) + +**Status: in Development** The workspace and its gates are in place, +and the protocol crates arrive phase by phase as described in +[docs/port-plan.md](docs/port-plan.md). + +## How it is written, and how it is checked + +npro is maintained alongside C libwebsockets. It follows the sansIO +refactor of 16 years of libwebsockets h1, h2, h3, ws and wt using `safe` +rust: the two abstract bodies of code are kept in sync. +Development and auditing of lws and npro make heavy use of Fable 5.1 +but it is tightly directed by humans. + +It is a port of behaviour, not a transliteration of C: the C library's +sansIO half is the specification, and the port is held to it by: + +- **transcripts**: byte-for-byte records of connections driven through C + lws with no socket and no clock of its own + (`minimal-examples-lowlevel/api-tests/api-test-sansio` in the C tree), + which npro replays; +- **the C state tables**: every state transition C allows, from + `lib/sansio/wsi-state.c`, which npro's state enums must match; +- **fuzzing**, seeded from the C library's fuzz corpora; +- **differential and conformance testing**, against C lws and the + autobahn, h2spec and h3spec suites, as the IO crate makes them possible. + +... and the enforced design rules: + +- every crate is `#![forbid(unsafe_code)]` +- nothing reachable from network data may panic +- arithmetic on lengths is checked +- the dependency tree stays close to empty (cargo deny + audit) +- maximally linted via clippy to enforce code quality +- fuzzing in CI on pushes and when CI idle + +## Licence + +MIT diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000..b519fb9 --- /dev/null +++ b/clippy.toml @@ -0,0 +1,5 @@ +# Tests may assert by panicking; nothing else may. +allow-unwrap-in-tests = true +allow-expect-in-tests = true +allow-panic-in-tests = true +allow-indexing-slicing-in-tests = true diff --git a/crates/npro/Cargo.toml b/crates/npro/Cargo.toml new file mode 100644 index 0000000..b2d1a58 --- /dev/null +++ b/crates/npro/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "npro" +description = "Safe sans-IO h1, h2, h3, ws and wt protocols: the Rust port of libwebsockets' sansIO half" +readme = "../../README.md" +keywords = ["websocket", "http2", "http3", "sans-io", "networking"] +categories = ["network-programming", "web-programming::websocket", "no-std"] +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true diff --git a/crates/npro/src/lib.rs b/crates/npro/src/lib.rs new file mode 100644 index 0000000..50d1f14 --- /dev/null +++ b/crates/npro/src/lib.rs @@ -0,0 +1,12 @@ +//! npro: safe, sans-IO network protocols. +//! +//! npro is the Rust port of the sansIO half of +//! [libwebsockets](https://libwebsockets.org): the h1, h2, h3, ws and wt +//! protocols as state machines that take bytes and time as input and +//! produce bytes and events, with no sockets, threads or clock of their own. +//! +//! This facade re-exports the protocol crates behind features as they are +//! written. Nothing is usable yet; see <https://npro.rs> for the status. + +#![no_std] +#![forbid(unsafe_code)] diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..ac49745 --- /dev/null +++ b/deny.toml @@ -0,0 +1,20 @@ +# cargo deny: what may enter the dependency tree. The tree is meant to stay +# close to empty; each dependency is justified in the commit that adds it. + +[graph] +all-features = true + +[advisories] +yanked = "deny" + +[licenses] +allow = ["MIT"] +confidence-threshold = 0.9 + +[bans] +multiple-versions = "deny" +wildcards = "deny" + +[sources] +unknown-registry = "deny" +unknown-git = "deny" diff --git a/docs/npro.png b/docs/npro.png new file mode 100644 index 0000000..a79cf1f Binary files /dev/null and b/docs/npro.png differ diff --git a/scripts/ci.sh b/scripts/ci.sh new file mode 100755 index 0000000..3771cea --- /dev/null +++ b/scripts/ci.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +# The gates every commit must pass, in the order that fails fastest. +# Run from anywhere in the tree: +# +# scripts/ci.sh +# +# Set CARGO_TARGET_DIR to keep build output out of the tree. The MSRV build +# needs the toolchain named in Cargo.toml's rust-version (rustup toolchain +# install 1.85 --profile minimal); cargo-deny and cargo-audit must be +# installed. + +set -eu + +cd "$(dirname "$0")/.." + +msrv=$(sed -n 's/^rust-version *= *"\(.*\)"/\1/p' Cargo.toml) + +echo "== fmt" +cargo fmt --all --check + +echo "== clippy" +cargo clippy --workspace --all-targets --all-features --locked -- -D warnings + +echo "== test" +cargo test --workspace --all-features --locked + +echo "== doc" +RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked + +echo "== msrv $msrv" +cargo "+$msrv" check --workspace --all-targets --all-features --locked + +echo "== deny" +cargo deny --all-features check + +echo "== audit" +cargo audit --deny warnings + +echo "== all gates passed" diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index b93cf3f..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -}
Page fetched 0s ago, creation time: 2ms (vhost etag hits: 0%, cache hits: 0%)