vantage_csv/
expr_data_source.rs1use vantage_expressions::traits::datasource::ExprDataSource;
7use vantage_expressions::traits::expressive::DeferredFn;
8use vantage_expressions::{Expression, defer_execute, execute_by_resolving};
9
10use crate::Csv;
11use crate::condition::resolve_param;
12use crate::type_system::AnyCsvType;
13
14impl ExprDataSource<AnyCsvType> for Csv {
15 async fn execute(&self, expr: &Expression<AnyCsvType>) -> vantage_core::Result<AnyCsvType> {
16 execute_by_resolving(
19 expr,
20 |template| AnyCsvType::new(template.to_string()),
21 |params| async move {
22 let mut results = Vec::with_capacity(params.len());
23 for param in params {
24 results.push(resolve_param(param).await?.value().clone());
25 }
26 Ok(AnyCsvType::new(results.join(",")))
27 },
28 )
29 .await
30 }
31
32 fn defer(&self, expr: Expression<AnyCsvType>) -> DeferredFn<AnyCsvType>
33 where
34 AnyCsvType: Clone + Send + Sync + 'static,
35 {
36 defer_execute(self, expr)
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43 use vantage_table::table::Table;
44 use vantage_table::traits::table_source::TableSource;
45 use vantage_types::EmptyEntity;
46
47 fn test_csv() -> Csv {
48 Csv::new(format!("{}/data", env!("CARGO_MANIFEST_DIR")))
49 }
50
51 #[tokio::test]
52 async fn test_execute_column_table_values_expr() {
53 let csv = test_csv();
54 let table = Table::<Csv, EmptyEntity>::new("client", csv.clone())
55 .with_column_of::<String>("name")
56 .with_column_of::<bool>("is_paying_client");
57
58 let name_col = csv.create_column::<String>("name");
59 let associated = csv.column_table_values_expr(&table, &name_col);
60 let result = csv.execute(associated.expression()).await.unwrap();
61
62 let names = result.try_get::<Vec<AnyCsvType>>().unwrap();
64 let name_strings: Vec<&str> = names.iter().map(|v| v.value().as_str()).collect();
65 assert!(name_strings.contains(&"Marty McFly"));
66 assert!(name_strings.contains(&"Doc Brown"));
67 assert!(name_strings.contains(&"Biff Tannen"));
68 }
69
70 #[tokio::test]
71 async fn test_execute_column_values_with_condition() {
72 use crate::operation::CsvOperation;
73
74 let csv = test_csv();
75 let mut table = Table::<Csv, EmptyEntity>::new("client", csv.clone())
76 .with_column_of::<String>("name")
77 .with_column_of::<bool>("is_paying_client");
78
79 table.add_condition(table["is_paying_client"].eq(AnyCsvType::new(true)));
80
81 let name_col = csv.create_column::<String>("name");
82 let associated = csv.column_table_values_expr(&table, &name_col);
83 let result = csv.execute(associated.expression()).await.unwrap();
84
85 let names = result.try_get::<Vec<AnyCsvType>>().unwrap();
86 let name_strings: Vec<&str> = names.iter().map(|v| v.value().as_str()).collect();
87 assert!(name_strings.contains(&"Marty McFly"));
88 assert!(name_strings.contains(&"Doc Brown"));
89 assert!(!name_strings.contains(&"Biff Tannen"));
90 }
91}