ReadByteable

Trait ReadByteable 

Source
pub trait ReadByteable: Read {
    // Provided method
    fn read_one<T: Byteable>(&mut self) -> Result<T> { ... }
}
Expand description

Extends std::io::Read with a method to read a Byteable type.

Provided Methods§

Source

fn read_one<T: Byteable>(&mut self) -> Result<T>

Reads one Byteable element from the reader.

This method will create a zero-filled byte array, read enough bytes from the underlying reader to fill it, and then convert the byte array into the specified Byteable type.

Examples found in repository?
examples/file_io.rs (line 107)
48fn main() -> io::Result<()> {
49    println!("=== Byteable Derive Macro Example ===\n");
50
51    // Example 1: Creating and inspecting a byteable struct
52    println!("1. Creating a NetworkPacket:");
53    let packet = NetworkPacket {
54        sequence: 42,
55        packet_type: LittleEndian::new(0x1234),
56        payload_length: BigEndian::new(1024),
57        timestamp: LittleEndian::new(1638360000),
58    };
59
60    println!("   Packet: {:?}", packet);
61    println!("   Sequence: {}", packet.sequence);
62    println!("   Packet Type: 0x{:04X}", packet.packet_type.get());
63    println!("   Payload Length: {} bytes", packet.payload_length.get());
64    println!("   Timestamp: {}", packet.timestamp.get());
65
66    // Convert to byte array
67    let bytes = packet.as_bytearray();
68    println!("   As bytes: {:?}", bytes);
69    println!("   Size: {} bytes\n", bytes.len());
70
71    // Example 2: Writing to a file
72    println!("2. Writing structs to a file:");
73    let mut file = File::create("example_data.bin")?;
74
75    // Write multiple packets
76    file.write_one(packet)?;
77
78    let packet2 = NetworkPacket {
79        sequence: 43,
80        packet_type: LittleEndian::new(0x5678),
81        payload_length: BigEndian::new(2048),
82        timestamp: LittleEndian::new(1638360001),
83    };
84    file.write_one(packet2)?;
85
86    // Write a device config
87    let config = DeviceConfig {
88        device_id: LittleEndian::new(0xABCDEF01),
89        version: 1,
90        flags: 0b10101010,
91        port: BigEndian::new(8080),
92        calibration: LittleEndian::new(3.14159),
93    };
94    file.write_one(config)?;
95
96    println!("   Written 2 NetworkPackets and 1 DeviceConfig to 'example_data.bin'");
97    println!(
98        "   File size: {} bytes\n",
99        std::mem::size_of::<NetworkPacket>() * 2 + std::mem::size_of::<DeviceConfig>()
100    );
101
102    // Example 3: Reading from a file
103    println!("3. Reading structs from the file:");
104    let mut file = File::open("example_data.bin")?;
105
106    // Read the packets back
107    let read_packet1: NetworkPacket = file.read_one()?;
108    let read_packet2: NetworkPacket = file.read_one()?;
109    let read_config: DeviceConfig = file.read_one()?;
110
111    println!("   First packet: {:?}", read_packet1);
112    println!("   Matches original: {}", read_packet1 == packet);
113    println!();
114
115    println!("   Second packet: {:?}", read_packet2);
116    println!("   Sequence: {}", read_packet2.sequence);
117    println!();
118
119    println!("   Device config: {:?}", read_config);
120    println!("   Device ID: 0x{:08X}", read_config.device_id.get());
121    println!("   Version: {}", read_config.version);
122    println!("   Flags: 0b{:08b}", read_config.flags);
123    println!("   Port: {}", read_config.port.get());
124    println!("   Calibration: {:.5}", read_config.calibration.get());
125    println!();
126
127    // Example 4: Random access with seek
128    println!("4. Random access with seek:");
129    file.seek(SeekFrom::Start(0))?;
130    let first: NetworkPacket = file.read_one()?;
131    println!("   Read first packet again: sequence = {}", first.sequence);
132
133    // Seek to the second packet
134    file.seek(SeekFrom::Start(std::mem::size_of::<NetworkPacket>() as u64))?;
135    let second: NetworkPacket = file.read_one()?;
136    println!("   Seeked to second packet: sequence = {}", second.sequence);
137    println!();
138
139    // Example 5: Demonstrating byte array conversion
140    println!("5. Manual byte array conversion:");
141    let test_packet = NetworkPacket {
142        sequence: 100,
143        packet_type: LittleEndian::new(0xFF00),
144        payload_length: BigEndian::new(512),
145        timestamp: LittleEndian::new(999999),
146    };
147
148    // Convert to bytes
149    let byte_array = test_packet.as_bytearray();
150    println!("   Original packet: {:?}", test_packet);
151    println!("   Byte array: {:?}", byte_array);
152
153    // Convert back from bytes
154    let reconstructed = NetworkPacket::from_bytearray(byte_array);
155    println!("   Reconstructed: {:?}", reconstructed);
156    println!("   Round-trip successful: {}", test_packet == reconstructed);
157
158    // Cleanup
159    println!("\n=== Example completed successfully! ===");
160    println!("Note: The file 'example_data.bin' has been created in the current directory.");
161
162    Ok(())
163}
More examples
Hide additional examples
examples/cursor_usage.rs (line 73)
39fn main() -> std::io::Result<()> {
40    println!("=== Cursor-based Byteable Example ===\n");
41
42    // Example 1: Writing to a cursor (in-memory buffer)
43    println!("1. Writing messages to an in-memory buffer:");
44
45    let header = MessageHeader {
46        magic: *b"DEMO",
47        version: 1,
48        message_type: 0x01,
49        payload_length: BigEndian::new(16),
50        sequence_number: LittleEndian::new(1001),
51    };
52
53    let login = LoginRequest {
54        user_id: LittleEndian::new(42),
55        session_token: LittleEndian::new(0x1234567890ABCDEF),
56        flags: 0b00001111,
57        padding: [0; 3],
58    };
59
60    // Write to cursor
61    let mut buffer = Cursor::new(Vec::new());
62    buffer.write_one(header)?;
63    buffer.write_one(login)?;
64
65    let bytes = buffer.into_inner();
66    println!("   Written {} bytes", bytes.len());
67    println!("   Buffer contents: {:02X?}\n", bytes);
68
69    // Example 2: Reading from a cursor
70    println!("2. Reading messages from the buffer:");
71    let mut reader = Cursor::new(bytes.clone());
72
73    let read_header: MessageHeader = reader.read_one()?;
74    let read_login: LoginRequest = reader.read_one()?;
75
76    println!("   Header:");
77    println!(
78        "      Magic: {}",
79        std::str::from_utf8(&read_header.magic).unwrap_or("???")
80    );
81    println!("      Version: {}", read_header.version);
82    println!("      Message Type: 0x{:02X}", read_header.message_type);
83    println!(
84        "      Payload Length: {} bytes",
85        read_header.payload_length.get()
86    );
87    println!(
88        "      Sequence Number: {}",
89        read_header.sequence_number.get()
90    );
91
92    println!("\n   Login Request:");
93    println!("      User ID: {}", read_login.user_id.get());
94    println!(
95        "      Session Token: 0x{:016X}",
96        read_login.session_token.get()
97    );
98    println!("      Flags: 0b{:08b}", read_login.flags);
99
100    println!(
101        "\n   Data matches: {}\n",
102        read_header == header && read_login == login
103    );
104
105    // Example 3: Building a packet with multiple messages
106    println!("3. Building a multi-message packet:");
107
108    let mut packet = Cursor::new(Vec::new());
109
110    // Write three different messages
111    let headers = [
112        MessageHeader {
113            magic: *b"MSG1",
114            version: 1,
115            message_type: 0x10,
116            payload_length: BigEndian::new(16),
117            sequence_number: LittleEndian::new(100),
118        },
119        MessageHeader {
120            magic: *b"MSG2",
121            version: 1,
122            message_type: 0x20,
123            payload_length: BigEndian::new(16),
124            sequence_number: LittleEndian::new(101),
125        },
126        MessageHeader {
127            magic: *b"MSG3",
128            version: 1,
129            message_type: 0x30,
130            payload_length: BigEndian::new(16),
131            sequence_number: LittleEndian::new(102),
132        },
133    ];
134
135    for header in &headers {
136        packet.write_one(*header)?;
137    }
138
139    let packet_bytes = packet.into_inner();
140    println!("   Packet size: {} bytes", packet_bytes.len());
141    println!(
142        "   Messages per packet: {}",
143        packet_bytes.len() / std::mem::size_of::<MessageHeader>()
144    );
145
146    // Read them back
147    let mut reader = Cursor::new(packet_bytes);
148    println!("\n   Reading messages:");
149    for i in 0..3 {
150        let msg: MessageHeader = reader.read_one()?;
151        println!(
152            "      Message {}: {} (type: 0x{:02X}, seq: {})",
153            i + 1,
154            std::str::from_utf8(&msg.magic).unwrap_or("???"),
155            msg.message_type,
156            msg.sequence_number.get()
157        );
158    }
159
160    // Example 4: Working with status responses
161    println!("\n4. Status response example:");
162
163    let status = StatusResponse {
164        status_code: BigEndian::new(200),
165        timestamp: LittleEndian::new(1700000000),
166        reserved: [0; 6],
167    };
168
169    let mut status_buffer = Cursor::new(Vec::new());
170    status_buffer.write_one(status)?;
171
172    let status_bytes = status_buffer.into_inner();
173    println!("   Status response bytes: {:?}", status_bytes);
174
175    let mut status_reader = Cursor::new(status_bytes);
176    let read_status: StatusResponse = status_reader.read_one()?;
177
178    println!("   Status Code: {}", read_status.status_code.get());
179    println!("   Timestamp: {}", read_status.timestamp.get());
180    println!("   Matches original: {}", read_status == status);
181
182    println!("\n=== Example completed successfully! ===");
183    Ok(())
184}

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<T: Read> ReadByteable for T

Implements ReadByteable for all types that implement std::io::Read.