66 lines
1.9 KiB
Rust
66 lines
1.9 KiB
Rust
//! Read-only view of the fleet, used by the reservation form to show which
|
|
//! cargo bikes can be picked.
|
|
|
|
use aide::{
|
|
axum::{
|
|
ApiRouter,
|
|
routing::{get_with, put_with},
|
|
},
|
|
transform::TransformOperation,
|
|
};
|
|
use axum::{Json, extract::Path, http::StatusCode};
|
|
use schemars::JsonSchema;
|
|
use serde::Deserialize;
|
|
|
|
use crate::{
|
|
api::helpers::{IdPath, admin, admin_desc, unexpected_error},
|
|
core::{
|
|
controller::{AnonAppController, AppController},
|
|
models::bike::{Bike, BikeStatus},
|
|
},
|
|
};
|
|
|
|
pub fn routes() -> ApiRouter {
|
|
ApiRouter::new()
|
|
.api_route("/", get_with(get_bikes, get_bikes_docs))
|
|
.api_route("/{id}/status", put_with(set_status, set_status_docs))
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, JsonSchema)]
|
|
struct SetStatusForm {
|
|
status: BikeStatus,
|
|
}
|
|
|
|
/// Takes a bike in or out of the fleet. Deleting is not offered: a bike that
|
|
/// has been booked must stay, for the history.
|
|
#[axum::debug_handler]
|
|
async fn set_status(
|
|
ac: AppController,
|
|
Path(IdPath { id }): Path<IdPath>,
|
|
Json(SetStatusForm { status }): Json<SetStatusForm>,
|
|
) -> Result<(), (StatusCode, String)> {
|
|
match admin(ac)?.set_bike_status(id, status).await {
|
|
Ok(()) => Ok(()),
|
|
Err(err) if err.is_not_found() => Err((StatusCode::NOT_FOUND, "No such bike".to_owned())),
|
|
Err(err) => unexpected_error("set_bike_status", err),
|
|
}
|
|
}
|
|
|
|
fn set_status_docs(op: TransformOperation) -> TransformOperation {
|
|
op.tag("Bikes")
|
|
.summary("Put a bike in or out of service")
|
|
.response_with::<403, (), _>(admin_desc)
|
|
.response::<404, ()>()
|
|
}
|
|
|
|
#[axum::debug_handler]
|
|
async fn get_bikes(aac: AnonAppController) -> Result<Json<Vec<Bike>>, (StatusCode, String)> {
|
|
match aac.get_bikes().await {
|
|
Ok(bikes) => Ok(Json(bikes)),
|
|
Err(err) => unexpected_error("get_bikes", err),
|
|
}
|
|
}
|
|
|
|
fn get_bikes_docs(op: TransformOperation) -> TransformOperation {
|
|
op.tag("Bikes").summary("Get the fleet")
|
|
}
|