altium_format/records/sch/
wire.rs1use crate::error::Result;
4use crate::traits::{FromParams, ToParams};
5use crate::types::{Coord, CoordRect, ParameterCollection, UnknownFields};
6use altium_format_derive::AltiumRecord;
7
8use super::{LineStyle, LineWidth, SchGraphicalBase, SchPrimitive};
9
10#[derive(Debug, Clone, Default, AltiumRecord)]
13#[altium(record_id = 27, format = "params")]
14pub struct SchWire {
15 #[altium(flatten)]
17 pub graphical: SchGraphicalBase,
18
19 #[altium(param = "LINEWIDTH", default)]
21 pub line_width: LineWidth,
22
23 #[altium(param = "LINESTYLE", default)]
25 pub line_style: LineStyle,
26
27 #[altium(
29 indexed_coords,
30 prefix_x = "X",
31 prefix_y = "Y",
32 count = "LOCATIONCOUNT"
33 )]
34 pub vertices: Vec<(i32, i32)>,
35
36 #[altium(unknown)]
38 pub unknown_params: UnknownFields,
39}
40
41impl SchWire {
43 pub fn polyline(&self) -> WirePolylineView<'_> {
45 WirePolylineView { wire: self }
46 }
47}
48
49pub struct WirePolylineView<'a> {
51 wire: &'a SchWire,
52}
53
54impl<'a> WirePolylineView<'a> {
55 pub fn polygon(&self) -> WirePolygonView<'a> {
56 WirePolygonView { wire: self.wire }
57 }
58}
59
60pub struct WirePolygonView<'a> {
62 wire: &'a SchWire,
63}
64
65impl<'a> WirePolygonView<'a> {
66 pub fn vertices(&self) -> &[(i32, i32)] {
67 &self.wire.vertices
68 }
69
70 pub fn graphical(&self) -> &SchGraphicalBase {
71 &self.wire.graphical
72 }
73}
74
75impl SchPrimitive for SchWire {
76 const RECORD_ID: i32 = 27;
77
78 fn location(&self) -> Option<crate::types::CoordPoint> {
79 Some(crate::types::CoordPoint::from_raw(
80 self.graphical.location_x,
81 self.graphical.location_y,
82 ))
83 }
84
85 fn record_type_name(&self) -> &'static str {
86 "Wire"
87 }
88
89 fn import_from_params(params: &ParameterCollection) -> Result<Self> {
90 Self::from_params(params)
91 }
92
93 fn export_to_params(&self) -> ParameterCollection {
94 self.to_params()
95 }
96
97 fn owner_index(&self) -> i32 {
98 self.graphical.base.owner_index
99 }
100
101 fn calculate_bounds(&self) -> CoordRect {
102 let Some(&(first_x, first_y)) = self.vertices.first() else {
103 return CoordRect::empty();
104 };
105
106 let (min_x, max_x, min_y, max_y) = self.vertices.iter().skip(1).fold(
107 (first_x, first_x, first_y, first_y),
108 |(min_x, max_x, min_y, max_y), &(x, y)| {
109 (min_x.min(x), max_x.max(x), min_y.min(y), max_y.max(y))
110 },
111 );
112
113 CoordRect::from_points(
114 Coord::from_raw(min_x),
115 Coord::from_raw(min_y),
116 Coord::from_raw(max_x),
117 Coord::from_raw(max_y),
118 )
119 }
120}