Created
July 14, 2017 01:54
-
-
Save categulario/ac5c8677bc692b5439ece543853ad9e0 to your computer and use it in GitHub Desktop.
parse from NMEA stream
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::io; | |
use std::str; | |
use bytes::BytesMut; | |
use tokio_io::codec::{Encoder, Decoder}; | |
use std::str::FromStr; | |
fn extract_coord(num: f32, orientation: &str) -> f32 { | |
let res = num%100.0; | |
let ans = (num/100.0).floor() + res/60.0; | |
if orientation == "N" || orientation == "E" { | |
return ans; | |
} else { | |
return -ans; | |
} | |
} | |
pub struct Pos { | |
lat: f32, | |
lon: f32, | |
device: i16, | |
} | |
impl FromStr for Pos { | |
type Err = String; | |
fn from_str(s: &str) -> Result<Pos, Self::Err> { | |
let pieces:Vec<&str> = s.split(',').collect(); | |
match pieces.get(0) { | |
Some(piece) => if *piece == "\n$POS" { | |
Ok(Pos{ | |
lon : extract_coord(pieces.get(6).unwrap().parse().unwrap(), pieces.get(7).unwrap()), | |
lat : extract_coord(pieces.get(4).unwrap().parse().unwrap(), pieces.get(5).unwrap()), | |
device : pieces.get(1).unwrap().parse().unwrap(), | |
}) | |
} else { | |
Err("No es una posición".to_string()) | |
}, | |
None => Err("Falló la conversión".to_string()), | |
} | |
} | |
} | |
pub struct LineCodec; | |
impl Decoder for LineCodec { | |
type Item = String; | |
type Error = io::Error; | |
fn decode(&mut self, buf: &mut BytesMut) -> io::Result<Option<String>> { | |
match buf.iter().position(|&b| b == b'#') { | |
Some(i) => { | |
let line = buf.split_to(i); | |
// remove the # | |
buf.split_to(1); | |
match str::from_utf8(&line) { | |
Ok(s) => { | |
let string = s.to_string(); | |
println!("{:?}", string); | |
Ok(Some(string)) | |
}, | |
Err(_) => Ok(None), | |
} | |
}, | |
None => Ok(None), | |
} | |
} | |
} | |
impl Encoder for LineCodec { | |
type Item = String; | |
type Error = io::Error; | |
fn encode(&mut self, msg: String, buf: &mut BytesMut) -> io::Result<()> { | |
buf.extend(msg.as_bytes()); | |
Ok(()) | |
} | |
} | |
#[test] | |
fn test_parse_coords() { | |
assert_eq!(extract_coord(2036.3883, "N"), 20.606472); | |
assert_eq!(extract_coord(10323.9808, "W"), -103.39967); | |
assert_eq!(extract_coord(2036.3883, "S"), -20.606472); | |
assert_eq!(extract_coord(10323.9808, "E"), 103.39967); | |
} | |
#[test] | |
fn test_parse_multibyte_to_pos() { | |
let pos:Pos = "\n$POS,1289,105127.000,A,2036.3883,N,10323.9808,W,0.0,1.7,130717,,,A/0000,0/0/93069700//f97/".parse().unwrap(); | |
assert_eq!(pos.lat, 20.6064716666666666); | |
assert_eq!(pos.lon, -103.39967); | |
assert_eq!(pos.device, 1289); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment