Add pluscodes; cleanup

This commit is contained in:
Austen Adler 2023-03-19 19:20:17 -04:00
parent 21a88e6cb8
commit 557615b551
5 changed files with 96 additions and 19 deletions

View File

@ -16,7 +16,7 @@ use std::str::FromStr;
pub struct Coordinate(pub f64, pub f64); pub struct Coordinate(pub f64, pub f64);
impl Coordinate { impl Coordinate {
pub fn parse(i: &str) -> IResult<&str, Coordinate> { pub fn parse(i: &str) -> IResult<&str, Self> {
map_opt( map_opt(
tuple((double, optional_separator(','), double)), tuple((double, optional_separator(','), double)),
|(ns, _, ew)| { |(ns, _, ew)| {
@ -30,3 +30,11 @@ impl Coordinate {
)(i) )(i)
} }
} }
impl FromStr for Coordinate {
type Err = ();
fn from_str(i: &str) -> Result<Self, Self::Err> {
Self::parse(i).map_err(|_| ()).map(|(_, ret)| ret)
}
}

View File

@ -15,7 +15,7 @@ use std::str::FromStr;
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub struct Coordinate(pub DMM, pub DMM); pub struct Coordinate(pub DMM, pub DMM);
impl Coordinate { impl Coordinate {
pub fn parse(i: &str) -> IResult<&str, Coordinate> { pub fn parse(i: &str) -> IResult<&str, Self> {
map_opt( map_opt(
tuple((DMM::parse, optional_separator(','), DMM::parse)), tuple((DMM::parse, optional_separator(','), DMM::parse)),
|(ns, _, ew)| { |(ns, _, ew)| {
@ -30,6 +30,14 @@ impl Coordinate {
} }
} }
impl FromStr for Coordinate {
type Err = ();
fn from_str(i: &str) -> Result<Self, Self::Err> {
Self::parse(i).map_err(|_| ()).map(|(_, ret)| ret)
}
}
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub struct DMM { pub struct DMM {
pub degrees: i16, pub degrees: i16,

View File

@ -16,7 +16,7 @@ use std::str::FromStr;
pub struct Coordinate(pub DMS, pub DMS); pub struct Coordinate(pub DMS, pub DMS);
impl Coordinate { impl Coordinate {
pub fn parse(i: &str) -> IResult<&str, Coordinate> { pub fn parse(i: &str) -> IResult<&str, Self> {
map_opt( map_opt(
tuple((DMS::parse, optional_separator(','), DMS::parse)), tuple((DMS::parse, optional_separator(','), DMS::parse)),
|(ns, _, ew)| { |(ns, _, ew)| {
@ -31,6 +31,14 @@ impl Coordinate {
} }
} }
impl FromStr for Coordinate {
type Err = ();
fn from_str(i: &str) -> Result<Self, Self::Err> {
Self::parse(i).map_err(|_| ()).map(|(_, ret)| ret)
}
}
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub struct DMS { pub struct DMS {
pub degrees: i16, pub degrees: i16,
@ -64,6 +72,7 @@ impl DMS {
)(i) )(i)
} }
} }
impl FromStr for DMS { impl FromStr for DMS {
type Err = (); type Err = ();

View File

@ -5,6 +5,7 @@ mod common;
pub mod dd; pub mod dd;
pub mod dmm; pub mod dmm;
pub mod dms; pub mod dms;
pub mod plus;
use dmm::DMM; use dmm::DMM;
use dms::DMS; use dms::DMS;
@ -50,8 +51,28 @@ pub enum Coordinate {
DD(dd::Coordinate), DD(dd::Coordinate),
DMS(dms::Coordinate), DMS(dms::Coordinate),
DM(dmm::Coordinate), DM(dmm::Coordinate),
// UTM(utm::UTMCoordinate), // UTM(utm::Coordinate),
// Plus(plus::PlusCoordinate), Plus(plus::Coordinate),
}
impl Coordinate {
pub fn parse(i: &str) -> IResult<&str, Self> {
map(
tuple((
space0,
alt((
map(dd::Coordinate::parse, Coordinate::DD),
map(dms::Coordinate::parse, Coordinate::DMS),
map(dmm::Coordinate::parse, Coordinate::DM),
// map(utm::Coordinate::parse, Coordinate::UTM),
map(plus::Coordinate::parse, Coordinate::Plus),
)),
space0,
eof,
)),
|(_, coordinate, _, _)| coordinate,
)(i)
}
} }
pub enum CoordinateSystem { pub enum CoordinateSystem {
@ -62,19 +83,6 @@ impl FromStr for Coordinate {
type Err = (); type Err = ();
fn from_str(i: &str) -> Result<Self, Self::Err> { fn from_str(i: &str) -> Result<Self, Self::Err> {
tuple(( Self::parse(i).map_err(|_| ()).map(|(_, ret)| ret)
space0,
alt((
map(dd::Coordinate::parse, Coordinate::DD),
map(dms::Coordinate::parse, Coordinate::DMS),
map(dmm::Coordinate::parse, Coordinate::DM),
// map(utm::parse_coordinate, Coordinate::UTM),
// map(plus::parse_coordinate, Coordinate::PLUS),
)),
space0,
eof,
))(i)
.map(|(_, (_, coordinate, _, _))| coordinate)
.map_err(|_| ())
} }
} }

View File

@ -0,0 +1,44 @@
use crate::{
common::{optional_separator, parse_direction},
Direction,
};
use nom::{
branch::alt,
bytes::complete::take_while,
character::complete::{self, space0, space1},
combinator::{eof, map, map_opt, map_res, opt},
number::complete::double,
sequence::{pair, tuple},
IResult,
};
use std::str::FromStr;
const PLUSCODE_CHARS: [char; 22] = [
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'C', 'F', 'G', 'H', 'J', 'M', 'P', 'Q', 'R',
'V', 'W', 'X',
];
#[derive(PartialEq, Debug)]
pub struct Coordinate(pub f64, pub f64);
impl Coordinate {
pub fn parse(i: &str) -> IResult<&str, Self> {
map_opt(pluscode_chars, |c| {
pluscodes::decode(c)
.map(|coord| Coordinate(coord.latitude, coord.longitude))
.ok()
})(i)
}
}
impl FromStr for Coordinate {
type Err = ();
fn from_str(i: &str) -> Result<Self, Self::Err> {
Self::parse(i).map_err(|_| ()).map(|(_, ret)| ret)
}
}
fn pluscode_chars(i: &str) -> IResult<&str, &str> {
take_while(|c| PLUSCODE_CHARS.contains(&c))(i)
}