use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Write};
use crate::error::Result;
use crate::traits::{FromBinary, ToBinary};
use crate::types::Coord;
#[derive(Debug, Clone, Default)]
pub struct PcbConnection {
pub net_index: u16,
pub from_x: Coord,
pub from_y: Coord,
pub to_x: Coord,
pub to_y: Coord,
pub from_component_index: i16,
pub from_pad_index: i16,
pub to_component_index: i16,
pub to_pad_index: i16,
pub raw_data: Vec<u8>,
}
impl PcbConnection {
pub const SIZE: usize = 43;
}
impl FromBinary for PcbConnection {
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
let mut data = vec![0u8; Self::SIZE];
reader.read_exact(&mut data)?;
let mut cursor = std::io::Cursor::new(&data);
let net_index = cursor.read_u16::<LittleEndian>()?;
cursor.set_position(8);
let from_x = Coord::from_raw(cursor.read_i32::<LittleEndian>()?);
let from_y = Coord::from_raw(cursor.read_i32::<LittleEndian>()?);
let to_x = Coord::from_raw(cursor.read_i32::<LittleEndian>()?);
let to_y = Coord::from_raw(cursor.read_i32::<LittleEndian>()?);
cursor.set_position(28);
let from_component_index = cursor.read_i16::<LittleEndian>().unwrap_or(-1);
cursor.set_position(32);
let from_pad_index = cursor.read_i16::<LittleEndian>().unwrap_or(-1);
cursor.set_position(35);
let to_component_index = cursor.read_i16::<LittleEndian>().unwrap_or(-1);
cursor.set_position(39);
let to_pad_index = cursor.read_i16::<LittleEndian>().unwrap_or(-1);
Ok(PcbConnection {
net_index,
from_x,
from_y,
to_x,
to_y,
from_component_index,
from_pad_index,
to_component_index,
to_pad_index,
raw_data: data,
})
}
}
impl ToBinary for PcbConnection {
fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
if self.raw_data.len() == Self::SIZE {
writer.write_all(&self.raw_data)?;
} else {
let mut data = vec![0u8; Self::SIZE];
let mut cursor = std::io::Cursor::new(&mut data[..]);
cursor.write_u16::<LittleEndian>(self.net_index)?;
cursor.set_position(4);
cursor.write_all(&[0xFF; 4])?;
cursor.write_i32::<LittleEndian>(self.from_x.to_raw())?;
cursor.write_i32::<LittleEndian>(self.from_y.to_raw())?;
cursor.write_i32::<LittleEndian>(self.to_x.to_raw())?;
cursor.write_i32::<LittleEndian>(self.to_y.to_raw())?;
writer.write_all(&data)?;
}
Ok(())
}
fn binary_size(&self) -> usize {
Self::SIZE
}
}