2 unstable releases
Uses new Rust 2024
| 0.1.0 | Nov 19, 2025 |
|---|---|
| 0.0.0 | Nov 13, 2025 |
#202 in Hardware support
775KB
13K
SLoC
POWERLINK XDC Parser (powerlink-rs-xdc)
A no_std compatible, high-performance parser and serializer for ETHERNET POWERLINK XML Device Configuration (XDC) files, written in pure Rust.
This crate is part of the powerlink-rs project. It is designed to parse, validate, provide an ergonomic, strongly-typed Rust API for accessing data from .xdc files, and serialize that data back to XML. It is based on the EPSG DS 311 specification.
Features
no_stdCompatible: Can be used in embedded and bare-metal environments (allocrequired).- High Performance: Uses the event-based
quick-xmlparser to minimize allocations and efficiently handle large files. - Ergonomic API: Translates raw XML data into strongly-typed Rust structs and enums.
- Safe: Built with safe Rust, with no
unwrap()orexpect()in library code. - Full Serialization: Includes
save_xdc_to_stringto serialize a completeXdcFilestruct back into a standard XDC XML string. - Core Crate Integration: Provides a
to_core_odconverter to directly build theObjectDictionaryrequired by thepowerlink-rscore crate. - Full Schema Support: Parses and resolves:
DeviceIdentityDeviceManager(including LEDs and modular support)ApplicationProcess(includingparameterList,dataTypeList, etc.)ObjectList(the Object Dictionary)NetworkManagement(includingGeneralFeatures,MNFeatures,CNFeatures,Diagnostic)- Modular Device Profiles (XDDM) for both Head and Child nodes.
Usage
use powerlink_rs_xdc::{load_xdc_from_str, to_core_od};
use std::fs;
fn main() {
// 1. Load the XDD/XDC file content
let xml_content = fs::read_to_string("tests/data/MyDevice.xdd")
.expect("Failed to read file");
// 2. Parse into a strongly-typed XdcFile struct
// (Use load_xdd_defaults_from_str for XDDs to prioritize defaultValue)
let xdc_file = load_xdc_from_str(&xml_content)
.expect("Failed to parse XDC");
println!("Device: {}", xdc_file.identity.product_name);
println!("Vendor ID: {:#010x}", xdc_file.identity.vendor_id);
// 3. Access the Object Dictionary
if let Some(obj) = xdc_file.object_dictionary.objects.iter().find(|o| o.index == 0x1000) {
println!("Device Type: {:?}", obj.data);
}
// 4. Convert to the core crate's ObjectDictionary format (if needed)
let core_od = to_core_od(&xdc_file)
.expect("Failed to convert to core OD");
}
Data Representation & Endianness
Important Design Decision:
While the POWERLINK protocol transmits data in Little Endian byte order, this crate treats all data within XDC/XDD files as human-readable strings.
- Storage: Values in
types.rs(e.g.,Object::data,Parameter::actual_value) are stored asString(e.g.,"0x1234","500"). - Parsing: The parser does not convert these strings into byte vectors or native integers during the initial load. This ensures full fidelity to the XML source (preserving hex vs decimal formatting).
- Conversion: Conversion from these strings to native Rust types (wrapped in the core crate's
ObjectValueenum) occurs in theconverter.rsmodule. Thepowerlink-rscore crate then handles the subsequent serialization to Little Endian bytes for network transmission.
This approach simplifies round-trip serialization (ensuring save_xdc_to_string produces XML that matches the input style) and decouples XML formatting from protocol-specific byte ordering.
Architecture & Module Responsibilities
The crate is designed around a three-stage pipeline: Parse -> Resolve -> Expose, with additional modules for serialization and conversion.
file.xdc -> parser.rs -> model/ -> resolver/ -> types.rs -> [Consumer]
types.rs -> converter.rs -> [powerlink-rs core]
types.rs -> builder/ -> file.xdc
src/parser.rs(Entry Point)- Responsibility: The main entry point for parsing an XDC file.
- Details: It takes the XML string content and uses
quick-xml'sfrom_strdeserializer. Its only job is to orchestrate the deserialization of the raw XML into the internalmodelstructs.
src/model/(InternalserdeModel)- Responsibility: Defines the raw, internal data structures that map 1:1 to the XDC XML schema.
- Details: These structs are considered an implementation detail and are not exposed publicly. They are heavily annotated with
#[serde(...)]attributes to guidequick-xml. Their goal is to capture the XML data as-is, includingStringrepresentations of enums, hex values, etc.
src/resolver/(Business Logic)- Responsibility: The "brains" of the crate. It converts the "dumb"
modelstructs into the "smart" publictypesstructs. - Details: This module contains all the business logic for parsing string values into enums, resolving data types (e.g., handling
uniqueIDReflookups betweenObjectListandApplicationProcess), and passing value strings through.
- Responsibility: The "brains" of the crate. It converts the "dumb"
src/types.rs(Public API)- Responsibility: Defines the public, ergonomic data structures that consumers of this crate will interact with.
- Details: These structs are clean, well-documented, and use rich types (e.g., enums) instead of strings where applicable, while keeping data values as human-readable strings.
src/converter.rs(Core Integration)- Responsibility: Translates the public
types::ObjectDictionaryinto thepowerlink_rs::od::ObjectDictionaryused by the corepowerlink-rscrate. This is where string-to-numeric parsing occurs.
- Responsibility: Translates the public
src/builder/(Serialization)- Responsibility: Provides a
save_xdc_to_stringfunction for serializing atypes::XdcFilestruct back into XML. - Details: This module converts the public
typesstructs back into the internalmodelstructs for serialization byquick-xml.
- Responsibility: Provides a
src/error.rs- Responsibility: Defines the crate's custom
XdcErrorenum. - Details: Provides detailed error information, distinguishing between XML parsing errors (from
quick-xml) and data resolution errors (e.g., "Invalid AccessType string").
- Responsibility: Defines the crate's custom
src/lib.rs- Responsibility: The main crate library entry point.
- Details: Re-exports the public API from
src/types.rsand the mainload_andsave_functions.
XDC Specification Coverage
This table tracks the crate's implementation status against the main features of the EPSG DS 311 specification.
| Feature / Element | XSD Definition | Status | Notes |
|---|---|---|---|
| ProfileHeader | ProfileHeader_DataType |
🟢 Implemented | All key fields modeled and resolved. |
| ProfileBody | ProfileBody_DataType |
🟢 Implemented | |
| ➡️ DeviceIdentity | t_DeviceIdentity |
🟢 Implemented | All fields from XSD are modeled and resolved. |
| ➡️ DeviceManager | t_DeviceManager |
🟢 Implemented | indicatorList (LEDs) and modular moduleManagement are modeled and resolved. |
| ➡️ ApplicationProcess | t_ApplicationProcess |
🟢 Implemented | All major sub-elements (parameterList, dataTypeList, parameterGroupList, functionTypeList, functionInstanceList) are modeled and resolved. |
| ➡️ ObjectList | ag_Powerlink_ObjectList |
🟢 Implemented | Fully modeled and resolved, including uniqueIDRef resolution from ApplicationProcess. |
| ➡️ Object | ag_Powerlink_Object |
🟢 Implemented | All key attributes modeled and resolved. |
| ➡️ SubObject | ag_Powerlink_Object |
🟢 Implemented | All key attributes modeled and resolved. |
| ➡️ NetworkManagement | t_NetworkManagement |
🟢 Implemented | All key sub-elements modeled and resolved. |
| ➡️ GeneralFeatures | t_GeneralFeatures |
🟢 Implemented | Key features are modeled and resolved. |
| ➡️ MNFeatures | t_MNFeatures |
🟢 Implemented | Key features are modeled and resolved. |
| ➡️ CNFeatures | t_CNFeatures |
🟢 Implemented | Key features are modeled and resolved. |
| ➡️ Diagnostic | t_Diagnostic |
🟢 Implemented | ErrorList and StaticErrorBitField are modeled and resolved. |
| Modular Support | *Modular_Head.xsd |
🟢 Implemented | All modular profile bodies, moduleManagement, interfaceList, and rangeList elements are modeled and resolved. |
Limitations
While the crate covers most of the EPSG DS 311 V1.2.1 specification and is sufficient for most standard device and communication profiles, certain optional or legacy elements are not yet implemented.
The parser is designed to be safe; it will ignore these unsupported elements rather than crashing.
Roadmap
Phase 1: Core Model & API
- Focus: Establish the 3-stage architecture and parse the most critical 80% of XDC data: the Object Dictionary.
- Key Features:
- Complete
serdemodels forProfileHeader. - Complete
serdemodels forObjectandSubObject, including all attributes (name,accessType,PDOmapping,objFlags, etc.). - Complete
serdemodels forDeviceIdentity.
- Complete
- Success Metric: The crate can successfully parse a real-world XDC file and provide full, typed access to its entire Object Dictionary and Device Identity.
- Status: 🟢 Complete
Phase 2: Full Specification Compliance
- Focus: Implement parsing for the remaining sections of the XDC schema, primarily
NetworkManagement,ApplicationProcess, and modular device extensions. - Key Features:
- Add
serdemodels forNetworkManagement,GeneralFeatures,MNFeatures,CNFeatures, andDiagnostic. - Add
serdemodels forDeviceManagerand all modular profile extensions (moduleManagement,interfaceList,rangeList). - Add public
typesfor all new data. - Implement
resolver.rslogic to map and validate all new data.
- Add
- Success Metric: The crate can parse 100% of the elements and attributes defined in the EPSG DS 311 XSDs, including modular device profiles.
- Status: 🟢 Complete
Phase 3: Comprehensive Testing & Validation
- Focus: Ensure the parser is robust, compliant, and correct by testing against robustness and edge cases.
- Key Features:
- Integrate a test suite of valid XDC files.
- Create specification-driven unit tests for all resolver logic (e.g.,
accessTypeparsing,PDOmappinglogic). - Develop fuzz tests to handle malformed or unexpected XML structures.
- Add tests for edge-case data type parsing (e.g.,
Unsigned24, bit-packed structs).
- Success Metric: The crate achieves high test coverage on edge cases and returns descriptive errors for malformed inputs without panicking.
- Status: 🟢 Complete
Phase 4: Serialization & Validation
- Focus: Provide ergonomic data creation tools and full serialization.
- Key Features:
- Implement
quick-xmlserialization to write anXdcFilestruct back to an XML string. - Add a high-level
validate()method toXdcFilethat checks for common semantic configuration errors (e.g., invalid PDO mappings). - Implement a
builder.rsAPI for programmatically creating newXdcFilestructs.
- Implement
- Success Metric: A user can create a valid XDC file from scratch, serialize it to XML, parse it back, and get an identical struct.
- Status: 🟢 Complete (
save_xdc_to_stringandto_core_odconverter are implemented).
Phase 5: Close the Gap with EPSG DS 311
- Focus: Implement all optional fields defined on the specification.
- Success Metric: The entire specification is implemented.
- Status: 🔴 Not started and not planned.
Dependencies
~1.7–2.5MB
~46K SLoC