1use bitflags::bitflags;
4use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
5use std::io::{Read, Write};
6
7use crate::error::Result;
8use crate::traits::{FromBinary, ToBinary};
9use crate::types::{Coord, CoordPoint, CoordRect, Layer};
10use altium_format_derive::AltiumRecord;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
16#[repr(u8)]
17pub enum PcbObjectId {
18 #[default]
19 None = 0,
20 Arc = 1,
22 Pad = 2,
24 Via = 3,
26 Track = 4,
28 Text = 5,
30 Fill = 6,
32 Connection = 7,
34 Net = 8,
36 Component = 9,
38 Polygon = 10,
40 Region = 11,
42 ComponentBody = 12,
44 Dimension = 13,
46 Coordinate = 14,
48 Class = 15,
50 Rule = 16,
52 FromTo = 17,
54 DifferentialPair = 18,
56 Violation = 19,
58 Embedded = 20,
60 EmbeddedBoard = 21,
62 Board = 24,
65 BoardOutline = 25,
67}
68
69impl PcbObjectId {
70 pub fn from_byte(value: u8) -> Self {
72 match value {
73 0 => PcbObjectId::None,
74 1 => PcbObjectId::Arc,
75 2 => PcbObjectId::Pad,
76 3 => PcbObjectId::Via,
77 4 => PcbObjectId::Track,
78 5 => PcbObjectId::Text,
79 6 => PcbObjectId::Fill,
80 7 => PcbObjectId::Connection,
81 8 => PcbObjectId::Net,
82 9 => PcbObjectId::Component,
83 10 => PcbObjectId::Polygon,
84 11 => PcbObjectId::Region,
85 12 => PcbObjectId::ComponentBody,
86 13 => PcbObjectId::Dimension,
87 14 => PcbObjectId::Coordinate,
88 15 => PcbObjectId::Class,
89 16 => PcbObjectId::Rule,
90 17 => PcbObjectId::FromTo,
91 18 => PcbObjectId::DifferentialPair,
92 19 => PcbObjectId::Violation,
93 20 => PcbObjectId::Embedded,
94 21 => PcbObjectId::EmbeddedBoard,
95 24 => PcbObjectId::Board,
96 25 => PcbObjectId::BoardOutline,
97 _ => PcbObjectId::None,
98 }
99 }
100
101 pub const fn to_byte(self) -> u8 {
103 self as u8
104 }
105
106 pub const fn name(self) -> &'static str {
108 match self {
109 PcbObjectId::None => "None",
110 PcbObjectId::Arc => "Arc",
111 PcbObjectId::Pad => "Pad",
112 PcbObjectId::Via => "Via",
113 PcbObjectId::Track => "Track",
114 PcbObjectId::Text => "Text",
115 PcbObjectId::Fill => "Fill",
116 PcbObjectId::Connection => "Connection",
117 PcbObjectId::Net => "Net",
118 PcbObjectId::Component => "Component",
119 PcbObjectId::Polygon => "Polygon",
120 PcbObjectId::Region => "Region",
121 PcbObjectId::ComponentBody => "ComponentBody",
122 PcbObjectId::Dimension => "Dimension",
123 PcbObjectId::Coordinate => "Coordinate",
124 PcbObjectId::Class => "Class",
125 PcbObjectId::Rule => "Rule",
126 PcbObjectId::FromTo => "FromTo",
127 PcbObjectId::DifferentialPair => "DifferentialPair",
128 PcbObjectId::Violation => "Violation",
129 PcbObjectId::Embedded => "Embedded",
130 PcbObjectId::EmbeddedBoard => "EmbeddedBoard",
131 PcbObjectId::Board => "Board",
132 PcbObjectId::BoardOutline => "BoardOutline",
133 }
134 }
135}
136
137bitflags! {
138 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
140 pub struct PcbFlags: u16 {
141 const UNKNOWN2 = 2;
142 const UNLOCKED = 4;
143 const UNKNOWN8 = 8;
144 const UNKNOWN16 = 16;
145 const TENTING_TOP = 32;
146 const TENTING_BOTTOM = 64;
147 const FABRICATION_TOP = 128;
148 const FABRICATION_BOTTOM = 256;
149 const KEEPOUT = 512;
150 }
151}
152
153impl Default for PcbFlags {
154 fn default() -> Self {
155 PcbFlags::UNLOCKED | PcbFlags::UNKNOWN8
156 }
157}
158
159#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
161#[repr(u8)]
162pub enum PcbStackMode {
163 #[default]
164 Simple = 0,
165 TopMiddleBottom = 1,
166 FullStack = 2,
167}
168
169impl PcbStackMode {
170 pub fn from_byte(value: u8) -> Self {
171 match value {
172 0 => PcbStackMode::Simple,
173 1 => PcbStackMode::TopMiddleBottom,
174 2 => PcbStackMode::FullStack,
175 _ => PcbStackMode::Simple,
176 }
177 }
178
179 pub const fn to_byte(self) -> u8 {
180 self as u8
181 }
182}
183
184#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
188#[repr(u8)]
189pub enum PcbPadShape {
190 NoShape = 0,
192 #[default]
194 Round = 1,
195 Rectangular = 2,
197 Octagonal = 3,
199 Circle = 4,
201 Arc = 5,
203 Terminator = 6,
205 RoundRect = 7,
207 RotatedRect = 8,
209 RoundedRectangle = 9,
211}
212
213impl PcbPadShape {
214 pub fn from_byte(value: u8) -> Self {
215 match value {
216 0 => PcbPadShape::NoShape,
217 1 => PcbPadShape::Round,
218 2 => PcbPadShape::Rectangular,
219 3 => PcbPadShape::Octagonal,
220 4 => PcbPadShape::Circle,
221 5 => PcbPadShape::Arc,
222 6 => PcbPadShape::Terminator,
223 7 => PcbPadShape::RoundRect,
224 8 => PcbPadShape::RotatedRect,
225 9 => PcbPadShape::RoundedRectangle,
226 _ => PcbPadShape::Round,
227 }
228 }
229
230 pub const fn to_byte(self) -> u8 {
231 self as u8
232 }
233
234 pub const fn name(self) -> &'static str {
236 match self {
237 PcbPadShape::NoShape => "NoShape",
238 PcbPadShape::Round => "Round",
239 PcbPadShape::Rectangular => "Rectangular",
240 PcbPadShape::Octagonal => "Octagonal",
241 PcbPadShape::Circle => "Circle",
242 PcbPadShape::Arc => "Arc",
243 PcbPadShape::Terminator => "Terminator",
244 PcbPadShape::RoundRect => "RoundRect",
245 PcbPadShape::RotatedRect => "RotatedRect",
246 PcbPadShape::RoundedRectangle => "RoundedRectangle",
247 }
248 }
249}
250
251#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
253#[repr(u8)]
254pub enum PcbPadHoleShape {
255 #[default]
256 Round = 0,
257 Square = 1,
258 Slot = 2,
259}
260
261impl PcbPadHoleShape {
262 pub fn from_byte(value: u8) -> Self {
263 match value {
264 0 => PcbPadHoleShape::Round,
265 1 => PcbPadHoleShape::Square,
266 2 => PcbPadHoleShape::Slot,
267 _ => PcbPadHoleShape::Round,
268 }
269 }
270
271 pub const fn to_byte(self) -> u8 {
272 self as u8
273 }
274}
275
276#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
278#[repr(u8)]
279pub enum PcbTextKind {
280 #[default]
281 Stroke = 0,
282 TrueType = 1,
283 BarCode = 2,
284}
285
286impl PcbTextKind {
287 pub fn from_byte(value: u8) -> Self {
288 match value {
289 0 => PcbTextKind::Stroke,
290 1 => PcbTextKind::TrueType,
291 2 => PcbTextKind::BarCode,
292 _ => PcbTextKind::Stroke,
293 }
294 }
295
296 pub const fn to_byte(self) -> u8 {
297 self as u8
298 }
299}
300
301#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
303#[repr(i16)]
304pub enum PcbTextStrokeFont {
305 #[default]
306 Default = 0,
307 SansSerif = 1,
308 Serif = 3,
309}
310
311impl PcbTextStrokeFont {
312 pub fn from_i16(value: i16) -> Self {
313 match value {
314 0 => PcbTextStrokeFont::Default,
315 1 => PcbTextStrokeFont::SansSerif,
316 3 => PcbTextStrokeFont::Serif,
317 _ => PcbTextStrokeFont::Default,
318 }
319 }
320
321 pub const fn to_i16(self) -> i16 {
322 self as i16
323 }
324}
325
326#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
328#[repr(u8)]
329pub enum PcbTextJustification {
330 BottomRight = 1,
331 MiddleRight = 2,
332 TopRight = 3,
333 BottomCenter = 4,
334 #[default]
335 MiddleCenter = 5,
336 TopCenter = 6,
337 BottomLeft = 7,
338 MiddleLeft = 8,
339 TopLeft = 9,
340}
341
342impl PcbTextJustification {
343 pub fn from_byte(value: u8) -> Self {
344 match value {
345 1 => PcbTextJustification::BottomRight,
346 2 => PcbTextJustification::MiddleRight,
347 3 => PcbTextJustification::TopRight,
348 4 => PcbTextJustification::BottomCenter,
349 5 => PcbTextJustification::MiddleCenter,
350 6 => PcbTextJustification::TopCenter,
351 7 => PcbTextJustification::BottomLeft,
352 8 => PcbTextJustification::MiddleLeft,
353 9 => PcbTextJustification::TopLeft,
354 _ => PcbTextJustification::MiddleCenter,
355 }
356 }
357
358 pub const fn to_byte(self) -> u8 {
359 self as u8
360 }
361}
362
363#[derive(Debug, Clone, Default)]
365pub struct PcbPrimitiveCommon {
366 pub layer: Layer,
368 pub flags: PcbFlags,
370 pub unique_id: Option<String>,
372}
373
374impl PcbPrimitiveCommon {
375 pub fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
377 let layer = Layer(reader.read_u8()?);
378 let flags = PcbFlags::from_bits_truncate(reader.read_u16::<LittleEndian>()?);
379
380 let mut ff_bytes = [0u8; 10];
382 reader.read_exact(&mut ff_bytes)?;
383 Ok(PcbPrimitiveCommon {
386 layer,
387 flags,
388 unique_id: None,
389 })
390 }
391
392 pub fn is_locked(&self) -> bool {
394 !self.flags.contains(PcbFlags::UNLOCKED)
395 }
396
397 pub fn is_tenting_top(&self) -> bool {
399 self.flags.contains(PcbFlags::TENTING_TOP)
400 }
401
402 pub fn is_tenting_bottom(&self) -> bool {
404 self.flags.contains(PcbFlags::TENTING_BOTTOM)
405 }
406
407 pub fn is_keepout(&self) -> bool {
409 self.flags.contains(PcbFlags::KEEPOUT)
410 }
411}
412
413impl FromBinary for PcbPrimitiveCommon {
414 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
415 PcbPrimitiveCommon::read_from(reader)
416 }
417}
418
419impl ToBinary for PcbPrimitiveCommon {
420 fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
421 writer.write_u8(self.layer.to_byte())?;
422 writer.write_u16::<LittleEndian>(self.flags.bits())?;
423 writer.write_all(&[0xFFu8; 10])?;
424 Ok(())
425 }
426
427 fn binary_size(&self) -> usize {
428 13
429 }
430}
431
432impl FromBinary for PcbFlags {
433 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
434 Ok(PcbFlags::from_bits_truncate(
435 reader.read_u16::<LittleEndian>()?,
436 ))
437 }
438}
439
440impl ToBinary for PcbFlags {
441 fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
442 writer.write_u16::<LittleEndian>(self.bits())?;
443 Ok(())
444 }
445
446 fn binary_size(&self) -> usize {
447 2
448 }
449}
450
451impl FromBinary for PcbStackMode {
452 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
453 Ok(PcbStackMode::from_byte(reader.read_u8()?))
454 }
455}
456
457impl ToBinary for PcbStackMode {
458 fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
459 writer.write_u8(self.to_byte())?;
460 Ok(())
461 }
462
463 fn binary_size(&self) -> usize {
464 1
465 }
466}
467
468impl FromBinary for PcbPadShape {
469 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
470 Ok(PcbPadShape::from_byte(reader.read_u8()?))
471 }
472}
473
474impl ToBinary for PcbPadShape {
475 fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
476 writer.write_u8(self.to_byte())?;
477 Ok(())
478 }
479
480 fn binary_size(&self) -> usize {
481 1
482 }
483}
484
485impl FromBinary for PcbPadHoleShape {
486 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
487 Ok(PcbPadHoleShape::from_byte(reader.read_u8()?))
488 }
489}
490
491impl ToBinary for PcbPadHoleShape {
492 fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
493 writer.write_u8(self.to_byte())?;
494 Ok(())
495 }
496
497 fn binary_size(&self) -> usize {
498 1
499 }
500}
501
502impl FromBinary for PcbTextKind {
503 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
504 Ok(PcbTextKind::from_byte(reader.read_u8()?))
505 }
506}
507
508impl ToBinary for PcbTextKind {
509 fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
510 writer.write_u8(self.to_byte())?;
511 Ok(())
512 }
513
514 fn binary_size(&self) -> usize {
515 1
516 }
517}
518
519impl FromBinary for PcbTextStrokeFont {
520 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
521 Ok(PcbTextStrokeFont::from_i16(
522 reader.read_i16::<LittleEndian>()?,
523 ))
524 }
525}
526
527impl ToBinary for PcbTextStrokeFont {
528 fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
529 writer.write_i16::<LittleEndian>(self.to_i16())?;
530 Ok(())
531 }
532
533 fn binary_size(&self) -> usize {
534 2
535 }
536}
537
538impl FromBinary for PcbTextJustification {
539 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
540 Ok(PcbTextJustification::from_byte(reader.read_u8()?))
541 }
542}
543
544impl ToBinary for PcbTextJustification {
545 fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
546 writer.write_u8(self.to_byte())?;
547 Ok(())
548 }
549
550 fn binary_size(&self) -> usize {
551 1
552 }
553}
554
555#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
563#[repr(u8)]
564pub enum CornerStyle {
565 #[default]
567 Deg90 = 0,
568 Deg45 = 1,
570 Round = 2,
572}
573
574impl CornerStyle {
575 pub fn from_byte(value: u8) -> Self {
576 match value {
577 0 => CornerStyle::Deg90,
578 1 => CornerStyle::Deg45,
579 2 => CornerStyle::Round,
580 _ => CornerStyle::Deg90,
581 }
582 }
583
584 pub const fn to_byte(self) -> u8 {
585 self as u8
586 }
587
588 pub const fn name(self) -> &'static str {
589 match self {
590 CornerStyle::Deg90 => "90",
591 CornerStyle::Deg45 => "45",
592 CornerStyle::Round => "Round",
593 }
594 }
595}
596
597#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
601#[repr(u8)]
602pub enum PlaneConnectionStyle {
603 NoConnect = 0,
605 #[default]
607 ReliefConnect = 1,
608 DirectConnect = 2,
610}
611
612impl PlaneConnectionStyle {
613 pub fn from_byte(value: u8) -> Self {
614 match value {
615 0 => PlaneConnectionStyle::NoConnect,
616 1 => PlaneConnectionStyle::ReliefConnect,
617 2 => PlaneConnectionStyle::DirectConnect,
618 _ => PlaneConnectionStyle::ReliefConnect,
619 }
620 }
621
622 pub const fn to_byte(self) -> u8 {
623 self as u8
624 }
625
626 pub const fn name(self) -> &'static str {
627 match self {
628 PlaneConnectionStyle::NoConnect => "NoConnect",
629 PlaneConnectionStyle::ReliefConnect => "Relief",
630 PlaneConnectionStyle::DirectConnect => "Direct",
631 }
632 }
633}
634
635#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
639#[repr(u8)]
640pub enum NetTopology {
641 #[default]
643 Shortest = 0,
644 Horizontal = 1,
646 Vertical = 2,
648 DaisyChainSimple = 3,
650 DaisyChainMidDriven = 4,
652 DaisyChainBalanced = 5,
654 Starburst = 6,
656}
657
658impl NetTopology {
659 pub fn from_byte(value: u8) -> Self {
660 match value {
661 0 => NetTopology::Shortest,
662 1 => NetTopology::Horizontal,
663 2 => NetTopology::Vertical,
664 3 => NetTopology::DaisyChainSimple,
665 4 => NetTopology::DaisyChainMidDriven,
666 5 => NetTopology::DaisyChainBalanced,
667 6 => NetTopology::Starburst,
668 _ => NetTopology::Shortest,
669 }
670 }
671
672 pub const fn to_byte(self) -> u8 {
673 self as u8
674 }
675
676 pub const fn name(self) -> &'static str {
677 match self {
678 NetTopology::Shortest => "Shortest",
679 NetTopology::Horizontal => "Horizontal",
680 NetTopology::Vertical => "Vertical",
681 NetTopology::DaisyChainSimple => "DaisyChain",
682 NetTopology::DaisyChainMidDriven => "DaisyChainMidDriven",
683 NetTopology::DaisyChainBalanced => "DaisyChainBalanced",
684 NetTopology::Starburst => "Starburst",
685 }
686 }
687}
688
689#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
693#[repr(u8)]
694pub enum DimensionKind {
695 #[default]
697 None = 0,
698 Linear = 1,
700 Angular = 2,
702 Radial = 3,
704 Leader = 4,
706 Datum = 5,
708 Baseline = 6,
710 Center = 7,
712 Original = 8,
714 LinearDiameter = 9,
716 RadialDiameter = 10,
718}
719
720impl DimensionKind {
721 pub fn from_byte(value: u8) -> Self {
722 match value {
723 0 => DimensionKind::None,
724 1 => DimensionKind::Linear,
725 2 => DimensionKind::Angular,
726 3 => DimensionKind::Radial,
727 4 => DimensionKind::Leader,
728 5 => DimensionKind::Datum,
729 6 => DimensionKind::Baseline,
730 7 => DimensionKind::Center,
731 8 => DimensionKind::Original,
732 9 => DimensionKind::LinearDiameter,
733 10 => DimensionKind::RadialDiameter,
734 _ => DimensionKind::None,
735 }
736 }
737
738 pub const fn to_byte(self) -> u8 {
739 self as u8
740 }
741
742 pub const fn name(self) -> &'static str {
743 match self {
744 DimensionKind::None => "None",
745 DimensionKind::Linear => "Linear",
746 DimensionKind::Angular => "Angular",
747 DimensionKind::Radial => "Radial",
748 DimensionKind::Leader => "Leader",
749 DimensionKind::Datum => "Datum",
750 DimensionKind::Baseline => "Baseline",
751 DimensionKind::Center => "Center",
752 DimensionKind::Original => "Original",
753 DimensionKind::LinearDiameter => "LinearDiameter",
754 DimensionKind::RadialDiameter => "RadialDiameter",
755 }
756 }
757}
758
759#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
763#[repr(u8)]
764pub enum PolyRegionKind {
765 #[default]
767 Copper = 0,
768 Cutout = 1,
770 NamedRegion = 2,
772}
773
774impl PolyRegionKind {
775 pub fn from_byte(value: u8) -> Self {
776 match value {
777 0 => PolyRegionKind::Copper,
778 1 => PolyRegionKind::Cutout,
779 2 => PolyRegionKind::NamedRegion,
780 _ => PolyRegionKind::Copper,
781 }
782 }
783
784 pub const fn to_byte(self) -> u8 {
785 self as u8
786 }
787
788 pub const fn name(self) -> &'static str {
789 match self {
790 PolyRegionKind::Copper => "Copper",
791 PolyRegionKind::Cutout => "Cutout",
792 PolyRegionKind::NamedRegion => "NamedRegion",
793 }
794 }
795}
796
797#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
803#[repr(u8)]
804pub enum UnitSystem {
805 #[default]
807 Metric = 0,
808 Imperial = 1,
810}
811
812impl UnitSystem {
813 pub fn from_byte(value: u8) -> Self {
814 match value {
815 0 => UnitSystem::Metric,
816 1 => UnitSystem::Imperial,
817 _ => UnitSystem::Metric,
818 }
819 }
820
821 pub const fn to_byte(self) -> u8 {
822 self as u8
823 }
824
825 pub const fn name(self) -> &'static str {
826 match self {
827 UnitSystem::Metric => "Metric",
828 UnitSystem::Imperial => "Imperial",
829 }
830 }
831}
832
833#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
837#[repr(u8)]
838pub enum TextAutoposition {
839 #[default]
841 Manual = 0,
842 TopLeft = 1,
844 CenterLeft = 2,
846 BottomLeft = 3,
848 TopCenter = 4,
850 CenterCenter = 5,
852 BottomCenter = 6,
854 TopRight = 7,
856 CenterRight = 8,
858 BottomRight = 9,
860}
861
862impl TextAutoposition {
863 pub fn from_byte(value: u8) -> Self {
864 match value {
865 0 => TextAutoposition::Manual,
866 1 => TextAutoposition::TopLeft,
867 2 => TextAutoposition::CenterLeft,
868 3 => TextAutoposition::BottomLeft,
869 4 => TextAutoposition::TopCenter,
870 5 => TextAutoposition::CenterCenter,
871 6 => TextAutoposition::BottomCenter,
872 7 => TextAutoposition::TopRight,
873 8 => TextAutoposition::CenterRight,
874 9 => TextAutoposition::BottomRight,
875 _ => TextAutoposition::Manual,
876 }
877 }
878
879 pub const fn to_byte(self) -> u8 {
880 self as u8
881 }
882
883 pub const fn name(self) -> &'static str {
884 match self {
885 TextAutoposition::Manual => "Manual",
886 TextAutoposition::TopLeft => "TopLeft",
887 TextAutoposition::CenterLeft => "CenterLeft",
888 TextAutoposition::BottomLeft => "BottomLeft",
889 TextAutoposition::TopCenter => "TopCenter",
890 TextAutoposition::CenterCenter => "Center",
891 TextAutoposition::BottomCenter => "BottomCenter",
892 TextAutoposition::TopRight => "TopRight",
893 TextAutoposition::CenterRight => "CenterRight",
894 TextAutoposition::BottomRight => "BottomRight",
895 }
896 }
897}
898
899#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
903#[repr(u8)]
904pub enum ComponentStyle {
905 #[default]
907 Unknown = 0,
908 Small = 1,
910 SmallSMT = 2,
912 Edge = 3,
914 DIP = 4,
916 SIP = 5,
918 SMSIP = 6,
920 SMDIP = 7,
922 LCC = 8,
924 BGA = 9,
926 PGA = 10,
928}
929
930impl ComponentStyle {
931 pub fn from_byte(value: u8) -> Self {
932 match value {
933 0 => ComponentStyle::Unknown,
934 1 => ComponentStyle::Small,
935 2 => ComponentStyle::SmallSMT,
936 3 => ComponentStyle::Edge,
937 4 => ComponentStyle::DIP,
938 5 => ComponentStyle::SIP,
939 6 => ComponentStyle::SMSIP,
940 7 => ComponentStyle::SMDIP,
941 8 => ComponentStyle::LCC,
942 9 => ComponentStyle::BGA,
943 10 => ComponentStyle::PGA,
944 _ => ComponentStyle::Unknown,
945 }
946 }
947
948 pub const fn to_byte(self) -> u8 {
949 self as u8
950 }
951
952 pub const fn name(self) -> &'static str {
953 match self {
954 ComponentStyle::Unknown => "Unknown",
955 ComponentStyle::Small => "Small",
956 ComponentStyle::SmallSMT => "SmallSMT",
957 ComponentStyle::Edge => "Edge",
958 ComponentStyle::DIP => "DIP",
959 ComponentStyle::SIP => "SIP",
960 ComponentStyle::SMSIP => "SMSIP",
961 ComponentStyle::SMDIP => "SMDIP",
962 ComponentStyle::LCC => "LCC",
963 ComponentStyle::BGA => "BGA",
964 ComponentStyle::PGA => "PGA",
965 }
966 }
967}
968
969#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
973#[repr(u8)]
974pub enum DielectricType {
975 #[default]
977 None = 0,
978 Core = 1,
980 PrePreg = 2,
982 SurfaceMaterial = 3,
984}
985
986impl DielectricType {
987 pub fn from_byte(value: u8) -> Self {
988 match value {
989 0 => DielectricType::None,
990 1 => DielectricType::Core,
991 2 => DielectricType::PrePreg,
992 3 => DielectricType::SurfaceMaterial,
993 _ => DielectricType::None,
994 }
995 }
996
997 pub const fn to_byte(self) -> u8 {
998 self as u8
999 }
1000
1001 pub const fn name(self) -> &'static str {
1002 match self {
1003 DielectricType::None => "None",
1004 DielectricType::Core => "Core",
1005 DielectricType::PrePreg => "PrePreg",
1006 DielectricType::SurfaceMaterial => "SurfaceMaterial",
1007 }
1008 }
1009}
1010
1011#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
1015#[repr(u8)]
1016pub enum ExtendedDrillType {
1017 #[default]
1019 Drilled = 0,
1020 Punched = 1,
1022 LaserDrilled = 2,
1024 PlasmaDrilled = 3,
1026}
1027
1028impl ExtendedDrillType {
1029 pub fn from_byte(value: u8) -> Self {
1030 match value {
1031 0 => ExtendedDrillType::Drilled,
1032 1 => ExtendedDrillType::Punched,
1033 2 => ExtendedDrillType::LaserDrilled,
1034 3 => ExtendedDrillType::PlasmaDrilled,
1035 _ => ExtendedDrillType::Drilled,
1036 }
1037 }
1038
1039 pub const fn to_byte(self) -> u8 {
1040 self as u8
1041 }
1042
1043 pub const fn name(self) -> &'static str {
1044 match self {
1045 ExtendedDrillType::Drilled => "Drilled",
1046 ExtendedDrillType::Punched => "Punched",
1047 ExtendedDrillType::LaserDrilled => "LaserDrilled",
1048 ExtendedDrillType::PlasmaDrilled => "PlasmaDrilled",
1049 }
1050 }
1051}
1052
1053#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
1057#[repr(u8)]
1058pub enum BoardSide {
1059 #[default]
1061 Top = 0,
1062 Bottom = 1,
1064}
1065
1066impl BoardSide {
1067 pub fn from_byte(value: u8) -> Self {
1068 match value {
1069 0 => BoardSide::Top,
1070 1 => BoardSide::Bottom,
1071 _ => BoardSide::Top,
1072 }
1073 }
1074
1075 pub const fn to_byte(self) -> u8 {
1076 self as u8
1077 }
1078
1079 pub const fn name(self) -> &'static str {
1080 match self {
1081 BoardSide::Top => "Top",
1082 BoardSide::Bottom => "Bottom",
1083 }
1084 }
1085}
1086
1087#[derive(Debug, Clone, Default, AltiumRecord)]
1093#[altium(format = "binary")]
1094pub struct PcbRectangularBase {
1095 #[altium(flatten)]
1097 pub common: PcbPrimitiveCommon,
1098 #[altium(coord_point)]
1100 pub corner1: CoordPoint,
1101 #[altium(coord_point)]
1103 pub corner2: CoordPoint,
1104 pub rotation: f64,
1106}
1107
1108impl PcbRectangularBase {
1109 pub fn width(&self) -> Coord {
1111 Coord::from_raw(self.corner2.x.to_raw() - self.corner1.x.to_raw())
1112 }
1113
1114 pub fn height(&self) -> Coord {
1116 Coord::from_raw(self.corner2.y.to_raw() - self.corner1.y.to_raw())
1117 }
1118
1119 pub fn calculate_bounds(&self) -> CoordRect {
1121 CoordRect::from_corners(self.corner1, self.corner2)
1122 }
1123}
1124
1125#[derive(Debug, Clone)]
1129pub enum PcbRecord {
1130 Arc(super::PcbArc),
1131 Pad(Box<super::PcbPad>),
1132 Via(super::PcbVia),
1133 Track(super::PcbTrack),
1134 Text(super::PcbText),
1135 Fill(super::PcbFill),
1136 Region(super::PcbRegion),
1137 ComponentBody(Box<super::PcbComponentBody>),
1138 Polygon(super::PcbPolygon),
1139 Unknown {
1141 object_id: PcbObjectId,
1142 raw_data: Vec<u8>,
1143 },
1144}
1145
1146impl PcbRecord {
1147 pub fn object_id(&self) -> PcbObjectId {
1149 match self {
1150 PcbRecord::Arc(_) => PcbObjectId::Arc,
1151 PcbRecord::Pad(_) => PcbObjectId::Pad,
1152 PcbRecord::Via(_) => PcbObjectId::Via,
1153 PcbRecord::Track(_) => PcbObjectId::Track,
1154 PcbRecord::Text(_) => PcbObjectId::Text,
1155 PcbRecord::Fill(_) => PcbObjectId::Fill,
1156 PcbRecord::Region(_) => PcbObjectId::Region,
1157 PcbRecord::ComponentBody(_) => PcbObjectId::ComponentBody,
1158 PcbRecord::Polygon(_) => PcbObjectId::Polygon,
1159 PcbRecord::Unknown { object_id, .. } => *object_id,
1160 }
1161 }
1162
1163 pub fn layer(&self) -> Layer {
1165 match self {
1166 PcbRecord::Arc(r) => r.common.layer,
1167 PcbRecord::Pad(r) => r.common.layer,
1168 PcbRecord::Via(r) => r.common.layer,
1169 PcbRecord::Track(r) => r.common.layer,
1170 PcbRecord::Text(r) => r.base.common.layer,
1171 PcbRecord::Fill(r) => r.base.common.layer,
1172 PcbRecord::Region(r) => r.common.layer,
1173 PcbRecord::ComponentBody(r) => r.common.layer,
1174 PcbRecord::Polygon(r) => r.layer,
1175 PcbRecord::Unknown { .. } => Layer::default(),
1176 }
1177 }
1178}