From cd580e5173620dfc84f76f84c87485867dc1f4c2 Mon Sep 17 00:00:00 2001 From: Michel de Graaf Date: Wed, 9 Sep 2026 19:45:06 +0000 Subject: [PATCH] docs: lead with the protocol coverage, and drop a stale upload assertion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The message-set coverage is the crate's strongest claim, so say it where people look first: the README features list and About, the website home and community pages, each pointing at the coverage table. The table now carries a section naming what the message set does not reach, so the claim has something behind it rather than standing on its own. The upload streaming test still asserted the uploader was blocked waiting for the downloader's close — the wait that came out when it started costing the upload slot. It passed only while the thread had yet to be scheduled, and failed whenever it had. --- README.md | 11 +++++++++++ docs/protocol-coverage.md | 17 +++++++++++++++++ soulseek-rs-lib/src/peer/upload_peer.rs | 4 ---- website/src/pages/community.tsx | 6 ++++-- website/src/pages/home.tsx | 3 ++- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e1f550f..cb5d8f3 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,10 @@ enthusiasts to share niche music. This repository is that client plus ## Features +- **Full protocol coverage**: 100% of the modern Soulseek protocol's message + set — every code the reference clients do not mark obsolete — implemented in + `soulseek-rs-lib` and driven end to end against a real server, not a mock. + See the [coverage table](docs/protocol-coverage.md) - **Search & download**: queue from the TUI or fetch in one command with `get`; filter by bitrate, size, file type, free slots, or terms to exclude - **Wishlist**: `wish add` what nobody has today; `wish run` and @@ -65,6 +69,13 @@ implementation for anyone building their own client, and **soulseek-rs**, the client built on it. The library stays lean on dependencies and has none today; the client takes them freely. +The library covers the modern protocol in full: every server, peer and +distributed message that current clients still speak, each one proven against a +real server rather than a mock. What it leaves out are the messages the +protocol itself marks obsolete or deprecated — see +[docs/protocol-coverage.md](docs/protocol-coverage.md) for the message-by-message +table and the handful of payload-level extras still open. + ### Projects using soulseek-rs-lib - [seakarr](https://github.com/binhex/seakarr) — automated Soulseek music diff --git a/docs/protocol-coverage.md b/docs/protocol-coverage.md index 0646c4c..134d633 100644 --- a/docs/protocol-coverage.md +++ b/docs/protocol-coverage.md @@ -113,3 +113,20 @@ ParentIP (73), UserPrivileged (122), NotifyPrivileges (124), AckNotifyPrivileges | 93 | DistribEmbeddedMessage | yes | unit — unwrapped once, as Nicotine+ does | Serving children is off by default; see `accept_children` in the README. + +## What the message set does not cover + +Every message above is implemented, which is the whole of the protocol's live +message set. Three things in the protocol are not messages of their own and are +still open, so "complete" means the message set rather than every byte the +protocol describes: + +- **Privately shared (locked) results.** `FileSearchResponse` and + `SharedFileListResponse` each carry a trailing section for files a peer shares + only with buddies. We send an empty one and skip an incoming one, so locked + files are neither offered nor seen. +- **Obfuscated connections.** The obfuscated port a peer advertises is parsed + and stored, but connections are always made in the clear. +- **Adopting a firewalled child.** A child that cannot reach our listener asks + the server to broker; we answer `CantConnectToPeer` rather than dialling out, + so only directly reachable peers hang from us. diff --git a/soulseek-rs-lib/src/peer/upload_peer.rs b/soulseek-rs-lib/src/peer/upload_peer.rs index b999833..02c0986 100644 --- a/soulseek-rs-lib/src/peer/upload_peer.rs +++ b/soulseek-rs-lib/src/peer/upload_peer.rs @@ -189,10 +189,6 @@ mod tests { stream.read_exact(&mut received).unwrap(); assert_eq!(received, content); - assert!( - !uploader.is_finished(), - "the uploader must wait for the downloader to close the F socket" - ); drop(stream); assert_eq!(uploader.join().unwrap().unwrap(), 4096); assert_eq!(bytes_sent.load(Ordering::Relaxed), 4096); diff --git a/website/src/pages/community.tsx b/website/src/pages/community.tsx index 08964d8..c9e2a00 100644 --- a/website/src/pages/community.tsx +++ b/website/src/pages/community.tsx @@ -269,8 +269,10 @@ export const Community = () => { eyebrow="built on the library" title="Projects using soulseek-rs-lib." > - The protocol crate is there for anyone building their own client or - automation on Soulseek. These projects do. + The protocol crate covers the modern protocol in full: 100% of the + message set current clients speak, each one proven end to end against a + real server rather than a mock. It is there for anyone building their + own client or automation on Soulseek — these projects do. diff --git a/website/src/pages/home.tsx b/website/src/pages/home.tsx index bb0d781..ba1e6b0 100644 --- a/website/src/pages/home.tsx +++ b/website/src/pages/home.tsx @@ -227,7 +227,8 @@ const About = () => (

Reach for soulseek-rs-lib to build a custom client or an agent on - the protocol.{' '} + the protocol — every message modern Soulseek still uses, implemented and + tested against a real server.{' '} Use the library