vantage_table/table/
row_fields.rs1use indexmap::IndexMap;
5use vantage_types::{Entity, Record};
6
7use crate::{
8 column::flags::ColumnFlag,
9 table::Table,
10 traits::{column_like::ColumnLike, table_source::TableSource},
11};
12
13impl<T: TableSource, E: Entity<T::Value>> Table<T, E> {
14 pub fn row_fields(&self) -> Vec<String> {
20 self.columns()
21 .iter()
22 .filter(|(_, column)| !column.flags().contains(&ColumnFlag::RequestParam))
23 .map(|(name, _)| name.clone())
24 .collect()
25 }
26}
27
28pub fn retain_matching<V, W: ?Sized>(
37 rows: &mut IndexMap<String, Record<V>>,
38 filters: &[(&str, &W)],
39 row_fields: &[String],
40 eq: impl Fn(&V, &W) -> bool,
41) {
42 rows.retain(|_, row| {
43 filters.iter().all(|(field, wanted)| match row.get(*field) {
44 Some(value) => eq(value, wanted),
45 None => !row_fields.iter().any(|f| f == field),
46 })
47 });
48}
49
50#[cfg(test)]
51mod tests {
52 use indexmap::IndexMap;
53 use vantage_types::{EmptyEntity, Record};
54
55 use super::retain_matching;
56 use crate::column::flags::ColumnFlag;
57 use crate::mocks::{mock_column::MockColumn, mock_table_source::MockTableSource};
58 use crate::table::Table;
59
60 #[test]
61 fn a_missing_field_fails_only_when_rows_carry_it() {
62 let row = |pairs: &[(&str, i64)]| -> Record<i64> {
63 pairs.iter().map(|(k, v)| (k.to_string(), *v)).collect()
64 };
65 let mut rows: IndexMap<String, Record<i64>> = [
66 ("a".to_string(), row(&[("size", 1)])),
67 ("b".to_string(), row(&[("size", 2)])),
68 ("c".to_string(), row(&[])),
69 ]
70 .into_iter()
71 .collect();
72 let row_fields = vec!["size".to_string()];
73
74 retain_matching(&mut rows, &[("prefix", &9)], &row_fields, |a, b| a == b);
76 assert_eq!(rows.len(), 3);
77
78 retain_matching(&mut rows, &[("size", &1)], &row_fields, |a, b| a == b);
80 assert_eq!(rows.keys().collect::<Vec<_>>(), ["a"]);
81 }
82
83 #[test]
84 fn row_fields_leave_out_request_params_but_keep_hidden_columns() {
85 let table = Table::<MockTableSource, EmptyEntity>::new("buckets", MockTableSource::new())
86 .with_column(MockColumn::<String>::new("region").with_flag(ColumnFlag::RequestParam))
87 .with_column(MockColumn::<String>::new("name"))
88 .with_column(MockColumn::<String>::new("owner").with_flag(ColumnFlag::Hidden));
89 assert_eq!(table.row_fields(), ["name", "owner"]);
90 }
91}