iso6709parse/parsers/
iso6709.rs

1use nom::IResult;
2
3pub mod human_readable {
4    use super::*;
5    use crate::parsers::altitude::human_readable::*;
6    use crate::parsers::latitude::human_readable::*;
7    use crate::parsers::longitude::human_readable::*;
8    use nom::character::complete::space1;
9    use nom::combinator::opt;
10    use nom::sequence::{preceded, separated_pair};
11    use nom::Parser;
12
13    /// Parser to obtain lat long
14    ///
15    ///
16    /// ```
17    /// # use iso6709parse::parsers::iso6709::human_readable::latlong_parser;
18    /// let coord = "15°30′00.000″N 95°15′00.000″W";
19    /// assert_eq!(latlong_parser(coord), Ok(("", (15.5, -95.25))));
20    ///
21    /// let coord = "15°30′00.000″N 95°15′00.000″W 123.45m";
22    /// assert_eq!(latlong_parser(coord), Ok((" 123.45m", (15.5, -95.25))));
23    /// ```
24    ///  
25    pub fn latlong_parser(inp: &str) -> IResult<&str, (f64, f64)> {
26        separated_pair(latitude_parser, space1, longitude_parser).parse(inp)
27    }
28
29    /// Parser to obtain lat long and altitude. Note that the lat, long are within their own tuple, inside the output tuple.
30    /// Since the `CRS` statement is required for altitude, it is parsed and discarded from the remaining string
31    ///
32    ///
33    /// ```
34    /// # use iso6709parse::parsers::iso6709::human_readable::latlong_altitude_parser;
35    /// let coord = "15°30′00.000″N 95°15′00.000″W";
36    /// assert!(latlong_altitude_parser(coord).is_err());
37    ///
38    /// let coord = "15°30′00.000″N 95°15′00.000″W 123.45m";
39    /// assert_eq!(latlong_altitude_parser(coord), Ok(("m", ((15.5, -95.25), 123.45))));
40    /// ```
41    ///  
42    pub fn latlong_altitude_parser(inp: &str) -> IResult<&str, ((f64, f64), f64)> {
43        separated_pair(latlong_parser, space1, altitude_parser).parse(inp)
44    }
45
46    /// Parser to obtain lat long and altitude if the altitude is present. Note that the lat, long are within their own tuple, inside the output tuple.
47    /// Since the `CRS` statement is required for altitude, it is parsed and discarded from the remaining string
48    ///
49    ///
50    /// ```
51    /// # use iso6709parse::parsers::iso6709::human_readable::latlong_altitude_option_parser;
52    /// let coord = "15°30′00.000″N 95°15′00.000″W";
53    /// assert_eq!(latlong_altitude_option_parser(coord), Ok(("", ((15.5, -95.25), None))));
54    ///
55    /// let coord = "15°30′00.000″N 95°15′00.000″W 123.45m";
56    /// assert_eq!(latlong_altitude_option_parser(coord), Ok(("m", ((15.5, -95.25), Some(123.45)))));
57    /// ```
58    ///  
59    pub fn latlong_altitude_option_parser(inp: &str) -> IResult<&str, ((f64, f64), Option<f64>)> {
60        (latlong_parser, opt(preceded(space1, altitude_parser))).parse(inp)
61    }
62
63    #[cfg(test)]
64    mod human_readable_tests {
65        use super::*;
66
67        #[test]
68        fn should_parse_readable() {
69            let coord = "15°30′00.000″N 95°15′00.000″W";
70            assert_eq!(latlong_parser(coord), Ok(("", (15.5, -95.25))));
71
72            let coord = "15°30′00.000″N 95°15′00.000″W 123.45m";
73            assert_eq!(latlong_parser(coord), Ok((" 123.45m", (15.5, -95.25))));
74        }
75
76        #[test]
77        fn should_parse_readable_altitude() {
78            let coord = "15°30′00.000″N 95°15′00.000″W";
79            assert!(latlong_altitude_parser(coord).is_err());
80
81            let coord = "15°30′00.000″N 95°15′00.000″W 123.45m";
82            assert_eq!(
83                latlong_altitude_parser(coord),
84                Ok(("m", ((15.5, -95.25), 123.45)))
85            );
86        }
87    }
88}
89
90pub mod string_expression {
91    use super::*;
92    pub(crate) use crate::parsers::altitude::string_expression::altitude_parser;
93    pub use crate::parsers::latitude::string_expression::latitude_parser;
94    pub use crate::parsers::longitude::string_expression::longitude_parser;
95    use nom::combinator::opt;
96    use nom::Parser;
97
98    /// Parser to obtain lat long
99    ///
100    ///
101    /// ```
102    /// # use iso6709parse::parsers::iso6709::string_expression::latlong_parser;
103    /// let coord = "+1200.00-02130.00";
104    /// assert_eq!(latlong_parser(coord), Ok(("", (12.0, -21.5))));
105    ///
106    /// let coord = "+1200.00-02130.00+2321CRS_WGS_85/";
107    /// assert_eq!(latlong_parser(coord), Ok(("+2321CRS_WGS_85/", (12.0, -21.5))));
108    /// ```
109    ///  
110    pub fn latlong_parser(inp: &str) -> IResult<&str, (f64, f64)> {
111        (latitude_parser, longitude_parser).parse(inp)
112    }
113
114    /// Parser to obtain lat long and altitude. Note that the lat, long are within their own tuple, inside the output tuple.
115    /// Since the `CRS` statement is required for altitude, it is parsed and discarded from the remaining string
116    ///
117    ///
118    /// ```
119    /// # use iso6709parse::parsers::iso6709::string_expression::latlong_altitude_parser;
120    /// let coord = "+1200.00-02130.00";
121    /// assert!(latlong_altitude_parser(coord).is_err());
122    ///
123    /// let coord = "+1200.00-02130.00+2321CRSWGS_85";
124    /// assert_eq!(latlong_altitude_parser(coord), Ok(("WGS_85", ((12.0, -21.5), 2321.0))));
125    /// ```
126    ///  
127    pub fn latlong_altitude_parser(inp: &str) -> IResult<&str, ((f64, f64), f64)> {
128        (latlong_parser, altitude_parser).parse(inp)
129    }
130
131    // Parser to obtain lat long and, if exists, the altitude. Note that the lat, long are within their own tuple, inside the output tuple.
132    /// Since the `CRS` statement is required for altitude, it is parsed and discarded from the remaining string
133    ///
134    ///
135    /// ```
136    /// # use iso6709parse::parsers::iso6709::string_expression::latlong_altitude_option_parser;
137    /// let coord = "+1200.00-02130.00";
138    /// assert_eq!(latlong_altitude_option_parser(coord), Ok(("", ((12.0, -21.5), None))));
139    ///
140    /// let coord = "+1200.00-02130.00+2321CRSWGS_85";
141    /// assert_eq!(latlong_altitude_option_parser(coord), Ok(("WGS_85", ((12.0, -21.5), Some(2321.0)))));
142    /// ```
143    ///  
144    pub fn latlong_altitude_option_parser(inp: &str) -> IResult<&str, ((f64, f64), Option<f64>)> {
145        (latlong_parser, opt(altitude_parser)).parse(inp)
146    }
147    #[cfg(test)]
148    mod string_expression_tests {
149        use super::*;
150
151        #[test]
152        fn should_parse_latlong() {
153            assert_eq!(latlong_parser("+35.50+170.00"), Ok(("", (35.5, 170.0))));
154            assert_eq!(latlong_parser("+35.50-170.10"), Ok(("", (35.5, -170.1))));
155            assert_eq!(latlong_parser("+35-170"), Ok(("", (35., -170.))));
156            assert_eq!(latlong_parser("+05.50-070.10"), Ok(("", (5.5, -70.1))));
157            assert_eq!(latlong_parser("N35.50W170.10"), Ok(("", (35.5, -170.1))));
158
159            assert_eq!(latlong_parser("+3530+17030"), Ok(("", (35.5, 170.5))));
160            assert_eq!(latlong_parser("+3530.0-17030.0"), Ok(("", (35.5, -170.5))));
161
162            assert_eq!(latlong_parser("+05.50-070.10"), Ok(("", (5.5, -70.1))));
163            assert_eq!(
164                latlong_parser("N35.50W170.10+8712CRSWGS_85/"),
165                Ok(("+8712CRSWGS_85/", (35.5, -170.1)))
166            )
167        }
168
169        #[test]
170        fn should_parse_latlong_altitude() {
171            assert_eq!(
172                latlong_altitude_parser("N35.50W170.10+8712CRSWGS_85/"),
173                Ok(("WGS_85/", ((35.5, -170.1), 8712.)))
174            );
175            assert_eq!(
176                latlong_altitude_parser("N35.50W170.10-8712CRSWGS_85/"),
177                Ok(("WGS_85/", ((35.5, -170.1), -8712.)))
178            );
179            assert_eq!(
180                latlong_altitude_parser("N35.50W170.10-8712.5CRSWGS_85/"),
181                Ok(("WGS_85/", ((35.5, -170.1), -8712.5)))
182            )
183        }
184    }
185}