use crate::db; use crate::db::errors::DatabaseError; use crate::db::{DbRelay, DbSchedule}; use futures::executor; use serde_derive::Serialize; use sqlx::pool::PoolConnection; use sqlx::Sqlite; pub trait FromDbModel { type DbModel: Clone; fn from_db_model( conn: &mut PoolConnection<Sqlite>, db_model: Self::DbModel, ) -> Result<Self, DatabaseError> where Self: Sized; } #[derive(Serialize, Debug)] pub struct Schedule { #[serde(flatten)] pub schedule: DbSchedule, pub tags: Vec<String>, } #[derive(Serialize, Debug)] pub struct Relay { #[serde(flatten)] pub relay: DbRelay, pub controller: db::DbController, pub tags: Vec<String>, } #[derive(Serialize, Debug)] pub struct Controller { #[serde(flatten)] pub controller: db::DbController, pub relays: Vec<Relay>, } impl FromDbModel for Schedule { type DbModel = DbSchedule; fn from_db_model( conn: &mut PoolConnection<Sqlite>, db_model: Self::DbModel, ) -> Result<Self, DatabaseError> { let schedule = db_model.clone(); let tags = executor::block_on(schedule.get_tags(conn))?; Ok(Schedule { schedule, tags }) } } impl FromDbModel for Relay { type DbModel = DbRelay; fn from_db_model( conn: &mut PoolConnection<Sqlite>, db_model: Self::DbModel, ) -> Result<Self, DatabaseError> { let relay = db_model.clone(); let controller = executor::block_on(relay.get_controller(conn))?; let tags = executor::block_on(relay.get_tags(conn))?; Ok(Relay { relay, controller, tags, }) } } pub fn convert_db_list<T: FromDbModel>( conn: &mut PoolConnection<Sqlite>, db_models: Vec<T::DbModel>, ) -> Result<Vec<T>, DatabaseError> { let mut result: Vec<T> = Vec::new(); db_models.into_iter().try_for_each(|s| { let new = T::from_db_model(conn, s); match new { Ok(new) => { result.push(new); Ok(()) } Err(e) => Err(e), } })?; Ok(result) }