use std::env::args; mod adsb; mod location; mod aircrafts; mod jabber; #[derive(Debug, Clone, Copy)] pub struct UsageError; impl std::fmt::Display for UsageError { fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { write!(fmt, "Usage error") } } impl std::error::Error for UsageError {} #[tokio::main] async fn main() -> Result<(), Box> { 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); })); tokio::task::LocalSet::new().run_until(async move { let aircrafts = aircrafts::Aircrafts::load("aircraftDatabase.csv"); let locations = location::Locations::load("locations.json"); let mut events = adsb::run("radiobert.serv.zentralwerk.org", 30005, locations); let args: Vec = args().collect(); if args.len() != 4 { println!("Usage: {} ", args[0]); Err(UsageError)?; } let jid = args[1].to_owned(); let password = args[2].to_owned(); let muc = args[3].to_owned(); let jabber = jabber::run(jid, password, muc).await; while let Some(event) = events.recv().await { println!("event: {:?}", event); let flight = if let Some(flight) = event.info.flight { format!("Flug {} [{}]", flight, event.info.hex) } else { format!("[{}]", event.info.hex) }; let identifier; if let Some(aircraft) = aircrafts.find(&event.info.hex) { println!("aircraft: {:?}", aircraft); match (&aircraft.owner, &aircraft.registration, &aircraft.model) { (Some(owner), Some(registration), Some(model)) => identifier = format!("{} {} ({})", owner, registration, model), (Some(owner), None, Some(model)) => identifier = format!("{} {} ({})", owner, flight, model), (Some(owner), Some(registration), None) => identifier = format!("{} {}", owner, registration), (Some(owner), None, None) => identifier = format!("{} {}", owner, flight), (None, Some(registration), Some(model)) => identifier = format!("{} ({})", registration, model), (None, None, Some(model)) => identifier = format!("{} ({})", flight, model), (None, Some(registration), None) => identifier = format!("{}", registration), (None, None, None) => identifier = flight, } } else { identifier = flight; } let text = match event.action { adsb::Action::Appeared => format!("{} ist {:.0}m über {} aufgetaucht", identifier, event.info.altitude_m.unwrap_or(0.0), event.location ), adsb::Action::Moved => format!("{} fliegt jetzt {:.0}m über {}", identifier, event.info.altitude_m.unwrap_or(0.0), event.location ), adsb::Action::Disappeared => format!("{} ist abgetaucht", identifier), adsb::Action::Ignored => format!("{} wird ab {:.0}m ignoriert", identifier, event.info.altitude_m.unwrap_or(0.0), ), }; println!(">> {}", text); jabber.send_message(text).await; } let result: Result<(), Box> = Ok(()); result }).await }