use chrono::Local; use clap::Parser; use nmea::Nmea; use nmea::SentenceType; use std::time::Duration; /// Command-line arguments using Clap. #[derive(Parser, Debug)] #[command( author, version, about = "A tool for echoing latitude and longitude from a GPS USB dongle." )] struct Cli { /// COM port #[arg(short = 'c', long)] com: Option, /// Format #[arg(short = 'f', long, default_value = "csv")] format: Option, } // Function to get the location fn get_loc(port: String, fmt: String) -> String { let mut nmea = Nmea::default(); // Harcode port for dev //let port_name = "/dev/tty.usbmodem1301"; let port_name = port; //fn read_loc(com: &str) -> &str { //println!("Reading from {port_name}"); let port = serialport::new(port_name, 9600) .timeout(Duration::from_millis(1000)) .open(); if let Ok(mut serial) = port { let mut buf = [0u8; 1024]; loop { match serial.read(&mut buf) { Ok(n) => { let data = String::from_utf8_lossy(&buf[..n]); for line in data.lines() { // Check sentence type let sentence_type = match nmea.parse(line) { Ok(sentence_type) => sentence_type, Err(_) => { break; } }; // Only keep the GLL sentences if sentence_type == SentenceType::GLL { let lat = match nmea.latitude { Some(lat) => lat, None => -9999.25, }; let lon = match nmea.longitude { Some(lon) => lon, None => -9999.25, }; let date = Local::now(); //println!("{}, {lat}, {lon}", date.format("%Y-%m-%d %H:%M:%S")); if fmt == "csv" { return format!( "{},{:.8},{:.8}", date.format("%Y-%m-%d %H:%M:%S"), lat, lon ); } else if fmt == "ssv" { return format!( "\"{}\" {:.8} {:.8}", date.format("%Y-%m-%d %H:%M:%S"), lat, lon ); } } } } Err(_) => {} // lol that I can just not put a return in? } } } else { // https://github.com/serialport/serialport-rs#listing-available-ports let ports = serialport::available_ports().expect("No ports found!"); println!("Available Ports:"); for p in ports { println!("{}", p.port_name); } return format!("\nCould not connect to port. Is it listed above?"); } } fn main() { // Arguments let cli = Cli::parse(); let com = match cli.com { Some(com) => com, None => { // https://github.com/serialport/serialport-rs#listing-available-ports let ports = serialport::available_ports().expect("No ports found!"); println!("Available Ports:"); for p in ports { println!("{}", p.port_name); } println!("\nMissing `-c` port argument, use one listed above."); return; } //todo!() }; let fmt = match cli.format { Some(fmt) => fmt, None => { return; } //todo!() }; // Run the function // Max rate is about 1 measurement per second //loop { let result = get_loc(com.clone(), fmt.clone()); println!("{result}"); //} }