VaidCord Rust
Rust SDK for VaidCord. Status: alpha — the core layers described in
UNITED.md are implemented: gateway, bot facade, router + middleware +
dispatcher, rate-limited REST client, typed models, and voice transport
foundations that are wire-compatible with the Python SDK.
Feature overview
Bot facade
Bot wires gateway dispatch -> parsed models -> the dispatcher:
use ;
async
Gateway
- Heartbeat runs on an independent tokio task (interval from HELLO, jittered first beat); a missed heartbeat ACK forces a reconnect.
- RESUME support (
session_id+resume_gateway_url+ sequence replay) and automatic reconnect with exponential backoff. - Close-code policy per the Discord docs (
classify_gateway_close_code): fatal (4004/4010-4014) vs re-identify (4007/4009/1000/1001) vs resume. - Typed
Intentsbitflags, op 3 presence updates and op 8 guild-member requests via the cloneableGatewayHandle.
Router, middleware, dispatcher
Middleware has (event, next) semantics; outer middleware wraps inner
middleware and the innermost wraps the handler. Routers nest via
Router::include, and the standalone Dispatcher precomposes each route's
middleware chain at include-time so the dispatch hot path is O(1) in
allocations (UNITED.md §7):
use ;
let mut child = named;
child.use_middleware;
child.on_message_filtered;
let mut root = named;
root.include; // root middleware would wrap child middleware
let mut dispatcher = new;
dispatcher.include;
Filters are unchanged: multi-filter AND routing, any = [..] OR composition,
command!, ExtractBag extraction, register_on_message! and
#[vaidcord::on_message(...)] all keep working.
REST client
- Per-route rate-limit buckets parsed from
X-RateLimit-*headers, with sleep-and-retry on 429 (retry_after, route or global) and exponential backoff on 5xx/transport errors. - Endpoints: messages (send/get/edit/delete + reactions), channels (get/modify/delete), guilds (roles/members CRUD basics, bans), interactions (create response, followups, edit original), webhooks (execute), threads (start/join/leave), and application command sync.
Models
Typed User, Channel, Message, Guild, Role, Member, Embed
(with a fluent builder), Interaction, Ready. All deserializers ignore
unknown fields.
Voice transport foundations
The voice module mirrors vaidcord-py/src/vaidcord/voice/ and is verified
wire-compatible (byte-for-byte known-answer tests generated from the Python
implementation):
- Voice gateway v8 websocket client: identify/resume/heartbeat with
seq_ack, READY, session description, SSRC->user map from op 5/12/13, and the close-code policy (classify_voice_close_code: resume / rejoin / fatal). The protocol state machine (VoiceGatewayState) is synchronous and fully unit-tested. - UDP socket with 74-byte IP discovery packets.
- RTP packet builder/parser (
_rtpsizeunencrypted prefix: 12-byte header + CSRCs + 4-byte extension preamble when the X bit is set). - Transport encryption in both directions for
aead_aes256_gcm_rtpsize,aead_xchacha20_poly1305_rtpsizeandxsalsa20_poly1305_lite_rtpsize(RustCrypto). Wire format:prefix || ciphertext || 4-byte BE nonce counter; AEAD nonce = zero-padded counter; AAD = the unencrypted prefix. - Drift-corrected 20 ms
FramePacer(MissedTickBehavior::Delay),speaking_payloadhelpers, anAudioSourcetrait yielding opus packets, and aVoiceReceiverthat decrypts inbound RTP into(user_id, opus)frames. - DAVE opcode/close-code constants and
DaveIdentifyConfigcarrier.
Opus encode/decode is optional:
= { = "0.1", = ["opus"] } # needs system libopus
Without the opus feature the SDK is opus-passthrough: you feed pre-encoded
opus packets in and receive opus packets out.
Examples
| Example | What it shows |
|---|---|
examples/basic.rs |
REST request parts + formatting helpers |
examples/router.rs |
imperative router registration |
examples/decorator_router.rs |
every #[on_message] filter form |
examples/bot_middleware.rs |
middleware ordering, nesting, dispatcher |
examples/voice_transport.rs |
no-network voice packet seal/open + IP discovery |
Run with cargo run --example bot_middleware etc.
Development