byteable/lib.rs
1//! # Byteable
2//!
3//! A Rust crate for converting Rust types to and from byte arrays, facilitating
4//! easy serialization and deserialization, especially for network protocols or
5//! embedded systems. It provides traits for working with byte arrays,
6//! byteable types, and handling endianness.
7//!
8//! ## Features
9//! - `derive`: Enables the `Byteable` derive macro for automatic implementation of the `Byteable` trait.
10//! - `tokio`: Provides asynchronous read and write capabilities using `tokio`'s I/O traits.
11//!
12//! ## Usage
13//!
14//! ### Basic Byteable Conversion
15//!
16//! Implement the `Byteable` trait manually or use the `#[derive(Byteable)]` macro (with the `derive` feature enabled):
17//!
18//! ```rust
19//! use byteable::{Byteable, ReadByteable, WriteByteable, LittleEndian};
20//! use std::io::Cursor;
21//!
22//! #[derive(Byteable, Clone, Copy, PartialEq, Debug)]
23//! #[repr(C, packed)]
24//! struct MyPacket {
25//! id: u16,
26//! value: LittleEndian<u32>,
27//! }
28//!
29//! let packet = MyPacket {
30//! id: 123,
31//! value: LittleEndian::new(0x01020304),
32//! };
33//!
34//! // Convert to byte array
35//! let byte_array = packet.as_bytearray();
36//!
37//! // Write to a writer. Cursor implements `std::io::Write`,
38//! // thus it gains `write_one` from `WriteByteable`.
39//! let mut buffer = Cursor::new(vec![]);
40//! buffer.write_one(packet).unwrap();
41//! assert_eq!(buffer.into_inner(), vec![123, 0, 4, 3, 2, 1]);
42//!
43//! // Read from a reader. Cursor implements `std::io::Read`,
44//! // thus it gains `read_one` from `ReadByteable`.
45//! let mut reader = Cursor::new(vec![123, 0, 4, 3, 2, 1]);
46//! let read_packet: MyPacket = reader.read_one().unwrap();
47//! assert_eq!(read_packet, packet);
48//! ```
49//!
50//! ### Endianness Handling
51//!
52//! Use `BigEndian<T>` or `LittleEndian<T>` wrappers to control the byte order of primitive types.
53//!
54//! ```rust
55//! use byteable::{BigEndian, LittleEndian, Endianable};
56//!
57//! let value_be = BigEndian::new(0x01020304u32);
58//! assert_eq!(value_be.get_raw().to_ne_bytes(), [1, 2, 3, 4]);
59//!
60//! let value_le = LittleEndian::new(0x01020304u32);
61//! assert_eq!(value_le.get_raw().to_ne_bytes(), [4, 3, 2, 1]);
62//! ```
63//!
64//! ### Asynchronous I/O (with `tokio` feature)
65//!
66//! ```rust
67//! #[cfg(feature = "tokio")]
68//! async fn async_example() -> std::io::Result<()> {
69//! use byteable::{Byteable, AsyncReadByteable, AsyncWriteByteable, LittleEndian};
70//! use std::io::Cursor;
71//!
72//! #[derive(Byteable, Clone, Copy, PartialEq, Debug)]
73//! #[repr(C, packed)]
74//! struct AsyncPacket {
75//! sequence: u8,
76//! data: LittleEndian<u16>,
77//! }
78//!
79//! let packet = AsyncPacket {
80//! sequence: 5,
81//! data: LittleEndian::new(0xAABB),
82//! };
83//!
84//! let mut buffer = Cursor::new(vec![]);
85//! buffer.write_one(packet).await?;
86//! assert_eq!(buffer.into_inner(), vec![5, 0xBB, 0xAA]);
87//!
88//! let mut reader = Cursor::new(vec![5, 0xBB, 0xAA]);
89//! let read_packet: AsyncPacket = reader.read_one().await?;
90//! assert_eq!(read_packet, packet);
91//! Ok(())
92//! }
93//! ```
94
95// Submodules
96mod byte_array;
97mod byteable;
98mod endian;
99mod io;
100
101#[cfg(feature = "tokio")]
102mod async_io;
103
104// Re-export derive macro
105#[cfg(feature = "derive")]
106pub use byteable_derive::Byteable;
107
108// Re-export from byte_array module
109pub use byte_array::ByteableByteArray;
110
111// Re-export from byteable module
112pub use byteable::{Byteable, ByteableRaw, ByteableRegular};
113
114// Re-export from io module
115pub use io::{ReadByteable, WriteByteable};
116
117// Re-export from async_io module (when tokio feature is enabled)
118#[cfg(feature = "tokio")]
119pub use async_io::{AsyncReadByteable, AsyncWriteByteable};
120
121// Re-export from endian module
122pub use endian::{BigEndian, Endianable, LittleEndian};