Organize parsers

This commit is contained in:
Austen Adler 2023-03-19 18:59:25 -04:00
parent cda11079e4
commit 21a88e6cb8
4 changed files with 93 additions and 85 deletions

View File

@ -15,16 +15,18 @@ use std::str::FromStr;
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub struct Coordinate(pub f64, pub f64); pub struct Coordinate(pub f64, pub f64);
pub fn parse_coordinate(i: &str) -> IResult<&str, Coordinate> { impl Coordinate {
map_opt( pub fn parse(i: &str) -> IResult<&str, Coordinate> {
tuple((double, optional_separator(','), double)), map_opt(
|(ns, _, ew)| { tuple((double, optional_separator(','), double)),
// Ensure this is a north/south then east/west direction |(ns, _, ew)| {
if (-90_f64..=90_f64).contains(&ns) && (-180_f64..=180_f64).contains(&ew) { // Ensure this is a north/south then east/west direction
Some(Coordinate(ns, ew)) if (-90_f64..=90_f64).contains(&ns) && (-180_f64..=180_f64).contains(&ew) {
} else { Some(Coordinate(ns, ew))
None } else {
} None
}, }
)(i) },
)(i)
}
} }

View File

@ -14,6 +14,21 @@ 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 {
pub fn parse(i: &str) -> IResult<&str, Coordinate> {
map_opt(
tuple((DMM::parse, optional_separator(','), DMM::parse)),
|(ns, _, ew)| {
// Ensure this is a north/south then east/west direction
if ns.direction.is_lat() && ew.direction.is_lon() {
Some(Coordinate(ns, ew))
} else {
None
}
},
)(i)
}
}
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub struct DMM { pub struct DMM {
@ -22,38 +37,26 @@ pub struct DMM {
pub direction: Direction, pub direction: Direction,
} }
pub fn parse_coordinate(i: &str) -> IResult<&str, Coordinate> { impl DMM {
map_opt( pub fn parse(i: &str) -> IResult<&str, DMM> {
tuple((parse, optional_separator(','), parse)), map(
|(ns, _, ew)| { tuple((
// Ensure this is a north/south then east/west direction // Degrees
if ns.direction.is_lat() && ew.direction.is_lon() { complete::i16,
Some(Coordinate(ns, ew)) optional_separator('°'),
} else { // Minutes
None double,
} optional_separator('\''),
}, // Direction
)(i) parse_direction,
} )),
|(degrees, (), minutes, (), direction)| DMM {
pub fn parse(i: &str) -> IResult<&str, DMM> { degrees,
map( minutes,
tuple(( direction,
// Degrees },
complete::i16, )(i)
optional_separator('°'), }
// Minutes
double,
optional_separator('\''),
// Direction
parse_direction,
)),
|(degrees, (), minutes, (), direction)| DMM {
degrees,
minutes,
direction,
},
)(i)
} }
impl FromStr for DMM { impl FromStr for DMM {
@ -81,6 +84,6 @@ impl FromStr for DMM {
/// }); /// });
/// ``` /// ```
fn from_str(i: &str) -> Result<Self, Self::Err> { fn from_str(i: &str) -> Result<Self, Self::Err> {
parse(i).map_err(|_| ()).map(|(_, ret)| ret) DMM::parse(i).map_err(|_| ()).map(|(_, ret)| ret)
} }
} }

View File

@ -15,42 +15,20 @@ use std::str::FromStr;
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub struct Coordinate(pub DMS, pub DMS); pub struct Coordinate(pub DMS, pub DMS);
pub fn parse_coordinate(i: &str) -> IResult<&str, Coordinate> { impl Coordinate {
map_opt( pub fn parse(i: &str) -> IResult<&str, Coordinate> {
tuple((parse, optional_separator(','), parse)), map_opt(
|(ns, _, ew)| { tuple((DMS::parse, optional_separator(','), DMS::parse)),
// Ensure this is a north/south then east/west direction |(ns, _, ew)| {
if ns.direction.is_lat() && ew.direction.is_lon() { // Ensure this is a north/south then east/west direction
Some(Coordinate(ns, ew)) if ns.direction.is_lat() && ew.direction.is_lon() {
} else { Some(Coordinate(ns, ew))
None } else {
} None
}, }
)(i) },
} )(i)
}
pub fn parse(i: &str) -> IResult<&str, DMS> {
map(
tuple((
// Degrees
complete::i16,
optional_separator('°'),
// Minutes
complete::i16,
optional_separator('\''),
// Seconds
double,
optional_separator('"'),
// Direction
parse_direction,
)),
|(degrees, (), minutes, (), seconds, (), direction)| DMS {
degrees,
minutes,
seconds,
direction,
},
)(i)
} }
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
@ -61,6 +39,31 @@ pub struct DMS {
pub direction: Direction, pub direction: Direction,
} }
impl DMS {
pub fn parse(i: &str) -> IResult<&str, DMS> {
map(
tuple((
// Degrees
complete::i16,
optional_separator('°'),
// Minutes
complete::i16,
optional_separator('\''),
// Seconds
double,
optional_separator('"'),
// Direction
parse_direction,
)),
|(degrees, (), minutes, (), seconds, (), direction)| DMS {
degrees,
minutes,
seconds,
direction,
},
)(i)
}
}
impl FromStr for DMS { impl FromStr for DMS {
type Err = (); type Err = ();
@ -88,6 +91,6 @@ impl FromStr for DMS {
/// }); /// });
/// ``` /// ```
fn from_str(i: &str) -> Result<Self, Self::Err> { fn from_str(i: &str) -> Result<Self, Self::Err> {
parse(i).map_err(|_| ()).map(|(_, ret)| ret) DMS::parse(i).map_err(|_| ()).map(|(_, ret)| ret)
} }
} }

View File

@ -65,9 +65,9 @@ impl FromStr for Coordinate {
tuple(( tuple((
space0, space0,
alt(( alt((
map(dd::parse_coordinate, Coordinate::DD), map(dd::Coordinate::parse, Coordinate::DD),
map(dms::parse_coordinate, Coordinate::DMS), map(dms::Coordinate::parse, Coordinate::DMS),
map(dmm::parse_coordinate, Coordinate::DM), map(dmm::Coordinate::parse, Coordinate::DM),
// map(utm::parse_coordinate, Coordinate::UTM), // map(utm::parse_coordinate, Coordinate::UTM),
// map(plus::parse_coordinate, Coordinate::PLUS), // map(plus::parse_coordinate, Coordinate::PLUS),
)), )),