use mysql::prelude::*; use mysql::*; use mysql_common::frunk::{hlist_pat, HList}; use struct_field_names_as_array::FieldNamesAsArray; use time::PrimitiveDateTime; #[allow(non_snake_case)] #[derive(Debug, PartialEq, FieldNamesAsArray)] pub struct Purchase { id: u32, pub nutrition_id: u32, pub amount: u32, pub datetime: PrimitiveDateTime, } type RowType = HList!(u32, u32, u32, PrimitiveDateTime); impl Purchase { fn get_sql_fields() -> String { Purchase::FIELD_NAMES_AS_ARRAY .iter() .cloned() .intersperse(", ") .collect() } fn query_map_helper() -> (String, impl Fn(RowType) -> Purchase) { let sql_query = format!("SELECT {} from purchases", Self::get_sql_fields()); println!("{}", sql_query); let construction_closure = |row: RowType| { let hlist_pat![id, nutrition_id, amount, datetime] = row; Purchase { id, nutrition_id, amount, datetime, } }; (sql_query, construction_closure) } pub async fn get_purchase_rows(sql_pool: Pool) -> Result> { let mut conn = sql_pool .get_conn() .expect("Cannot establish database connection"); let (purchases_query, purchases_closure) = Self::query_map_helper(); let purchases_val: Vec = conn .query_map(purchases_query, purchases_closure) .expect("Data in database doesn't match the Purchase class"); Ok(purchases_val) } }