altium_format/records/sch/
implementation.rs1use crate::error::Result;
6use crate::traits::{FromParams, ToParams};
7use crate::types::{CoordRect, ParameterCollection, UnknownFields};
8use altium_format_derive::AltiumRecord;
9
10use super::{SchPrimitive, SchPrimitiveBase};
11
12#[derive(Debug, Clone, Default, AltiumRecord)]
16#[altium(record_id = 44, format = "params")]
17pub struct SchImplementationList {
18 #[altium(flatten)]
20 pub base: SchPrimitiveBase,
21
22 #[altium(unknown)]
24 pub unknown_params: UnknownFields,
25}
26
27impl SchPrimitive for SchImplementationList {
28 const RECORD_ID: i32 = 44;
29
30 fn record_type_name(&self) -> &'static str {
31 "ImplementationList"
32 }
33
34 fn import_from_params(params: &ParameterCollection) -> Result<Self> {
35 Self::from_params(params)
36 }
37
38 fn export_to_params(&self) -> ParameterCollection {
39 self.to_params()
40 }
41
42 fn owner_index(&self) -> i32 {
43 self.base.owner_index
44 }
45
46 fn calculate_bounds(&self) -> CoordRect {
47 CoordRect::default()
48 }
49}
50
51const IMPLEMENTATION_KNOWN_KEYS: &[&str] = &[
53 "RECORD",
54 "OWNERINDEX",
55 "ISNOTACCESIBLE",
56 "OWNERPARTID",
57 "OWNERPARTDISPLAYMODE",
58 "GRAPHICALLYLOCKED",
59 "DESCRIPTION",
60 "MODELNAME",
61 "MODELTYPE",
62 "DATAFILECOUNT",
63 "ISCURRENT",
64];
65
66#[derive(Debug, Clone, Default)]
70pub struct SchImplementation {
71 pub base: SchPrimitiveBase,
73 pub description: String,
75 pub model_name: String,
77 pub model_type: String,
79 pub data_files: Vec<String>,
81 pub is_current: bool,
83 pub unknown_params: UnknownFields,
85}
86
87impl SchPrimitive for SchImplementation {
88 const RECORD_ID: i32 = 45;
89
90 fn record_type_name(&self) -> &'static str {
91 "Implementation"
92 }
93
94 fn get_property(&self, name: &str) -> Option<String> {
95 match name {
96 "MODELNAME" => Some(self.model_name.clone()),
97 "MODELTYPE" => Some(self.model_type.clone()),
98 _ => None,
99 }
100 }
101
102 fn import_from_params(params: &ParameterCollection) -> Result<Self> {
103 let base = SchPrimitiveBase::import_from_params(params);
104
105 let data_file_count = params
106 .get("DATAFILECOUNT")
107 .map(|v| v.as_int_or(0))
108 .unwrap_or(0);
109
110 let mut data_files = Vec::new();
111 for i in 1..=data_file_count {
112 if let Some(file) = params.get(&format!("MODELDATAFILEKIND{}", i)) {
113 data_files.push(file.as_str().to_string());
114 }
115 }
116
117 let indexed_prefixes: Vec<String> = (1..=data_file_count)
119 .map(|i| format!("MODELDATAFILEKIND{}", i))
120 .collect();
121 let prefix_refs: Vec<&str> = indexed_prefixes.iter().map(|s| s.as_str()).collect();
122
123 let mut all_known: Vec<&str> = IMPLEMENTATION_KNOWN_KEYS.to_vec();
125 all_known.extend(prefix_refs.iter());
126
127 Ok(SchImplementation {
128 base,
129 description: params
130 .get("DESCRIPTION")
131 .map(|v| v.as_str().to_string())
132 .unwrap_or_default(),
133 model_name: params
134 .get("MODELNAME")
135 .map(|v| v.as_str().to_string())
136 .unwrap_or_default(),
137 model_type: params
138 .get("MODELTYPE")
139 .map(|v| v.as_str().to_string())
140 .unwrap_or_default(),
141 data_files,
142 is_current: params
143 .get("ISCURRENT")
144 .map(|v| v.as_bool_or(false))
145 .unwrap_or(false),
146 unknown_params: UnknownFields::from_remaining_params(params, &all_known),
147 })
148 }
149
150 fn export_to_params(&self) -> ParameterCollection {
151 let mut params = ParameterCollection::new();
152 params.add_int("RECORD", Self::RECORD_ID);
153 self.base.export_to_params(&mut params);
154 params.add("DESCRIPTION", &self.description);
155 params.add("MODELNAME", &self.model_name);
156 params.add("MODELTYPE", &self.model_type);
157 params.add_int("DATAFILECOUNT", self.data_files.len() as i32);
158 for (i, file) in self.data_files.iter().enumerate() {
159 params.add(&format!("MODELDATAFILEKIND{}", i + 1), file);
160 }
161 params.add_bool("ISCURRENT", self.is_current);
162
163 self.unknown_params.merge_into_params(&mut params);
165
166 params
167 }
168
169 fn owner_index(&self) -> i32 {
170 self.base.owner_index
171 }
172
173 fn calculate_bounds(&self) -> CoordRect {
174 CoordRect::default()
175 }
176}
177
178#[derive(Debug, Clone, Default, AltiumRecord)]
180#[altium(record_id = 46, format = "params")]
181pub struct SchMapDefinerList {
182 #[altium(flatten)]
184 pub base: SchPrimitiveBase,
185
186 #[altium(unknown)]
188 pub unknown_params: UnknownFields,
189}
190
191impl SchPrimitive for SchMapDefinerList {
192 const RECORD_ID: i32 = 46;
193
194 fn record_type_name(&self) -> &'static str {
195 "MapDefinerList"
196 }
197
198 fn import_from_params(params: &ParameterCollection) -> Result<Self> {
199 Self::from_params(params)
200 }
201
202 fn export_to_params(&self) -> ParameterCollection {
203 self.to_params()
204 }
205
206 fn owner_index(&self) -> i32 {
207 self.base.owner_index
208 }
209
210 fn calculate_bounds(&self) -> CoordRect {
211 CoordRect::default()
212 }
213}
214
215const MAP_DEFINER_KNOWN_KEYS: &[&str] = &[
217 "RECORD",
218 "OWNERINDEX",
219 "ISNOTACCESIBLE",
220 "OWNERPARTID",
221 "OWNERPARTDISPLAYMODE",
222 "GRAPHICALLYLOCKED",
223 "DESINTF",
224 "DESIMPCOUNT",
225 "ISTRIVIAL",
226];
227
228#[derive(Debug, Clone, Default)]
232pub struct SchMapDefiner {
233 pub base: SchPrimitiveBase,
235 pub designator_interface: String,
237 pub designator_implementation: Vec<String>,
239 pub is_trivial: bool,
241 pub unknown_params: UnknownFields,
243}
244
245impl SchPrimitive for SchMapDefiner {
246 const RECORD_ID: i32 = 47;
247
248 fn record_type_name(&self) -> &'static str {
249 "MapDefiner"
250 }
251
252 fn import_from_params(params: &ParameterCollection) -> Result<Self> {
253 let base = SchPrimitiveBase::import_from_params(params);
254
255 let impl_count = params
256 .get("DESIMPCOUNT")
257 .map(|v| v.as_int_or(0))
258 .unwrap_or(0);
259
260 let mut implementations = Vec::new();
261 for i in 0..impl_count {
262 if let Some(des) = params.get(&format!("DESIMP{}", i)) {
263 implementations.push(des.as_str().to_string());
264 }
265 }
266
267 let indexed_prefixes: Vec<String> =
269 (0..impl_count).map(|i| format!("DESIMP{}", i)).collect();
270 let prefix_refs: Vec<&str> = indexed_prefixes.iter().map(|s| s.as_str()).collect();
271
272 let mut all_known: Vec<&str> = MAP_DEFINER_KNOWN_KEYS.to_vec();
274 all_known.extend(prefix_refs.iter());
275
276 Ok(SchMapDefiner {
277 base,
278 designator_interface: params
279 .get("DESINTF")
280 .map(|v| v.as_str().to_string())
281 .unwrap_or_default(),
282 designator_implementation: implementations,
283 is_trivial: params
284 .get("ISTRIVIAL")
285 .map(|v| v.as_bool_or(false))
286 .unwrap_or(false),
287 unknown_params: UnknownFields::from_remaining_params(params, &all_known),
288 })
289 }
290
291 fn export_to_params(&self) -> ParameterCollection {
292 let mut params = ParameterCollection::new();
293 params.add_int("RECORD", Self::RECORD_ID);
294 self.base.export_to_params(&mut params);
295 params.add("DESINTF", &self.designator_interface);
296 params.add_int("DESIMPCOUNT", self.designator_implementation.len() as i32);
297 for (i, des) in self.designator_implementation.iter().enumerate() {
298 params.add(&format!("DESIMP{}", i), des);
299 }
300 params.add_bool("ISTRIVIAL", self.is_trivial);
301
302 self.unknown_params.merge_into_params(&mut params);
304
305 params
306 }
307
308 fn owner_index(&self) -> i32 {
309 self.base.owner_index
310 }
311
312 fn calculate_bounds(&self) -> CoordRect {
313 CoordRect::default()
314 }
315}
316
317#[derive(Debug, Clone, Default, AltiumRecord)]
319#[altium(record_id = 48, format = "params")]
320pub struct SchImplementationParameters {
321 #[altium(flatten)]
323 pub base: SchPrimitiveBase,
324
325 #[altium(unknown)]
327 pub unknown_params: UnknownFields,
328}
329
330impl SchPrimitive for SchImplementationParameters {
331 const RECORD_ID: i32 = 48;
332
333 fn record_type_name(&self) -> &'static str {
334 "ImplementationParameters"
335 }
336
337 fn import_from_params(params: &ParameterCollection) -> Result<Self> {
338 Self::from_params(params)
339 }
340
341 fn export_to_params(&self) -> ParameterCollection {
342 self.to_params()
343 }
344
345 fn owner_index(&self) -> i32 {
346 self.base.owner_index
347 }
348
349 fn calculate_bounds(&self) -> CoordRect {
350 CoordRect::default()
351 }
352}