unifly_api/integration/types/
common.rs1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use uuid::Uuid;
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13#[serde(rename_all = "camelCase")]
14#[serde(bound(deserialize = "T: serde::de::DeserializeOwned"))]
15pub struct Page<T> {
16 pub offset: i64,
17 pub limit: i32,
18 pub count: i32,
19 pub total_count: i64,
20 #[serde(deserialize_with = "lenient_items")]
21 pub data: Vec<T>,
22}
23
24fn lenient_items<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
25where
26 D: serde::Deserializer<'de>,
27 T: serde::de::DeserializeOwned,
28{
29 let raw = Vec::<Value>::deserialize(deserializer)?;
30 Ok(raw
31 .into_iter()
32 .filter_map(|item| match serde_json::from_value::<T>(item) {
33 Ok(parsed) => Some(parsed),
34 Err(error) => {
35 tracing::warn!(
39 item_type = std::any::type_name::<T>(),
40 category = ?error.classify(),
41 "skipping list item that failed to parse"
42 );
43 None
44 }
45 })
46 .collect())
47}
48
49#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
51#[serde(rename_all = "camelCase")]
52pub struct SiteResponse {
53 pub id: Uuid,
54 pub name: String,
55 pub internal_reference: String,
57}
58
59#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
61#[serde(rename_all = "camelCase")]
62pub struct ApplicationInfoResponse {
63 #[serde(flatten)]
64 pub fields: HashMap<String, Value>,
65}
66
67#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
69#[serde(rename_all = "camelCase")]
70pub struct ErrorResponse {
71 pub message: Option<String>,
72 #[serde(flatten)]
73 pub extra: HashMap<String, Value>,
74}