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}