百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
P

packed_struct.rs

> 编程语言
开源

Rust 的位级封装和解封

177 stars0 点赞0 次浏览
访问官网GitHub

工具介绍

Rust 的位级封装和解封

Bit-level packing and unpacking for Rust

Introduction

Packing and unpacking bit-level structures is usually a programming tasks that needlessly reinvents the wheel. This library provides a meta-programming approach, using attributes to define fields and how they should be packed. The resulting trait implementations provide safe packing, unpacking and runtime debugging formatters with per-field documentation generated for each structure.

Features

  • Plain Rust structures, decorated with attributes
  • MSB or LSB integers of user-defined bit widths
  • Primitive enum code generation helper
  • MSB0 or LSB0 bit positioning
  • Documents the field's packing table
  • Runtime packing visualization
  • Nested packed types
  • Arrays of packed structures as fields
  • Reserved fields, their bits are always 0 or 1

Crate-level feature flags

  • std: use the Rust standard library. Default.
  • alloc: use the alloc crate for no_std + alloc scenarios. Requires nightly Rust.
  • use_serde: add serialization support to the built-in helper types.
  • byte_types_64, byte_types_256: enlarge the size of the generated array, byte and bit width types.

Sample usage

Cargo.toml

[dependencies]
packed_struct = "0.10"

Importing the library with the the most common traits and the derive macros

// This is only needed for pre Rust 2018
#[macro_use] extern crate packed_struct;
// Prelude import with the common imports
use packed_struct::prelude::*;

Example of a single-byte structure, with a 3 bit integer, primitive enum and a bool field.

…

Packing attributes

Syntax

use packed_struct::prelude::*;

#[derive(PackedStruct)]
#[packed_struct(attr1="val", attr2="val")]
pub struct Structure {
    #[packed_field(attr1="val", attr2="val")]
    field: u8
}

Per-structure attributes

Attribute Values Comment
size_bytes 1 ... n Size of the packed byte stream
bit_numbering msb0 or lsb0 Bit numbering for bit positioning of fields. Required if the bits attribute field is used.
endian msb or lsb Default integer endianness

Per-field attributes

Attribute Values Comment
bits 0, 0..1, ... Position of the field in the packed structure. Three modes are supported: a single bit, the starting bit, or a range of bits. See details below.
bytes 0, 0..1, ... Same as above, multiplied by 8.
size_bits 1, ... Specifies the size of the packed structure. Mandatory for certain types. Specifying a range of bits like bits="0..2" can substite the required usage of size_bits.
size_bytes 1, ... Same as above, multiplied by 8.
element_size_bits 1, ... For packed arrays, specifies the size of a single element of the array. Explicitly stating the size of the entire array can substite the usage of this attribute.
element_size_bytes 1, ... Same as above, multiplied by 8.
ty enum Packing helper for primitive enums.
endian msb or lsb Integer endianness. Applies to u16/i16 and larger types.

Bit and byte positioning

Used for either bits or bytes on fields. The examples are for MSB0 positioning.

Value Comment
0 A single bit or byte
0.., 0: The field starts at bit zero
0..2 Exclusive range, bits zero and one
0:1, 0..=1 Inclusive range, bits zero and one

More examples

Mixed endian integers

use packed_struct::prelude::*;

#[derive(PackedStruct)]
pub struct EndianExample {
    #[packed_field(endian="lsb")]
    int1: u16,
    #[packed_field(endian="msb")]
    int2: i32
}

fn main() -> Result {
    let example = EndianExample {
        int1: 0xBBAA,
        int2: 0x11223344
    };

    let packed = example.pack()?;
    assert_eq!([0xAA, 0xBB, 0x11, 0x22, 0x33, 0x44], packed);
    Ok(())
}

24 bit LSB integers

use packed_struct::prelude::*;

#[derive(PackedStruct)]
#[packed_struct(endian="lsb")]
pub struct LsbIntExample {
    int1: Integer>,
}

fn main() -> Result {
    let example = LsbIntExample {
        int1: 0xCCBBAA.into()
    };

    let packed = example.pack()?;
    assert_eq!([0xAA, 0xBB, 0xCC], packed);
    Ok(())
}

Nested packed types

…

Nested packed types within arrays

…

Primitive enums with simple discriminants

Supported backing integer types: u8, u16, u32, u64, i8, i16, i32, i64.

Explicit or implicit backing type:

use packed_struct::prelude::*;

#[derive(PrimitiveEnum, Clone, Copy, PartialEq, Debug)]
pub enum ImplicitType {
    VariantMin = 0,
    VariantMax = 255
}

#[derive(PrimitiveEnum_i16, Clone, Copy)]
pub enum ExplicitType {
    VariantMin = -32768,
    VariantMax = 32767
}

fn main() {
    use packed_struct::PrimitiveEnum;

    let t = ImplicitType::VariantMin;
    let tn: u8 = t.to_primitive();
    assert_eq!(0, tn);

    let t = ImplicitType::from_primitive(255).unwrap();
    assert_eq!(ImplicitType::VariantMax, t);
}

Primitive enum packing with support for catch-all unknown values

use packed_struct::prelude::*;

#[derive(PrimitiveEnum_u8, Debug, Clone, Copy)]
pub enum Field {
    A = 1,
    B = 2,
    C = 3
}

#[derive(PackedStruct, Debug, PartialEq)]
#[packed_struct(bit_numbering="msb0")]
pub struct Register {
    #[packed_field(bits="0..4", ty="enum")]
    field: EnumCatchAll
}

License: MIT OR Apache-2.0

Issues· 0 开放

查看全部 Issues在 GitHub 打开

暂无开放 Issues,或尚未同步最近议题。

> 标签

Rust

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月18日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言