1use std::collections::HashMap;
2
3use serde::{ser::SerializeSeq, Deserialize, Serialize};
4
5use crate::{
6 models::instances::InstanceId, ApiErrorDetail, FromErrorDetail, IntegerStringOrObject,
7};
8
9#[derive(Serialize, Deserialize, Debug, Hash, PartialEq, Eq, Clone)]
10#[serde(untagged, rename_all_fields = "camelCase")]
11pub enum Identity {
13 Id {
15 id: i64,
17 },
18 ExternalId {
20 external_id: String,
22 },
23}
24
25impl Identity {
26 pub fn id(id: i64) -> Self {
28 Identity::Id { id }
29 }
30
31 pub fn external_id(external_id: impl Into<String>) -> Self {
33 Identity::ExternalId {
34 external_id: external_id.into(),
35 }
36 }
37
38 pub fn into_external_id(self) -> Option<String> {
40 match self {
41 Identity::ExternalId { external_id } => Some(external_id),
42 _ => None,
43 }
44 }
45
46 pub fn into_id(self) -> Option<i64> {
48 match self {
49 Identity::Id { id } => Some(id),
50 _ => None,
51 }
52 }
53
54 pub fn as_external_id(&self) -> Option<&String> {
56 match self {
57 Identity::ExternalId { external_id } => Some(external_id),
58 _ => None,
59 }
60 }
61
62 pub fn as_id(&self) -> Option<i64> {
64 match self {
65 Identity::Id { id } => Some(*id),
66 _ => None,
67 }
68 }
69}
70
71impl Default for Identity {
72 fn default() -> Self {
73 Identity::Id { id: 0 }
74 }
75}
76
77impl From<i64> for Identity {
78 fn from(id: i64) -> Self {
79 Identity::Id { id }
80 }
81}
82
83impl From<&String> for Identity {
84 fn from(value: &String) -> Self {
85 Self::from(value.clone())
86 }
87}
88
89impl From<String> for Identity {
90 fn from(external_id: String) -> Self {
91 Identity::ExternalId { external_id }
92 }
93}
94
95impl From<&str> for Identity {
96 fn from(external_id: &str) -> Self {
97 Identity::ExternalId {
98 external_id: external_id.to_owned(),
99 }
100 }
101}
102
103impl FromErrorDetail for Identity {
104 fn from_detail(detail: &HashMap<String, Box<IntegerStringOrObject>>) -> Option<Self> {
105 ApiErrorDetail::get_integer(detail, "id")
106 .map(|id| Identity::Id { id })
107 .or_else(|| {
108 ApiErrorDetail::get_string(detail, "externalId").map(|id| Identity::ExternalId {
109 external_id: id.to_owned(),
110 })
111 })
112 }
113}
114
115#[derive(Serialize, Deserialize, Debug, Clone)]
116#[serde(rename_all = "camelCase")]
117pub struct CogniteId {
119 id: i64,
121}
122
123impl FromErrorDetail for CogniteId {
124 fn from_detail(detail: &HashMap<String, Box<IntegerStringOrObject>>) -> Option<Self> {
125 ApiErrorDetail::get_integer(detail, "id").map(|id| CogniteId { id })
126 }
127}
128
129#[derive(Serialize, Deserialize, Debug, Clone, Default)]
130#[serde(rename_all = "camelCase")]
131pub struct CogniteExternalId {
133 pub external_id: String,
135}
136
137impl FromErrorDetail for CogniteExternalId {
138 fn from_detail(detail: &HashMap<String, Box<IntegerStringOrObject>>) -> Option<Self> {
139 ApiErrorDetail::get_string(detail, "externalId").map(|external_id| CogniteExternalId {
140 external_id: external_id.to_owned(),
141 })
142 }
143}
144
145pub trait EqIdentity {
147 fn eq(&self, id: &Identity) -> bool;
149}
150
151impl From<String> for CogniteExternalId {
152 fn from(external_id: String) -> Self {
153 CogniteExternalId { external_id }
154 }
155}
156
157impl From<i64> for CogniteId {
158 fn from(id: i64) -> Self {
159 CogniteId { id }
160 }
161}
162
163#[derive(Debug, Deserialize, Serialize, Clone, Hash, Eq, PartialEq)]
164#[serde(rename_all_fields = "camelCase")]
165#[serde(untagged)]
166pub enum IdentityOrInstance {
168 Identity(Identity),
170 InstanceId {
172 instance_id: InstanceId,
174 },
175}
176
177impl IdentityOrInstance {
178 pub fn id(id: i64) -> Self {
180 Self::Identity(Identity::id(id))
181 }
182
183 pub fn external_id(external_id: impl Into<String>) -> Self {
185 Self::Identity(Identity::external_id(external_id))
186 }
187
188 pub fn instance_id(instance_id: impl Into<InstanceId>) -> Self {
190 Self::InstanceId {
191 instance_id: instance_id.into(),
192 }
193 }
194
195 pub fn as_id(&self) -> Option<i64> {
197 match self {
198 Self::Identity(i) => i.as_id(),
199 _ => None,
200 }
201 }
202
203 pub fn as_external_id(&self) -> Option<&String> {
205 match self {
206 Self::Identity(i) => i.as_external_id(),
207 _ => None,
208 }
209 }
210
211 pub fn as_identity(&self) -> Option<&Identity> {
213 match self {
214 Self::Identity(i) => Some(i),
215 _ => None,
216 }
217 }
218
219 pub fn as_instance_id(&self) -> Option<&InstanceId> {
221 match self {
222 Self::InstanceId { instance_id: i } => Some(i),
223 _ => None,
224 }
225 }
226}
227
228impl Default for IdentityOrInstance {
230 fn default() -> Self {
231 Self::Identity(Default::default())
232 }
233}
234
235impl From<&str> for IdentityOrInstance {
236 fn from(value: &str) -> Self {
237 Self::Identity(Identity::from(value))
238 }
239}
240
241impl From<&String> for IdentityOrInstance {
242 fn from(value: &String) -> Self {
243 Self::Identity(Identity::from(value))
244 }
245}
246
247impl From<String> for IdentityOrInstance {
248 fn from(value: String) -> Self {
249 Self::Identity(Identity::from(value))
250 }
251}
252
253impl From<i64> for IdentityOrInstance {
254 fn from(value: i64) -> Self {
255 Self::Identity(Identity::from(value))
256 }
257}
258
259impl From<Identity> for IdentityOrInstance {
260 fn from(value: Identity) -> Self {
261 Self::Identity(value)
262 }
263}
264
265impl From<InstanceId> for IdentityOrInstance {
266 fn from(value: InstanceId) -> Self {
267 Self::InstanceId { instance_id: value }
268 }
269}
270
271impl PartialEq<i64> for IdentityOrInstance {
272 fn eq(&self, other: &i64) -> bool {
273 self.as_id().as_ref() == Some(other)
274 }
275}
276
277impl PartialEq<str> for IdentityOrInstance {
278 fn eq(&self, other: &str) -> bool {
279 self.as_external_id().map(|a| a.as_str()) == Some(other)
280 }
281}
282
283impl PartialEq<InstanceId> for IdentityOrInstance {
284 fn eq(&self, other: &InstanceId) -> bool {
285 self.as_instance_id() == Some(other)
286 }
287}
288
289impl PartialEq<Identity> for IdentityOrInstance {
290 fn eq(&self, other: &Identity) -> bool {
291 self.as_identity() == Some(other)
292 }
293}
294
295impl FromErrorDetail for IdentityOrInstance {
296 fn from_detail(detail: &HashMap<String, Box<IntegerStringOrObject>>) -> Option<Self> {
297 if let Some(object) = ApiErrorDetail::get_object(detail, "instanceId") {
298 match (
299 ApiErrorDetail::get_string(object, "space"),
300 ApiErrorDetail::get_string(object, "externalId"),
301 ) {
302 (Some(space), Some(external_id)) => Some(Self::InstanceId {
303 instance_id: InstanceId {
304 space: space.to_owned(),
305 external_id: external_id.to_owned(),
306 },
307 }),
308 _ => None,
309 }
310 } else {
311 Identity::from_detail(detail).map(Self::Identity)
312 }
313 }
314}
315
316pub struct IdentityList<R>(R);
321
322impl<R> From<R> for IdentityList<R> {
323 fn from(value: R) -> Self {
324 IdentityList(value)
325 }
326}
327
328pub struct IdentityOrInstanceList<R>(R);
333
334impl<T> Serialize for IdentityOrInstanceList<T>
335where
336 IdentityList<T>: Serialize,
337 T: Copy,
338{
339 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
340 where
341 S: serde::Serializer,
342 {
343 IdentityList(self.0).serialize(serializer)
344 }
345}
346
347impl<R> From<R> for IdentityOrInstanceList<R> {
348 fn from(value: R) -> Self {
349 IdentityOrInstanceList(value)
350 }
351}
352
353macro_rules! identity_list_ser_directly {
354 ($r:ident, $t:ty) => {
355 impl Serialize for $r<$t> {
356 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
357 where
358 S: serde::Serializer,
359 {
360 self.0.serialize(serializer)
361 }
362 }
363 };
364 ($r:ident, $t:ty, $n:ident) => {
365 impl<const $n: usize> Serialize for $r<$t> {
366 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
367 where
368 S: serde::Serializer,
369 {
370 self.0.serialize(serializer)
371 }
372 }
373 };
374}
375
376identity_list_ser_directly!(IdentityList, &Vec<Identity>);
377identity_list_ser_directly!(IdentityOrInstanceList, &Vec<IdentityOrInstance>);
378identity_list_ser_directly!(IdentityList, &Vec<CogniteExternalId>);
379identity_list_ser_directly!(IdentityList, &Vec<CogniteId>);
380identity_list_ser_directly!(IdentityList, &Vec<&Identity>);
381identity_list_ser_directly!(IdentityOrInstanceList, &Vec<&IdentityOrInstance>);
382identity_list_ser_directly!(IdentityList, &Vec<&CogniteExternalId>);
383identity_list_ser_directly!(IdentityList, &Vec<&CogniteId>);
384identity_list_ser_directly!(IdentityList, &[Identity]);
385identity_list_ser_directly!(IdentityOrInstanceList, &[IdentityOrInstance]);
386identity_list_ser_directly!(IdentityList, &[CogniteExternalId]);
387identity_list_ser_directly!(IdentityList, &[CogniteId]);
388identity_list_ser_directly!(IdentityList, &[&Identity]);
389identity_list_ser_directly!(IdentityOrInstanceList, &[&IdentityOrInstance]);
390identity_list_ser_directly!(IdentityList, &[&CogniteExternalId]);
391identity_list_ser_directly!(IdentityList, &[&CogniteId]);
392identity_list_ser_directly!(IdentityList, &[Identity; N], N);
393identity_list_ser_directly!(IdentityOrInstanceList, &[IdentityOrInstance; N], N);
394identity_list_ser_directly!(IdentityList, &[CogniteExternalId; N], N);
395identity_list_ser_directly!(IdentityList, &[CogniteId; N], N);
396identity_list_ser_directly!(IdentityList, &[&Identity; N], N);
397identity_list_ser_directly!(IdentityOrInstanceList, &[&IdentityOrInstance; N], N);
398identity_list_ser_directly!(IdentityList, &[&CogniteExternalId; N], N);
399identity_list_ser_directly!(IdentityList, &[&CogniteId; N], N);
400
401#[derive(Serialize)]
402#[serde(rename_all = "camelCase")]
403struct ExternalIdRef<'a, T> {
404 external_id: &'a T,
405}
406
407macro_rules! identity_list_ser_external_id {
408 ($t:ty) => {
409 impl Serialize for IdentityList<$t> {
410 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
411 where
412 S: serde::Serializer,
413 {
414 let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
415 for id in self.0.iter() {
416 seq.serialize_element(&ExternalIdRef { external_id: id })?;
417 }
418 seq.end()
419 }
420 }
421 };
422
423 ($t:ty, $n:ident) => {
424 impl<const $n: usize> Serialize for IdentityList<$t> {
425 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
426 where
427 S: serde::Serializer,
428 {
429 let mut seq = serializer.serialize_seq(Some($n))?;
430 for id in self.0.iter() {
431 seq.serialize_element(&ExternalIdRef { external_id: id })?;
432 }
433 seq.end()
434 }
435 }
436 };
437}
438identity_list_ser_external_id!(&Vec<String>);
439identity_list_ser_external_id!(&[String]);
440identity_list_ser_external_id!(&[String; N], N);
441identity_list_ser_external_id!(&Vec<&String>);
442identity_list_ser_external_id!(&[&String]);
443identity_list_ser_external_id!(&[&String; N], N);
444identity_list_ser_external_id!(&Vec<&str>);
445identity_list_ser_external_id!(&[&str]);
446identity_list_ser_external_id!(&[&str; N], N);
447
448macro_rules! identity_list_ser_id {
449 ($t:ty) => {
450 impl Serialize for IdentityList<$t> {
451 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
452 where
453 S: serde::Serializer,
454 {
455 let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
456 for id in self.0.iter() {
457 seq.serialize_element(&CogniteId { id: *id })?;
458 }
459 seq.end()
460 }
461 }
462 };
463
464 ($t:ty, $n:ident) => {
465 impl<const N: usize> Serialize for IdentityList<$t> {
466 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
467 where
468 S: serde::Serializer,
469 {
470 let mut seq = serializer.serialize_seq(Some(N))?;
471 for id in self.0.iter() {
472 seq.serialize_element(&CogniteId { id: *id })?;
473 }
474 seq.end()
475 }
476 }
477 };
478}
479
480identity_list_ser_id!(&Vec<i64>);
481identity_list_ser_id!(&[i64]);
482identity_list_ser_id!(&[i64; N], N);
483
484#[derive(Serialize)]
485#[serde(rename_all = "camelCase")]
486struct InstanceIdRef<'a> {
487 instance_id: &'a InstanceId,
488}
489
490macro_rules! identity_list_ser_instance_id {
491 ($t:ty) => {
492 impl Serialize for IdentityOrInstanceList<$t> {
493 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
494 where
495 S: serde::Serializer,
496 {
497 let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
498 for id in self.0.iter() {
499 seq.serialize_element(&InstanceIdRef { instance_id: id })?;
500 }
501 seq.end()
502 }
503 }
504 };
505
506 ($t:ty, $n:ident) => {
507 impl<const N: usize> Serialize for IdentityOrInstanceList<$t> {
508 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
509 where
510 S: serde::Serializer,
511 {
512 let mut seq = serializer.serialize_seq(Some(N))?;
513 for id in self.0.iter() {
514 seq.serialize_element(&InstanceIdRef { instance_id: id })?;
515 }
516 seq.end()
517 }
518 }
519 };
520}
521
522identity_list_ser_instance_id!(&Vec<InstanceId>);
523identity_list_ser_instance_id!(&[InstanceId]);
524identity_list_ser_instance_id!(&[InstanceId; N], N);
525identity_list_ser_instance_id!(&Vec<&InstanceId>);
526identity_list_ser_instance_id!(&[&InstanceId]);
527identity_list_ser_instance_id!(&[&InstanceId; N], N);
528
529macro_rules! identity_list_ser_single {
530 ($r:ident, $t:ty) => {
531 impl Serialize for $r<$t> {
532 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
533 where
534 S: serde::Serializer,
535 {
536 Serialize::serialize(&$r(&[self.0]), serializer)
537 }
538 }
539 };
540}
541
542identity_list_ser_single!(IdentityList, i64);
543identity_list_ser_single!(IdentityList, &str);
544identity_list_ser_single!(IdentityList, &String);
545identity_list_ser_single!(IdentityOrInstanceList, &InstanceId);
546identity_list_ser_single!(IdentityList, &Identity);
547identity_list_ser_single!(IdentityOrInstanceList, &IdentityOrInstance);
548identity_list_ser_single!(IdentityList, &CogniteExternalId);
549identity_list_ser_single!(IdentityList, &CogniteId);