cognite/dto/data_modeling/instances/
extensions.rs

1use serde::Serialize;
2
3use crate::{
4    get_instance_properties,
5    models::{instances::NodeOrEdge, views::ViewReference, SourceReference},
6    Error,
7};
8
9use super::{EdgeOrNodeData, InstanceId, NodeOrEdgeCreate, NodeWrite};
10
11mod common;
12pub use common::*;
13mod extractors;
14pub use extractors::*;
15mod timeseries;
16pub use timeseries::*;
17mod units;
18pub use units::*;
19
20/// Trait to convert from Node/Edge into this type.
21pub trait FromReadable<TProperties>: Sized {
22    /// Try converting from node/edge into this type.
23    ///
24    /// # Arguments
25    ///
26    /// * `value` - Node/edge to retrieved.
27    /// * `view` - A view reference representing the source of this type.
28    fn try_from(
29        value: NodeOrEdge<TProperties>,
30        view: Option<&ViewReference>,
31    ) -> crate::Result<Self>;
32}
33
34/// Trait for data models special instance
35pub trait WithView {
36    /// Default space.
37    const SPACE: &'static str;
38    /// Default external ID.
39    const EXTERNAL_ID: &'static str;
40    /// Default version.
41    const VERSION: &'static str;
42}
43
44/// Trait to generate a `NodeWrite` instance for this type.
45pub trait WithInstance {
46    /// The properties of new instances of this type.
47    type Properties: Serialize;
48
49    /// Generate a new instance of this type.
50    fn instance(self) -> NodeOrEdgeCreate<Self::Properties>;
51}
52
53#[derive(Clone, Debug, Default)]
54/// Cognite extendable type. This is a data model convenience that allows ease of use of the
55/// `cognite_client.models.instances.apply(...)` method.
56pub struct CogniteExtendable<TProperties> {
57    /// The where the instance belong. This can be none if the default view is preferred.
58    pub view: Option<ViewReference>,
59    /// Id of the instance.
60    pub id: InstanceId,
61    /// An audit of the lifecycle of the instance
62    pub audit: CogniteAuditable,
63    /// Properties of this type.
64    pub properties: TProperties,
65}
66
67impl<TProperties: Default> CogniteExtendable<TProperties> {
68    /// Create a new instance of this type.
69    pub fn new(space: String, external_id: String, properties: TProperties) -> Self {
70        CogniteExtendable {
71            id: InstanceId { space, external_id },
72            view: None,
73            properties,
74            ..Default::default()
75        }
76    }
77}
78
79impl<TProperties: WithView> WithView for CogniteExtendable<TProperties> {
80    const SPACE: &'static str = TProperties::SPACE;
81    const EXTERNAL_ID: &'static str = TProperties::EXTERNAL_ID;
82    const VERSION: &'static str = TProperties::VERSION;
83}
84
85impl<TProperties: Serialize + WithView> WithInstance for CogniteExtendable<TProperties> {
86    type Properties = TProperties;
87
88    fn instance(self) -> NodeOrEdgeCreate<TProperties> {
89        NodeOrEdgeCreate::Node(NodeWrite {
90            space: self.id.space.clone(),
91            external_id: self.id.external_id.clone(),
92            existing_version: None,
93            r#type: None,
94            sources: Some(vec![EdgeOrNodeData {
95                source: SourceReference::View(
96                    self.view
97                        .unwrap_or(ViewReference {
98                            space: TProperties::SPACE.to_string(),
99                            external_id: TProperties::EXTERNAL_ID.to_string(),
100                            version: TProperties::VERSION.to_string(),
101                        })
102                        .clone(),
103                ),
104                properties: self.properties,
105            }]),
106        })
107    }
108}
109
110impl<TProperties: Clone + WithView> FromReadable<TProperties> for CogniteExtendable<TProperties> {
111    fn try_from(
112        value: NodeOrEdge<TProperties>,
113        view: Option<&ViewReference>,
114    ) -> crate::Result<CogniteExtendable<TProperties>> {
115        match value {
116            NodeOrEdge::Node(node_definition) => {
117                let mut properties = node_definition
118                    .properties
119                    .ok_or(Error::Other("Invalid properties".to_string()))?;
120                let extracted_properties = get_instance_properties(
121                    view.unwrap_or(&ViewReference {
122                        space: TProperties::SPACE.to_string(),
123                        external_id: TProperties::EXTERNAL_ID.to_string(),
124                        version: TProperties::VERSION.to_string(),
125                    }),
126                    &mut properties,
127                )
128                .ok_or(Error::Other("Invalid properties".to_string()))?;
129                Ok(CogniteExtendable {
130                    view: view.cloned(),
131                    id: InstanceId {
132                        external_id: node_definition.external_id,
133                        space: node_definition.space,
134                    },
135                    audit: CogniteAuditable {
136                        created_time: node_definition.created_time,
137                        last_updated_time: node_definition.last_updated_time,
138                        deleted_time: node_definition.deleted_time,
139                    },
140                    properties: extracted_properties.clone(),
141                })
142            }
143            _ => Err(Error::Other("Invalid type".to_string())),
144        }
145    }
146}