use actix_web::{dev, get, http::StatusCode, web, FromRequest, HttpRequest, HttpResponse};
use futures::future;
use crate::rest_api::{
actix_web_3::{request, AcceptServiceIdParam, QueryPaging, QueryServiceId, StoreState},
resources::locations::v1,
};
use super::DEFAULT_GRID_PROTOCOL_VERSION;
#[get("/location/{id}")]
pub async fn get_location(
store_state: web::Data<StoreState>,
location_id: web::Path<String>,
query: web::Query<QueryServiceId>,
version: ProtocolVersion,
_: AcceptServiceIdParam,
) -> HttpResponse {
let store = store_state.store_factory.get_grid_location_store();
match version {
ProtocolVersion::V1 => {
match v1::get_location(
store,
location_id.into_inner(),
query.into_inner().service_id.as_deref(),
) {
Ok(res) => HttpResponse::Ok().json(res),
Err(err) => HttpResponse::build(
StatusCode::from_u16(err.status_code())
.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),
)
.json(err),
}
}
}
}
#[get("/location")]
pub async fn list_locations(
req: HttpRequest,
store_state: web::Data<StoreState>,
query_service_id: web::Query<QueryServiceId>,
query_paging: web::Query<QueryPaging>,
version: ProtocolVersion,
_: AcceptServiceIdParam,
) -> HttpResponse {
let store = store_state.store_factory.get_grid_location_store();
match version {
ProtocolVersion::V1 => {
let paging = query_paging.into_inner();
let service_id = query_service_id.into_inner().service_id;
match request::get_base_url(&req).and_then(|url| {
v1::list_locations(
url,
store,
service_id.as_deref(),
paging.offset(),
paging.limit(),
)
}) {
Ok(res) => HttpResponse::Ok().json(res),
Err(err) => HttpResponse::build(
StatusCode::from_u16(err.status_code())
.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),
)
.json(err),
}
}
}
}
pub enum ProtocolVersion {
V1,
}
impl FromRequest for ProtocolVersion {
type Error = HttpResponse;
type Future = future::Ready<Result<Self, Self::Error>>;
type Config = ();
fn from_request(req: &HttpRequest, _: &mut dev::Payload) -> Self::Future {
let protocol_version = match req
.headers()
.get("GridProtocolVersion")
.map(|ver| ver.to_str().map(String::from))
{
Some(Ok(ver)) => ver,
Some(Err(err)) => {
error!(
"Failed to parse version using default version {}: {}",
DEFAULT_GRID_PROTOCOL_VERSION, err
);
DEFAULT_GRID_PROTOCOL_VERSION.to_string()
}
None => {
warn!(
"No Protocol version specified, defaulting to version {}",
DEFAULT_GRID_PROTOCOL_VERSION
);
DEFAULT_GRID_PROTOCOL_VERSION.to_string()
}
};
match protocol_version.as_str() {
"1" => future::ok(ProtocolVersion::V1),
_ => future::ok(ProtocolVersion::V1),
}
}
}