{"id":20047239,"url":"https://github.com/wojciech-graj/bin-proto","last_synced_at":"2025-05-05T10:31:14.739Z","repository":{"id":229712758,"uuid":"777472456","full_name":"wojciech-graj/bin-proto","owner":"wojciech-graj","description":"Simple bit-level protocol definitions in Rust.","archived":false,"fork":false,"pushed_at":"2025-04-15T13:31:26.000Z","size":671,"stargazers_count":22,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-28T10:03:01.465Z","etag":null,"topics":["binary-protocol","bit","bitfield","bitstream","codec","protocol","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wojciech-graj.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-25T23:04:49.000Z","updated_at":"2025-04-15T13:31:30.000Z","dependencies_parsed_at":"2024-03-29T23:33:38.335Z","dependency_job_id":"7095f9c2-2104-4d23-9e09-82b064c87d22","html_url":"https://github.com/wojciech-graj/bin-proto","commit_stats":null,"previous_names":["wojciech-graj/bin-proto"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wojciech-graj%2Fbin-proto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wojciech-graj%2Fbin-proto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wojciech-graj%2Fbin-proto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wojciech-graj%2Fbin-proto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wojciech-graj","download_url":"https://codeload.github.com/wojciech-graj/bin-proto/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252480425,"owners_count":21754774,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binary-protocol","bit","bitfield","bitstream","codec","protocol","rust"],"created_at":"2024-11-13T11:34:43.473Z","updated_at":"2025-05-05T10:31:14.732Z","avatar_url":"https://github.com/wojciech-graj.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bin-proto\n\n[![crates](https://img.shields.io/crates/v/bin-proto.svg)](https://crates.io/crates/bin-proto)\n[![tests](https://github.com/wojciech-graj/bin-proto/actions/workflows/ci.yml/badge.svg)](https://github.com/wojciech-graj/bin-proto/actions/workflows/ci.yml)\n[![docs.rs](https://docs.rs/bin-proto/badge.svg)](https://docs.rs/bin-proto)\n![msrv](https://img.shields.io/crates/msrv/bin-proto)\n[![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE.txt)\n\nSimple \u0026 fast structured bit-level binary co/dec in Rust.\n\nAn improved and modernized fork of\n[protocol](https://crates.io/crates/protocol). A more efficient but (slightly)\nless feature-rich alternative to [deku](https://crates.io/crates/deku).\n\nThis crate adds a trait (and a custom derive for ease-of-use) that can be\nimplemented on types, allowing structured data to be sent and received from any\nbinary stream. It is recommended to use\n[bitstream_io](https://docs.rs/bitstream-io/latest/bitstream_io/) if you need\nbit streams, as their `BitRead` and `BitWrite` traits are being used internally.\n\n## Example\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nbin-proto = \"0.8\"\n```\n\nAnd then define a type with the `#[derive(bin_proto::BitDecode, bin_proto::BitEncode)]` attributes.\n\n```rust\nuse bin_proto::{BitDecode, BitEncode, BitCodec};\n\n#[derive(Debug, BitDecode, BitEncode, PartialEq)]\n#[codec(discriminant_type = u8)]\n#[codec(bits = 4)]\nenum E {\n    V1 = 1,\n    #[codec(discriminant = 4)]\n    V4,\n}\n\n#[derive(Debug, BitDecode, BitEncode, PartialEq)]\nstruct S {\n    #[codec(bits = 1)]\n    bitflag: bool,\n    #[codec(bits = 3)]\n    bitfield: u8,\n    enum_: E,\n    #[codec(write_value = self.arr.len() as u8)]\n    arr_len: u8,\n    #[codec(tag = arr_len as usize)]\n    arr: Vec\u003cu8\u003e,\n    #[codec(tag_type = u16, tag_value = self.prefixed_arr.len() as u16)]\n    prefixed_arr: Vec\u003cu8\u003e,\n    #[codec(flexible_array_member)]\n    read_to_end: Vec\u003cu8\u003e,\n}\n\nassert_eq!(\n    S::decode_bytes(\u0026[\n        0b1000_0000 // bitflag: true (1)\n       | 0b101_0000 // bitfield: 5 (101)\n           | 0b0001, // enum_: V1 (0001)\n        0x02, // arr_len: 2\n        0x21, 0x37, // arr: [0x21, 0x37]\n        0x00, 0x01, 0x33, // prefixed_arr: [0x33]\n        0x01, 0x02, 0x03, // read_to_end: [0x01, 0x02, 0x03]\n    ], bin_proto::BigEndian).unwrap(),\n    S {\n        bitflag: true,\n        bitfield: 5,\n        enum_: E::V1,\n        arr_len: 2,\n        arr: vec![0x21, 0x37],\n        prefixed_arr: vec![0x33],\n        read_to_end: vec![0x01, 0x02, 0x03],\n    }\n);\n```\n\nYou can implement `BitEncode` and `BitDecode` on your own types, and parse with context:\n\n```rust\nuse bin_proto::{BitDecode, BitEncode};\n\npub struct Ctx;\n\npub struct NeedsCtx;\n\nimpl BitDecode\u003cCtx\u003e for NeedsCtx {\n    fn decode\u003cR, E\u003e(\n        _read: \u0026mut R,\n        _ctx: \u0026mut Ctx,\n        _tag: (),\n    ) -\u003e bin_proto::Result\u003cSelf\u003e\n    where\n        R: bin_proto::BitRead,\n        E: bin_proto::Endianness,\n    {\n        // Use ctx here\n        Ok(Self)\n    }\n}\n\nimpl BitEncode\u003cCtx\u003e for NeedsCtx {\n    fn encode\u003cW, E\u003e(\n        \u0026self,\n        _write: \u0026mut W,\n        _ctx: \u0026mut Ctx,\n        _tag: (),\n    ) -\u003e bin_proto::Result\u003c()\u003e\n    where\n        W: bin_proto::BitWrite,\n        E: bin_proto::Endianness,\n    {\n        // Use ctx here\n        Ok(())\n    }\n}\n\n#[derive(BitDecode, BitEncode)]\n#[codec(ctx = Ctx)]\npub struct WithCtx(NeedsCtx);\n\nWithCtx(NeedsCtx)\n    .encode_bytes_ctx(bin_proto::BigEndian, \u0026mut Ctx, ())\n    .unwrap();\n```\n\n## Performance / Alternatives\n\nThis crate's main alternative is [deku](https://crates.io/crates/deku), and [binrw](https://crates.io/crates/binrw) for byte-level protocols.\n\nSee [GitHub Actions](https://github.com/wojciech-graj/bin-proto/actions) for latest benchmark results with comparison against deku.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwojciech-graj%2Fbin-proto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwojciech-graj%2Fbin-proto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwojciech-graj%2Fbin-proto/lists"}