91 lines
2.8 KiB
Rust
91 lines
2.8 KiB
Rust
|
|
#[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)),
|
||
|
|
}
|
||
|
|
}
|