use crate::handlers::{CheckGpioLevel, DbExecutor, GpioId, SetGpioLevel};
use crate::models;
use crate::rpi;
use actix::Addr;
use actix_web::Error as actixError;
use actix_web::{http, middleware, App, AsyncResponder, FutureResponse, HttpResponse, Path, State};
use futures::{future, Future};
pub struct AppState {
pub db: Addr<DbExecutor>,
pub gpio_arc_mutex: rpi::GpioArcMutex,
}
pub fn gpio_status_route(
(req, state): (Path<i32>, State<AppState>),
) -> FutureResponse<HttpResponse> {
state
.db
.send(GpioId {
gpio_id: req.into_inner(),
})
.from_err()
.and_then(|res| match res {
Ok(user) => Ok(HttpResponse::Ok().json(user)),
Err(err) => {
let err_string = err.to_string();
let mut response = HttpResponse::from_error(err);
response.set_body(err_string);
Ok(response)
}
})
.responder()
}
pub fn set_gpio_level_route(
(req, state): (Path<(i32, String)>, State<AppState>),
) -> FutureResponse<HttpResponse> {
let path_gpio_id: i32 = req.0;
let path_gpio_level = req.1.clone();
let path_gpio_level_copy = req.1.clone(); let gpio_arc_mutex = state.gpio_arc_mutex.clone();
state
.db
.send(CheckGpioLevel {
gpio_id: path_gpio_id,
gpio_level: (&path_gpio_level).to_string(),
})
.from_err()
.and_then(|res| future::result(res).from_err())
.and_then(move |_| {
let level_updated =
rpi::set_gpio_level_rpi(path_gpio_id, &path_gpio_level, gpio_arc_mutex);
future::result(level_updated).from_err()
})
.and_then(move |_| {
state
.db
.send(SetGpioLevel {
gpio_id: path_gpio_id,
gpio_level: (&path_gpio_level_copy).to_string(),
})
.from_err()
})
.and_then(|res| future::result(res).from_err())
.then(|res: Result<models::Gpio, actixError>| match res {
Ok(response) => Ok(HttpResponse::Ok().json(response)),
Err(err) => {
let err_string = err.to_string();
let mut response = HttpResponse::from_error(err);
response.set_body(err_string);
Ok(response)
}
})
.responder()
}
pub fn create_app(app_state: AppState) -> App<AppState> {
App::with_state(app_state)
.middleware(middleware::Logger::default())
.resource("/status/{id}", |r| {
r.method(http::Method::GET).with(gpio_status_route)
})
.resource("/set/level/{id}/{level}", |r| {
r.method(http::Method::GET).with(set_gpio_level_route)
})
}