use std::fmt;
use tokenizer::PeekableTokens;
use types::coord::Coord;
use FromTokens;
use Geometry;
#[derive(Default)]
pub struct Point(pub Option<Coord>);
impl Point {
pub fn as_item(self) -> Geometry {
Geometry::Point(self)
}
}
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self.0 {
Some(ref coord) => {
let mut lrs = String::new();
if coord.z.is_some() {
lrs += "Z";
}
if coord.m.is_some() {
lrs += "M";
}
if !lrs.is_empty() {
lrs = " ".to_string() + &lrs;
}
write!(f, "POINT{}({})", lrs, coord)
}
None => f.write_str("POINT EMPTY"),
}
}
}
impl FromTokens for Point {
fn from_tokens(tokens: &mut PeekableTokens) -> Result<Self, &'static str> {
let result = <Coord as FromTokens>::from_tokens(tokens);
result.map(|coord| Point(Some(coord)))
}
}
#[cfg(test)]
mod tests {
use super::{Coord, Point};
use {Geometry, Wkt};
#[test]
fn basic_point() {
let mut wkt = Wkt::from_str("POINT (10 -20)").ok().unwrap();
assert_eq!(1, wkt.items.len());
let coord = match wkt.items.pop().unwrap() {
Geometry::Point(Point(Some(coord))) => coord,
_ => unreachable!(),
};
assert_eq!(10.0, coord.x);
assert_eq!(-20.0, coord.y);
assert_eq!(None, coord.z);
assert_eq!(None, coord.m);
}
#[test]
fn basic_point_whitespace() {
let mut wkt = Wkt::from_str(" \n\t\rPOINT \n\t\r( \n\r\t10 \n\t\r-20 \n\t\r) \n\t\r")
.ok()
.unwrap();
assert_eq!(1, wkt.items.len());
let coord = match wkt.items.pop().unwrap() {
Geometry::Point(Point(Some(coord))) => coord,
_ => unreachable!(),
};
assert_eq!(10.0, coord.x);
assert_eq!(-20.0, coord.y);
assert_eq!(None, coord.z);
assert_eq!(None, coord.m);
}
#[test]
fn invalid_points() {
Wkt::from_str("POINT ()").err().unwrap();
Wkt::from_str("POINT (10)").err().unwrap();
Wkt::from_str("POINT 10").err().unwrap();
Wkt::from_str("POINT (10 -20 40)").err().unwrap();
}
#[test]
fn write_empty_point() {
let point = Point(None);
assert_eq!("POINT EMPTY", format!("{}", point));
}
#[test]
fn write_2d_point() {
let point = Point(Some(Coord {
x: 10.12345,
y: 20.67891,
z: None,
m: None,
}));
assert_eq!("POINT(10.12345 20.67891)", format!("{}", point));
}
#[test]
fn write_point_with_z_coord() {
let point = Point(Some(Coord {
x: 10.12345,
y: 20.67891,
z: Some(-32.56455),
m: None,
}));
assert_eq!("POINT Z(10.12345 20.67891 -32.56455)", format!("{}", point));
}
#[test]
fn write_point_with_m_coord() {
let point = Point(Some(Coord {
x: 10.12345,
y: 20.67891,
z: None,
m: Some(10.),
}));
assert_eq!("POINT M(10.12345 20.67891 10)", format!("{}", point));
}
#[test]
fn write_point_with_zm_coord() {
let point = Point(Some(Coord {
x: 10.12345,
y: 20.67891,
z: Some(-32.56455),
m: Some(10.),
}));
assert_eq!(
"POINT ZM(10.12345 20.67891 -32.56455 10)",
format!("{}", point)
);
}
}