1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
//! Simple & fast bit-level binary co/dec in Rust.
//!
//! For more information about `#[derive(Protocol)]` and its attributes, see [macro@Protocol].
//!
//! # Example
//!
//! ```
//! # use bin_proto::Protocol;
//! #[derive(Debug, Protocol, PartialEq)]
//! #[protocol(discriminant_type = "u8")]
//! #[protocol(bits = 4)]
//! enum E {
//! V1 = 1,
//! #[protocol(discriminant = "4")]
//! V4,
//! }
//!
//! #[derive(Debug, Protocol, PartialEq)]
//! struct S {
//! #[protocol(bits = 1)]
//! bitflag: bool,
//! #[protocol(bits = 3)]
//! bitfield: u8,
//! enum_: E,
//! #[protocol(write_value = "self.arr.len() as u8")]
//! arr_len: u8,
//! #[protocol(length = "arr_len as usize")]
//! arr: Vec<u8>,
//! #[protocol(flexible_array_member)]
//! read_to_end: Vec<u8>,
//! }
//!
//! assert_eq!(
//! S::from_bytes(&[
//! 0b1000_0000 // bitflag: true (1)
//! | 0b101_0000 // bitfield: 5 (101)
//! | 0b0001, // enum_: V1 (0001)
//! 0x02, // arr_len: 2
//! 0x21, 0x37, // arr: [0x21, 0x37]
//! 0x01, 0x02, 0x03, // read_to_end: [0x01, 0x02, 0x03]
//! ], bin_proto::ByteOrder::BigEndian).unwrap(),
//! S {
//! bitflag: true,
//! bitfield: 5,
//! enum_: E::V1,
//! arr_len: 2,
//! arr: vec![0x21, 0x37],
//! read_to_end: vec![0x01, 0x02, 0x03],
//! }
//! );
//! ```
pub use self::bit_field::BitField;
pub use self::bit_read::BitRead;
pub use self::bit_write::BitWrite;
pub use self::byte_order::ByteOrder;
pub use self::enum_ext::EnumExt;
pub use self::error::{Error, Result};
pub use self::externally_length_prefixed::ExternallyLengthPrefixed;
pub use self::flexible_array_member::FlexibleArrayMember;
pub use self::protocol::Protocol;
/// Derive the `Protocol` trait.
///
/// # Attributes
///
/// ## `#[protocol(discriminant_type = "<type>")]`
/// - Applies to: `enum` with `#[derive(Protocol)]`.
/// - `<type>`: an arbitrary type that implements `Protocol`
///
/// Specify if enum variant should be determined by a string or interger
/// representation of its discriminant.
///
/// ```
/// # use bin_proto::Protocol;
/// #[derive(Protocol)]
/// #[protocol(discriminant_type = "u8")]
/// enum Example {
/// Variant1 = 1,
/// Variant5 = 5,
/// }
/// ```
///
/// ## `#[protocol(discriminant = "<value>")]`
/// - Applies to: `enum` variant
/// - `<value>`: unique value of the discriminant's type
///
/// ```
/// # use bin_proto::Protocol;
/// #[derive(Protocol)]
/// #[protocol(discriminant_type = "u8")]
/// enum Example {
/// #[protocol(discriminant = "1")]
/// Variant1,
/// Variant5 = 5,
/// }
/// ```
///
/// Specify the discriminant for a variant.
///
/// ## `#[protocol(bits = <width>)]`
/// - Applies to: `impl BitField`, `enum` with discriminant that `impl BitField`
///
/// Determine width of field in bits.
///
/// **WARNING**: Bitfields disregard ByteOrder and instead have the same
/// endianness as the underlying `BitRead` / `BitWrite` instance. If you're
/// using bitfields, you almost always want a big endian stream.
///
/// ```
/// # use bin_proto::Protocol;
/// #[derive(Protocol)]
/// struct Nibble(#[protocol(bits = 4)] u8);
/// ```
///
/// ## `#[protocol(flexible_array_member)]`
/// - Applies to: `impl FlexibleArrayMember`
///
/// Variable-length field is final field in container, hence lacks a length
/// prefix and should be read until eof.
///
/// ```
/// # use bin_proto::Protocol;
/// #[derive(Protocol)]
/// struct ReadToEnd(#[protocol(flexible_array_member)] Vec<u8>);
/// ```
///
/// ## `#[protocol(length = "<expr>")]`
/// - Applies to: `impl ExternallyLengthPrefixed`
/// - `<expr>`: arbitrary `usize` expression. Fields in parent container can be
/// used without prefixing them with `self`.
///
/// Specify length of variable-length field.
///
/// ```
/// # use bin_proto::Protocol;
/// #[derive(Protocol)]
/// pub struct WithElementsLength {
/// pub count: u32,
/// pub foo: bool,
/// #[protocol(length = "count as usize")]
/// pub data: Vec<u32>,
/// }
/// ```
///
/// ## `#[protocol(write_value = "<expr>")]`
/// - Applies to: fields
/// - `<expr>`: An expression that can be coerced to the field type, potentially
/// using `self`
///
/// Specify an expression that should be used as the field's value for writing.
///
/// ```
/// # use bin_proto::Protocol;
/// #[derive(Protocol)]
/// pub struct WithElementsLengthAuto {
/// #[protocol(write_value = "self.data.len() as u32")]
/// pub count: u32,
/// pub foo: bool,
/// #[protocol(length = "count as usize")]
/// pub data: Vec<u32>,
/// }
/// ```
#[cfg(feature = "derive")]
pub use bin_proto_derive::Protocol;
mod bit_field;
mod bit_read;
mod bit_write;
#[macro_use]
mod externally_length_prefixed;
mod byte_order;
mod flexible_array_member;
mod types;
mod enum_ext;
mod error;
#[macro_use]
mod protocol;
mod util;
pub extern crate bitstream_io;
/// ```compile_fail
/// #[derive(bin_proto::Protocol)]
/// struct MutuallyExclusiveAttrs {
/// pub length: u8,
/// #[protocol(flexible_array_member)]
/// #[protocol(length = "length as usize")]
/// pub reason: String,
/// }
/// ```
#[cfg(all(feature = "derive", doctest))]
#[allow(unused)]
fn compile_fail_if_multiple_exclusive_attrs() {}