geoq_wkt/types/
coord.rs

1// Copyright 2014-2015 The GeoRust Developers
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//	http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt;
16use tokenizer::{PeekableTokens, Token};
17use FromTokens;
18use types::CoordType;
19
20#[derive(Default)]
21pub struct Coord<T = f64>
22where T: CoordType,
23{
24    pub x: T,
25    pub y: T,
26    pub z: Option<T>,
27    pub m: Option<T>,
28}
29
30impl<T: CoordType> fmt::Display for Coord<T> {
31    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
32        write!(f, "{} {}", self.x, self.y)?;
33        if let Some(z) = self.z {
34            write!(f, " {}", z)?;
35        }
36        if let Some(m) = self.m {
37            write!(f, " {}", m)?;
38        }
39        Ok(())
40    }
41}
42
43impl<T: CoordType> Coord<T> {
44    pub fn new(x: T, y: T) -> Coord<T> {
45        Coord{x, y, z: None, m: None}
46    }
47}
48
49impl<T: CoordType> FromTokens<T> for Coord<T> {
50    fn from_tokens(tokens: &mut PeekableTokens<T>) -> Result<Self, &'static str> {
51        let x = match tokens.next() {
52            Some(Token::Number(n)) => n,
53            _ => return Err("Expected a number for the X coordinate"),
54        };
55        let y = match tokens.next() {
56            Some(Token::Number(n)) => n,
57            _ => return Err("Expected a number for the Y coordinate"),
58        };
59        Ok(Coord {
60            x: x,
61            y: y,
62            z: None,
63            m: None,
64        })
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::Coord;
71
72    #[test]
73    fn write_2d_coord() {
74        let coord = Coord {
75            x: 10.1,
76            y: 20.2,
77            z: None,
78            m: None,
79        };
80
81        assert_eq!("10.1 20.2", format!("{}", coord));
82    }
83
84    #[test]
85    fn write_3d_coord() {
86        let coord = Coord {
87            x: 10.1,
88            y: 20.2,
89            z: Some(-30.3),
90            m: None,
91        };
92
93        assert_eq!("10.1 20.2 -30.3", format!("{}", coord));
94    }
95
96    #[test]
97    fn write_2d_coord_with_linear_referencing_system() {
98        let coord = Coord {
99            x: 10.1,
100            y: 20.2,
101            z: None,
102            m: Some(10.),
103        };
104
105        assert_eq!("10.1 20.2 10", format!("{}", coord));
106    }
107
108    #[test]
109    fn write_3d_coord_with_linear_referencing_system() {
110        let coord = Coord {
111            x: 10.1,
112            y: 20.2,
113            z: Some(-30.3),
114            m: Some(10.),
115        };
116
117        assert_eq!("10.1 20.2 -30.3 10", format!("{}", coord));
118    }
119}