Skip to main content

altium_format/ops/
categorization.rs

1// SPDX-License-Identifier: GPL-3.0-only
2// SPDX-FileCopyrightText: 2026 Alexander Kiselev <alex@akiselev.com>
3//
4//! Component categorization logic shared across schdoc and schlib.
5
6/// Categorize a component by its library reference into a human-readable type.
7///
8/// Returns category name for grouping (Resistor, Capacitor, IC, etc.).
9///
10/// Library-reference categorization was chosen over designator-prefix matching because Altium
11/// components use semantic library names (e.g., 'LPC1768_MCU') but may share designator prefixes
12/// (U1, U2). Library-based categorization captures component type accurately whereas designator
13/// prefix only indicates generic IC category. Tradeoff: More complex pattern matching, but handles
14/// multi-function ICs correctly.
15pub fn categorize_component(lib_ref: &str, description: &str) -> &'static str {
16    let lib_lower = lib_ref.to_lowercase();
17    let desc_lower = description.to_lowercase();
18
19    // ICs and processors
20    if lib_lower.contains("fpga") || lib_lower.contains("cpld") {
21        return "FPGA/CPLD";
22    }
23    if lib_lower.contains("mcu")
24        || lib_lower.contains("processor")
25        || lib_lower.contains("cortex")
26        || lib_lower.contains("arm")
27        || lib_lower.contains("lpc")
28        || desc_lower.contains("mcu")
29        || desc_lower.contains("microcontroller")
30    {
31        return "Microcontroller";
32    }
33    if lib_lower.contains("ddr")
34        || lib_lower.contains("sdram")
35        || lib_lower.contains("flash")
36        || lib_lower.contains("eeprom")
37        || lib_lower.contains("memory")
38    {
39        return "Memory";
40    }
41    if lib_lower.contains("adc") || desc_lower.contains("analog-to-digital") {
42        return "ADC";
43    }
44    if lib_lower.contains("dac") || desc_lower.contains("digital-to-analog") {
45        return "DAC";
46    }
47    if lib_lower.contains("phy")
48        || lib_lower.contains("ethernet")
49        || lib_lower.contains("transceiver")
50    {
51        return "Transceiver/PHY";
52    }
53    if lib_lower.contains("pll")
54        || lib_lower.contains("clock")
55        || lib_lower.contains("oscillator")
56        || lib_lower.contains("xtal")
57    {
58        return "Clock/Oscillator";
59    }
60    if lib_lower.contains("regulator")
61        || lib_lower.contains("ldo")
62        || lib_lower.contains("buck")
63        || lib_lower.contains("boost")
64        || lib_lower.contains("dcdc")
65        || lib_lower.contains("power module")
66        || desc_lower.contains("regulator")
67        || desc_lower.contains("power module")
68    {
69        return "Power Supply";
70    }
71    if lib_lower.contains("opamp")
72        || lib_lower.contains("op-amp")
73        || lib_lower.contains("amplifier")
74    {
75        return "Amplifier";
76    }
77    if lib_lower.contains("mux")
78        || lib_lower.contains("switch")
79        || lib_lower.contains("multiplexer")
80    {
81        return "Mux/Switch";
82    }
83    if lib_lower.contains("buffer") || lib_lower.contains("driver") || lib_lower.contains("level") {
84        return "Buffer/Driver";
85    }
86
87    // Passives
88    if lib_lower.contains("capacitor") || (lib_lower.starts_with('c') && lib_lower.len() <= 5) {
89        return "Capacitor";
90    }
91    if lib_lower.contains("resistor") || (lib_lower.starts_with('r') && lib_lower.len() <= 5) {
92        return "Resistor";
93    }
94    if lib_lower.contains("inductor")
95        || lib_lower.contains("ferrite")
96        || lib_lower.contains("choke")
97    {
98        return "Inductor/Ferrite";
99    }
100
101    // Discrete semiconductors
102    if lib_lower.contains("diode") || lib_lower.contains("esd") || lib_lower.contains("tvs") {
103        return "Diode/Protection";
104    }
105    if lib_lower.contains("transistor") || lib_lower.contains("mosfet") || lib_lower.contains("fet")
106    {
107        return "Transistor";
108    }
109    if lib_lower.contains("led") {
110        return "LED";
111    }
112
113    // Connectors
114    if lib_lower.contains("connector")
115        || lib_lower.contains("header")
116        || lib_lower.contains("socket")
117        || lib_lower.contains("terminal")
118        || lib_lower.contains("jack")
119        || lib_lower.contains("usb")
120        || lib_lower.contains("rj45")
121    {
122        return "Connector";
123    }
124
125    // Test points
126    if lib_lower.contains("test") || lib_lower.contains("tp") {
127        return "Test Point";
128    }
129
130    "Other IC"
131}