cognite/dto/data_modeling/
views.rs

1use std::collections::HashMap;
2
3use derivative::Derivative;
4use serde::{Deserialize, Serialize};
5use serde_with::skip_serializing_none;
6
7use crate::{
8    models::{
9        CDFExternalIdReference, PrimitiveProperty, TaggedContainerReference, TaggedViewReference,
10        TextProperty, UsedFor,
11    },
12    to_query, AdvancedFilter, IntoParams, RawValue, SetCursor,
13};
14
15use super::{
16    common::{EnumProperty, SourcePropertyReference},
17    instances::InstanceId,
18    query::QueryDirection,
19};
20
21#[derive(Serialize, Deserialize, Clone, Debug, Default)]
22#[serde(rename_all = "camelCase")]
23/// Reference to a view.
24pub struct ViewReference {
25    /// Space ID.
26    pub space: String,
27    /// View external ID.
28    pub external_id: String,
29    /// View version.
30    pub version: String,
31}
32
33#[derive(Default, Clone, Debug)]
34/// Query for listing views.
35pub struct ViewQuery {
36    /// Maximum number of views to return. Default 10, maximum 1000.
37    pub limit: Option<i32>,
38    /// Optional cursor for pagination.
39    pub cursor: Option<String>,
40    /// Filter on view space.
41    pub space: Option<String>,
42    /// Include properties inherited from views each view implements.
43    pub include_inherited_properties: Option<bool>,
44    /// Whether to include all versions of the view, or just the latest.
45    pub all_versions: Option<bool>,
46    /// Whether to include global views.
47    pub include_global: Option<bool>,
48}
49
50impl IntoParams for ViewQuery {
51    fn into_params(self) -> Vec<(String, String)> {
52        let mut params = Vec::<(String, String)>::new();
53        to_query("limit", &self.limit, &mut params);
54        to_query("cursor", &self.cursor, &mut params);
55        to_query("space", &self.space, &mut params);
56        to_query(
57            "includeInheritedProperties",
58            &self.include_inherited_properties,
59            &mut params,
60        );
61        to_query("allVersions", &self.all_versions, &mut params);
62        params
63    }
64}
65
66impl SetCursor for ViewQuery {
67    fn set_cursor(&mut self, cursor: Option<String>) {
68        self.cursor = cursor;
69    }
70}
71
72#[derive(Serialize, Deserialize, Clone, Debug)]
73#[serde(untagged)]
74/// Create a view or reference an existing view.
75pub enum ViewCreateOrReference {
76    /// Create a new view.
77    Create(ViewCreateDefinition),
78    /// Reference an existing view.
79    Reference(ViewReference),
80}
81
82impl From<ViewDefinitionOrReference> for ViewCreateOrReference {
83    fn from(value: ViewDefinitionOrReference) -> Self {
84        match value {
85            ViewDefinitionOrReference::Definition(x) => Self::Create(x.into()),
86            ViewDefinitionOrReference::Reference(x) => Self::Reference(x),
87        }
88    }
89}
90
91#[derive(Serialize, Deserialize, Clone, Debug)]
92#[serde(untagged)]
93/// A reference to an existing view, or a definition for a newly created view.
94pub enum ViewDefinitionOrReference {
95    /// Definition for a newly created view.
96    Definition(ViewDefinition),
97    /// Refernece to an existing view.
98    Reference(ViewReference),
99}
100
101#[skip_serializing_none]
102#[derive(Serialize, Deserialize, Clone, Debug, Default)]
103#[serde(rename_all = "camelCase")]
104/// Create a new view.
105pub struct ViewCreateDefinition {
106    /// External ID identifying this view.
107    ///
108    /// The values `Query`, `Mutation`, `Subscription`, `String`, `Int32`, `Int64`, `Int`,
109    /// `Float32`, `Float64`, `Float`, `Timestamp`, `JSONObject`, `Date`, `Numeric`,
110    /// `Boolean`, `PageInfo`, `File`, `Sequence` and `TimeSeries` are reserved.
111    pub external_id: String,
112    /// Space this view belongs to.
113    pub space: String,
114    /// Human readsable name for the view.
115    pub name: Option<String>,
116    /// Description of the content and use of this view.
117    pub description: Option<String>,
118    /// Filter for instances included in this view.
119    pub filter: Option<AdvancedFilter>,
120    /// List of views this view implements.
121    pub implements: Option<Vec<TaggedViewReference>>,
122    /// Whether this view should be used for nodes, edges, or both.
123    pub used_for: Option<UsedFor>,
124    /// View version.
125    pub version: String,
126    /// Collection of properties and connections for this view.
127    pub properties: HashMap<String, CreateViewPropertyOrConnectionDefinition>,
128}
129
130impl From<ViewDefinition> for ViewCreateDefinition {
131    fn from(value: ViewDefinition) -> Self {
132        Self {
133            external_id: value.external_id,
134            space: value.space,
135            name: value.name,
136            description: value.description,
137            implements: value.implements,
138            version: value.version,
139            used_for: Some(value.used_for),
140            filter: value.filter,
141            properties: value
142                .properties
143                .into_iter()
144                .map(|(key, val)| (key, val.into()))
145                .collect(),
146        }
147    }
148}
149
150#[skip_serializing_none]
151#[derive(Serialize, Deserialize, Clone, Debug)]
152#[serde(rename_all = "camelCase", untagged)]
153/// New view property or definition of a connection.
154pub enum CreateViewPropertyOrConnectionDefinition {
155    /// New view property referencing a container.
156    CreateViewProperty(CreateViewProperty),
157    /// Connection referencing a view.
158    ConnectionDefinition(ConnectionDefinition),
159}
160
161impl From<ViewDefinitionProperties> for CreateViewPropertyOrConnectionDefinition {
162    fn from(value: ViewDefinitionProperties) -> Self {
163        match value {
164            ViewDefinitionProperties::ViewCorePropertyDefinition(p) => {
165                Self::CreateViewProperty(p.into())
166            }
167            ViewDefinitionProperties::ConnectionDefinition(d) => Self::ConnectionDefinition(d),
168        }
169    }
170}
171
172#[skip_serializing_none]
173#[derive(Serialize, Deserialize, Clone, Debug)]
174#[serde(rename_all = "camelCase")]
175/// Create a new view property.
176pub struct CreateViewProperty {
177    /// Human readable property name.
178    pub name: Option<String>,
179    /// Description of content and suggested use for this property.
180    pub description: Option<String>,
181    /// Reference to an existing container.
182    pub container: TaggedContainerReference,
183    /// The unique identifier for the property (Unique within the referenced container).
184    pub container_property_identifier: String,
185    /// Indicates what type a referenced direct relation is expected to be.
186    pub source: Option<TaggedViewReference>,
187}
188
189impl From<ViewCorePropertyDefinition> for CreateViewProperty {
190    fn from(value: ViewCorePropertyDefinition) -> Self {
191        Self {
192            name: value.name,
193            description: value.description,
194            container: value.container,
195            container_property_identifier: value.container_property_identifier,
196            source: match value.r#type {
197                ViewCorePropertyType::Direct(v) => v.source,
198                _ => None,
199            },
200        }
201    }
202}
203
204#[skip_serializing_none]
205#[derive(Serialize, Deserialize, Clone, Debug)]
206#[serde(rename_all = "camelCase")]
207/// Definition of a connection going through an edge.
208pub struct EdgeConnection {
209    /// Readable connection name.
210    pub name: Option<String>,
211    /// Description of the connection.
212    pub description: Option<String>,
213    /// Reference to the node pointed to by the edge type. Consists of a
214    /// space and an external ID.
215    pub r#type: InstanceId,
216    /// Direction of the connection. Defaults to `outwards`.
217    pub direction: Option<QueryDirection>,
218    /// Which view this connection references.
219    pub source: TaggedViewReference,
220    /// Which view the edges of this connection belong to.
221    pub edge_source: Option<TaggedViewReference>,
222}
223
224#[skip_serializing_none]
225#[derive(Serialize, Deserialize, Clone, Debug)]
226#[serde(rename_all = "camelCase")]
227/// Connection to a view through a reverse direct relation.
228pub struct ReverseDirectRelationConnection {
229    /// Readable connection name.
230    pub name: Option<String>,
231    /// Description of the connection.
232    pub description: Option<String>,
233    /// Which view this connection references.
234    pub source: TaggedViewReference,
235    /// Which property this connection uses.
236    pub through: SourcePropertyReference,
237    /// Whether this relation targets a list of direct relations.
238    pub targets_list: Option<bool>,
239}
240
241#[skip_serializing_none]
242#[derive(Serialize, Deserialize, Clone, Debug)]
243#[serde(rename_all = "snake_case", tag = "connectionType")]
244/// Definition of a connection. Describes edges or reverse direct relations
245/// that are expected to exist.
246pub enum ConnectionDefinition {
247    /// A single edge is expected to exist.
248    SingleEdgeConnection(EdgeConnection),
249    /// Multiple edges are expected to exist.
250    MultiEdgeConnection(EdgeConnection),
251    /// A single reverse direct relation is expected to exist.
252    SingleReverseDirectRelation(ReverseDirectRelationConnection),
253    /// Multiple reverse direct relations are expected to exist.
254    MultiReverseDirectRelation(ReverseDirectRelationConnection),
255}
256
257#[skip_serializing_none]
258#[derive(Serialize, Deserialize, Clone, Debug, Default)]
259#[serde(rename_all = "camelCase")]
260/// Definition of a view.
261pub struct ViewDefinition {
262    /// View external ID.
263    pub external_id: String,
264    /// View space.
265    pub space: String,
266    /// Human readable name.
267    pub name: Option<String>,
268    /// Description for contents and intended use of view.
269    pub description: Option<String>,
270    /// Filter for instances in view.
271    pub filter: Option<AdvancedFilter>,
272    /// List of views this view implements.
273    pub implements: Option<Vec<TaggedViewReference>>,
274    /// Version of view.
275    pub version: String,
276    /// Time this view was created, in milliseconds since epoch.
277    pub created_time: i64,
278    /// Time this view was last modified, in milliseconds since epoch.
279    pub last_updated_time: i64,
280    /// Whether this view can be written to, i.e. it maps all non-nullable properties.
281    pub writable: bool,
282    /// Whether this view can be used for nodes, edges, or both.
283    pub used_for: UsedFor,
284    /// List of properties and connections in this view.
285    pub properties: HashMap<String, ViewDefinitionProperties>,
286}
287
288#[skip_serializing_none]
289#[derive(Serialize, Deserialize, Clone, Debug)]
290#[serde(rename_all = "camelCase", untagged)]
291#[allow(clippy::large_enum_variant)]
292/// Properties in a view definition.
293pub enum ViewDefinitionProperties {
294    /// A view property referencing a property in a container.
295    ViewCorePropertyDefinition(ViewCorePropertyDefinition),
296    /// A connection to a view.
297    ConnectionDefinition(ConnectionDefinition),
298}
299
300#[derive(Serialize, Deserialize, Derivative, Clone, Debug, Copy)]
301#[serde(rename_all = "camelCase")]
302/// Validity state of a constraint or index.
303pub enum ConstraintOrIndexState {
304    /// The constraint is violated.
305    Failed,
306    /// The constraint is currently satisfied.
307    Current,
308    /// The constraint is pending validation.
309    Pending,
310}
311
312#[derive(Serialize, Deserialize, Derivative, Clone, Debug, Default)]
313#[serde(rename_all = "camelCase")]
314/// State of constraints on a property.
315pub struct ViewConstraintState {
316    /// Status of nullability on properties with isNullable set to false.
317    pub nullability: Option<ConstraintOrIndexState>,
318}
319
320#[skip_serializing_none]
321#[derive(Serialize, Deserialize, Derivative, Clone, Debug)]
322#[serde(rename_all = "camelCase")]
323/// Definition of a view property.
324pub struct ViewCorePropertyDefinition {
325    #[derivative(Default(value = "true"))]
326    /// Whether the property value is optional.
327    pub nullable: Option<bool>,
328    /// Whether the property value auto-increments.
329    pub auto_increment: Option<bool>,
330    /// Default value of the property.
331    pub default_value: Option<RawValue>,
332    /// Description of the content and suggested use for this property.
333    pub description: Option<String>,
334    /// Human readable property name.
335    pub name: Option<String>,
336    /// Property type.
337    pub r#type: ViewCorePropertyType,
338    /// Container reference.
339    pub container: TaggedContainerReference,
340    /// Unique identifier within the referenced container.
341    pub container_property_identifier: String,
342    #[serde(default)]
343    /// Whether this property is immutable.
344    pub immutable: bool,
345    #[serde(default)]
346    /// State of constraints on this property.
347    pub constraint_state: ViewConstraintState,
348}
349
350#[derive(Serialize, Deserialize, Derivative, Clone, Debug)]
351#[serde(rename_all = "lowercase", tag = "type")]
352/// View property type.
353pub enum ViewCorePropertyType {
354    /// Text property
355    Text(TextProperty),
356    /// Boolean property.
357    Boolean(PrimitiveProperty),
358    /// 32 bit floating point property.
359    Float32(PrimitiveProperty),
360    /// 64 bit floating point property.
361    Float64(PrimitiveProperty),
362    /// 32 bit integer property.
363    Int32(PrimitiveProperty),
364    /// 64 bit integer property.
365    Int64(PrimitiveProperty),
366    /// Timestamp property.
367    Timestamp(PrimitiveProperty),
368    /// Date property.
369    Date(PrimitiveProperty),
370    /// JSON object property.
371    Json(PrimitiveProperty),
372    /// Reference to a CDF timeseries.
373    Timeseries(CDFExternalIdReference),
374    /// Reference to a CDF file.
375    File(CDFExternalIdReference),
376    /// Reference to a CDF sequence.
377    Sequence(CDFExternalIdReference),
378    /// Direct relation to a node.
379    Direct(ViewDirectNodeRelation),
380    /// Enum property.
381    Enum(EnumProperty),
382}
383
384#[skip_serializing_none]
385#[derive(Serialize, Deserialize, Derivative, Clone, Debug)]
386#[serde(rename_all = "camelCase")]
387/// Direct node relation type, can include a hint to specify the view this direct
388/// relation points to.
389pub struct ViewDirectNodeRelation {
390    /// The required type for the node the direct relation points to.
391    pub container: Option<TaggedContainerReference>,
392    /// Hint showing the view that the direct relation points to.
393    pub source: Option<TaggedViewReference>,
394    #[serde(default)]
395    /// Whether this property is a list.
396    pub list: bool,
397    /// Maximum number of items in the list, if this is a list property.
398    pub max_list_size: Option<i32>,
399}