Skip to main content

vantage_dataset/im/
valueset_insertable.rs

1use async_trait::async_trait;
2use vantage_types::{Entity, Record};
3
4use crate::{im::ImTable, traits::InsertableValueSet};
5
6#[async_trait]
7impl<E> InsertableValueSet for ImTable<E>
8where
9    E: Entity,
10{
11    async fn insert_return_id_value(
12        &self,
13        record: &Record<Self::Value>,
14    ) -> crate::traits::Result<Self::Id> {
15        // Extract ID from record if present, otherwise generate random ID
16        let id = if let Some(record_id) = record.get("id") {
17            if record_id.is_null() {
18                self.generate_id()
19            } else if let Some(id_str) = record_id.as_str() {
20                if id_str.is_empty() {
21                    self.generate_id()
22                } else {
23                    id_str.to_string()
24                }
25            } else if let Some(id_num) = record_id.as_u64() {
26                id_num.to_string()
27            } else {
28                self.generate_id()
29            }
30        } else {
31            self.generate_id()
32        };
33
34        // Get current table and insert record
35        let mut table = self.data_source.get_or_create_table(&self.table_name);
36        table.insert(id.clone(), record.clone());
37
38        // Update the table in data source
39        self.data_source.update_table(&self.table_name, table);
40
41        Ok(id)
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48    use crate::im::ImDataSource;
49    use serde::{Deserialize, Serialize};
50
51    #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
52    struct User {
53        id: Option<String>,
54        name: String,
55    }
56
57    #[tokio::test]
58    async fn test_insert_return_id_value() {
59        let ds = ImDataSource::new();
60        let table = ImTable::<User>::new(&ds, "users");
61
62        let mut record = Record::new();
63        record.insert(
64            "name".to_string(),
65            serde_json::Value::String("Alice".to_string()),
66        );
67        let id = table.insert_return_id_value(&record).await.unwrap();
68        assert!(!id.is_empty());
69    }
70
71    #[tokio::test]
72    async fn test_insert_return_id_value_with_existing_id() {
73        let ds = ImDataSource::new();
74        let table = ImTable::<User>::new(&ds, "users");
75
76        let mut record = Record::new();
77        record.insert(
78            "id".to_string(),
79            serde_json::Value::String("user-123".to_string()),
80        );
81        record.insert(
82            "name".to_string(),
83            serde_json::Value::String("Bob".to_string()),
84        );
85        let id = table.insert_return_id_value(&record).await.unwrap();
86        assert_eq!(id, "user-123");
87    }
88
89    #[tokio::test]
90    async fn test_insert_return_id_value_with_null_id() {
91        let ds = ImDataSource::new();
92        let table = ImTable::<User>::new(&ds, "users");
93
94        let mut record = Record::new();
95        record.insert("id".to_string(), serde_json::Value::Null);
96        record.insert(
97            "name".to_string(),
98            serde_json::Value::String("Charlie".to_string()),
99        );
100        let id = table.insert_return_id_value(&record).await.unwrap();
101        assert!(!id.is_empty());
102        assert_ne!(id, "null");
103    }
104}