// https://www.112centraal.nl/capcodes?codes=000723153 use std::str::FromStr; #[derive(Debug)] pub enum Service { Politie, Brandweer, Ambulance, Overige(&'static str), } impl std::fmt::Display for Service { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "{}", match self { Service::Politie => "Politie", Service::Brandweer => "Brandweer", Service::Ambulance => "Ambulance", Service::Overige(o) => *o, } ) } } #[derive(Debug)] pub struct CapCode { pub capcode: &'static str, pub region: &'static str, pub location: &'static str, pub service: Service, pub description: &'static str, } include!(concat!(env!("OUT_DIR"), "/capcodes.rs")); #[allow(unused)] #[derive(Debug)] pub struct Message { pub raw: String, pub protocol: String, pub timestamp: String, pub flags: String, pub frameid: String, pub capcodes_raw: String, pub capcodes: Vec<&'static CapCode>, pub format: String, pub message: String, } impl std::fmt::Display for Message { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.capcodes.is_empty() { write!(f, "[{}]: {}", self.capcodes_raw, self.message)?; return Ok(()); } let mut iterator = self.capcodes.iter().peekable(); while let Some(code) = iterator.next() { write!(f, "[{}]", code.service)?; if !code.region.is_empty() { write!(f, "[{}]", code.region.trim())?; } if !code.location.is_empty() { write!(f, "[{}]", code.location.trim())?; } if !code.description.is_empty() { write!(f, "[{}]", code.description.trim())?; } write!(f, ": ")?; write!(f, "{}", self.message)?; if iterator.peek().is_some() { writeln!(f)?; } } Ok(()) } } impl FromStr for Message { type Err = crate::Error; fn from_str(s: &str) -> std::result::Result { let mut parts = s.split('|'); //.collect::>(); if parts.clone().count() != 7 { return Err("Invalid message".into()); } let Some(protocol) = parts.next() else { return Err("Missing Protocol".into()); }; let Some(timestamp) = parts.next() else { return Err("Missing Timestamp".into()); }; let Some(flags) = parts.next() else { return Err("Missing Flags".into()); }; let Some(frameid) = parts.next() else { return Err("Missing FrameID".into()); }; let Some(capcodes) = parts.next() else { return Err("Missing Cap Codes".into()); }; let Some(format) = parts.next() else { return Err("Missing Format".into()); }; let Some(message) = parts.next() else { return Err("Missing Message".into()); }; let mut cc = vec![]; let parts = capcodes.split(' '); for c in parts { let c = &c[2..]; let Some(cap) = CAPCODES.get(c) else { eprintln!("Missing CapCode: {}", c); continue; }; cc.push(cap); } Ok(Self { raw: s.to_string(), protocol: protocol.to_string(), timestamp: timestamp.to_string(), flags: flags.to_string(), frameid: frameid.to_string(), capcodes_raw: capcodes.to_string(), capcodes: cc, format: format.to_string(), message: message.trim().to_string(), }) } }