Skip to main content

Crate varing

Crate varing 

Source
Expand description

varing

Protobuf’s varint encoding/decoding for LEB128 friendly types with full const context operations supports.

github LoC Build codecov

docs.rs crates.io crates.io license

Discord

§Installation

[dependencies]
varing = "0.14"

no_std is supported by disabling the default std feature:

[dependencies]
varing = { version = "0.14", default-features = false }

§Quick Start

Encode and decode primitive integers as varints:

use varing::Varint;

// Encode
let mut buf = [0u8; u32::MAX_ENCODED_LEN.get()];
let len = 300u32.encode(&mut buf).unwrap();

// Decode
let (bytes_read, decoded) = u32::decode(&buf).unwrap();
assert_eq!(decoded, 300u32);
assert_eq!(bytes_read, len);

Signed integers use zigzag encoding, so small absolute values stay compact:

use varing::Varint;

let mut buf = [0u8; i64::MAX_ENCODED_LEN.get()];
let len = (-1i64).encode(&mut buf).unwrap();
assert_eq!(len.get(), 1); // -1 encodes to a single byte

Encode/decode sequences:

use varing::{Varint, encode_sequence, decode_sequence, encoded_sequence_len};

let values: Vec<u64> = (0..1024).collect();
let encoded_len = encoded_sequence_len(values.iter());
let mut buf = vec![0; encoded_len];

encode_sequence(values.iter(), &mut buf).unwrap();
let (_bytes_read, decoded) = decode_sequence::<u64, Vec<u64>>(&buf).unwrap();
assert_eq!(decoded, values);

All encoding and decoding functions are available in const context as free functions:

use varing::{encode_u32_varint, decode_u32_varint, encoded_u32_varint_len};

const ENCODED: varing::utils::Buffer<6> = encode_u32_varint(300);

const VALUE: u32 = {
    let Ok((_len, val)) = decode_u32_varint(ENCODED.as_slice()) else { panic!() };
    val
};

assert_eq!(VALUE, 300);
assert_eq!(ENCODED.len(), encoded_u32_varint_len(300).get());

§Optional Features

The following feature flags enable varint support for types from third-party crates. Multiple versions of the same crate can be enabled simultaneously.

FeatureCrateNotes
arbitrary-int (= v2)arbitrary-int v1Unsigned types + signed types (u1..u127, i1..i127)
arbitrary-int_1arbitrary-int v1Unsigned (u1..u127)
bnum (= v0.13)bnum
chrono (= v0.4)chronoNot fully const-compatible
chrono-tz (= v0.10)chrono-tz
ethereum-types (= v0.16)ethereum-types
ethereum-types_0_16ethereum-types v0.16
ethereum-types_0_15ethereum-types v0.15
float8 (= v0.4)float8
half (= v2)half
num-complex (= v0.4)num-complex
num-rational (= v0.4)num-rational
primitive-types (= v0.14)primitive-types
primitive-types_0_14primitive-types v0.14
primitive-types_0_13primitive-types v0.13
ruint (= v1)ruintNot const-compatible
time (= v0.3)time

§Benchmarks

varing’s varint encode/decode is competitive with the fastest Rust varint crates and at parity with prost — protobuf’s own varint implementation.

The tables below show single-value and bulk (1000-value sweep) timings for u64 (all protobuf varints are u64), lower is better. Figures are the median of one cargo bench run on Apple Silicon (aarch64) and are only meaningful relative to each other on the same machine — reproduce with cargo bench.

Encode u64

valuevaringprostinteger-encodingunsigned-varintleb128
1 byte527 ps1.20 ns542 ps874 ps429 ps
10 bytes2.16 ns6.00 ns2.14 ns2.34 ns2.14 ns
mixed ×10002.44 µs2.29 µs2.51 µs3.91 µs9.13 µs

Decode u64

valuevaringprostinteger-encodingunsigned-varintleb128
1 byte386 ps749 ps775 ps573 ps524 ps
10 bytes1.96 ns1.71 ns2.76 ns2.28 ns5.35 ns
mixed ×10002.06 µs2.29 µs1.86 µs2.04 µs3.44 µs

