s0-meter/src/rest_api.rs

91 lines
2.8 KiB
Rust
Raw Normal View History

2021-02-23 00:08:28 +01:00
#[allow(dead_code)]
#[cfg(test)]
#[path = "./rest_api_test.rs"]
mod rest_api_test;
use serde::{Deserialize, Serialize};
use tide;
use tide::prelude::json;
// struct PinConfiguration {
// channel: usize,
// gpio: usize,
// }
#[derive(Serialize, Deserialize, Debug)]
pub struct PulseInfo {
timestamp_ns: u64,
pin_id: usize,
level: bool,
}
#[derive(Clone)]
pub struct RestApiConfig {
pub ip_and_port: String,
pub get_channels: fn() -> Vec<usize>,
pub get_pulses_by_channel: fn(channel: usize) -> Result<Vec<PulseInfo>, std::io::Error>,
}
pub async fn start<'a>(config: &'a RestApiConfig) -> std::io::Result<()> {
let mut app = tide::with_state(config.clone());
app.at("/api_versions").get(api_versions_get);
app.at("/v1/channels").get(v1_channels_get);
app.at("/v1/channel/:channel_id/pulses")
.get(v1_channel_pulses_get);
let ip_and_port = String::from(&config.ip_and_port);
match app.listen(ip_and_port).await {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}
async fn api_versions_get(_: tide::Request<RestApiConfig>) -> tide::Result {
#[derive(Serialize)]
struct ApiVersionInfo {
version: String,
path: String,
}
let mut version_list = Vec::<ApiVersionInfo>::new();
version_list.push(ApiVersionInfo {
version: String::from("1.0"),
path: String::from("v1"),
});
Ok(tide::Response::builder(200)
.content_type(tide::http::mime::JSON)
.body(json!({ "api_versions": &version_list }))
.build())
}
async fn v1_channels_get(req: tide::Request<RestApiConfig>) -> tide::Result {
let channel_list = &(req.state().get_channels)();
Ok(tide::Response::builder(200)
.content_type(tide::http::mime::JSON)
.body(json!({ "channels": channel_list }))
.build())
}
async fn v1_channel_pulses_get(req: tide::Request<RestApiConfig>) -> tide::Result {
match req.param("channel_id") {
Ok(channel_id) => match usize::from_str_radix(channel_id, 10) {
Ok(channel_id) => {
let info = &req.state().ip_and_port;
let channel_pulses_res = &(req.state().get_pulses_by_channel)(channel_id);
match channel_pulses_res {
Ok(channel_pulses) => Ok(tide::Response::builder(200)
.content_type(tide::http::mime::JSON)
.body(json!({
"channel": channel_id,
"pulses": channel_pulses,
"question": "channel",
"info": info,
}))
.build()),
Err(_) => Ok(tide::Response::new(404)),
}
}
Err(_) => Ok(tide::Response::new(405)),
},
Err(_e) => Ok(tide::Response::new(404)),
}
}