WriteByteable

Trait WriteByteable 

Source
pub trait WriteByteable: Write {
    // Provided method
    fn write_one<T: Byteable>(&mut self, data: T) -> Result<()> { ... }
}
Expand description

Extends std::io::Write with a method to write a Byteable type.

Provided Methods§

Source

fn write_one<T: Byteable>(&mut self, data: T) -> Result<()>

Writes one Byteable element to the writer.

This method will convert the Byteable data into its byte array representation and then write all those bytes to the underlying writer.

Examples found in repository?
examples/file_io.rs (line 76)
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 62)
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: Write> WriteByteable for T

Implements WriteByteable for all types that implement std::io::Write.