Skip to main content

altium_format/traits/
binary.rs

1//! Binary serialization traits for PCB records.
2
3use crate::error::Result;
4use std::io::{Read, Write};
5
6/// Import a type from a binary stream.
7///
8/// This trait is automatically implemented by the `AltiumRecord` derive macro
9/// for binary-based record types (PCB records).
10pub trait FromBinary: Sized {
11    /// Read this type from a binary stream.
12    fn read_from<R: Read>(reader: &mut R) -> Result<Self>;
13
14    /// Read this type and preserve remaining bytes for non-destructive editing.
15    ///
16    /// The `block_size` parameter indicates the total size of the data block,
17    /// allowing remaining bytes to be captured.
18    fn read_from_preserving<R: Read>(
19        reader: &mut R,
20        _block_size: usize,
21    ) -> Result<(Self, Vec<u8>)> {
22        let value = Self::read_from(reader)?;
23        Ok((value, Vec::new()))
24    }
25}
26
27/// Export a type to a binary stream.
28///
29/// This trait is automatically implemented by the `AltiumRecord` derive macro
30/// for binary-based record types (PCB records).
31pub trait ToBinary {
32    /// Write this type to a binary stream.
33    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()>;
34
35    /// Calculate the binary size of this type.
36    ///
37    /// Used for writing block headers that include size information.
38    fn binary_size(&self) -> usize;
39}
40
41// Basic type implementations
42
43impl FromBinary for i8 {
44    fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
45        use byteorder::ReadBytesExt;
46        Ok(reader.read_i8()?)
47    }
48}
49
50impl ToBinary for i8 {
51    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
52        use byteorder::WriteBytesExt;
53        writer.write_i8(*self)?;
54        Ok(())
55    }
56
57    fn binary_size(&self) -> usize {
58        1
59    }
60}
61
62impl FromBinary for u8 {
63    fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
64        use byteorder::ReadBytesExt;
65        Ok(reader.read_u8()?)
66    }
67}
68
69impl ToBinary for u8 {
70    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
71        use byteorder::WriteBytesExt;
72        writer.write_u8(*self)?;
73        Ok(())
74    }
75
76    fn binary_size(&self) -> usize {
77        1
78    }
79}
80
81impl FromBinary for i16 {
82    fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
83        use byteorder::{LittleEndian, ReadBytesExt};
84        Ok(reader.read_i16::<LittleEndian>()?)
85    }
86}
87
88impl ToBinary for i16 {
89    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
90        use byteorder::{LittleEndian, WriteBytesExt};
91        writer.write_i16::<LittleEndian>(*self)?;
92        Ok(())
93    }
94
95    fn binary_size(&self) -> usize {
96        2
97    }
98}
99
100impl FromBinary for u16 {
101    fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
102        use byteorder::{LittleEndian, ReadBytesExt};
103        Ok(reader.read_u16::<LittleEndian>()?)
104    }
105}
106
107impl ToBinary for u16 {
108    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
109        use byteorder::{LittleEndian, WriteBytesExt};
110        writer.write_u16::<LittleEndian>(*self)?;
111        Ok(())
112    }
113
114    fn binary_size(&self) -> usize {
115        2
116    }
117}
118
119impl FromBinary for i32 {
120    fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
121        use byteorder::{LittleEndian, ReadBytesExt};
122        Ok(reader.read_i32::<LittleEndian>()?)
123    }
124}
125
126impl ToBinary for i32 {
127    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
128        use byteorder::{LittleEndian, WriteBytesExt};
129        writer.write_i32::<LittleEndian>(*self)?;
130        Ok(())
131    }
132
133    fn binary_size(&self) -> usize {
134        4
135    }
136}
137
138impl FromBinary for u32 {
139    fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
140        use byteorder::{LittleEndian, ReadBytesExt};
141        Ok(reader.read_u32::<LittleEndian>()?)
142    }
143}
144
145impl ToBinary for u32 {
146    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
147        use byteorder::{LittleEndian, WriteBytesExt};
148        writer.write_u32::<LittleEndian>(*self)?;
149        Ok(())
150    }
151
152    fn binary_size(&self) -> usize {
153        4
154    }
155}
156
157impl FromBinary for i64 {
158    fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
159        use byteorder::{LittleEndian, ReadBytesExt};
160        Ok(reader.read_i64::<LittleEndian>()?)
161    }
162}
163
164impl ToBinary for i64 {
165    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
166        use byteorder::{LittleEndian, WriteBytesExt};
167        writer.write_i64::<LittleEndian>(*self)?;
168        Ok(())
169    }
170
171    fn binary_size(&self) -> usize {
172        8
173    }
174}
175
176impl FromBinary for u64 {
177    fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
178        use byteorder::{LittleEndian, ReadBytesExt};
179        Ok(reader.read_u64::<LittleEndian>()?)
180    }
181}
182
183impl ToBinary for u64 {
184    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
185        use byteorder::{LittleEndian, WriteBytesExt};
186        writer.write_u64::<LittleEndian>(*self)?;
187        Ok(())
188    }
189
190    fn binary_size(&self) -> usize {
191        8
192    }
193}
194
195impl FromBinary for f32 {
196    fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
197        use byteorder::{LittleEndian, ReadBytesExt};
198        Ok(reader.read_f32::<LittleEndian>()?)
199    }
200}
201
202impl ToBinary for f32 {
203    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
204        use byteorder::{LittleEndian, WriteBytesExt};
205        writer.write_f32::<LittleEndian>(*self)?;
206        Ok(())
207    }
208
209    fn binary_size(&self) -> usize {
210        4
211    }
212}
213
214impl FromBinary for f64 {
215    fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
216        use byteorder::{LittleEndian, ReadBytesExt};
217        Ok(reader.read_f64::<LittleEndian>()?)
218    }
219}
220
221impl ToBinary for f64 {
222    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
223        use byteorder::{LittleEndian, WriteBytesExt};
224        writer.write_f64::<LittleEndian>(*self)?;
225        Ok(())
226    }
227
228    fn binary_size(&self) -> usize {
229        8
230    }
231}
232
233impl FromBinary for bool {
234    fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
235        use byteorder::ReadBytesExt;
236        Ok(reader.read_u8()? != 0)
237    }
238}
239
240impl ToBinary for bool {
241    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
242        use byteorder::WriteBytesExt;
243        writer.write_u8(if *self { 1 } else { 0 })?;
244        Ok(())
245    }
246
247    fn binary_size(&self) -> usize {
248        1
249    }
250}