Skip to main content

cmsis_pdsc_parser/
part_taxonomy.rs

1//! Contains the types required to represent a [PDSC Part-Taxonomy](https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/element_part-taxonomy.html#element_part-taxonomy) element
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
6/// Represents the [PDSC part-taxonomy](https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/element_part-taxonomy.html#element_part-taxonomy) element
7///
8/// Groups `description` entries that define the hardware part classes and group names used in a pack.
9pub struct PartTaxonomy {
10    /// Hardware part class and group descriptions (1..*)
11    #[serde(rename = "description", default)]
12    pub descriptions: Vec<PartTaxonomyDescription>,
13}
14
15#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
16/// Represents a [PDSC part-taxonomy description](https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/element_part-taxonomy.html#element_part-taxonomyDescription) entry
17///
18/// Defines a hardware part class or a class-and-group combination used to categorise parts.
19pub struct PartTaxonomyDescription {
20    /// Hardware part class name (e.g. `Microcontroller`, `Memory`, `Sensor`)
21    #[serde(rename = "Hclass")]
22    pub class: String,
23
24    /// Hardware part group name within the class
25    #[serde(rename = "Hgroup")]
26    pub group: Option<String>,
27
28    /// Path or URL to documentation for this class/group
29    pub doc: Option<String>,
30
31    /// Generator identifier associated with this class/group
32    pub generator: Option<String>,
33
34    /// Publishing permission; default `true`
35    pub public: Option<bool>,
36
37    /// Condition ID that applies to this class/group
38    pub condition: Option<String>,
39
40    /// Human-readable description of the hardware part class or group; empty string if absent
41    #[serde(rename = "#content")]
42    pub content: String,
43}
44
45#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
46/// Predefined hardware part class names per
47/// [HclassType](https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/element_part-taxonomy.html#HclassType)
48pub enum HclassType {
49    AmplifiersAndComparators,
50    /// "Audio ICs"
51    AudioIcs,
52    Automotive,
53    ClocksAndTimers,
54    DataConverters,
55    /// "Digital Set-Top Box ICs"
56    DigitalSetTopBoxIcs,
57    DiodesAndRectifiers,
58    ImagingAndPhotonicsDevices,
59    InterfacesAndTransceivers,
60    Memories,
61    /// "MEMS and Sensors"
62    MemsAndSensors,
63    MotorDrivers,
64    /// "NFC"
65    Nfc,
66    Other,
67    Positioning,
68    PowerManagement,
69    PowerModules,
70    PowerTransistors,
71    Protections,
72    RadioFrequency,
73    /// "Reset and Supervisor ICs"
74    ResetAndSupervisorIcs,
75    /// "Secure MCUs"
76    SecureMcus,
77    /// "SiC Devices"
78    SicDevices,
79    SpaceDevices,
80    SwitchesAndMultiplexers,
81    /// "Thyristors and AC Switches"
82    ThyristorsAndAcSwitches,
83    TouchAndDisplayControllers,
84    Wireless,
85}
86
87impl TryFrom<&str> for HclassType {
88    type Error = ();
89    fn try_from(s: &str) -> Result<Self, Self::Error> {
90        match s {
91            "Amplifiers and Comparators" => Ok(Self::AmplifiersAndComparators),
92            "Audio ICs" => Ok(Self::AudioIcs),
93            "Automotive" => Ok(Self::Automotive),
94            "Clocks and Timers" => Ok(Self::ClocksAndTimers),
95            "Data Converters" => Ok(Self::DataConverters),
96            "Digital Set-Top Box ICs" => Ok(Self::DigitalSetTopBoxIcs),
97            "Diodes and Rectifiers" => Ok(Self::DiodesAndRectifiers),
98            "Imaging and Photonics Devices" => Ok(Self::ImagingAndPhotonicsDevices),
99            "Interfaces and Transceivers" => Ok(Self::InterfacesAndTransceivers),
100            "Memories" => Ok(Self::Memories),
101            "MEMS and Sensors" => Ok(Self::MemsAndSensors),
102            "Motor Drivers" => Ok(Self::MotorDrivers),
103            "NFC" => Ok(Self::Nfc),
104            "Other" => Ok(Self::Other),
105            "Positioning" => Ok(Self::Positioning),
106            "Power Management" => Ok(Self::PowerManagement),
107            "Power Modules" => Ok(Self::PowerModules),
108            "Power Transistors" => Ok(Self::PowerTransistors),
109            "Protections" => Ok(Self::Protections),
110            "Radio Frequency" => Ok(Self::RadioFrequency),
111            "Reset and Supervisor ICs" => Ok(Self::ResetAndSupervisorIcs),
112            "Secure MCUs" => Ok(Self::SecureMcus),
113            "SiC Devices" => Ok(Self::SicDevices),
114            "Space Devices" => Ok(Self::SpaceDevices),
115            "Switches and Multiplexers" => Ok(Self::SwitchesAndMultiplexers),
116            "Thyristors and AC Switches" => Ok(Self::ThyristorsAndAcSwitches),
117            "Touch and Display Controllers" => Ok(Self::TouchAndDisplayControllers),
118            "Wireless" => Ok(Self::Wireless),
119            _ => Err(()),
120        }
121    }
122}
123
124impl TryFrom<String> for HclassType {
125    type Error = ();
126    fn try_from(s: String) -> Result<Self, Self::Error> {
127        Self::try_from(s.as_str())
128    }
129}
130
131#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
132/// Predefined hardware part group names per
133/// [HgroupType](https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/element_part-taxonomy.html#HgroupType)
134pub enum HgroupType {
135    Comparators,
136    CurrentSensing,
137    OpAmp,
138    PowerOpAmp,
139    VideoAmplifiers,
140    Amplifiers,
141    /// "MEMS Sensor"
142    MemsSensor,
143    Processors,
144    /// "Sound Terminal ICs"
145    SoundTerminalIcs,
146    /// "ADAS (Advanced Driver Assistance Systems)"
147    Adas,
148    AnalogAndPower,
149    InfotainmentAndTelematics,
150    /// "Logic ICs"
151    LogicIcs,
152    Microcontrollers,
153    /// "RTC"
154    Rtc,
155    Timers,
156    /// "A2D - D2A"
157    A2dD2a,
158    /// "Isolated ADCs"
159    IsolatedAdcs,
160    /// "Metering ICs"
161    MeteringIcs,
162    DemodulatorsAndTuners,
163    SetTopBoxProcessors,
164    Diodes,
165    Rectifiers,
166    AmbientLightSensors,
167    ImageSensors,
168    ImagingProcessors,
169    TimeOfFlightSensors,
170    Interfaces,
171    /// "I/O Expanders"
172    IoExpanders,
173    LevelTranslators,
174    Transceivers,
175    /// "EEPROM"
176    Eeprom,
177    Flash,
178    /// "RAM"
179    Ram,
180    Environmental,
181    Infrared,
182    /// "MEMS Hybrid"
183    MemsHybrid,
184    /// "MEMS Microphone"
185    MemsMicrophone,
186    /// "MEMS Motion"
187    MemsMotion,
188    Proximity,
189    Brushed,
190    Brushless,
191    GateDrivers,
192    Stepper,
193    Secure,
194    Reader,
195    Tag,
196    TagAndReader,
197    /// "GNSS ICs"
198    GnssIcs,
199    /// "GNSS Modules"
200    GnssModules,
201    /// "AC-DC Converters"
202    AcDcConverters,
203    /// "Battery Management ICs"
204    BatteryManagementIcs,
205    DcDcSwitchingConverters,
206    DisplaySuppliesAndControllers,
207    /// "eFuses and hot-swap ICs"
208    EFusesAndHotSwapIcs,
209    EnergyHarvesting,
210    /// "GaN Power ICs"
211    GanPowerIcs,
212    HighDensityPowerDrivers,
213    IntelligentPowerSwitches,
214    /// "LED Drivers"
215    LedDrivers,
216    /// "Lighting ICs"
217    LightingIcs,
218    LinearVoltageRegulators,
219    /// "LNB Supplies"
220    LnbSupplies,
221    /// "Photovoltaic ICs"
222    PhotovoltaicIcs,
223    /// "Power Over Ethernet ICs"
224    PowerOverEthernetIcs,
225    VoltageReferences,
226    /// "Wireless Charger ICs"
227    WirelessChargerIcs,
228    /// "ACEPACK"
229    Acepack,
230    /// "SLLIMM"
231    Sllimm,
232    /// "IGBTs"
233    Igbts,
234    Bipolar,
235    /// "MOSFETs"
236    Mosfets,
237    WideBandgap,
238    /// "ASIP"
239    Asip,
240    /// "EMI Filters"
241    EmiFilters,
242    /// "TSS"
243    Tss,
244    /// "TVS"
245    Tvs,
246    /// "RF DMOS"
247    RfDmos,
248    /// "RF LDMOS"
249    RfLdmos,
250    MicroprocessorSupervisors,
251    OnOffControllers,
252    ResetAndVoltageDetectors,
253    /// "Smart Reset ICs"
254    SmartResetIcs,
255    /// "Voltage Protection ICs"
256    VoltageProtectionIcs,
257    WatchdogTimers,
258    Authentication,
259    /// "SIM"
260    Sim,
261    /// "SiC Diodes"
262    SicDiodes,
263    /// "SiC MOSFETs"
264    SicMosfets,
265    /// "LEO Rad-Hard ICs"
266    LeoRadHardIcs,
267    /// "Rad-Hard Analog ICs"
268    RadHardAnalogIcs,
269    /// "Rad-Hard ASIC Platforms"
270    RadHardAsicPlatforms,
271    RadHardDiscretes,
272    RadHardInterfaces,
273    /// "Rad-Hard Logic ICs"
274    RadHardLogicIcs,
275    RadHardPowerManagement,
276    Switches,
277    Multiplexers,
278    Thyristors,
279    Triacs,
280    LongRange,
281    /// "RF Front-end"
282    RfFrontEnd,
283    /// "RF Solutions"
284    RfSolutions,
285    ShortRange,
286}
287
288impl TryFrom<&str> for HgroupType {
289    type Error = ();
290    #[allow(clippy::too_many_lines)]
291    fn try_from(s: &str) -> Result<Self, Self::Error> {
292        match s {
293            "Comparators" => Ok(Self::Comparators),
294            "Current Sensing" => Ok(Self::CurrentSensing),
295            "Op Amp" => Ok(Self::OpAmp),
296            "Power Op Amp" => Ok(Self::PowerOpAmp),
297            "Video Amplifiers" => Ok(Self::VideoAmplifiers),
298            "Amplifiers" => Ok(Self::Amplifiers),
299            "MEMS Sensor" => Ok(Self::MemsSensor),
300            "Processors" => Ok(Self::Processors),
301            "Sound Terminal ICs" => Ok(Self::SoundTerminalIcs),
302            "ADAS (Advanced Driver Assistance Systems)" => Ok(Self::Adas),
303            "Analog and Power" => Ok(Self::AnalogAndPower),
304            "Infotainment and Telematics" => Ok(Self::InfotainmentAndTelematics),
305            "Logic ICs" => Ok(Self::LogicIcs),
306            "Microcontrollers" => Ok(Self::Microcontrollers),
307            "RTC" => Ok(Self::Rtc),
308            "Timers" => Ok(Self::Timers),
309            "A2D - D2A" => Ok(Self::A2dD2a),
310            "Isolated ADCs" => Ok(Self::IsolatedAdcs),
311            "Metering ICs" => Ok(Self::MeteringIcs),
312            "Demodulators and Tuners" => Ok(Self::DemodulatorsAndTuners),
313            "Set-Top-Box Processors" => Ok(Self::SetTopBoxProcessors),
314            "Diodes" => Ok(Self::Diodes),
315            "Rectifiers" => Ok(Self::Rectifiers),
316            "Ambient Light Sensors" => Ok(Self::AmbientLightSensors),
317            "Image Sensors" => Ok(Self::ImageSensors),
318            "Imaging Processors" => Ok(Self::ImagingProcessors),
319            "Time-of-Flight Sensors" => Ok(Self::TimeOfFlightSensors),
320            "Interfaces" => Ok(Self::Interfaces),
321            "I/O Expanders" => Ok(Self::IoExpanders),
322            "Level Translators" => Ok(Self::LevelTranslators),
323            "Transceivers" => Ok(Self::Transceivers),
324            "EEPROM" => Ok(Self::Eeprom),
325            "Flash" => Ok(Self::Flash),
326            "RAM" => Ok(Self::Ram),
327            "Environmental" => Ok(Self::Environmental),
328            "Infrared" => Ok(Self::Infrared),
329            "MEMS Hybrid" => Ok(Self::MemsHybrid),
330            "MEMS Microphone" => Ok(Self::MemsMicrophone),
331            "MEMS Motion" => Ok(Self::MemsMotion),
332            "Proximity" => Ok(Self::Proximity),
333            "Brushed" => Ok(Self::Brushed),
334            "Brushless" => Ok(Self::Brushless),
335            "Gate Drivers" => Ok(Self::GateDrivers),
336            "Stepper" => Ok(Self::Stepper),
337            "Secure" => Ok(Self::Secure),
338            "Reader" => Ok(Self::Reader),
339            "Tag" => Ok(Self::Tag),
340            "Tag and Reader" => Ok(Self::TagAndReader),
341            "GNSS ICs" => Ok(Self::GnssIcs),
342            "GNSS Modules" => Ok(Self::GnssModules),
343            "AC-DC Converters" => Ok(Self::AcDcConverters),
344            "Battery Management ICs" => Ok(Self::BatteryManagementIcs),
345            "DC-DC Switching Converters" => Ok(Self::DcDcSwitchingConverters),
346            "Display Supplies and Controllers" => Ok(Self::DisplaySuppliesAndControllers),
347            "eFuses and hot-swap ICs" => Ok(Self::EFusesAndHotSwapIcs),
348            "Energy Harvesting" => Ok(Self::EnergyHarvesting),
349            "GaN Power ICs" => Ok(Self::GanPowerIcs),
350            "High-Density Power Drivers" => Ok(Self::HighDensityPowerDrivers),
351            "Intelligent Power Switches" => Ok(Self::IntelligentPowerSwitches),
352            "LED Drivers" => Ok(Self::LedDrivers),
353            "Lighting ICs" => Ok(Self::LightingIcs),
354            "Linear Voltage Regulators" => Ok(Self::LinearVoltageRegulators),
355            "LNB Supplies" => Ok(Self::LnbSupplies),
356            "Photovoltaic ICs" => Ok(Self::PhotovoltaicIcs),
357            "Power Over Ethernet ICs" => Ok(Self::PowerOverEthernetIcs),
358            "Voltage References" => Ok(Self::VoltageReferences),
359            "Wireless Charger ICs" => Ok(Self::WirelessChargerIcs),
360            "ACEPACK" => Ok(Self::Acepack),
361            "SLLIMM" => Ok(Self::Sllimm),
362            "IGBTs" => Ok(Self::Igbts),
363            "Bipolar" => Ok(Self::Bipolar),
364            "MOSFETs" => Ok(Self::Mosfets),
365            "Wide Bandgap" => Ok(Self::WideBandgap),
366            "ASIP" => Ok(Self::Asip),
367            "EMI Filters" => Ok(Self::EmiFilters),
368            "TSS" => Ok(Self::Tss),
369            "TVS" => Ok(Self::Tvs),
370            "RF DMOS" => Ok(Self::RfDmos),
371            "RF LDMOS" => Ok(Self::RfLdmos),
372            "Microprocessor Supervisors" => Ok(Self::MicroprocessorSupervisors),
373            "On-Off Controllers" => Ok(Self::OnOffControllers),
374            "Reset and Voltage Detectors" => Ok(Self::ResetAndVoltageDetectors),
375            "Smart Reset ICs" => Ok(Self::SmartResetIcs),
376            "Voltage Protection ICs" => Ok(Self::VoltageProtectionIcs),
377            "Watchdog Timers" => Ok(Self::WatchdogTimers),
378            "Authentication" => Ok(Self::Authentication),
379            "SIM" => Ok(Self::Sim),
380            "SiC Diodes" => Ok(Self::SicDiodes),
381            "SiC MOSFETs" => Ok(Self::SicMosfets),
382            "LEO Rad-Hard ICs" => Ok(Self::LeoRadHardIcs),
383            "Rad-Hard Analog ICs" => Ok(Self::RadHardAnalogIcs),
384            "Rad-Hard ASIC Platforms" => Ok(Self::RadHardAsicPlatforms),
385            "Rad-Hard Discretes" => Ok(Self::RadHardDiscretes),
386            "Rad-Hard Interfaces" => Ok(Self::RadHardInterfaces),
387            "Rad-Hard Logic ICs" => Ok(Self::RadHardLogicIcs),
388            "Rad-Hard Power Management" => Ok(Self::RadHardPowerManagement),
389            "Switches" => Ok(Self::Switches),
390            "Multiplexers" => Ok(Self::Multiplexers),
391            "Thyristors" => Ok(Self::Thyristors),
392            "Triacs" => Ok(Self::Triacs),
393            "Long Range" => Ok(Self::LongRange),
394            "RF Front-end" => Ok(Self::RfFrontEnd),
395            "RF Solutions" => Ok(Self::RfSolutions),
396            "Short Range" => Ok(Self::ShortRange),
397            _ => Err(()),
398        }
399    }
400}
401
402impl TryFrom<String> for HgroupType {
403    type Error = ();
404    fn try_from(s: String) -> Result<Self, Self::Error> {
405        Self::try_from(s.as_str())
406    }
407}
408
409#[cfg(test)]
410mod tests {
411    use crate::part_taxonomy::{PartTaxonomy, PartTaxonomyDescription};
412
413    #[test]
414    fn parse_part_taxonomy() {
415        let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
416<part-taxonomy>
417    <description Hclass="Microcontroller" Hgroup="ARM Cortex-M" doc="Docs/MCU/index.html"
418                 generator="MyGen" public="true" condition="MyCondition">ARM Cortex-M microcontrollers</description>
419    <description Hclass="Memory"/>
420</part-taxonomy>"#;
421
422        let pt: PartTaxonomy = serde_roxmltree::from_str(xml_str).unwrap();
423        assert_eq!(pt.descriptions.len(), 2);
424
425        assert_eq!(
426            pt.descriptions[0],
427            PartTaxonomyDescription {
428                class: "Microcontroller".to_string(),
429                group: Some("ARM Cortex-M".to_string()),
430                doc: Some("Docs/MCU/index.html".to_string()),
431                generator: Some("MyGen".to_string()),
432                public: Some(true),
433                condition: Some("MyCondition".to_string()),
434                content: "ARM Cortex-M microcontrollers".to_string(),
435            }
436        );
437        assert_eq!(
438            pt.descriptions[1],
439            PartTaxonomyDescription {
440                class: "Memory".to_string(),
441                group: None,
442                doc: None,
443                generator: None,
444                public: None,
445                condition: None,
446                content: "".to_string(),
447            }
448        );
449    }
450
451    #[test]
452    fn parse_part_taxonomy_minimal() {
453        let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
454<part-taxonomy>
455    <description Hclass="Sensor"/>
456</part-taxonomy>"#;
457
458        let pt: PartTaxonomy = serde_roxmltree::from_str(xml_str).unwrap();
459        assert_eq!(pt.descriptions.len(), 1);
460
461        let desc = &pt.descriptions[0];
462        assert_eq!(desc.class, "Sensor");
463        assert_eq!(desc.group, None);
464        assert_eq!(desc.doc, None);
465        assert_eq!(desc.generator, None);
466        assert_eq!(desc.public, None);
467        assert_eq!(desc.content, "");
468    }
469
470    #[test]
471    fn parse_part_taxonomy_content() {
472        let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
473<part-taxonomy>
474    <description Hclass="Wireless">Wireless connectivity modules</description>
475</part-taxonomy>"#;
476
477        let pt: PartTaxonomy = serde_roxmltree::from_str(xml_str).unwrap();
478        let desc = &pt.descriptions[0];
479
480        assert_eq!(desc.class, "Wireless");
481        assert_eq!(desc.group, None);
482        assert_eq!(desc.content, "Wireless connectivity modules");
483    }
484
485    #[test]
486    fn hclass_type_try_from() {
487        use crate::part_taxonomy::HclassType;
488
489        assert_eq!(HclassType::try_from("Wireless"), Ok(HclassType::Wireless));
490        assert_eq!(
491            HclassType::try_from("MEMS and Sensors"),
492            Ok(HclassType::MemsAndSensors)
493        );
494        assert_eq!(HclassType::try_from("NFC"), Ok(HclassType::Nfc));
495        assert_eq!(
496            HclassType::try_from("SiC Devices"),
497            Ok(HclassType::SicDevices)
498        );
499        assert_eq!(
500            HclassType::try_from("Thyristors and AC Switches"),
501            Ok(HclassType::ThyristorsAndAcSwitches)
502        );
503        assert_eq!(HclassType::try_from("Unknown Class"), Err(()));
504
505        let s = "Secure MCUs".to_string();
506        assert_eq!(HclassType::try_from(s), Ok(HclassType::SecureMcus));
507    }
508
509    #[test]
510    fn hgroup_type_try_from() {
511        use crate::part_taxonomy::HgroupType;
512
513        assert_eq!(HgroupType::try_from("A2D - D2A"), Ok(HgroupType::A2dD2a));
514        assert_eq!(
515            HgroupType::try_from("ADAS (Advanced Driver Assistance Systems)"),
516            Ok(HgroupType::Adas)
517        );
518        assert_eq!(
519            HgroupType::try_from("eFuses and hot-swap ICs"),
520            Ok(HgroupType::EFusesAndHotSwapIcs)
521        );
522        assert_eq!(
523            HgroupType::try_from("I/O Expanders"),
524            Ok(HgroupType::IoExpanders)
525        );
526        assert_eq!(
527            HgroupType::try_from("SiC MOSFETs"),
528            Ok(HgroupType::SicMosfets)
529        );
530        assert_eq!(
531            HgroupType::try_from("RF Front-end"),
532            Ok(HgroupType::RfFrontEnd)
533        );
534        assert_eq!(HgroupType::try_from("Unknown Group"), Err(()));
535
536        let s = "LEO Rad-Hard ICs".to_string();
537        assert_eq!(HgroupType::try_from(s), Ok(HgroupType::LeoRadHardIcs));
538    }
539}