powerlink_rs_xdc/
types.rs

1//! Public, ergonomic data structures for representing a parsed XDC file.
2//!
3//! These types are the primary interface for consumers of this crate. They abstract
4//! away the complexity of the underlying XML schema (handled by the `model` module)
5//! and provide resolved, easy-to-use structures.
6//!
7//! **Note on Data Storage:**
8//! Values (e.g., `Object::data`, `Parameter::actual_value`) are stored as `String`s
9//! (e.g., "0x1234", "500"). This maintains fidelity to the XML source and allows
10//! high-level manipulation without forcing immediate conversion to native binary types.
11//! Conversion to `powerlink-rs` native types happens in the `converter` module.
12
13use alloc::string::String;
14use alloc::vec::Vec;
15
16/// Represents a fully parsed and resolved XDC/XDD file.
17///
18/// This is the root structure returned by `load_xdc_from_str` or `load_xdd_defaults_from_str`.
19#[derive(Debug, Default, PartialEq)]
20pub struct XdcFile {
21    /// Metadata from the `<ProfileHeader>` block.
22    pub header: ProfileHeader,
23
24    /// Information from the `<DeviceIdentity>` block.
25    pub identity: Identity,
26
27    /// Information from the `<DeviceFunction>` block (e.g., capabilities, connectors).
28    pub device_function: Vec<DeviceFunction>,
29
30    /// Information from the `<DeviceManager>` block (e.g., LEDs, modular management).
31    pub device_manager: Option<DeviceManager>,
32
33    /// Information from the `<NetworkManagement>` block (e.g., cycle timing, feature flags).
34    pub network_management: Option<NetworkManagement>,
35
36    /// Information from the `<ApplicationProcess>` block (e.g., parameters, templates).
37    pub application_process: Option<ApplicationProcess>,
38
39    /// The complete Object Dictionary for the device.
40    pub object_dictionary: ObjectDictionary,
41
42    /// Information from the `<moduleManagement>` block in the *Communication Profile*.
43    pub module_management_comm: Option<ModuleManagementComm>,
44}
45
46/// Represents the `<ProfileHeader>` block, containing file metadata.
47#[derive(Debug, Default, PartialEq)]
48pub struct ProfileHeader {
49    /// The profile identification string.
50    pub identification: String,
51    /// The profile revision.
52    pub revision: String,
53    /// The profile name.
54    pub name: String,
55    /// The source/creator of the profile.
56    pub source: String,
57    /// The profile creation date (ISO 8601).
58    pub date: Option<String>,
59}
60
61/// Represents the `<DeviceIdentity>` block.
62#[derive(Debug, Default, PartialEq)]
63pub struct Identity {
64    /// The vendor name.
65    pub vendor_name: String,
66    /// The unique vendor ID (parsed from hex to u32).
67    pub vendor_id: u32,
68    /// Descriptive text about the vendor (first available label).
69    pub vendor_text: Option<String>,
70
71    /// The device family name.
72    pub device_family: Option<String>,
73    /// The product family name.
74    pub product_family: Option<String>,
75
76    /// The product name.
77    pub product_name: String,
78    /// The unique product ID (parsed from hex to u32).
79    pub product_id: u32,
80    /// Descriptive text about the product.
81    pub product_text: Option<String>,
82
83    /// List of order numbers associated with the device.
84    pub order_number: Vec<String>,
85    /// List of version entries (HW, SW, FW).
86    pub versions: Vec<Version>,
87
88    /// The build date of the device definition.
89    pub build_date: Option<String>,
90    /// The revision of the specification used.
91    pub specification_revision: Option<String>,
92    /// The specific instance name of the device.
93    pub instance_name: Option<String>,
94}
95
96/// Represents a `<version>` element.
97#[derive(Debug, Default, Clone, PartialEq)]
98pub struct Version {
99    /// The type of version (e.g., "HW", "SW", "FW").
100    pub version_type: String,
101    /// The version value.
102    pub value: String,
103}
104
105/// Represents the `<DeviceFunction>` block.
106/// (EPSG DS 311, 7.4.6)
107#[derive(Debug, Default, PartialEq)]
108pub struct DeviceFunction {
109    /// Device capabilities and standard compliance information.
110    pub capabilities: Option<Capabilities>,
111    /// Links to device pictures or icons.
112    pub pictures: Vec<Picture>,
113    /// Links to external text resource files.
114    pub dictionaries: Vec<Dictionary>,
115    /// Definitions of physical connectors.
116    pub connectors: Vec<Connector>,
117    /// Links to firmware files.
118    pub firmware_list: Vec<Firmware>,
119    /// List of classification keywords (e.g., "IO", "Drive").
120    pub classifications: Vec<Classification>,
121}
122
123/// Represents the `<capabilities>` element.
124/// (EPSG DS 311, 7.4.6.2)
125#[derive(Debug, Default, PartialEq)]
126pub struct Capabilities {
127    /// A list of characteristics, often grouped by category.
128    pub characteristics: Vec<CharacteristicList>,
129    /// A list of standards this device complies with.
130    pub standard_compliance: Vec<StandardCompliance>,
131}
132
133/// Represents a `<characteristicsList>`, grouping characteristics by category.
134/// (EPSG DS 311, 7.4.6.2.2)
135#[derive(Debug, Default, PartialEq)]
136pub struct CharacteristicList {
137    /// An optional category name for this group.
138    pub category: Option<String>,
139    /// The list of characteristics in this group.
140    pub characteristics: Vec<Characteristic>,
141}
142
143/// Represents a single `<characteristic>`.
144/// (EPSG DS 311, 7.4.6.2.2.2)
145#[derive(Debug, Default, PartialEq)]
146pub struct Characteristic {
147    /// The name of the characteristic (e.g., "Transfer rate").
148    pub name: String,
149    /// A list of values for this characteristic (e.g., "100 MBit/s").
150    pub content: Vec<String>,
151}
152
153/// Represents a `<compliantWith>` element describing standard compliance.
154/// (EPSG DS 311, 7.4.6.2.2.5)
155#[derive(Debug, Default, PartialEq)]
156pub struct StandardCompliance {
157    /// The name of the standard (e.g., "EN 61131-2").
158    pub name: String,
159    /// The range of compliance, either "international" or "internal".
160    pub range: String,
161    /// An optional description.
162    pub description: Option<String>,
163}
164
165/// Represents a `<picture>` element.
166/// (EPSG DS 311, 7.4.6.3)
167#[derive(Debug, Default, PartialEq)]
168pub struct Picture {
169    /// The URI to the picture file.
170    pub uri: String,
171    /// The type of picture ("frontPicture", "icon", "additional", "none").
172    pub picture_type: String,
173    /// An optional number/index for the picture.
174    pub number: Option<u32>,
175    /// An optional label.
176    pub label: Option<String>,
177    /// An optional description.
178    pub description: Option<String>,
179}
180
181/// Represents a `<dictionary>` element for external text resources.
182/// (EPSG DS 311, 7.4.6.4)
183#[derive(Debug, Default, PartialEq)]
184pub struct Dictionary {
185    /// The URI to the text resource file.
186    pub uri: String,
187    /// The language of the dictionary (e.g., "en", "de").
188    pub lang: String,
189    /// The ID used to reference this dictionary within the XDC.
190    pub dict_id: String,
191}
192
193/// Represents a `<connector>` element.
194/// (EPSG DS 311, 7.4.6.5)
195#[derive(Debug, Default, PartialEq)]
196pub struct Connector {
197    /// The ID of the connector.
198    pub id: String,
199    /// The type of connector (e.g., "POWERLINK", "RJ45").
200    pub connector_type: String,
201    /// Optional reference to a modular interface ID.
202    pub interface_id_ref: Option<String>,
203    /// Optional label.
204    pub label: Option<String>,
205    /// Optional description.
206    pub description: Option<String>,
207}
208
209/// Represents a `<firmware>` element.
210/// (EPSG DS 311, 7.4.6.6)
211#[derive(Debug, Default, PartialEq)]
212pub struct Firmware {
213    /// The URI to the firmware file.
214    pub uri: String,
215    /// The revision number this firmware corresponds to.
216    pub device_revision_number: u32,
217    /// Optional build date of the firmware.
218    pub build_date: Option<String>,
219    /// Optional label.
220    pub label: Option<String>,
221    /// Optional description.
222    pub description: Option<String>,
223}
224
225/// Represents a `<classification>` element.
226/// (EPSG DS 311, 7.4.6.7)
227#[derive(Debug, Default, PartialEq)]
228pub struct Classification {
229    /// The classification value (e.g., "Controller", "IO", "Drive").
230    pub value: String,
231}
232
233// --- Device Manager ---
234
235/// Represents the `<DeviceManager>` block.
236#[derive(Debug, Default, PartialEq)]
237pub struct DeviceManager {
238    /// Contains information about device indicators, primarily LEDs.
239    pub indicator_list: Option<IndicatorList>,
240    /// Contains information about modular device interfaces (if applicable).
241    pub module_management: Option<ModuleManagementDevice>,
242}
243
244/// Represents an `<indicatorList>` containing LED definitions.
245#[derive(Debug, Default, PartialEq)]
246pub struct IndicatorList {
247    /// A list of all LEDs defined for the device.
248    pub leds: Vec<LED>,
249    /// A list of states defined by a combination of multiple LEDs.
250    pub combined_states: Vec<CombinedState>,
251}
252
253/// Represents a single `<LED>` indicator.
254#[derive(Debug, Default, PartialEq)]
255pub struct LED {
256    /// Primary label for the LED (e.g., "STATUS").
257    pub label: Option<String>,
258    /// Description of the LED's purpose.
259    pub description: Option<String>,
260    /// Color configuration ("monocolor" or "bicolor").
261    pub colors: String,
262    /// The functionality type ("IO", "device", "communication").
263    pub led_type: Option<String>,
264    /// A list of all defined states for this LED.
265    pub states: Vec<LEDstate>,
266}
267
268/// Represents a single state for a specific `<LED>` (e.g., "flashing red").
269#[derive(Debug, Default, PartialEq)]
270pub struct LEDstate {
271    /// The unique ID used to reference this state.
272    pub unique_id: String,
273    /// The state ("on", "off", "flashing").
274    pub state: String,
275    /// The color in this state ("green", "amber", "red").
276    pub color: String,
277    /// Primary label for this state.
278    pub label: Option<String>,
279    /// Description of this state.
280    pub description: Option<String>,
281}
282
283/// Represents a state composed of multiple LEDs (e.g., "Error Stop").
284#[derive(Debug, Default, PartialEq)]
285pub struct CombinedState {
286    /// Primary label for this combined state.
287    pub label: Option<String>,
288    /// Description of this combined state.
289    pub description: Option<String>,
290    /// A list of `uniqueID`s referencing the constituent `<LEDstate>`s.
291    pub led_state_refs: Vec<String>,
292}
293
294// --- Modular Device Management ---
295
296/// Represents the `<moduleManagement>` block from the *Device* profile.
297#[derive(Debug, Default, PartialEq)]
298pub struct ModuleManagementDevice {
299    /// A list of interfaces (e.g., bus controllers) on the head module.
300    pub interfaces: Vec<InterfaceDevice>,
301    /// Information about this device if it acts as a module (child).
302    pub module_interface: Option<ModuleInterface>,
303}
304
305/// Represents an `<interface>` on a modular head (Device profile).
306#[derive(Debug, Default, PartialEq)]
307pub struct InterfaceDevice {
308    /// The unique ID for this interface.
309    pub unique_id: String,
310    /// The type of interface (e.g., "X2X").
311    pub interface_type: String,
312    /// The maximum number of child modules supported.
313    pub max_modules: u32,
314    /// Addressing mode for child modules (`manual` or `position`).
315    pub module_addressing: String,
316    /// A list of URIs to XDC/XDD files for compatible modules.
317    pub file_list: Vec<String>,
318    /// A list of pre-configured/connected modules.
319    pub connected_modules: Vec<ConnectedModule>,
320}
321
322/// Represents a `<connectedModule>` entry, linking a slot to a child module.
323#[derive(Debug, Default, PartialEq)]
324pub struct ConnectedModule {
325    /// The reference to a `childID` in a module's XDC.
326    pub child_id_ref: String,
327    /// The physical position (slot), 1-based.
328    pub position: u32,
329    /// The bus address, if different from position.
330    pub address: Option<u32>,
331}
332
333/// Represents a `<moduleInterface>` (properties of a child module).
334#[derive(Debug, Default, PartialEq)]
335pub struct ModuleInterface {
336    /// The unique ID of this child module.
337    pub child_id: String,
338    /// The interface type this module connects to.
339    pub interface_type: String,
340    /// Supported addressing mode (`manual`, `position`, `next`).
341    pub module_addressing: String,
342}
343
344/// Represents the `<moduleManagement>` block from the *Communication* profile.
345#[derive(Debug, Default, PartialEq)]
346pub struct ModuleManagementComm {
347    /// A list of interfaces and their Object Dictionary range definitions.
348    pub interfaces: Vec<InterfaceComm>,
349}
350
351/// Represents an `<interface>` in the Communication profile, mapping hardware interfaces to OD ranges.
352#[derive(Debug, Default, PartialEq)]
353pub struct InterfaceComm {
354    /// The `uniqueID` of the corresponding interface in the Device profile.
355    pub unique_id_ref: String,
356    /// The list of OD index ranges assigned to this interface.
357    pub ranges: Vec<Range>,
358}
359
360/// Represents a `<range>` of OD indices for a modular interface.
361#[derive(Debug, Default, PartialEq)]
362pub struct Range {
363    /// Name of the range.
364    pub name: String,
365    /// The starting index (e.g., 0x3000).
366    pub base_index: u16,
367    /// The maximum index (e.g., 0x3FFF).
368    pub max_index: Option<u16>,
369    /// The maximum sub-index (e.g., 0xFF).
370    pub max_sub_index: u8,
371    /// Assignment mode (`index` or `subindex`).
372    pub sort_mode: String,
373    /// Calculation mode for next index (`continuous` or `address`).
374    pub sort_number: String,
375    /// The step size between new indices.
376    pub sort_step: Option<u32>,
377    /// The default PDO mapping for objects created in this range.
378    pub pdo_mapping: Option<ObjectPdoMapping>,
379}
380
381// --- Network Management ---
382
383/// Represents the `<NetworkManagement>` block.
384#[derive(Debug, Default, PartialEq)]
385pub struct NetworkManagement {
386    pub general_features: GeneralFeatures,
387    pub mn_features: Option<MnFeatures>,
388    pub cn_features: Option<CnFeatures>,
389    pub diagnostic: Option<Diagnostic>,
390}
391
392/// Represents `<GeneralFeatures>`.
393#[derive(Debug, Default, PartialEq)]
394pub struct GeneralFeatures {
395    /// `DLLFeatureMN`: Supports Managing Node functionality.
396    pub dll_feature_mn: bool,
397    /// `NMTBootTimeNotActive`: Time in microseconds to wait in NmtNotActive.
398    pub nmt_boot_time_not_active: u32,
399    /// `NMTCycleTimeMax`: Max cycle time in microseconds.
400    pub nmt_cycle_time_max: u32,
401    /// `NMTCycleTimeMin`: Min cycle time in microseconds.
402    pub nmt_cycle_time_min: u32,
403    /// `NMTErrorEntries`: Size of error history.
404    pub nmt_error_entries: u32,
405    /// `NMTMaxCNNumber`: Max number of CNs.
406    pub nmt_max_cn_number: Option<u8>,
407    /// `PDODynamicMapping`: Supports dynamic PDO mapping.
408    pub pdo_dynamic_mapping: Option<bool>,
409    /// `SDOClient`: Supports SDO Client.
410    pub sdo_client: Option<bool>,
411    /// `SDOServer`: Supports SDO Server.
412    pub sdo_server: Option<bool>,
413    /// `SDOSupportASnd`: Supports SDO over ASnd.
414    pub sdo_support_asnd: Option<bool>,
415    /// `SDOSupportUdpIp`: Supports SDO over UDP/IP.
416    pub sdo_support_udp_ip: Option<bool>,
417
418    /// `NMTIsochronous`: Supports isochronous operation.
419    pub nmt_isochronous: Option<bool>,
420    /// `SDOSupportPDO`: Supports SDO embedded in PDO.
421    pub sdo_support_pdo: Option<bool>,
422    /// `NMTExtNmtCmds`: Supports extended NMT commands.
423    pub nmt_ext_nmt_cmds: Option<bool>,
424    /// `CFMConfigManager`: Supports Configuration Manager.
425    pub cfm_config_manager: Option<bool>,
426    /// `NMTNodeIDBySW`: Supports setting Node ID via software.
427    pub nmt_node_id_by_sw: Option<bool>,
428    /// `SDOCmdReadAllByIndex`: Supports reading all sub-indices.
429    pub sdo_cmd_read_all_by_index: Option<bool>,
430    /// `SDOCmdWriteAllByIndex`: Supports writing all sub-indices.
431    pub sdo_cmd_write_all_by_index: Option<bool>,
432    /// `SDOCmdReadMultParam`: Supports multiple parameter read.
433    pub sdo_cmd_read_mult_param: Option<bool>,
434    /// `SDOCmdWriteMultParam`: Supports multiple parameter write.
435    pub sdo_cmd_write_mult_param: Option<bool>,
436    /// `NMTPublishActiveNodes`: Supports publishing Active Nodes list.
437    pub nmt_publish_active_nodes: Option<bool>,
438    /// `NMTPublishConfigNodes`: Supports publishing Configured Nodes list.
439    pub nmt_publish_config_nodes: Option<bool>,
440}
441
442/// Represents `<MNFeatures>`, specific to Managing Nodes.
443#[derive(Debug, Default, PartialEq)]
444pub struct MnFeatures {
445    /// `DLLMNFeatureMultiplex`: Supports multiplexing.
446    pub dll_mn_feature_multiplex: Option<bool>,
447    /// `DLLMNPResChaining`: Supports PRes Chaining.
448    pub dll_mn_pres_chaining: Option<bool>,
449    /// `NMTSimpleBoot`: Supports simple boot-up.
450    pub nmt_simple_boot: bool,
451
452    /// `NMTServiceUdpIp`: Supports NMT services over UDP.
453    pub nmt_service_udp_ip: Option<bool>,
454    /// `NMTMNBasicEthernet`: Supports Basic Ethernet mode.
455    pub nmt_mn_basic_ethernet: Option<bool>,
456}
457
458/// Public representation of the `NMTCNDNA` attribute (Dynamic Node Addressing).
459#[derive(Debug, Clone, Copy, PartialEq, Eq)]
460pub enum NmtCnDna {
461    /// Do not clear configuration.
462    DoNotClear,
463    /// Clear configuration on transition PRE_OP1 -> PRE_OP2.
464    ClearOnPreOp1ToPreOp2,
465    /// Clear configuration on NMT_Reset_Node.
466    ClearOnNmtResetNode,
467}
468
469/// Represents `<CNFeatures>`, specific to Controlled Nodes.
470#[derive(Debug, Default, PartialEq)]
471pub struct CnFeatures {
472    /// `DLLCNFeatureMultiplex`: Supports multiplexing.
473    pub dll_cn_feature_multiplex: Option<bool>,
474    /// `DLLCNPResChaining`: Supports PRes Chaining.
475    pub dll_cn_pres_chaining: Option<bool>,
476    /// `NMTCNPreOp2ToReady2Op`: Transition time in nanoseconds.
477    pub nmt_cn_pre_op2_to_ready2_op: Option<u32>,
478    /// `NMTCNSoC2PReq`: SoC to PReq latency in nanoseconds.
479    pub nmt_cn_soc_2_preq: u32,
480    /// `NMTCNDNA`: Dynamic Node Addressing behavior.
481    pub nmt_cn_dna: Option<NmtCnDna>,
482}
483
484/// Represents `<Diagnostic>` capabilities.
485#[derive(Debug, Default, PartialEq)]
486pub struct Diagnostic {
487    /// List of defined errors.
488    pub errors: Vec<ErrorDefinition>,
489    /// Definitions for bits in the Static Error Bit Field.
490    pub static_error_bit_field: Option<Vec<StaticErrorBit>>,
491}
492
493/// Represents one `<Error>` entry in the `<ErrorList>`.
494#[derive(Debug, Default, PartialEq)]
495pub struct ErrorDefinition {
496    /// The name of the error.
497    pub name: String,
498    /// The error code value.
499    pub value: String,
500    /// Additional information fields.
501    pub add_info: Vec<AddInfo>,
502}
503
504/// Represents one `<addInfo>` element.
505#[derive(Debug, Default, PartialEq)]
506pub struct AddInfo {
507    pub name: String,
508    pub bit_offset: u8,
509    pub len: u8,
510    pub description: Option<String>,
511}
512
513/// Represents one `<ErrorBit>` from the `<StaticErrorBitField>`.
514#[derive(Debug, Default, PartialEq)]
515pub struct StaticErrorBit {
516    pub name: String,
517    pub offset: u8,
518    pub label: Option<String>,
519    pub description: Option<String>,
520}
521
522// --- Application Process ---
523
524/// Represents `<allowedValues>` for a parameter.
525#[derive(Debug, Clone, PartialEq, Default)]
526pub struct AllowedValues {
527    /// Optional reference to a template.
528    pub template_id_ref: Option<String>,
529    /// List of enumerated allowed values.
530    pub values: Vec<Value>,
531    /// List of allowed ranges.
532    pub ranges: Vec<ValueRange>,
533}
534
535/// Represents a single `<value>`.
536#[derive(Debug, Clone, PartialEq, Default)]
537pub struct Value {
538    /// The literal value string (e.g., "1", "0x0A").
539    pub value: String,
540    /// Optional label.
541    pub label: Option<String>,
542    /// Optional offset for scaling.
543    pub offset: Option<String>,
544    /// Optional multiplier for scaling.
545    pub multiplier: Option<String>,
546}
547
548/// Represents a `<range>`.
549#[derive(Debug, Clone, PartialEq, Default)]
550pub struct ValueRange {
551    /// The minimum value.
552    pub min_value: String,
553    /// The maximum value.
554    pub max_value: String,
555    /// Optional step size.
556    pub step: Option<String>,
557}
558
559/// Represents the `<ApplicationProcess>` block, defining application parameters and types.
560#[derive(Debug, Default, PartialEq)]
561pub struct ApplicationProcess {
562    /// User-defined data types.
563    pub data_types: Vec<AppDataType>,
564    /// Parameter templates.
565    pub templates: Vec<Parameter>,
566    /// Actual parameters.
567    pub parameters: Vec<Parameter>,
568    /// Parameter groupings.
569    pub parameter_groups: Vec<ParameterGroup>,
570    /// Function type definitions.
571    pub function_types: Vec<FunctionType>,
572    /// Function instances.
573    pub function_instances: Vec<FunctionInstance>,
574}
575
576/// Enum representing user-defined data types from `<dataTypeList>`.
577#[derive(Debug, PartialEq)]
578pub enum AppDataType {
579    Struct(AppStruct),
580    Array(AppArray),
581    Enum(AppEnum),
582    Derived(AppDerived),
583}
584
585/// Represents a `<struct>` data type.
586#[derive(Debug, Default, PartialEq)]
587pub struct AppStruct {
588    pub name: String,
589    pub unique_id: String,
590    pub label: Option<String>,
591    pub description: Option<String>,
592    pub members: Vec<StructMember>,
593}
594
595/// Represents a `<varDeclaration>` within a struct.
596#[derive(Debug, Default, PartialEq)]
597pub struct StructMember {
598    pub name: String,
599    pub unique_id: String,
600    /// The data type ID or name.
601    pub data_type: String,
602    /// Size in bits.
603    pub size: Option<u32>,
604    pub label: Option<String>,
605    pub description: Option<String>,
606}
607
608/// Represents an `<array>` data type.
609#[derive(Debug, Default, PartialEq)]
610pub struct AppArray {
611    pub name: String,
612    pub unique_id: String,
613    pub label: Option<String>,
614    pub description: Option<String>,
615    pub lower_limit: u32,
616    pub upper_limit: u32,
617    /// The data type of array elements.
618    pub data_type: String,
619}
620
621/// Represents an `<enum>` data type.
622#[derive(Debug, Default, PartialEq)]
623pub struct AppEnum {
624    pub name: String,
625    pub unique_id: String,
626    pub label: Option<String>,
627    pub description: Option<String>,
628    /// The base data type.
629    pub data_type: String,
630    pub size_in_bits: Option<u32>,
631    pub values: Vec<EnumValue>,
632}
633
634/// Represents a single `<enumValue>`.
635#[derive(Debug, Default, PartialEq)]
636pub struct EnumValue {
637    pub name: String,
638    pub value: String,
639    pub label: Option<String>,
640    pub description: Option<String>,
641}
642
643/// Represents a `<derived>` data type.
644#[derive(Debug, Default, PartialEq)]
645pub struct AppDerived {
646    pub name: String,
647    pub unique_id: String,
648    pub label: Option<String>,
649    pub description: Option<String>,
650    /// The base data type.
651    pub data_type: String,
652    pub count: Option<Count>,
653}
654
655/// Represents a `<count>` element within a derived type.
656#[derive(Debug, Default, PartialEq)]
657pub struct Count {
658    pub unique_id: String,
659    pub access: Option<ParameterAccess>,
660    pub default_value: Option<String>,
661}
662
663/// Represents a `<parameterGroup>`.
664#[derive(Debug, Default, PartialEq)]
665pub struct ParameterGroup {
666    pub unique_id: String,
667    pub label: Option<String>,
668    pub description: Option<String>,
669    /// Nested groups or parameter references.
670    pub items: Vec<ParameterGroupItem>,
671}
672
673/// An item inside a `<parameterGroup>`.
674#[derive(Debug, PartialEq)]
675pub enum ParameterGroupItem {
676    Group(ParameterGroup),
677    Parameter(ParameterRef),
678}
679
680/// Represents a reference to a parameter within a group.
681#[derive(Debug, Default, PartialEq)]
682pub struct ParameterRef {
683    pub unique_id_ref: String,
684    pub visible: bool,
685    pub locked: bool,
686    pub bit_offset: Option<u32>,
687}
688
689// --- Parameter ---
690
691/// The data type of a parameter.
692#[derive(Debug, Clone, PartialEq)]
693pub enum ParameterDataType {
694    // Simple types
695    BOOL,
696    BITSTRING,
697    BYTE,
698    CHAR,
699    WORD,
700    DWORD,
701    LWORD,
702    SINT,
703    INT,
704    DINT,
705    LINT,
706    USINT,
707    UINT,
708    UDINT,
709    ULINT,
710    REAL,
711    LREAL,
712    STRING,
713    WSTRING,
714    // Reference types
715    DataTypeIDRef(String),
716    VariableRef,
717}
718
719impl Default for ParameterDataType {
720    fn default() -> Self {
721        ParameterDataType::BOOL
722    }
723}
724
725/// Represents a `<parameter>` or `<parameterTemplate>`.
726#[derive(Debug, Default, PartialEq)]
727pub struct Parameter {
728    pub unique_id: String,
729    pub access: Option<ParameterAccess>,
730    pub support: Option<ParameterSupport>,
731    pub persistent: bool,
732    pub offset: Option<String>,
733    pub multiplier: Option<String>,
734    pub template_id_ref: Option<String>,
735    pub data_type: ParameterDataType,
736    pub label: Option<String>,
737    pub description: Option<String>,
738    pub actual_value: Option<Value>,
739    pub default_value: Option<Value>,
740    pub allowed_values: Option<AllowedValues>,
741}
742
743/// Represents a `<functionType>`.
744#[derive(Debug, Default, PartialEq)]
745pub struct FunctionType {
746    pub name: String,
747    pub unique_id: String,
748    pub package: Option<String>,
749    pub label: Option<String>,
750    pub description: Option<String>,
751    pub version_info: Vec<VersionInfo>,
752    pub interface: InterfaceList,
753}
754
755/// Represents a `<versionInfo>` element.
756#[derive(Debug, Default, PartialEq)]
757pub struct VersionInfo {
758    pub organization: String,
759    pub version: String,
760    pub author: String,
761    pub date: String,
762    pub label: Option<String>,
763    pub description: Option<String>,
764}
765
766/// Represents an `<interfaceList>`.
767#[derive(Debug, Default, PartialEq)]
768pub struct InterfaceList {
769    pub inputs: Vec<VarDeclaration>,
770    pub outputs: Vec<VarDeclaration>,
771    pub configs: Vec<VarDeclaration>,
772}
773
774/// Represents a `<varDeclaration>` in an interface list.
775#[derive(Debug, Default, PartialEq)]
776pub struct VarDeclaration {
777    pub name: String,
778    pub unique_id: String,
779    pub data_type: String,
780    pub size: Option<u32>,
781    pub initial_value: Option<String>,
782    pub label: Option<String>,
783    pub description: Option<String>,
784}
785
786/// Represents a `<functionInstance>`.
787#[derive(Debug, Default, PartialEq)]
788pub struct FunctionInstance {
789    pub name: String,
790    pub unique_id: String,
791    pub type_id_ref: String,
792    pub label: Option<String>,
793    pub description: Option<String>,
794}
795
796// --- Object Dictionary ---
797
798/// Access types for an Object Dictionary entry.
799#[derive(Debug, Clone, Copy, PartialEq, Eq)]
800pub enum ParameterAccess {
801    Constant,
802    ReadOnly,
803    WriteOnly,
804    ReadWrite,
805    ReadWriteInput,
806    ReadWriteOutput,
807    NoAccess,
808}
809
810/// Support level for an Object Dictionary entry.
811#[derive(Debug, Clone, Copy, PartialEq, Eq)]
812pub enum ParameterSupport {
813    Mandatory,
814    Optional,
815    Conditional,
816}
817
818/// PDO mapping capabilities.
819#[derive(Debug, Clone, Copy, PartialEq, Eq)]
820pub enum ObjectPdoMapping {
821    No,
822    Default,
823    Optional,
824    Tpdo,
825    Rpdo,
826}
827
828/// Represents the complete `<ObjectList>` (Object Dictionary).
829#[derive(Debug, Default, PartialEq)]
830pub struct ObjectDictionary {
831    pub objects: Vec<Object>,
832}
833
834/// Represents a single `<Object>` (an OD Index).
835#[derive(Debug, Default, PartialEq)]
836pub struct Object {
837    /// The object index (parsed from hex string).
838    pub index: u16,
839
840    // --- Metadata ---
841    /// Object name.
842    pub name: String,
843    /// Object type (e.g., "7" for VAR, "8" for ARRAY, "9" for RECORD).
844    pub object_type: String,
845    /// Data type ID (e.g., "0006").
846    pub data_type: Option<String>,
847    /// Low limit for the value.
848    pub low_limit: Option<String>,
849    /// High limit for the value.
850    pub high_limit: Option<String>,
851    /// Access type.
852    pub access_type: Option<ParameterAccess>,
853    /// PDO mapping capability.
854    pub pdo_mapping: Option<ObjectPdoMapping>,
855    /// Object flags.
856    pub obj_flags: Option<String>,
857    /// Support level.
858    pub support: Option<ParameterSupport>,
859    /// Persistence flag.
860    pub persistent: bool,
861    /// Allowed values constraint.
862    pub allowed_values: Option<AllowedValues>,
863
864    // --- Value ---
865    /// The resolved value for this object.
866    ///
867    /// This prioritizes `actualValue` (XDC) or `defaultValue` (XDD) depending on the
868    /// parsing mode. It resolves `uniqueIDRef` links to Application Process parameters.
869    /// stored as a human-readable string.
870    pub data: Option<String>,
871
872    // --- Children ---
873    /// List of sub-objects.
874    pub sub_objects: Vec<SubObject>,
875}
876
877/// Represents a `<SubObject>` (an OD Sub-Index).
878#[derive(Debug, Default, PartialEq)]
879pub struct SubObject {
880    /// The sub-index (parsed from hex string).
881    pub sub_index: u8,
882
883    // --- Metadata ---
884    pub name: String,
885    pub object_type: String,
886    pub data_type: Option<String>,
887    pub low_limit: Option<String>,
888    pub high_limit: Option<String>,
889    pub access_type: Option<ParameterAccess>,
890    pub pdo_mapping: Option<ObjectPdoMapping>,
891    pub obj_flags: Option<String>,
892    pub support: Option<ParameterSupport>,
893    pub persistent: bool,
894    pub allowed_values: Option<AllowedValues>,
895
896    // --- Value ---
897    /// The resolved value for this sub-object (human-readable string).
898    pub data: Option<String>,
899}