tiny-varint
A dependency-free, high-performance variable-length integer (VarInt) encoding/decoding Rust library, fully compatible with no_std environments.
Features
- ✅ Depends only on zigzag-rs: Supports
#![no_std]environments - ✅ Full Type Support: Supports all Rust native integer types
- ✅ High-performance Implementation: Optimized critical paths for resource-constrained scenarios
- ✅ Iterator-based Interface: No dynamic memory allocation required, suitable for embedded systems
- ✅ Zigzag Encoding: Efficiently handles signed integers
- ✅ Type-aware VarintValue: Unified type for mixed data serialization
- ✅ Rich Error Handling: Detailed error types and messages
Installation
[]
= "0.2.0"
Feature Overview
Core Functions
| Feature | Function Name | Description |
|---|---|---|
| Generic Encoding | encode<T: VarInt>() |
Encodes any integer type to varint |
| Generic Decoding | decode<T: VarInt>() |
Decodes a varint to any integer type |
| ZigZag Encoding | encode_zigzag() |
Encodes signed integers using zigzag |
| ZigZag Decoding | decode_zigzag() |
Decodes zigzag-encoded signed integers |
| Batch Processing | VarIntEncoder/VarIntDecoder |
Batch encodes/decodes integer arrays |
| Iterator-based Encoding | bytes_of() |
Iterator-based encoding method |
| Iterator-based Decoding | values_from() |
Iterator-based decoding method |
| Unified Value Type | VarintValue |
Type-aware encoding for mixed integer types |
Direct Usage with encode/decode
The simplest way to use tiny-varint is with the generic encode and decode functions:
use ;
// Encode an unsigned integer
let mut buffer = ;
let bytes_written = encode.unwrap;
println!;
// Decode it back
let = .unwrap;
assert_eq!;
// Works with any integer type - even signed integers
let bytes_written = encode.unwrap;
let = .unwrap;
assert_eq!;
Using Encoders/Decoders
use ;
// Encoder example
let mut buffer = ;
let mut encoder = new;
// Write multiple values
encoder.write?;
encoder.write?;
encoder.write_zigzag?;
// Get encoded bytes
let bytes_written = encoder.position;
// Decoder example
let mut decoder = new;
// Read values
let v1 = decoder.?; // 123
let v2 = decoder.?; // 456
let v3 = decoder.?; // -789
Using Iterator-based Methods
use ;
// Encoding iterator - No buffer pre-allocation needed
let value = 16384u64;
for byte in bytes_of
// Decoding iterator - Decode from any byte source
let buffer = ; // Encoded value 16384
for result in
Using VarintValue for Mixed Types
The VarintValue enum allows working with different integer types through a unified interface:
use ;
// Create values of different types
let values = ;
// Serialize mixed-type values
let mut buffer = ;
let mut pos = 0;
for value in &values
// Deserialize values while preserving their original types
let mut read_pos = 0;
let mut index = 0;
while read_pos < pos
// Each value maintains its original type
assert!;
assert!;
assert!;
Performance Optimizations
tiny-varint has been optimized for various use cases:
- Avoid Boundary Checks: Pre-validate buffer sizes to reduce in-loop checks
- Inline Critical Functions: Critical paths marked with
#[inline(always)] - Optimized Size Calculation: Use lookup-based approach to quickly determine encoding size
- Batch Processing Optimization: Batch operations avoid multiple boundary checks
- Iterator-based Design: Directly operate on provided buffers without copying data
Example Code
Basic Encoding/Decoding
use ;
// Encode a single u64 value
let mut buffer = ;
let bytes_written = encode?;
println!;
// Decode a single u64 value
let = ?;
println!;
// Works with any integer type
let bytes_written = encode?;
let = ?;
assert_eq!;
ZigZag Encoding Signed Integers
use ;
// Encode an i32 value
let mut buffer = ;
let bytes_written = encode_zigzag?;
// Decode back to i32
let = ?;
assert_eq!;
Batch Processing
use ;
// Encode multiple values
let values = ;
let mut buffer = ;
let mut encoder = new;
let bytes_written = encoder.write_batch?;
// Decode multiple values
let mut decoded = ;
let mut decoder = new;
decoder.read_batch?;
assert_eq!;
Type-aware Protocol Messages
use ;
// Create a simple protocol message
let msg = Message ;
// Serialize the message
let mut buffer = ;
let mut pos = 0;
// Write fields - types are preserved automatically
pos += msg.id.to_bytes.unwrap;
pos += msg.temperature.to_bytes.unwrap;
// Write number of data points
pos += varint!.to_bytes.unwrap;
// Write each data point
for point in &msg.data_points
// Total message size
println!;
Complete Examples
Check the examples directory for more examples:
License
Dual-licensed under MIT/Apache-2.0 licenses.