use actix_web::get; use actix_web::web::{scope, Data, ServiceConfig}; use askama_actix::Template; use oswilno_contract::accounts; use oswilno_contract::parking_space_rents; use oswilno_contract::parking_spaces; use sea_orm::prelude::*; use std::collections::HashMap; use std::sync::Arc; pub fn mount(config: &mut ServiceConfig) { config.service( scope("/parking_spaces") .service(all_parking_spaces) .service(all_parial_parking_spaces), ); } #[derive(Template)] #[template(path = "../templates/parking-spaces/all.html")] struct AllParkingSpace { parking_space_rents: Vec, parking_space_by_id: HashMap, account_by_id: HashMap, } #[derive(Template)] #[template(path = "../templates/parking-spaces/all-partial.html")] struct AllPartialParkingSpace { parking_space_rents: Vec, parking_space_by_id: HashMap, account_by_id: HashMap, } #[get("/all")] async fn all_parking_spaces(db: Data) -> AllParkingSpace { let db = db.into_inner(); load_parking_spaces(db).await } #[get("/all-partial")] async fn all_parial_parking_spaces( db: Data, ) -> AllPartialParkingSpace { let db = db.into_inner(); let AllParkingSpace { parking_space_rents, parking_space_by_id, account_by_id, } = load_parking_spaces(db).await; AllPartialParkingSpace { parking_space_rents, parking_space_by_id, account_by_id, } } async fn load_parking_spaces(db: Arc) -> AllParkingSpace { let rents = parking_space_rents::Entity::find().all(&*db).await.unwrap(); let (parking_space_by_id, account_ids) = { let ids = rents .iter() .map(|r| r.parking_space_id) .collect::>(); let v = parking_spaces::Entity::find() .filter(parking_spaces::Column::Id.is_in(ids)) .all(&*db) .await .unwrap(); let len = v.len(); v.into_iter().fold( (HashMap::with_capacity(len), Vec::with_capacity(len)), |(mut by_id, mut ids), space| { ids.push(space.account_id); by_id.insert(space.id, space); (by_id, ids) }, ) }; let account_by_id = { let accounts = accounts::Entity::find() .filter(accounts::Column::Id.is_in(account_ids)) .all(&*db) .await .unwrap(); let len = accounts.len(); accounts .into_iter() .fold(HashMap::with_capacity(len), |mut agg, account| { agg.insert(account.id, account); agg }) }; AllParkingSpace { account_by_id, parking_space_rents: rents, parking_space_by_id, } }