Skip to main content

vantage_dataset/im/
dataset_readable.rs

1use async_trait::async_trait;
2use indexmap::IndexMap;
3
4use vantage_types::{Entity, TryFromRecord};
5
6use crate::{
7    im::ImTable,
8    traits::{DataSet, ReadableDataSet, Result},
9};
10use vantage_core::util::error::vantage_error;
11
12#[async_trait]
13impl<E> DataSet<E> for ImTable<E> where E: Entity {}
14
15#[async_trait]
16impl<E> ReadableDataSet<E> for ImTable<E>
17where
18    E: Entity,
19    <E as TryFromRecord<serde_json::Value>>::Error: std::fmt::Debug,
20{
21    async fn list(&self) -> Result<IndexMap<Self::Id, E>> {
22        // Snapshot id+record pairs under the lock; convert outside it.
23        let rows = self.data_source.with_table(&self.table_name, |table| {
24            table
25                .iter()
26                .map(|(id, record)| (id.clone(), record.clone()))
27                .collect::<Vec<_>>()
28        });
29
30        let mut records = IndexMap::new();
31        for (id, record) in rows {
32            // Add the id field to the record for conversion
33            let mut record_with_id = record;
34            record_with_id.insert("id".to_string(), serde_json::Value::String(id.clone()));
35
36            let entity: E = E::try_from_record(&record_with_id)
37                .map_err(|e| vantage_error!("Failed to convert record to entity: {:?}", e))?;
38            records.insert(id, entity);
39        }
40
41        Ok(records)
42    }
43
44    async fn get(&self, id: impl Into<Self::Id> + Send) -> Result<Option<E>> {
45        let id = id.into();
46
47        let Some(record) = self
48            .data_source
49            .with_table(&self.table_name, |table| table.get(&id).cloned())
50        else {
51            return Ok(None);
52        };
53
54        let mut record_with_id = record;
55        record_with_id.insert("id".to_string(), serde_json::Value::String(id.clone()));
56
57        let entity = E::try_from_record(&record_with_id)
58            .map_err(|e| vantage_error!("Failed to convert record to entity: {:?}", e))?;
59        Ok(Some(entity))
60    }
61
62    async fn get_some(&self) -> Result<Option<(Self::Id, E)>> {
63        let Some((id, record)) = self.data_source.with_table(&self.table_name, |table| {
64            table
65                .iter()
66                .next()
67                .map(|(id, record)| (id.clone(), record.clone()))
68        }) else {
69            return Ok(None);
70        };
71
72        // Add the id field to the record for conversion
73        let mut record_with_id = record;
74        record_with_id.insert("id".to_string(), serde_json::Value::String(id.clone()));
75
76        let entity: E = E::try_from_record(&record_with_id)
77            .map_err(|e| vantage_error!("Failed to convert record to entity: {:?}", e))?;
78        Ok(Some((id, entity)))
79    }
80}
81
82// Tests are in tests/im_dataset.rs integration tests