1+ use std:: { f64:: consts:: PI , fmt:: Debug } ;
2+
13use macaddr:: { MacAddr6 , MacAddr8 } ;
4+ use itertools:: Itertools ;
5+ use geo_types:: { coord, Coord , CoordNum , Line , Polygon } ;
6+ use byteorder:: { ReadBytesExt , BigEndian } ;
27use tokio_postgres:: types:: { FromSql , Type } ;
38
49macro_rules! build_additional_rust_type {
@@ -60,3 +65,150 @@ impl<'a> FromSql<'a> for RustMacAddr8 {
6065 true
6166 }
6267}
68+
69+ build_additional_rust_type ! ( RustLine , Line ) ;
70+ build_additional_rust_type ! ( RustPolygon , Polygon ) ;
71+
72+ impl < ' a > FromSql < ' a > for RustLine {
73+ fn from_sql (
74+ _ty : & Type ,
75+ raw : & ' a [ u8 ] ,
76+ ) -> Result < RustLine , Box < dyn std:: error:: Error + Sync + Send > > {
77+ if raw. len ( ) == 4 {
78+ let mut vec_raw: Vec < u8 > = vec ! [ ] ;
79+ vec_raw. extend_from_slice ( raw) ;
80+ let mut buf: & [ u8 ] = vec_raw. as_slice ( ) ;
81+
82+ let x1 = buf. read_f64 :: < BigEndian > ( ) ?;
83+ let y1 = buf. read_f64 :: < BigEndian > ( ) ?;
84+ let first_coord: Coord < f64 > = coord ! ( x: x1, y: y1) ;
85+
86+ let x2 = buf. read_f64 :: < BigEndian > ( ) ?;
87+ let y2 = buf. read_f64 :: < BigEndian > ( ) ?;
88+ let second_coord = coord ! ( x: x2, y: y2) ;
89+
90+ let new_line = Line :: new ( first_coord, second_coord) ;
91+ return Ok ( RustLine :: new ( new_line) ) ;
92+ }
93+ Err ( "Cannot convert PostgreSQL LINE into rust Line" . into ( ) )
94+ }
95+
96+ fn accepts ( _ty : & Type ) -> bool {
97+ true
98+ }
99+ }
100+
101+ // impl<'a> FromSql<'a> for RustPolygon {
102+ // fn from_sql(
103+ // _ty: &Type,
104+ // raw: &'a [u8],
105+ // ) -> Result<RustPolygon, Box<dyn std::error::Error + Sync + Send>> {
106+ // if raw.len() % 2 == 0 {
107+ // let mut vec_raw: Vec<u8> = vec![];
108+ // vec_raw.extend_from_slice(raw);
109+
110+ // for (x, y) in vec_raw.tuple_windows() {
111+ // let coord = coord!(x: x, y: y);
112+ // }
113+
114+ // let new_polygon = Polygon::new(exterior, interiors)
115+ // return Ok(RustPolygon::new(new_polygon));
116+ // }
117+ // Err("Cannot convert PostgreSQL POLYGON into rust Polygon".into())
118+ // }
119+
120+ // fn accepts(_ty: &Type) -> bool {
121+ // true
122+ // }
123+ // }
124+
125+
126+ // add macro for creating circles
127+
128+ #[ derive( Eq , PartialEq , Clone , Copy , Debug , Hash ) ]
129+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
130+ pub struct Circle < T : CoordNum = f64 > {
131+ center : Coord < T > ,
132+ radius : T ,
133+ }
134+
135+ impl < T : CoordNum > Circle < T > {
136+ pub fn new ( x : T , y : T , r : T ) -> Self {
137+ Self { center : Coord :: new ( x, y) , radius : r}
138+ }
139+
140+ pub fn center ( self ) -> Coord < T > {
141+ self . center
142+ }
143+
144+ pub fn set_center ( & mut self , center : Coord < T > ) -> & mut Self {
145+ self . center = center;
146+ self
147+ }
148+
149+ pub fn center_mut ( & mut self ) -> & mut Coord < T > {
150+ & mut self . center
151+ }
152+
153+ pub fn radius ( self ) -> T {
154+ self . radius
155+ }
156+
157+ pub fn set_radius ( & mut self , radius : T ) -> & mut Self {
158+ self . radius = radius;
159+ self
160+ }
161+
162+ pub fn radius_mut ( & mut self ) -> & mut T {
163+ & mut self . radius
164+ }
165+ }
166+
167+ impl < T : CoordNum > Circle < T > {
168+ pub fn area ( self ) -> T {
169+ PI * self . radius * self . radius
170+ }
171+ pub fn perimeter ( self ) -> T {
172+ 2.0 * PI * self . radius
173+ }
174+
175+ pub fn contains ( self , point : & Coord < T > ) -> bool {
176+ self . center . distance_to ( point) <= self . radius
177+ }
178+
179+ pub fn intersects ( self , other : & Self ) -> bool {
180+ self . center . distance_to ( & other. center ) <= self . radius + other. radius
181+ }
182+ }
183+
184+ impl < T : CoordNum > Default for Circle < T > {
185+ fn default ( ) -> Self {
186+ let default_center = Coord :: default ( ) ;
187+ Self { center : default_center, radius : 0.0 }
188+ }
189+ }
190+
191+ impl < ' a > FromSql < ' a > for Circle {
192+ fn from_sql (
193+ _ty : & Type ,
194+ raw : & ' a [ u8 ] ,
195+ ) -> Result < Circle , Box < dyn std:: error:: Error + Sync + Send > > {
196+ if raw. len ( ) == 3 {
197+ let mut vec_raw: Vec < u8 > = vec ! [ ] ;
198+ vec_raw. extend_from_slice ( raw) ;
199+ let mut buf: & [ u8 ] = vec_raw. as_slice ( ) ;
200+
201+ let x = buf. read_f64 :: < BigEndian > ( ) ?;
202+ let y = buf. read_f64 :: < BigEndian > ( ) ?;
203+ let r = buf. read_f64 :: < BigEndian > ( ) ?;
204+
205+ let new_circle = Circle :: new ( x, y, r) ;
206+ return Ok ( new_circle) ;
207+ }
208+ Err ( "Cannot convert PostgreSQL CIRCLE into rust Circle" . into ( ) )
209+ }
210+
211+ fn accepts ( _ty : & Type ) -> bool {
212+ true
213+ }
214+ }
0 commit comments