altium_format/records/pcb/
net.rs1use crate::types::{Color, Coord, Layer, ParameterCollection};
7
8#[derive(Debug, Clone, Default)]
14pub struct PcbNet {
15 pub name: String,
17 pub layer: Layer,
19 pub locked: bool,
21 pub visible: bool,
23 pub primitive_lock: bool,
25 pub user_routed: bool,
27 pub keepout: bool,
29 pub union_index: i32,
31 pub color: Color,
33 pub loop_removal: bool,
35 pub override_color_for_draw: bool,
37 pub layer_widths: Vec<(String, Coord)>,
40 pub unique_id: String,
42 pub params: ParameterCollection,
44}
45
46impl PcbNet {
47 pub fn from_params(params: &ParameterCollection) -> Self {
49 let mut net = Self {
50 name: params
51 .get("NAME")
52 .map(|v| v.as_str().to_string())
53 .unwrap_or_default(),
54 layer: params
55 .get("LAYER")
56 .map(|v| v.as_layer())
57 .unwrap_or_default(),
58 locked: params
59 .get("LOCKED")
60 .map(|v| v.as_bool_or(false))
61 .unwrap_or(false),
62 visible: params
63 .get("VISIBLE")
64 .map(|v| v.as_bool_or(true))
65 .unwrap_or(true),
66 primitive_lock: params
67 .get("PRIMITIVELOCK")
68 .map(|v| v.as_bool_or(false))
69 .unwrap_or(false),
70 user_routed: params
71 .get("USERROUTED")
72 .map(|v| v.as_bool_or(true))
73 .unwrap_or(true),
74 keepout: params
75 .get("KEEPOUT")
76 .map(|v| v.as_bool_or(false))
77 .unwrap_or(false),
78 union_index: params
79 .get("UNIONINDEX")
80 .map(|v| v.as_int_or(0))
81 .unwrap_or(0),
82 color: params
83 .get("COLOR")
84 .and_then(|v| v.as_color().ok())
85 .unwrap_or_default(),
86 loop_removal: params
87 .get("LOOPREMOVAL")
88 .map(|v| v.as_bool_or(true))
89 .unwrap_or(true),
90 override_color_for_draw: params
91 .get("OVERRIDECOLORFORDRAW")
92 .map(|v| v.as_bool_or(false))
93 .unwrap_or(false),
94 layer_widths: Vec::new(),
95 unique_id: params
96 .get("UNIQUEID")
97 .map(|v| v.as_str().to_string())
98 .unwrap_or_default(),
99 params: params.clone(),
100 };
101
102 for (key, value) in params.iter() {
105 if key.ends_with("_MRWIDTH") {
106 if let Ok(width) = value.as_coord() {
107 let layer_name = key.trim_end_matches("_MRWIDTH").to_string();
108 net.layer_widths.push((layer_name, width));
109 }
110 }
111 }
112
113 net
114 }
115
116 pub fn to_params(&self) -> ParameterCollection {
118 let mut params = self.params.clone();
119
120 params.add("NAME", &self.name);
121 params.add("LAYER", &self.layer.to_string());
122 params.add("LOCKED", if self.locked { "TRUE" } else { "FALSE" });
123 params.add("VISIBLE", if self.visible { "TRUE" } else { "FALSE" });
124 params.add(
125 "PRIMITIVELOCK",
126 if self.primitive_lock { "TRUE" } else { "FALSE" },
127 );
128 params.add(
129 "USERROUTED",
130 if self.user_routed { "TRUE" } else { "FALSE" },
131 );
132 params.add("KEEPOUT", if self.keepout { "TRUE" } else { "FALSE" });
133 params.add_int("UNIONINDEX", self.union_index);
134 params.add_color("COLOR", self.color);
135 params.add(
136 "LOOPREMOVAL",
137 if self.loop_removal { "TRUE" } else { "FALSE" },
138 );
139 params.add(
140 "OVERRIDECOLORFORDRAW",
141 if self.override_color_for_draw {
142 "TRUE"
143 } else {
144 "FALSE"
145 },
146 );
147
148 for (layer_name, width) in &self.layer_widths {
150 params.add_coord(&format!("{}_MRWIDTH", layer_name), *width);
151 }
152
153 if !self.unique_id.is_empty() {
154 params.add("UNIQUEID", &self.unique_id);
155 }
156
157 params
158 }
159
160 pub fn get_layer_width(&self, layer_name: &str) -> Option<Coord> {
162 self.layer_widths
163 .iter()
164 .find(|(name, _)| name.eq_ignore_ascii_case(layer_name))
165 .map(|(_, width)| *width)
166 }
167
168 pub fn top_layer_width(&self) -> Option<Coord> {
170 self.get_layer_width("TOPLAYER")
171 }
172
173 pub fn bottom_layer_width(&self) -> Option<Coord> {
175 self.get_layer_width("BOTTOMLAYER")
176 }
177}