1use crate::handlers::{CheckGpioLevel, DbExecutor, GpioId, SetGpioLevel};
2use crate::models;
3use crate::rpi;
4use actix::Addr;
5use actix_web::Error as actixError;
6use actix_web::{http, middleware, App, AsyncResponder, FutureResponse, HttpResponse, Path, State};
7use futures::{future, Future};
8
9pub struct AppState {
11 pub db: Addr<DbExecutor>,
12 pub gpio_arc_mutex: rpi::GpioArcMutex,
13}
14
15pub fn gpio_status_route(
17 (req, state): (Path<i32>, State<AppState>),
18) -> FutureResponse<HttpResponse> {
19 state
20 .db
21 .send(GpioId {
22 gpio_id: req.into_inner(),
23 })
24 .from_err()
25 .and_then(|res| match res {
26 Ok(user) => Ok(HttpResponse::Ok().json(user)),
27 Err(err) => {
28 let err_string = err.to_string();
29 let mut response = HttpResponse::from_error(err);
30 response.set_body(err_string);
31 Ok(response)
32 }
33 })
34 .responder()
35}
36
37pub fn set_gpio_level_route(
39 (req, state): (Path<(i32, String)>, State<AppState>),
40) -> FutureResponse<HttpResponse> {
41 let path_gpio_id: i32 = req.0;
42 let path_gpio_level = req.1.clone();
43 let path_gpio_level_copy = req.1.clone(); let gpio_arc_mutex = state.gpio_arc_mutex.clone();
45
46 state
50 .db
51 .send(CheckGpioLevel {
52 gpio_id: path_gpio_id,
53 gpio_level: (&path_gpio_level).to_string(),
54 })
55 .from_err()
56 .and_then(|res| future::result(res).from_err())
57 .and_then(move |_| {
58 let level_updated =
60 rpi::set_gpio_level_rpi(path_gpio_id, &path_gpio_level, gpio_arc_mutex);
61 future::result(level_updated).from_err()
62 })
63 .and_then(move |_| {
64 state
66 .db
67 .send(SetGpioLevel {
68 gpio_id: path_gpio_id,
69 gpio_level: (&path_gpio_level_copy).to_string(),
70 })
71 .from_err()
72 })
73 .and_then(|res| future::result(res).from_err())
74 .then(|res: Result<models::Gpio, actixError>| match res {
75 Ok(response) => Ok(HttpResponse::Ok().json(response)),
76 Err(err) => {
77 let err_string = err.to_string();
78 let mut response = HttpResponse::from_error(err);
79 response.set_body(err_string);
80 Ok(response)
81 }
82 })
83 .responder()
84}
85
86pub fn create_app(app_state: AppState) -> App<AppState> {
88 App::with_state(app_state)
89 .middleware(middleware::Logger::default())
91 .resource("/status/{id}", |r| {
92 r.method(http::Method::GET).with(gpio_status_route)
93 })
94 .resource("/set/level/{id}/{level}", |r| {
95 r.method(http::Method::GET).with(set_gpio_level_route)
96 })
97}