libhaystack/haystack/filter/filtered/
grid.rs

1// Copyright (C) 2020 - 2022, J2 Innovations
2
3//! Haystack Filtered Grid
4
5use super::super::Filter;
6use super::Filtered;
7use super::ListFiltered;
8use crate::val::Dict;
9use crate::val::Grid;
10
11/// Implement the Filtered trait for Grid.
12impl<'a> Filtered<'a, Option<&'a Dict>> for Grid {
13    /// This will find the first matching Dict in the grid, one None
14    //
15    /// # Example
16    /// ```
17    ///  use libhaystack::dict;
18    ///  use libhaystack::val::{Dict, Grid, Value};
19    ///  use libhaystack::filter::{Filter, Filtered};
20    ///  let rows = vec![
21    ///   dict! {
22    ///    "site" => Value::make_marker(),
23    ///    "dis" => Value::make_str("Site")
24    ///   },
25    ///   dict! {
26    ///    "equip" => Value::make_marker(),
27    ///    "navName" => Value::make_str("Equip")
28    ///   },
29    ///   ];
30    ///  let grid = Grid::make_from_dicts(rows);
31    ///  assert_eq!(grid.filter(&Filter::try_from("equip and navName").expect("Filter")), Some(&dict! {
32    ///    "equip" => Value::make_marker(),
33    ///    "navName" => Value::make_str("Equip")
34    ///   }));
35    /// ```
36    fn filter(&'a self, filter: &Filter) -> Option<&'a Dict> {
37        self.rows.iter().find(|&dict| dict.filter(filter))
38    }
39}
40
41impl<'a> ListFiltered<'a, Dict> for Grid {
42    /// Find all rows in the grid that match the given filter.
43    ///
44    /// # Example
45    /// ```
46    ///  use libhaystack::dict;
47    ///  use libhaystack::val::{Dict, Grid, Value};
48    ///  use libhaystack::filter::{Filter, ListFiltered};
49    ///  let rows = vec![
50    ///   dict! { "a" => Value::make_marker()},
51    ///   dict! { "b" => Value::make_marker()}];
52    ///  let grid = Grid::make_from_dicts(rows);
53    ///  let res = grid.filter_all(&Filter::try_from("a or b").unwrap());
54    ///  assert_eq!(res.len(), 2);
55    /// ```
56    fn filter_all(&'a self, filter: &Filter) -> Vec<&'a Dict> {
57        let mut dicts = Vec::<&'a Dict>::new();
58        for dict in &self.rows {
59            if dict.filter(filter) {
60                dicts.push(dict)
61            }
62        }
63        dicts
64    }
65}