On the bulk sweep varing is within ~10% of prost in both directions (faster on decode, slightly slower on encode); on single values it is substantially faster than prost, whose figures include its bytes::BufMut API overhead. prost appears only in the u64 groups because that is the only varint width it exposes; leb128 is u64-only for unsigned values and uses a different signed format, so it is excluded from the signed groups. The full suite in benches/varint.rs also covers u16, u32, u128, and zigzag i64.

§Testing

  • Property-based testing with quickcheck for all types (including optional features).
  • Fuzz testing with cargo fuzz for all types.
§License

varing is under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE, LICENSE-MIT for details.

Copyright (c) 2026 Al Liu.

Modules§

arbitrary_intarbitrary-int_1 or arbitrary-int_2
LEB128 encoding/decoding for u1, u2 .. u127 and i1, i2 .. i127 (v2)
bnumbnum_0_13
LEB128 encoding/decoding for bnum types.
chronochrono_0_4
LEB128 encoding/decoding for chrono types.
chrono_tzchrono-tz_0_10
LEB128 encoding/decoding for chrono-tz types.
ethereum_typesethereum-types_0_15 or ethereum-types_0_16
LEB128 encoding/decoding for ethereum-types types.
num_complexnum-complex_0_4
LEB128 encoding/decoding for num-complex types.
num_rationalnum-rational_0_4
LEB128 encoding/decoding for num-rational types.
packable
Packable trait for types that can be packed into a single value.
primitive_typesprimitive-types_0_13 or primitive-types_0_14
LEB128 encoding/decoding for primitive-types types.
timetime_0_3
LEB128 encoding/decoding for time types.
utils
Utilities for encoding and decoding LEB128 variable length integers.

Structs§

InsufficientData
An error that occurs when trying to decode data from a buffer with insufficient data.
InsufficientSpace
An error that occurs when trying to write data to a buffer with insufficient space.
MapDecoder
An iterator that decodes a sequence of varint values from a buffer.
SequenceDecoder
An iterator that decodes a sequence of varint values from a buffer.

Enums§

ConstDecodeError
Decoding varint error.
ConstEncodeError
Encode varint error
DecodeError
Decoding varint error.
EncodeError
Encode varint error

Traits§

Varint
A trait for types that can be encoded as variable-length integers (varints).

Functions§

