cal_core/
shared.rs

1use std::fmt::{Debug, Formatter};
2use std::collections::BTreeMap;
3use bson::DateTime;
4use serde::{Deserialize, Deserializer, Serialize};
5use serde_json::Value;
6#[cfg(feature = "openapi")]
7use utoipa::ToSchema;
8
9#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Hash)]
10#[serde(rename_all = "camelCase")]
11#[cfg_attr(feature = "openapi", derive(ToSchema))]
12pub struct RecordReference {
13    #[serde(deserialize_with = "object_id_as_string", rename = "_id")]
14    pub id: String,
15    pub name: String,
16    #[serde(default)]
17    pub meta: BTreeMap<String, String>,
18}
19
20impl RecordReference {
21    /// Create a new RecordReference with empty metadata
22    pub fn new(id: String, name: String) -> Self {
23        Self {
24            id,
25            name,
26            meta: BTreeMap::new(),
27        }
28    }
29
30    /// Create a new RecordReference with metadata
31    pub fn with_meta(id: String, name: String, meta: BTreeMap<String, String>) -> Self {
32        Self { id, name, meta }
33    }
34
35    /// Create from a HashMap (for compatibility)
36    pub fn with_meta_from_hashmap(id: String, name: String, meta: std::collections::HashMap<String, String>) -> Self {
37        Self {
38            id,
39            name,
40            meta: meta.into_iter().collect()
41        }
42    }
43
44    /// Convenience methods matching Java API
45    pub fn id(&self) -> &str {
46        &self.id
47    }
48
49    pub fn name(&self) -> &str {
50        &self.name
51    }
52}
53
54pub fn from_str<'de, D>(deserializer: D) -> Result<u16, D::Error>
55where
56    D: Deserializer<'de>,
57{
58    let value = Value::deserialize(deserializer)?;
59    if value.is_string() {
60        Ok(value.as_str().unwrap().parse().unwrap())
61    } else if value.is_u64() {
62        Ok(value.as_u64().unwrap() as u16)
63    } else if value.is_i64() {
64        Ok(value.as_i64().unwrap() as u16)
65    } else {
66        Err(serde::de::Error::custom("Cannot map extension to u16"))
67    }
68}
69
70pub fn object_id_as_string<'de, D>(deserializer: D) -> Result<String, D::Error>
71where
72    D: Deserializer<'de>,
73{
74    let value = Value::deserialize(deserializer)?;
75    if value.is_string() {
76        Ok(value.as_str().unwrap().to_string())
77    } else {
78        match value.get("$oid") {
79            Some(v) => Ok(v.as_str().unwrap().to_string()),
80            None => Err(serde::de::Error::custom("Oid is required")),
81        }
82    }
83}
84
85pub fn build_timestamp() -> DateTime {
86    DateTime::now()
87}
88
89pub fn build_id() -> String {
90    bson::uuid::Uuid::new().to_string()
91}
92
93impl Debug for RecordReference {
94    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
95        f.debug_struct("RecordReference")
96            .field("id", &self.id)
97            .field("name", &self.name)
98            .field("meta", &self.meta)
99            .finish()
100    }
101}