oswilno/crates/oswilno-parking-space/src/lib.rs
2023-08-03 16:16:46 +02:00

103 lines
3.0 KiB
Rust

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_rents::Model>,
parking_space_by_id: HashMap<i32, parking_spaces::Model>,
account_by_id: HashMap<i32, accounts::Model>,
}
#[derive(Template)]
#[template(path = "../templates/parking-spaces/all-partial.html")]
struct AllPartialParkingSpace {
parking_space_rents: Vec<parking_space_rents::Model>,
parking_space_by_id: HashMap<i32, parking_spaces::Model>,
account_by_id: HashMap<i32, accounts::Model>,
}
#[get("/all")]
async fn all_parking_spaces(db: Data<sea_orm::DatabaseConnection>) -> AllParkingSpace {
let db = db.into_inner();
load_parking_spaces(db).await
}
#[get("/all-partial")]
async fn all_parial_parking_spaces(
db: Data<sea_orm::DatabaseConnection>,
) -> 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<DatabaseConnection>) -> 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::<Vec<i32>>();
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,
}
}