consume_varint
Calculates the number of bytes occupied by a varint encoded value in the buffer.
consume_varint_checked
Calculates the number of bytes occupied by a varint encoded value in the buffer.
decode_char
Decodes a char in LEB128 encoded format from the buffer.
decode_duration
Decodes a Duration in LEB128 encoded format from the buffer.
decode_f8e4m3_varintfloat8_0_4
Decodes an F8E4M3 in LEB128 encoded format from the buffer.
decode_f8e5m2_varintfloat8_0_4
Decodes an F8E5M2 in LEB128 encoded format from the buffer.
decode_f16_varinthalf_2
Decodes an f16 in LEB128 encoded format from the buffer.
decode_f32_varint
Decodes an f32 in LEB128 encoded format from the buffer.
decode_f64_varint
Decodes an f64 in LEB128 encoded format from the buffer.
decode_i8_varint
Decodes an i8 in LEB128 encoded format from the buffer.
decode_i16_varint
Decodes an i16 in LEB128 encoded format from the buffer.
decode_i32_varint
Decodes an i32 in LEB128 encoded format from the buffer.
decode_i64_varint
Decodes an i64 in LEB128 encoded format from the buffer.
decode_i128_varint
Decodes an i128 in LEB128 encoded format from the buffer.
decode_map
Decodes a collection of entries from the buffer.
decode_sequence
Decodes a sequence of values from the buffer.
decode_u8_varint
Decodes a u8 in LEB128 encoded format from the buffer.
decode_u16_varint
Decodes a u16 in LEB128 encoded format from the buffer.
decode_u32_varint
Decodes a u32 in LEB128 encoded format from the buffer.
decode_u64_varint
Decodes a u64 in LEB128 encoded format from the buffer.
decode_u128_varint
Decodes a u128 in LEB128 encoded format from the buffer.
encode_char
Encodes a char value into LEB128 variable length format, and writes it to the buffer.
encode_char_to
Encodes a char value into LEB128 variable length format, and writes it to the buffer.
encode_duration
Encodes a Duration value into LEB128 variable length format, and writes it to the buffer.
encode_duration_to
Encodes a Duration value into LEB128 variable length format, and writes it to the buffer.
encode_f8e4m3_sequence_tofloat8_0_4
Encodes a sequence of F8E4M3 to the buffer.
encode_f8e4m3_varintfloat8_0_4
Encodes a F8E4M3 value into LEB128 variable length format, and writes it to the buffer.
encode_f8e4m3_varint_tofloat8_0_4
Encodes a F8E4M3 value into LEB128 variable length format, and writes it to the buffer.
encode_f8e5m2_sequence_tofloat8_0_4
Encodes a sequence of F8E5M2 to the buffer.
encode_f8e5m2_varintfloat8_0_4
Encodes a F8E5M2 value into LEB128 variable length format, and writes it to the buffer.
encode_f8e5m2_varint_tofloat8_0_4
Encodes a F8E5M2 value into LEB128 variable length format, and writes it to the buffer.
encode_f16_sequence_tohalf_2
Encodes a sequence of f16 to the buffer.
encode_f16_varinthalf_2
Encodes an f16 value into LEB128 variable length format, and writes it to the buffer.
encode_f16_varint_tohalf_2
Encodes an f16 value into LEB128 variable length format, and writes it to the buffer.
encode_f32_sequence_to
Encodes a sequence of f32 to the buffer.
encode_f32_varint
Encodes an f32 value into LEB128 variable length format, and writes it to the buffer.
encode_f32_varint_to
Encodes an f32 value into LEB128 variable length format, and writes it to the buffer.
encode_f64_sequence_to
Encodes a sequence of f64 to the buffer.
encode_f64_varint
Encodes an f64 value into LEB128 variable length format, and writes it to the buffer.
encode_f64_varint_to
Encodes an f64 value into LEB128 variable length format, and writes it to the buffer.
encode_i8_sequence_to
Encodes a sequence of i8 to the buffer.
encode_i8_varint
Encodes an i8 value into LEB128 variable length format, and writes it to the buffer.
encode_i8_varint_to
Encodes an i8 value into LEB128 variable length format, and writes it to the buffer.
encode_i16_sequence_to
Encodes a sequence of i16 to the buffer.
encode_i16_varint
Encodes an i16 value into LEB128 variable length format, and writes it to the buffer.
encode_i16_varint_to
Encodes an i16 value into LEB128 variable length format, and writes it to the buffer.
encode_i32_sequence_to
Encodes a sequence of i32 to the buffer.
encode_i32_varint
Encodes an i32 value into LEB128 variable length format, and writes it to the buffer.
encode_i32_varint_to
Encodes an i32 value into LEB128 variable length format, and writes it to the buffer.
encode_i64_sequence_to
Encodes a sequence of i64 to the buffer.
encode_i64_varint
Encodes an i64 value into LEB128 variable length format, and writes it to the buffer.
encode_i64_varint_to
Encodes an i64 value into LEB128 variable length format, and writes it to the buffer.
encode_i128_sequence_to
Encodes a sequence of i128 to the buffer.
encode_i128_varint
Encodes an i128 value into LEB128 variable length format, and writes it to the buffer.
encode_i128_varint_to
Encodes an i128 value into LEB128 variable length format, and writes it to the buffer.
encode_map
Encodes a map of entries as varints and writes them to the buffer.
encode_sequence
Encodes a sequence of values as varints and writes them to the buffer.
encode_u8_sequence_to
Encodes a sequence of u8 to the buffer.
encode_u8_varint
Encodes an u8 value into LEB128 variable length format, and writes it to the buffer.
encode_u8_varint_to
Encodes an u8 value into LEB128 variable length format, and writes it to the buffer.
encode_u16_sequence_to
Encodes a sequence of u16 to the buffer.
encode_u16_varint
Encodes an u16 value into LEB128 variable length format, and writes it to the buffer.
encode_u16_varint_to
Encodes an u16 value into LEB128 variable length format, and writes it to the buffer.
encode_u32_sequence_to
Encodes a sequence of u32 to the buffer.
encode_u32_varint
Encodes an u32 value into LEB128 variable length format, and writes it to the buffer.
encode_u32_varint_to
Encodes an u32 value into LEB128 variable length format, and writes it to the buffer.
encode_u64_sequence_to
Encodes a sequence of u64 to the buffer.
encode_u64_varint
Encodes an u64 value into LEB128 variable length format, and writes it to the buffer.
encode_u64_varint_to
Encodes an u64 value into LEB128 variable length format, and writes it to the buffer.
encode_u128_sequence_to
Encodes a sequence of u128 to the buffer.
encode_u128_varint
Encodes an u128 value into LEB128 variable length format, and writes it to the buffer.
encode_u128_varint_to
Encodes an u128 value into LEB128 variable length format, and writes it to the buffer.
encoded_char_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range char::ENCODED_LEN_RANGE.
encoded_duration_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range Duration::ENCODED_LEN_RANGE.
encoded_f8e4m3_sequence_lenfloat8_0_4
Returns the encoded length of a sequence of F8E4M3 values.
encoded_f8e4m3_varint_lenfloat8_0_4
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range of F8E4M3::ENCODED_LEN_RANGE
encoded_f8e5m2_sequence_lenfloat8_0_4
Returns the encoded length of a sequence of F8E5M2 values.
encoded_f8e5m2_varint_lenfloat8_0_4
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range of F8E5M2::ENCODED_LEN_RANGE
encoded_f16_sequence_lenhalf_2
Returns the encoded length of a sequence of f16 values
encoded_f16_varint_lenhalf_2
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range of [f16::ENCODED_LEN_RANGE].
encoded_f32_sequence_len
Returns the encoded length of a sequence of f32 values
encoded_f32_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range of f32::ENCODED_LEN_RANGE.
encoded_f64_sequence_len
Returns the encoded length of a sequence of f64 values
encoded_f64_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range of f64::ENCODED_LEN_RANGE.
encoded_i8_sequence_len
Returns the encoded length of a sequence of i8 values
encoded_i8_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range of i8::ENCODED_LEN_RANGE.
encoded_i16_sequence_len
Returns the encoded length of a sequence of i16 values
encoded_i16_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range of i16::ENCODED_LEN_RANGE.
encoded_i32_sequence_len
Returns the encoded length of a sequence of i32 values
encoded_i32_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range of i32::ENCODED_LEN_RANGE.
encoded_i64_sequence_len
Returns the encoded length of a sequence of i64 values
encoded_i64_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range i64::ENCODED_LEN_RANGE.
encoded_i128_sequence_len
Returns the encoded length of a sequence of i128 values
encoded_i128_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range i128::ENCODED_LEN_RANGE.
encoded_map_len
Returns the total length of a map of entries.
encoded_sequence_len
Returns the total number of bytes needed to encode a sequence of values.
encoded_u8_sequence_len
Returns the encoded length of a sequence of u8 values
encoded_u8_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range of u8::ENCODED_LEN_RANGE.
encoded_u16_sequence_len
Returns the encoded length of a sequence of u16 values
encoded_u16_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range of u16::ENCODED_LEN_RANGE.
encoded_u32_sequence_len
Returns the encoded length of a sequence of u32 values
encoded_u32_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range of u32::ENCODED_LEN_RANGE.
encoded_u64_sequence_len
Returns the encoded length of a sequence of u64 values
encoded_u64_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range u64::ENCODED_LEN_RANGE.
encoded_u128_sequence_len
Returns the encoded length of a sequence of u128 values
encoded_u128_varint_len
Returns the encoded length of the value in LEB128 variable length format. The returned value will be in range u128::ENCODED_LEN_RANGE.
map_decoder
Returns a sequence decoder for the given buffer.
sequence_decoder
Returns a sequence decoder for the given buffer.
try_consume_varint
Calculates the number of bytes occupied by a varint encoded value in the buffer.

Type Aliases§

CharBuffer
A buffer for storing LEB128 encoded char value.