Skip to main content

dpp_aas/
model.rs

1use serde::{Deserialize, Serialize};
2
3// ─── Semantic ID reference ────────────────────────────────────────────────────
4
5/// IDTA AAS Part 1 §5.3.11 Key — one segment of a semantic identifier reference.
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
7#[serde(rename_all = "camelCase")]
8pub struct AasSemIdKey {
9    #[serde(rename = "type")]
10    pub key_type: String,
11    pub value: String,
12}
13
14/// IDTA AAS Part 1 §5.3.11 Reference — typed container for semantic identifiers.
15///
16/// External semantic IDs (ECLASS IRDIs, IDTA URNs, Catena-X URNs) use
17/// `type = "ExternalReference"` with a single `GlobalReference` key.
18#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
19#[serde(rename_all = "camelCase")]
20pub struct AasSemId {
21    #[serde(rename = "type")]
22    pub ref_type: String,
23    pub keys: Vec<AasSemIdKey>,
24}
25
26impl AasSemId {
27    /// Build an external semantic ID reference from a URI or IRDI string.
28    pub fn external(value: &str) -> Self {
29        Self {
30            ref_type: "ExternalReference".into(),
31            keys: vec![AasSemIdKey {
32                key_type: "GlobalReference".into(),
33                value: value.to_owned(),
34            }],
35        }
36    }
37}
38
39// ─── Submodel element types ───────────────────────────────────────────────────
40
41/// AAS data type for `Property` values.
42#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
43#[serde(rename_all = "camelCase")]
44pub enum AasDataType {
45    #[serde(rename = "xs:string")]
46    String,
47    #[serde(rename = "xs:double")]
48    Double,
49    #[serde(rename = "xs:integer")]
50    Integer,
51    #[serde(rename = "xs:boolean")]
52    Boolean,
53    #[serde(rename = "xs:dateTime")]
54    DateTime,
55}
56
57/// An AAS Property — a single leaf-level value.
58#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
59#[serde(rename_all = "camelCase")]
60pub struct AasProperty {
61    pub id_short: String,
62    pub value_type: AasDataType,
63    /// Value serialised as a string (AAS convention for all types).
64    pub value: String,
65    /// Physical unit of the value, e.g. `"kgCO2e"`, `"kg"`, `"V"`, `"%"`.
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub unit: Option<String>,
68    /// Semantic identifier per IDTA AAS Part 1 §5.3.11 Reference type.
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub semantic_id: Option<AasSemId>,
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub description: Option<String>,
73}
74
75/// An AAS SubmodelElementCollection — a named group of elements.
76#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
77#[serde(rename_all = "camelCase")]
78pub struct AasCollection {
79    pub id_short: String,
80    pub value: Vec<AasSubmodelElement>,
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub semantic_id: Option<AasSemId>,
83}
84
85/// An AAS ReferenceElement — an external link (URL/URN).
86///
87/// Used for repair manuals, due-diligence documents, disassembly instructions,
88/// and other external resources linked from DPP fields.
89#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
90#[serde(rename_all = "camelCase")]
91pub struct AasReference {
92    pub id_short: String,
93    /// Target URI or URN.
94    pub value: String,
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub semantic_id: Option<AasSemId>,
97}
98
99/// AAS SubmodelElement — a property, collection, or external reference.
100#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
101#[serde(tag = "modelType")]
102pub enum AasSubmodelElement {
103    Property(AasProperty),
104    SubmodelElementCollection(AasCollection),
105    Reference(AasReference),
106}
107
108/// An AAS Submodel — one named grouping of product data.
109#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
110#[serde(rename_all = "camelCase")]
111pub struct AasSubmodel {
112    pub id: String,
113    pub id_short: String,
114    /// IDTA AAS Part 2 §5.2.4: `"Submodel"` for all AAS submodels.
115    pub model_type: String,
116    /// IDTA AAS Part 2 §5.2.4: `"Instance"` for runtime data (not templates).
117    pub kind: String,
118    #[serde(skip_serializing_if = "Option::is_none")]
119    pub semantic_id: Option<AasSemId>,
120    pub submodel_elements: Vec<AasSubmodelElement>,
121}
122
123// ─── Shell container types ────────────────────────────────────────────────────
124
125/// A name/value specific asset identifier (e.g., `gtin`, `batchId`).
126#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
127#[serde(rename_all = "camelCase")]
128pub struct SpecificAssetId {
129    pub name: String,
130    pub value: String,
131}
132
133/// AAS asset identification block.
134///
135/// `global_asset_id` is the canonical URI for the physical product built from
136/// the GTIN. `specific_asset_ids` carry GTIN, batch, and serial identifiers
137/// for GS1 Digital Link resolution and registry look-up.
138#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
139#[serde(rename_all = "camelCase")]
140pub struct AssetInformation {
141    pub global_asset_id: String,
142    pub specific_asset_ids: Vec<SpecificAssetId>,
143}
144
145/// A reference from an `AasShell` to one of its submodels (ID only).
146#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
147#[serde(rename_all = "camelCase")]
148pub struct AasSubmodelRef {
149    pub id: String,
150}
151
152/// AAS Shell — the top-level container for a product's digital twin.
153///
154/// Holds the asset identification and references to submodels. Submodels are
155/// served alongside the shell as `Vec<AasSubmodel>` from [`build_aas_from_passport`](super::build_aas_from_passport)
156/// and would be exposed from separate API endpoints in a running AAS server
157/// (`/shells/{aasId}` vs. `/submodels/{submodelId}`).
158#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
159#[serde(rename_all = "camelCase")]
160pub struct AasShell {
161    pub id: String,
162    pub id_short: String,
163    /// IDTA AAS Part 2 §5.2.4: always `"AssetAdministrationShell"`.
164    pub model_type: String,
165    /// IDTA AAS Part 2 §5.2.4: `"Instance"` for runtime data (not templates).
166    pub kind: String,
167    pub asset_information: AssetInformation,
168    pub submodels: Vec<AasSubmodelRef>,
169}