use bitflags::bitflags;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::io::{Read, Write};
use crate::error::Result;
use crate::traits::{FromBinary, ToBinary};
use crate::types::{Coord, CoordPoint, CoordRect, Layer};
use altium_format_derive::AltiumRecord;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum PcbObjectId {
#[default]
None = 0,
Arc = 1,
Pad = 2,
Via = 3,
Track = 4,
Text = 5,
Fill = 6,
Connection = 7,
Net = 8,
Component = 9,
Polygon = 10,
Region = 11,
ComponentBody = 12,
Dimension = 13,
Coordinate = 14,
Class = 15,
Rule = 16,
FromTo = 17,
DifferentialPair = 18,
Violation = 19,
Embedded = 20,
EmbeddedBoard = 21,
Board = 24,
BoardOutline = 25,
}
impl PcbObjectId {
pub fn from_byte(value: u8) -> Self {
match value {
0 => PcbObjectId::None,
1 => PcbObjectId::Arc,
2 => PcbObjectId::Pad,
3 => PcbObjectId::Via,
4 => PcbObjectId::Track,
5 => PcbObjectId::Text,
6 => PcbObjectId::Fill,
7 => PcbObjectId::Connection,
8 => PcbObjectId::Net,
9 => PcbObjectId::Component,
10 => PcbObjectId::Polygon,
11 => PcbObjectId::Region,
12 => PcbObjectId::ComponentBody,
13 => PcbObjectId::Dimension,
14 => PcbObjectId::Coordinate,
15 => PcbObjectId::Class,
16 => PcbObjectId::Rule,
17 => PcbObjectId::FromTo,
18 => PcbObjectId::DifferentialPair,
19 => PcbObjectId::Violation,
20 => PcbObjectId::Embedded,
21 => PcbObjectId::EmbeddedBoard,
24 => PcbObjectId::Board,
25 => PcbObjectId::BoardOutline,
_ => PcbObjectId::None,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
PcbObjectId::None => "None",
PcbObjectId::Arc => "Arc",
PcbObjectId::Pad => "Pad",
PcbObjectId::Via => "Via",
PcbObjectId::Track => "Track",
PcbObjectId::Text => "Text",
PcbObjectId::Fill => "Fill",
PcbObjectId::Connection => "Connection",
PcbObjectId::Net => "Net",
PcbObjectId::Component => "Component",
PcbObjectId::Polygon => "Polygon",
PcbObjectId::Region => "Region",
PcbObjectId::ComponentBody => "ComponentBody",
PcbObjectId::Dimension => "Dimension",
PcbObjectId::Coordinate => "Coordinate",
PcbObjectId::Class => "Class",
PcbObjectId::Rule => "Rule",
PcbObjectId::FromTo => "FromTo",
PcbObjectId::DifferentialPair => "DifferentialPair",
PcbObjectId::Violation => "Violation",
PcbObjectId::Embedded => "Embedded",
PcbObjectId::EmbeddedBoard => "EmbeddedBoard",
PcbObjectId::Board => "Board",
PcbObjectId::BoardOutline => "BoardOutline",
}
}
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PcbFlags: u16 {
const UNKNOWN2 = 2;
const UNLOCKED = 4;
const UNKNOWN8 = 8;
const UNKNOWN16 = 16;
const TENTING_TOP = 32;
const TENTING_BOTTOM = 64;
const FABRICATION_TOP = 128;
const FABRICATION_BOTTOM = 256;
const KEEPOUT = 512;
}
}
impl Default for PcbFlags {
fn default() -> Self {
PcbFlags::UNLOCKED | PcbFlags::UNKNOWN8
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum PcbStackMode {
#[default]
Simple = 0,
TopMiddleBottom = 1,
FullStack = 2,
}
impl PcbStackMode {
pub fn from_byte(value: u8) -> Self {
match value {
0 => PcbStackMode::Simple,
1 => PcbStackMode::TopMiddleBottom,
2 => PcbStackMode::FullStack,
_ => PcbStackMode::Simple,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum PcbPadShape {
NoShape = 0,
#[default]
Round = 1,
Rectangular = 2,
Octagonal = 3,
Circle = 4,
Arc = 5,
Terminator = 6,
RoundRect = 7,
RotatedRect = 8,
RoundedRectangle = 9,
}
impl PcbPadShape {
pub fn from_byte(value: u8) -> Self {
match value {
0 => PcbPadShape::NoShape,
1 => PcbPadShape::Round,
2 => PcbPadShape::Rectangular,
3 => PcbPadShape::Octagonal,
4 => PcbPadShape::Circle,
5 => PcbPadShape::Arc,
6 => PcbPadShape::Terminator,
7 => PcbPadShape::RoundRect,
8 => PcbPadShape::RotatedRect,
9 => PcbPadShape::RoundedRectangle,
_ => PcbPadShape::Round,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
PcbPadShape::NoShape => "NoShape",
PcbPadShape::Round => "Round",
PcbPadShape::Rectangular => "Rectangular",
PcbPadShape::Octagonal => "Octagonal",
PcbPadShape::Circle => "Circle",
PcbPadShape::Arc => "Arc",
PcbPadShape::Terminator => "Terminator",
PcbPadShape::RoundRect => "RoundRect",
PcbPadShape::RotatedRect => "RotatedRect",
PcbPadShape::RoundedRectangle => "RoundedRectangle",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum PcbPadHoleShape {
#[default]
Round = 0,
Square = 1,
Slot = 2,
}
impl PcbPadHoleShape {
pub fn from_byte(value: u8) -> Self {
match value {
0 => PcbPadHoleShape::Round,
1 => PcbPadHoleShape::Square,
2 => PcbPadHoleShape::Slot,
_ => PcbPadHoleShape::Round,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum PcbTextKind {
#[default]
Stroke = 0,
TrueType = 1,
BarCode = 2,
}
impl PcbTextKind {
pub fn from_byte(value: u8) -> Self {
match value {
0 => PcbTextKind::Stroke,
1 => PcbTextKind::TrueType,
2 => PcbTextKind::BarCode,
_ => PcbTextKind::Stroke,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(i16)]
pub enum PcbTextStrokeFont {
#[default]
Default = 0,
SansSerif = 1,
Serif = 3,
}
impl PcbTextStrokeFont {
pub fn from_i16(value: i16) -> Self {
match value {
0 => PcbTextStrokeFont::Default,
1 => PcbTextStrokeFont::SansSerif,
3 => PcbTextStrokeFont::Serif,
_ => PcbTextStrokeFont::Default,
}
}
pub const fn to_i16(self) -> i16 {
self as i16
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum PcbTextJustification {
BottomRight = 1,
MiddleRight = 2,
TopRight = 3,
BottomCenter = 4,
#[default]
MiddleCenter = 5,
TopCenter = 6,
BottomLeft = 7,
MiddleLeft = 8,
TopLeft = 9,
}
impl PcbTextJustification {
pub fn from_byte(value: u8) -> Self {
match value {
1 => PcbTextJustification::BottomRight,
2 => PcbTextJustification::MiddleRight,
3 => PcbTextJustification::TopRight,
4 => PcbTextJustification::BottomCenter,
5 => PcbTextJustification::MiddleCenter,
6 => PcbTextJustification::TopCenter,
7 => PcbTextJustification::BottomLeft,
8 => PcbTextJustification::MiddleLeft,
9 => PcbTextJustification::TopLeft,
_ => PcbTextJustification::MiddleCenter,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
}
#[derive(Debug, Clone, Default)]
pub struct PcbPrimitiveCommon {
pub layer: Layer,
pub flags: PcbFlags,
pub unique_id: Option<String>,
}
impl PcbPrimitiveCommon {
pub fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
let layer = Layer(reader.read_u8()?);
let flags = PcbFlags::from_bits_truncate(reader.read_u16::<LittleEndian>()?);
let mut ff_bytes = [0u8; 10];
reader.read_exact(&mut ff_bytes)?;
Ok(PcbPrimitiveCommon {
layer,
flags,
unique_id: None,
})
}
pub fn is_locked(&self) -> bool {
!self.flags.contains(PcbFlags::UNLOCKED)
}
pub fn is_tenting_top(&self) -> bool {
self.flags.contains(PcbFlags::TENTING_TOP)
}
pub fn is_tenting_bottom(&self) -> bool {
self.flags.contains(PcbFlags::TENTING_BOTTOM)
}
pub fn is_keepout(&self) -> bool {
self.flags.contains(PcbFlags::KEEPOUT)
}
}
impl FromBinary for PcbPrimitiveCommon {
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
PcbPrimitiveCommon::read_from(reader)
}
}
impl ToBinary for PcbPrimitiveCommon {
fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
writer.write_u8(self.layer.to_byte())?;
writer.write_u16::<LittleEndian>(self.flags.bits())?;
writer.write_all(&[0xFFu8; 10])?;
Ok(())
}
fn binary_size(&self) -> usize {
13
}
}
impl FromBinary for PcbFlags {
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
Ok(PcbFlags::from_bits_truncate(
reader.read_u16::<LittleEndian>()?,
))
}
}
impl ToBinary for PcbFlags {
fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
writer.write_u16::<LittleEndian>(self.bits())?;
Ok(())
}
fn binary_size(&self) -> usize {
2
}
}
impl FromBinary for PcbStackMode {
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
Ok(PcbStackMode::from_byte(reader.read_u8()?))
}
}
impl ToBinary for PcbStackMode {
fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
writer.write_u8(self.to_byte())?;
Ok(())
}
fn binary_size(&self) -> usize {
1
}
}
impl FromBinary for PcbPadShape {
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
Ok(PcbPadShape::from_byte(reader.read_u8()?))
}
}
impl ToBinary for PcbPadShape {
fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
writer.write_u8(self.to_byte())?;
Ok(())
}
fn binary_size(&self) -> usize {
1
}
}
impl FromBinary for PcbPadHoleShape {
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
Ok(PcbPadHoleShape::from_byte(reader.read_u8()?))
}
}
impl ToBinary for PcbPadHoleShape {
fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
writer.write_u8(self.to_byte())?;
Ok(())
}
fn binary_size(&self) -> usize {
1
}
}
impl FromBinary for PcbTextKind {
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
Ok(PcbTextKind::from_byte(reader.read_u8()?))
}
}
impl ToBinary for PcbTextKind {
fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
writer.write_u8(self.to_byte())?;
Ok(())
}
fn binary_size(&self) -> usize {
1
}
}
impl FromBinary for PcbTextStrokeFont {
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
Ok(PcbTextStrokeFont::from_i16(
reader.read_i16::<LittleEndian>()?,
))
}
}
impl ToBinary for PcbTextStrokeFont {
fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
writer.write_i16::<LittleEndian>(self.to_i16())?;
Ok(())
}
fn binary_size(&self) -> usize {
2
}
}
impl FromBinary for PcbTextJustification {
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
Ok(PcbTextJustification::from_byte(reader.read_u8()?))
}
}
impl ToBinary for PcbTextJustification {
fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
writer.write_u8(self.to_byte())?;
Ok(())
}
fn binary_size(&self) -> usize {
1
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum CornerStyle {
#[default]
Deg90 = 0,
Deg45 = 1,
Round = 2,
}
impl CornerStyle {
pub fn from_byte(value: u8) -> Self {
match value {
0 => CornerStyle::Deg90,
1 => CornerStyle::Deg45,
2 => CornerStyle::Round,
_ => CornerStyle::Deg90,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
CornerStyle::Deg90 => "90",
CornerStyle::Deg45 => "45",
CornerStyle::Round => "Round",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum PlaneConnectionStyle {
NoConnect = 0,
#[default]
ReliefConnect = 1,
DirectConnect = 2,
}
impl PlaneConnectionStyle {
pub fn from_byte(value: u8) -> Self {
match value {
0 => PlaneConnectionStyle::NoConnect,
1 => PlaneConnectionStyle::ReliefConnect,
2 => PlaneConnectionStyle::DirectConnect,
_ => PlaneConnectionStyle::ReliefConnect,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
PlaneConnectionStyle::NoConnect => "NoConnect",
PlaneConnectionStyle::ReliefConnect => "Relief",
PlaneConnectionStyle::DirectConnect => "Direct",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum NetTopology {
#[default]
Shortest = 0,
Horizontal = 1,
Vertical = 2,
DaisyChainSimple = 3,
DaisyChainMidDriven = 4,
DaisyChainBalanced = 5,
Starburst = 6,
}
impl NetTopology {
pub fn from_byte(value: u8) -> Self {
match value {
0 => NetTopology::Shortest,
1 => NetTopology::Horizontal,
2 => NetTopology::Vertical,
3 => NetTopology::DaisyChainSimple,
4 => NetTopology::DaisyChainMidDriven,
5 => NetTopology::DaisyChainBalanced,
6 => NetTopology::Starburst,
_ => NetTopology::Shortest,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
NetTopology::Shortest => "Shortest",
NetTopology::Horizontal => "Horizontal",
NetTopology::Vertical => "Vertical",
NetTopology::DaisyChainSimple => "DaisyChain",
NetTopology::DaisyChainMidDriven => "DaisyChainMidDriven",
NetTopology::DaisyChainBalanced => "DaisyChainBalanced",
NetTopology::Starburst => "Starburst",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum DimensionKind {
#[default]
None = 0,
Linear = 1,
Angular = 2,
Radial = 3,
Leader = 4,
Datum = 5,
Baseline = 6,
Center = 7,
Original = 8,
LinearDiameter = 9,
RadialDiameter = 10,
}
impl DimensionKind {
pub fn from_byte(value: u8) -> Self {
match value {
0 => DimensionKind::None,
1 => DimensionKind::Linear,
2 => DimensionKind::Angular,
3 => DimensionKind::Radial,
4 => DimensionKind::Leader,
5 => DimensionKind::Datum,
6 => DimensionKind::Baseline,
7 => DimensionKind::Center,
8 => DimensionKind::Original,
9 => DimensionKind::LinearDiameter,
10 => DimensionKind::RadialDiameter,
_ => DimensionKind::None,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
DimensionKind::None => "None",
DimensionKind::Linear => "Linear",
DimensionKind::Angular => "Angular",
DimensionKind::Radial => "Radial",
DimensionKind::Leader => "Leader",
DimensionKind::Datum => "Datum",
DimensionKind::Baseline => "Baseline",
DimensionKind::Center => "Center",
DimensionKind::Original => "Original",
DimensionKind::LinearDiameter => "LinearDiameter",
DimensionKind::RadialDiameter => "RadialDiameter",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum PolyRegionKind {
#[default]
Copper = 0,
Cutout = 1,
NamedRegion = 2,
}
impl PolyRegionKind {
pub fn from_byte(value: u8) -> Self {
match value {
0 => PolyRegionKind::Copper,
1 => PolyRegionKind::Cutout,
2 => PolyRegionKind::NamedRegion,
_ => PolyRegionKind::Copper,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
PolyRegionKind::Copper => "Copper",
PolyRegionKind::Cutout => "Cutout",
PolyRegionKind::NamedRegion => "NamedRegion",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum UnitSystem {
#[default]
Metric = 0,
Imperial = 1,
}
impl UnitSystem {
pub fn from_byte(value: u8) -> Self {
match value {
0 => UnitSystem::Metric,
1 => UnitSystem::Imperial,
_ => UnitSystem::Metric,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
UnitSystem::Metric => "Metric",
UnitSystem::Imperial => "Imperial",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum TextAutoposition {
#[default]
Manual = 0,
TopLeft = 1,
CenterLeft = 2,
BottomLeft = 3,
TopCenter = 4,
CenterCenter = 5,
BottomCenter = 6,
TopRight = 7,
CenterRight = 8,
BottomRight = 9,
}
impl TextAutoposition {
pub fn from_byte(value: u8) -> Self {
match value {
0 => TextAutoposition::Manual,
1 => TextAutoposition::TopLeft,
2 => TextAutoposition::CenterLeft,
3 => TextAutoposition::BottomLeft,
4 => TextAutoposition::TopCenter,
5 => TextAutoposition::CenterCenter,
6 => TextAutoposition::BottomCenter,
7 => TextAutoposition::TopRight,
8 => TextAutoposition::CenterRight,
9 => TextAutoposition::BottomRight,
_ => TextAutoposition::Manual,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
TextAutoposition::Manual => "Manual",
TextAutoposition::TopLeft => "TopLeft",
TextAutoposition::CenterLeft => "CenterLeft",
TextAutoposition::BottomLeft => "BottomLeft",
TextAutoposition::TopCenter => "TopCenter",
TextAutoposition::CenterCenter => "Center",
TextAutoposition::BottomCenter => "BottomCenter",
TextAutoposition::TopRight => "TopRight",
TextAutoposition::CenterRight => "CenterRight",
TextAutoposition::BottomRight => "BottomRight",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum ComponentStyle {
#[default]
Unknown = 0,
Small = 1,
SmallSMT = 2,
Edge = 3,
DIP = 4,
SIP = 5,
SMSIP = 6,
SMDIP = 7,
LCC = 8,
BGA = 9,
PGA = 10,
}
impl ComponentStyle {
pub fn from_byte(value: u8) -> Self {
match value {
0 => ComponentStyle::Unknown,
1 => ComponentStyle::Small,
2 => ComponentStyle::SmallSMT,
3 => ComponentStyle::Edge,
4 => ComponentStyle::DIP,
5 => ComponentStyle::SIP,
6 => ComponentStyle::SMSIP,
7 => ComponentStyle::SMDIP,
8 => ComponentStyle::LCC,
9 => ComponentStyle::BGA,
10 => ComponentStyle::PGA,
_ => ComponentStyle::Unknown,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
ComponentStyle::Unknown => "Unknown",
ComponentStyle::Small => "Small",
ComponentStyle::SmallSMT => "SmallSMT",
ComponentStyle::Edge => "Edge",
ComponentStyle::DIP => "DIP",
ComponentStyle::SIP => "SIP",
ComponentStyle::SMSIP => "SMSIP",
ComponentStyle::SMDIP => "SMDIP",
ComponentStyle::LCC => "LCC",
ComponentStyle::BGA => "BGA",
ComponentStyle::PGA => "PGA",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum DielectricType {
#[default]
None = 0,
Core = 1,
PrePreg = 2,
SurfaceMaterial = 3,
}
impl DielectricType {
pub fn from_byte(value: u8) -> Self {
match value {
0 => DielectricType::None,
1 => DielectricType::Core,
2 => DielectricType::PrePreg,
3 => DielectricType::SurfaceMaterial,
_ => DielectricType::None,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
DielectricType::None => "None",
DielectricType::Core => "Core",
DielectricType::PrePreg => "PrePreg",
DielectricType::SurfaceMaterial => "SurfaceMaterial",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum ExtendedDrillType {
#[default]
Drilled = 0,
Punched = 1,
LaserDrilled = 2,
PlasmaDrilled = 3,
}
impl ExtendedDrillType {
pub fn from_byte(value: u8) -> Self {
match value {
0 => ExtendedDrillType::Drilled,
1 => ExtendedDrillType::Punched,
2 => ExtendedDrillType::LaserDrilled,
3 => ExtendedDrillType::PlasmaDrilled,
_ => ExtendedDrillType::Drilled,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
ExtendedDrillType::Drilled => "Drilled",
ExtendedDrillType::Punched => "Punched",
ExtendedDrillType::LaserDrilled => "LaserDrilled",
ExtendedDrillType::PlasmaDrilled => "PlasmaDrilled",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum BoardSide {
#[default]
Top = 0,
Bottom = 1,
}
impl BoardSide {
pub fn from_byte(value: u8) -> Self {
match value {
0 => BoardSide::Top,
1 => BoardSide::Bottom,
_ => BoardSide::Top,
}
}
pub const fn to_byte(self) -> u8 {
self as u8
}
pub const fn name(self) -> &'static str {
match self {
BoardSide::Top => "Top",
BoardSide::Bottom => "Bottom",
}
}
}
#[derive(Debug, Clone, Default, AltiumRecord)]
#[altium(format = "binary")]
pub struct PcbRectangularBase {
#[altium(flatten)]
pub common: PcbPrimitiveCommon,
#[altium(coord_point)]
pub corner1: CoordPoint,
#[altium(coord_point)]
pub corner2: CoordPoint,
pub rotation: f64,
}
impl PcbRectangularBase {
pub fn width(&self) -> Coord {
Coord::from_raw(self.corner2.x.to_raw() - self.corner1.x.to_raw())
}
pub fn height(&self) -> Coord {
Coord::from_raw(self.corner2.y.to_raw() - self.corner1.y.to_raw())
}
pub fn calculate_bounds(&self) -> CoordRect {
CoordRect::from_corners(self.corner1, self.corner2)
}
}
#[derive(Debug, Clone)]
pub enum PcbRecord {
Arc(super::PcbArc),
Pad(Box<super::PcbPad>),
Via(super::PcbVia),
Track(super::PcbTrack),
Text(super::PcbText),
Fill(super::PcbFill),
Region(super::PcbRegion),
ComponentBody(Box<super::PcbComponentBody>),
Polygon(super::PcbPolygon),
Unknown {
object_id: PcbObjectId,
raw_data: Vec<u8>,
},
}
impl PcbRecord {
pub fn object_id(&self) -> PcbObjectId {
match self {
PcbRecord::Arc(_) => PcbObjectId::Arc,
PcbRecord::Pad(_) => PcbObjectId::Pad,
PcbRecord::Via(_) => PcbObjectId::Via,
PcbRecord::Track(_) => PcbObjectId::Track,
PcbRecord::Text(_) => PcbObjectId::Text,
PcbRecord::Fill(_) => PcbObjectId::Fill,
PcbRecord::Region(_) => PcbObjectId::Region,
PcbRecord::ComponentBody(_) => PcbObjectId::ComponentBody,
PcbRecord::Polygon(_) => PcbObjectId::Polygon,
PcbRecord::Unknown { object_id, .. } => *object_id,
}
}
pub fn layer(&self) -> Layer {
match self {
PcbRecord::Arc(r) => r.common.layer,
PcbRecord::Pad(r) => r.common.layer,
PcbRecord::Via(r) => r.common.layer,
PcbRecord::Track(r) => r.common.layer,
PcbRecord::Text(r) => r.base.common.layer,
PcbRecord::Fill(r) => r.base.common.layer,
PcbRecord::Region(r) => r.common.layer,
PcbRecord::ComponentBody(r) => r.common.layer,
PcbRecord::Polygon(r) => r.layer,
PcbRecord::Unknown { .. } => Layer::default(),
}
}
}