Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Bloop Client Framework
This library handles the connection lifecycle for Bloop protocol clients: DNS lookup, TLS, protocol handshake, authentication, keep-alive pings, and reconnecting after failures. Applications observe the connection through a status watch and perform request-response exchanges through typed operations.
The wire format lives in the bloop-protocol crate.
Quick start
use ;
let client = builder
.config
.build?;
let mut status = client.status;
status.wait_for.await?;
let achievements = client.bloop.await?;
let audio = client.retrieve_audio.await?;
The client can also start without configuration (status Unconfigured) and receive credentials at runtime via
configure, e.g. when they arrive on a provisioning tag. Rejected credentials latch the client until new ones
arrive; use InvalidCredentialsPolicy::Retry to keep retrying instead.
Custom messages
Extensions define their messages with the bloop-protocol derives (direct dependency required, opcodes 0x80 and
above) and pair each request with its response type through the Request trait:
use Request;
use ;
// Fully typed request-response:
let accepted = client.custom.await?;
Protocol errors, including extension-defined codes, arrive as RequestError::Error(ErrorResponse). For exchanges
that fall outside the one-to-one mapping there is request_raw.
On-connect hook
Work that must happen on every (re)connect, such as preloading extension data, runs inside the connection attempt,
before the status flips to Connected; a hook failure fails the attempt:
let builder = builder.on_connect;
All server I/O inside the hook must go through the Session: the hook runs on the client's own connection task,
so calling methods on a captured BloopClient handle in the hook deadlocks the client. AudioCache accepts a
&mut Session for the same reason.
Audio cache
AudioCache keeps achievement audio on disk, keyed by achievement ID and audio hash, so server-side updates
invalidate stale files naturally:
let cache = new;
// On demand, e.g. when a bloop awards an achievement:
if let Some = cache.ensure.await?
// Or as a preload after a PreloadOutcome::Mismatch:
let skipped = cache.sync.await?;
sync returns the IDs of achievements whose audio the server refused to deliver; a non-empty list means the sync
was partial, so don't persist the new manifest hash and the next preload check will retry.
NFC reader
The nfc feature provides a channel-backed reader handle with cancel-safe waits, suitable for select! loops, plus
NDEF text-record parsing. The nfc-mfrc522 feature adds the built-in backend for MFRC522 modules over SPI (Linux):
use ;
let reader = spawn_mfrc522.await?;
let uid = reader.wait_for_card.await?;
let achievements = client.bloop.await?;
reader.wait_for_removal.await?;
Custom or emulated backends serve the other end of NfcReader::channel() instead, and serve_mfrc522 runs the
built-in backend blocking on the calling thread for applications that supervise reader threads themselves.
Features
All features are off by default:
[]
= { = "1", = ["audio", "nfc-mfrc522"] }
| Feature | Description |
|---|---|
audio |
Audio playback for achievement and UI sounds |
nfc |
NFC reader handle, backend channel, and NDEF parsing |
nfc-mfrc522 |
Built-in MFRC522 reader backend (Linux, SPI + GPIO) |
tokio-graceful-shutdown |
Implements IntoSubsystem for the client, quitting cleanly on shutdown |
TLS
The server certificate is verified through the operating system's certificate verifier
(rustls-platform-verifier). On Linux this reads the system CA
bundle once at startup, so locally installed CAs (e.g. for self-signed certificates) require an application restart.
RootCertSource::DangerousDisabled skips verification entirely for testing.