Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

Serialization with Bitcode

Loading…

Serialization with Bitcode

Relevant source files

This page documents how the bitcode library provides compact binary serialization for RPC parameters, responses, and metadata throughout the muxio framework. For information about defining service methods that use these serialized types, see Creating Service Definitions. For details on how method identifiers are generated, see Method ID Generation.

Purpose and Role

The bitcode crate serves as the serialization layer that transforms strongly-typed Rust structs into compact binary representations suitable for network transmission. This enables type-safe RPC communication while maintaining minimal payload sizes and efficient encoding/decoding performance.

Sources:

Bitcode in the Data Pipeline

Diagram: Bitcode serialization flow between application types and wire format

Sources:

Core Traits and Functions

Trait/FunctionPurposeUsage Context
bitcode::EncodeDerive macro for serializationApplied to request/response parameter structs
bitcode::DecodeDerive macro for deserializationApplied to request/response parameter structs
bitcode::encode(&T)Encodes a value to Vec<u8>Used before sending RPC requests/responses
bitcode::decode::<T>(&[u8])Decodes bytes to type TUsed after receiving RPC requests/responses

Sources:

Type Definitions with Bitcode

Types used in RPC communication must derive both Encode and Decode traits. These derivations are typically combined with Debug and PartialEq for testing and debugging purposes.

Diagram: Type definition pattern for serializable RPC parameters

graph TB
    subgraph "Example Type Definition"
        Struct["#[derive(Encode, Decode, PartialEq, Debug)]\nstruct AddRequestParams"]
Field1["numbers: Vec&lt;f64&gt;"]
Struct --> Field1
    end
    
    subgraph "Bitcode Derive Macros"
        EncodeMacro["bitcode_derive::Encode"]
DecodeMacro["bitcode_derive::Decode"]
end
    
    subgraph "Generated Implementations"
        EncodeImpl["impl Encode for AddRequestParams"]
DecodeImpl["impl Decode for AddRequestParams"]
end
    
 
   Struct -.->|expands to| EncodeMacro
 
   Struct -.->|expands to| DecodeMacro
    
 
   EncodeMacro --> EncodeImpl
 
   DecodeMacro --> DecodeImpl

Example from test suite:

tests/rpc_dispatcher_tests.rs:10-28 demonstrates the standard pattern:

Sources:

Integration with RPC Request/Response Types

The serialized bytes produced by bitcode::encode() are stored in specific fields of the RPC protocol structures:

RPC TypeFieldPurpose
RpcRequestrpc_param_bytes: Option<Vec<u8>>Encoded method parameters sent in header metadata
RpcRequestrpc_prebuffered_payload_bytes: Option<Vec<u8>>Encoded payload data for prebuffered requests
RpcResponserpc_prebuffered_payload_bytes: Option<Vec<u8>>Encoded response payload
RpcHeaderrpc_metadata_bytes: Vec<u8>Encoded metadata (parameters or status)

Sources:

Request Encoding Pattern

Diagram: Encoding flow for RPC request parameters

Example from test suite:

tests/rpc_dispatcher_tests.rs:42-49 demonstrates encoding request parameters:

Sources:

Response Decoding Pattern

Diagram: Decoding flow for RPC response payload

Example from test suite:

tests/rpc_dispatcher_tests.rs:100-116 demonstrates decoding response payloads:

Sources:

graph LR
    subgraph "Receive Phase"
        ReqBytes["rpc_param_bytes"]
DecodeReq["bitcode::decode\n&lt;AddRequestParams&gt;"]
ReqParams["AddRequestParams"]
ReqBytes --> DecodeReq
 
       DecodeReq --> ReqParams
    end
    
    subgraph "Processing"
        Logic["Business Logic\n(sum numbers)"]
RespParams["AddResponseParams"]
ReqParams --> Logic
 
       Logic --> RespParams
    end
    
    subgraph "Send Phase"
        EncodeResp["bitcode::encode"]
RespBytes["rpc_prebuffered_payload_bytes"]
RespParams --> EncodeResp
 
       EncodeResp --> RespBytes
    end

Server-Side Processing Pattern

The server decodes incoming request parameters, processes them, and encodes response payloads:

Diagram: Complete encode-process-decode cycle on server

Example from test suite:

tests/rpc_dispatcher_tests.rs:151-167 demonstrates the complete server-side pattern:

Sources:

Supported Types

Bitcode supports a wide range of Rust types through its derive macros:

Type CategoryExamplesNotes
Primitivesi32, u64, f64, boolDirect binary encoding
Standard collectionsVec<T>, HashMap<K,V>, Option<T>Length-prefixed encoding
Tuples(T1, T2, T3)Sequential encoding
StructsCustom types with #[derive(Encode, Decode)]Field-by-field encoding
EnumsTagged unions with variantsDiscriminant + variant data

Sources:

graph TB
    Bytes["Incoming Bytes"]
Decode["bitcode::decode&lt;T&gt;()"]
Success["Ok(T)"]
Error["Err(bitcode::Error)"]
Bytes --> Decode
 
   Decode -->|Valid binary| Success
 
   Decode -->|Invalid/incompatible| Error
    
 
   Error -->|Handle| ErrorHandler["Error Handler\n(log, return error response)"]

Error Handling

Decoding operations return Result types to handle malformed or incompatible binary data:

Diagram: Error handling in bitcode deserialization

The test code demonstrates using .unwrap() for simplicity, but production code should handle decode errors gracefully:

tests/rpc_dispatcher_tests.rs:152-153 shows unwrapping (test code):

Sources:

Compact Binary Format

Bitcode produces compact binary representations compared to text-based formats like JSON. The format characteristics include:

FeatureBenefit
No field names in outputReduces payload size by relying on struct definition order
Variable-length integer encodingSmaller values use fewer bytes
No schema overheadBinary is decoded based on compile-time type information
Aligned data structuresOptimized for fast deserialization via bytemuck

Sources:

Dependencies and Ecosystem Integration

The bitcode crate integrates with the broader Rust ecosystem:

Diagram: Bitcode dependency graph

Sources:

Usage in Muxio Ecosystem

Bitcode is used throughout the muxio workspace:

CrateUsage
muxioCore RPC protocol structures
muxio-rpc-serviceService definition trait bounds
example-muxio-rpc-service-definitionShared RPC parameter types
muxio-rpc-service-endpointServer-side deserialization
muxio-rpc-service-callerClient-side serialization

Sources: