1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use crate::handlers::{CheckGpioLevel, DbExecutor, GpioId, SetGpioLevel};
use crate::models;
use crate::rpi;
use actix::Addr;
use actix_web::Error;
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(_) => Ok(HttpResponse::InternalServerError().into()),
})
.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, Error>| match res {
Ok(response) => Ok(HttpResponse::Ok().json(response)),
Err(err) => Ok(HttpResponse::InternalServerError().body(err.to_string())),
})
.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)
})
}