geo/algorithm/convert.rs
1use crate::{Coord, CoordNum, MapCoords};
2
3/// Convert (infalliby) the type of a geometry’s coordinate value.
4///
5/// # Examples
6///
7/// ```rust
8/// use geo::{Convert, LineString, line_string};
9///
10/// let line_string_32: LineString<f32> = line_string![
11/// (x: 5., y: 10.),
12/// (x: 3., y: 1.),
13/// (x: 8., y: 9.),
14/// ];
15///
16/// let line_string_64: LineString<f64> = line_string_32.convert();
17/// ```
18///
19pub trait Convert<T, U> {
20 type Output;
21
22 fn convert(&self) -> Self::Output;
23}
24impl<G, T: CoordNum, U: CoordNum> Convert<T, U> for G
25where
26 G: MapCoords<T, U>,
27 U: From<T>,
28{
29 type Output = <Self as MapCoords<T, U>>::Output;
30
31 fn convert(&self) -> Self::Output {
32 self.map_coords(|Coord { x, y }| Coord {
33 x: x.into(),
34 y: y.into(),
35 })
36 }
37}
38
39/// Convert (fallibly) the type of a geometry’s coordinate value.
40///
41/// # Examples
42///
43/// ```rust
44/// use geo::{TryConvert, LineString, line_string};
45///
46/// let line_string_64: LineString<i64> = line_string![
47/// (x: 5, y: 10),
48/// (x: 3, y: 1),
49/// (x: 8, y: 9),
50/// ];
51///
52/// let line_string_32: Result<LineString<i32>, _> = line_string_64.try_convert();
53/// ```
54///
55pub trait TryConvert<T, U> {
56 type Output;
57
58 fn try_convert(&self) -> Self::Output;
59}
60impl<G, T: CoordNum, U: CoordNum> TryConvert<T, U> for G
61where
62 G: MapCoords<T, U>,
63 U: TryFrom<T>,
64{
65 type Output = Result<<Self as MapCoords<T, U>>::Output, <U as TryFrom<T>>::Error>;
66
67 fn try_convert(&self) -> Self::Output {
68 self.try_map_coords(|Coord { x, y }| {
69 Ok(Coord {
70 x: x.try_into()?,
71 y: y.try_into()?,
72 })
73 })
74 }
75}