heliwatch/http-json/src/main.rs

65 lines
1.9 KiB
Rust

use warp::{http::Response, Filter};
use adsb_deku::ICAO;
use beast::aircrafts::Entry;
use serde::Serialize;
#[derive(Serialize)]
pub struct Aircraft {
hex: String,
flight: Option<String>,
category: Option<u8>,
lat: Option<f64>,
lon: Option<f64>,
/// ft
altitude: Option<u32>,
track: Option<i16>,
/// kts
speed: Option<u16>,
}
impl Aircraft {
pub fn new(icao_address: &ICAO, entry: &Entry) -> Self {
Aircraft {
hex: format!("{}", icao_address),
flight: entry.callsign.clone(),
category: entry.category.map(|category| category.1),
lat: entry.position().map(|pos| pos.latitude),
lon: entry.position().map(|pos| pos.longitude),
altitude: entry.altitude.clone(),
track: entry.heading.map(|heading| heading as i16),
speed: entry.speed.map(|speed| speed as u16),
}
}
}
#[tokio::main]
async fn main() {
let orig_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(move |panic_info| {
// invoke the default handler and exit the process
orig_hook(panic_info);
std::process::exit(1);
}));
let aircrafts = beast::aircrafts::Aircrafts::new();
aircrafts.connect("radiobert.serv.zentralwerk.org", 30005);
let hello = warp::path!("data.json")
.map(move || {
let data = aircrafts.read()
.iter()
.map(|(icao_address, entry)| Aircraft::new(icao_address, &entry.read().unwrap()))
.collect::<Vec<Aircraft>>();
let json = serde_json::ser::to_vec_pretty(&data)
.unwrap_or_else(|_| vec![]);
Response::builder()
.header("Content-Type", "application/json")
.body(json)
});
warp::serve(hello)
.run(([0, 0, 0, 0], 8080))
.await;
}