vantage_dataset/im/
valueset_writable.rs1use async_trait::async_trait;
2use vantage_types::{Entity, Record};
3
4use crate::{im::ImTable, traits::WritableValueSet};
5
6#[async_trait]
7impl<E> WritableValueSet for ImTable<E>
8where
9 E: Entity,
10{
11 async fn insert_value(
12 &self,
13 id: &Self::Id,
14 record: &Record<Self::Value>,
15 ) -> crate::traits::Result<Record<Self::Value>> {
16 let mut table = self.data_source.get_or_create_table(&self.table_name);
17
18 if let Some(existing_record) = table.get(id) {
20 return Ok(existing_record.clone());
21 }
22
23 table.insert(id.clone(), record.clone());
24 self.data_source.update_table(&self.table_name, table);
25
26 Ok(record.clone())
27 }
28
29 async fn replace_value(
30 &self,
31 id: &Self::Id,
32 record: &Record<Self::Value>,
33 ) -> crate::traits::Result<Record<Self::Value>> {
34 let mut table = self.data_source.get_or_create_table(&self.table_name);
35
36 table.insert(id.clone(), record.clone());
37 self.data_source.update_table(&self.table_name, table);
38
39 Ok(record.clone())
40 }
41
42 async fn patch_value(
43 &self,
44 id: &Self::Id,
45 partial: &Record<Self::Value>,
46 ) -> crate::traits::Result<Record<Self::Value>> {
47 let mut table = self.data_source.get_or_create_table(&self.table_name);
48
49 let mut existing_record = table
51 .get(id)
52 .ok_or_else(|| {
53 vantage_core::util::error::vantage_error!("Record with id '{}' not found", id)
54 })?
55 .clone();
56
57 for (key, value) in partial.iter() {
59 existing_record.insert(key.clone(), value.clone());
60 }
61
62 table.insert(id.clone(), existing_record.clone());
63 self.data_source.update_table(&self.table_name, table);
64
65 Ok(existing_record)
66 }
67
68 async fn delete(&self, id: &Self::Id) -> crate::traits::Result<()> {
69 let mut table = self.data_source.get_or_create_table(&self.table_name);
70
71 table.shift_remove(id);
73
74 self.data_source.update_table(&self.table_name, table);
75 Ok(())
76 }
77
78 async fn delete_all(&self) -> crate::traits::Result<()> {
79 let mut table = self.data_source.get_or_create_table(&self.table_name);
80 table.clear();
81 self.data_source.update_table(&self.table_name, table);
82 Ok(())
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use crate::im::ImDataSource;
90 use serde::{Deserialize, Serialize};
91 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
92 struct User {
93 id: Option<String>,
94 name: String,
95 }
96
97 #[tokio::test]
98 async fn test_replace_value() {
99 let ds = ImDataSource::new();
100 let table = ImTable::<User>::new(&ds, "users");
101
102 let mut record = Record::new();
103 record.insert(
104 "name".to_string(),
105 serde_json::Value::String("Alice".to_string()),
106 );
107 table
108 .replace_value(&"user1".to_string(), &record)
109 .await
110 .unwrap();
111 }
112
113 #[tokio::test]
114 async fn test_patch_value() {
115 let ds = ImDataSource::new();
116 let table = ImTable::<User>::new(&ds, "users");
117
118 let mut patch = Record::new();
120 patch.insert(
121 "name".to_string(),
122 serde_json::Value::String("Updated".to_string()),
123 );
124 let result = table.patch_value(&"nonexistent".to_string(), &patch).await;
125 assert!(result.is_err());
126 }
127
128 #[tokio::test]
129 async fn test_delete() {
130 let ds = ImDataSource::new();
131 let table = ImTable::<User>::new(&ds, "users");
132
133 table.delete(&"nonexistent".to_string()).await.unwrap();
135 }
136
137 #[tokio::test]
138 async fn test_delete_all() {
139 let ds = ImDataSource::new();
140 let table = ImTable::<User>::new(&ds, "users");
141
142 table.delete_all().await.unwrap();
143 }
144}