pobsd_db/
query_result.rs

1//! Provides a representation of the query result returned when
2//! interogating the database. Query results are themselves queriable
3//! and return another query result.
4use crate::Item;
5use paste::paste;
6use pobsd_parser::Game;
7
8macro_rules! get_game_by {
9    ($field:ident) => {
10        paste! {
11            /// Get game by field name (case sensitive)
12            pub fn [<get_game_by_ $field>](self, field: &str) -> QueryResult<&'a Game> {
13                let mut items: Vec<&Game> = self
14                    .items
15                    .clone()
16                    .into_iter()
17                    .filter(|a| a.$field.eq(&Some(field.to_string())))
18                    .collect();
19                items.sort();
20                QueryResult{
21                    count: items.len(),
22                    items
23                }
24            }
25        }
26    };
27    (array $field:ident) => {
28        paste! {
29            /// Get game by field name (case sensitive)
30            pub fn [<get_game_by_ $field>](self, field: &str) -> QueryResult<&'a Game> {
31                let mut items: Vec<&Game> = self
32                    .items
33                    .clone()
34                    .into_iter()
35                    .filter(|a| match &a.$field {
36                        Some(items) => items.contains(&field.to_string()),
37                        None => false,
38                    })
39                    .collect();
40                items.sort();
41                QueryResult{
42                    count: items.len(),
43                    items
44                }
45            }
46        }
47    };
48}
49
50/// Representation of the result of a query
51pub struct QueryResult<T> {
52    /// Number of items in the query result
53    pub count: usize,
54    /// Vector of items
55    pub items: Vec<T>,
56}
57
58impl<T> QueryResult<T> {
59    // Returns a reference to an element or subslice depending on the type of index
60    pub fn get(&self, index: usize) -> Option<&T> {
61        self.items.get(index)
62    }
63    // Returns a mutable reference to an element or subslice depending on the type of index
64    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
65        self.items.get_mut(index)
66    }
67    // Return the vector of items stored in the query result
68    pub fn into_inner(self) -> Vec<T> {
69        self.items
70    }
71}
72
73impl QueryResult<Item> {
74    /// Get item by name (case sensitive)
75    pub fn get_item_by_name(&self, name: &str) -> Option<Item> {
76        let mut items: Vec<&Item> = self.items.iter().filter(|a| a.eq(&name)).collect();
77        items.pop().cloned()
78    }
79    /// Search items by name (case insensitive)
80    pub fn search_item_by_name(self, name: &str) -> QueryResult<Item> {
81        let items: Vec<Item> = self
82            .items
83            .into_iter()
84            .filter(|a| a.to_lowercase().contains(&name.to_lowercase()))
85            .collect();
86        QueryResult {
87            count: items.len(),
88            items,
89        }
90    }
91}
92
93impl<'a> QueryResult<&'a Game> {
94    /// Get game by name (case sensitive)
95    pub fn get_game_by_name(self, name: &str) -> Option<&'a Game> {
96        let mut items: Vec<&Game> = self.items.into_iter().filter(|a| a.name.eq(name)).collect();
97        items.pop()
98    }
99    /// Search games by name (case insensitive)
100    pub fn search_game_by_name(self, name: &str) -> QueryResult<&'a Game> {
101        let items: Vec<&Game> = self
102            .items
103            .into_iter()
104            .filter(|a| a.name.to_lowercase().contains(&name.to_lowercase()))
105            .collect();
106        QueryResult {
107            count: items.len(),
108            items,
109        }
110    }
111    get_game_by!(runtime);
112    get_game_by!(year);
113    get_game_by!(dev);
114    get_game_by!(publi);
115    get_game_by!(engine);
116    get_game_by!(array genres);
117    get_game_by!(array tags);
118}