Skip to main content

surrealdb_types/flatbuffers/
geometry.rs

1use anyhow::Context;
2use surrealdb_protocol::fb::v1 as proto_fb;
3
4use super::{FromFlatbuffers, ToFlatbuffers};
5use crate::Geometry;
6
7impl ToFlatbuffers for Geometry {
8	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Geometry<'bldr>>;
9
10	#[inline]
11	fn to_fb<'bldr>(
12		&self,
13		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
14	) -> anyhow::Result<Self::Output<'bldr>> {
15		match self {
16			Geometry::Point(point) => {
17				let geometry = point.to_fb(builder)?;
18				Ok(proto_fb::Geometry::create(
19					builder,
20					&proto_fb::GeometryArgs {
21						geometry_type: proto_fb::GeometryType::Point,
22						geometry: Some(geometry.as_union_value()),
23					},
24				))
25			}
26			Geometry::Line(line_string) => {
27				let geometry = line_string.to_fb(builder)?;
28				Ok(proto_fb::Geometry::create(
29					builder,
30					&proto_fb::GeometryArgs {
31						geometry_type: proto_fb::GeometryType::LineString,
32						geometry: Some(geometry.as_union_value()),
33					},
34				))
35			}
36			Geometry::Polygon(polygon) => {
37				let geometry = polygon.to_fb(builder)?;
38				Ok(proto_fb::Geometry::create(
39					builder,
40					&proto_fb::GeometryArgs {
41						geometry_type: proto_fb::GeometryType::Polygon,
42						geometry: Some(geometry.as_union_value()),
43					},
44				))
45			}
46			Geometry::MultiPoint(multi_point) => {
47				let geometry = multi_point.to_fb(builder)?;
48				Ok(proto_fb::Geometry::create(
49					builder,
50					&proto_fb::GeometryArgs {
51						geometry_type: proto_fb::GeometryType::MultiPoint,
52						geometry: Some(geometry.as_union_value()),
53					},
54				))
55			}
56			Geometry::MultiLine(multi_line_string) => {
57				let geometry = multi_line_string.to_fb(builder)?;
58				Ok(proto_fb::Geometry::create(
59					builder,
60					&proto_fb::GeometryArgs {
61						geometry_type: proto_fb::GeometryType::MultiLineString,
62						geometry: Some(geometry.as_union_value()),
63					},
64				))
65			}
66			Geometry::MultiPolygon(multi_polygon) => {
67				let geometry = multi_polygon.to_fb(builder)?;
68				Ok(proto_fb::Geometry::create(
69					builder,
70					&proto_fb::GeometryArgs {
71						geometry_type: proto_fb::GeometryType::MultiPolygon,
72						geometry: Some(geometry.as_union_value()),
73					},
74				))
75			}
76			Geometry::Collection(geometries) => {
77				let mut geometries_vec = Vec::with_capacity(geometries.len());
78				for geometry in geometries {
79					geometries_vec.push(geometry.to_fb(builder)?);
80				}
81				let geometries_vector = builder.create_vector(&geometries_vec);
82
83				let collection = proto_fb::GeometryCollection::create(
84					builder,
85					&proto_fb::GeometryCollectionArgs {
86						geometries: Some(geometries_vector),
87					},
88				);
89
90				Ok(proto_fb::Geometry::create(
91					builder,
92					&proto_fb::GeometryArgs {
93						geometry_type: proto_fb::GeometryType::Collection,
94						geometry: Some(collection.as_union_value()),
95					},
96				))
97			}
98		}
99	}
100}
101
102impl FromFlatbuffers for Geometry {
103	type Input<'a> = proto_fb::Geometry<'a>;
104
105	#[inline]
106	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
107		match input.geometry_type() {
108			proto_fb::GeometryType::Point => {
109				let point = input
110					.geometry_as_point()
111					.ok_or_else(|| anyhow::anyhow!("Expected Point geometry"))?;
112				Ok(Geometry::Point(geo::Point::from_fb(point)?))
113			}
114			proto_fb::GeometryType::LineString => {
115				let line_string = input
116					.geometry_as_line_string()
117					.ok_or_else(|| anyhow::anyhow!("Expected LineString geometry"))?;
118				Ok(Geometry::Line(geo::LineString::from_fb(line_string)?))
119			}
120			proto_fb::GeometryType::Polygon => {
121				let polygon = input
122					.geometry_as_polygon()
123					.ok_or_else(|| anyhow::anyhow!("Expected Polygon geometry"))?;
124				Ok(Geometry::Polygon(geo::Polygon::from_fb(polygon)?))
125			}
126			proto_fb::GeometryType::MultiPoint => {
127				let multi_point = input
128					.geometry_as_multi_point()
129					.ok_or_else(|| anyhow::anyhow!("Expected MultiPoint geometry"))?;
130				Ok(Geometry::MultiPoint(geo::MultiPoint::from_fb(multi_point)?))
131			}
132			proto_fb::GeometryType::MultiLineString => {
133				let multi_line_string = input
134					.geometry_as_multi_line_string()
135					.ok_or_else(|| anyhow::anyhow!("Expected MultiLineString geometry"))?;
136				Ok(Geometry::MultiLine(geo::MultiLineString::from_fb(multi_line_string)?))
137			}
138			proto_fb::GeometryType::MultiPolygon => {
139				let multi_polygon = input
140					.geometry_as_multi_polygon()
141					.ok_or_else(|| anyhow::anyhow!("Expected MultiPolygon geometry"))?;
142				Ok(Geometry::MultiPolygon(geo::MultiPolygon::from_fb(multi_polygon)?))
143			}
144			proto_fb::GeometryType::Collection => {
145				let collection = input
146					.geometry_as_collection()
147					.ok_or_else(|| anyhow::anyhow!("Expected GeometryCollection"))?;
148				let geometries_reader = collection.geometries().context("Geometries is not set")?;
149				let mut geometries = Vec::with_capacity(geometries_reader.len());
150				for geometry in geometries_reader {
151					geometries.push(Geometry::from_fb(geometry)?);
152				}
153				Ok(Geometry::Collection(geometries))
154			}
155			_ => Err(anyhow::anyhow!(
156				"Unsupported geometry type for FlatBuffers deserialization: {:?}",
157				input.geometry_type()
158			)),
159		}
160	}
161}
162
163impl ToFlatbuffers for geo::Point {
164	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Point<'bldr>>;
165
166	#[inline]
167	fn to_fb<'bldr>(
168		&self,
169		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
170	) -> anyhow::Result<Self::Output<'bldr>> {
171		Ok(proto_fb::Point::create(
172			builder,
173			&proto_fb::PointArgs {
174				x: self.x(),
175				y: self.y(),
176			},
177		))
178	}
179}
180
181impl FromFlatbuffers for geo::Point {
182	type Input<'a> = proto_fb::Point<'a>;
183
184	#[inline]
185	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
186		Ok(geo::Point::new(input.x(), input.y()))
187	}
188}
189
190impl ToFlatbuffers for geo::Coord {
191	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Point<'bldr>>;
192
193	#[inline]
194	fn to_fb<'bldr>(
195		&self,
196		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
197	) -> anyhow::Result<Self::Output<'bldr>> {
198		Ok(proto_fb::Point::create(
199			builder,
200			&proto_fb::PointArgs {
201				x: self.x,
202				y: self.y,
203			},
204		))
205	}
206}
207
208impl FromFlatbuffers for geo::Coord {
209	type Input<'a> = proto_fb::Point<'a>;
210
211	#[inline]
212	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
213		Ok(geo::Coord {
214			x: input.x(),
215			y: input.y(),
216		})
217	}
218}
219
220impl ToFlatbuffers for geo::LineString {
221	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::LineString<'bldr>>;
222
223	#[inline]
224	fn to_fb<'bldr>(
225		&self,
226		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
227	) -> anyhow::Result<Self::Output<'bldr>> {
228		let mut points = Vec::with_capacity(self.0.len());
229		for point in &self.0 {
230			points.push(point.to_fb(builder)?);
231		}
232		let points_vector = builder.create_vector(&points);
233		Ok(proto_fb::LineString::create(
234			builder,
235			&proto_fb::LineStringArgs {
236				points: Some(points_vector),
237			},
238		))
239	}
240}
241
242impl FromFlatbuffers for geo::LineString {
243	type Input<'a> = proto_fb::LineString<'a>;
244
245	#[inline]
246	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
247		let mut points = Vec::new();
248		for point in input.points().context("Points is not set")? {
249			points.push(geo::Coord::from_fb(point)?);
250		}
251		Ok(Self(points))
252	}
253}
254
255impl ToFlatbuffers for geo::Polygon {
256	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Polygon<'bldr>>;
257
258	#[inline]
259	fn to_fb<'bldr>(
260		&self,
261		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
262	) -> anyhow::Result<Self::Output<'bldr>> {
263		let exterior = self.exterior().to_fb(builder)?;
264		let mut interiors = Vec::with_capacity(self.interiors().len());
265		for interior in self.interiors() {
266			interiors.push(interior.to_fb(builder)?);
267		}
268		let interiors_vector = builder.create_vector(&interiors);
269		Ok(proto_fb::Polygon::create(
270			builder,
271			&proto_fb::PolygonArgs {
272				exterior: Some(exterior),
273				interiors: Some(interiors_vector),
274			},
275		))
276	}
277}
278
279impl FromFlatbuffers for geo::Polygon {
280	type Input<'a> = proto_fb::Polygon<'a>;
281
282	#[inline]
283	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
284		let exterior =
285			input.exterior().ok_or_else(|| anyhow::anyhow!("Missing exterior in Polygon"))?;
286		let exterior = geo::LineString::from_fb(exterior)?;
287
288		let mut interiors = Vec::new();
289		if let Some(interiors_reader) = input.interiors() {
290			for interior in interiors_reader {
291				interiors.push(geo::LineString::from_fb(interior)?);
292			}
293		}
294
295		Ok(Self::new(exterior, interiors))
296	}
297}
298
299impl ToFlatbuffers for geo::MultiPoint {
300	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::MultiPoint<'bldr>>;
301
302	#[inline]
303	fn to_fb<'bldr>(
304		&self,
305		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
306	) -> anyhow::Result<Self::Output<'bldr>> {
307		let mut points = Vec::with_capacity(self.0.len());
308		for point in &self.0 {
309			points.push(point.to_fb(builder)?);
310		}
311		let points_vector = builder.create_vector(&points);
312		Ok(proto_fb::MultiPoint::create(
313			builder,
314			&proto_fb::MultiPointArgs {
315				points: Some(points_vector),
316			},
317		))
318	}
319}
320
321impl FromFlatbuffers for geo::MultiPoint {
322	type Input<'a> = proto_fb::MultiPoint<'a>;
323
324	#[inline]
325	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
326		let mut points = Vec::new();
327		for point in input.points().context("Points is not set")? {
328			points.push(geo::Point::from_fb(point)?);
329		}
330		Ok(Self(points))
331	}
332}
333
334impl ToFlatbuffers for geo::MultiLineString {
335	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::MultiLineString<'bldr>>;
336
337	#[inline]
338	fn to_fb<'bldr>(
339		&self,
340		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
341	) -> anyhow::Result<Self::Output<'bldr>> {
342		let mut lines = Vec::with_capacity(self.0.len());
343		for line in &self.0 {
344			lines.push(line.to_fb(builder)?);
345		}
346		let lines_vector = builder.create_vector(&lines);
347		Ok(proto_fb::MultiLineString::create(
348			builder,
349			&proto_fb::MultiLineStringArgs {
350				lines: Some(lines_vector),
351			},
352		))
353	}
354}
355
356impl FromFlatbuffers for geo::MultiLineString {
357	type Input<'a> = proto_fb::MultiLineString<'a>;
358
359	#[inline]
360	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
361		let mut lines = Vec::new();
362		for line in input.lines().context("Lines is not set")? {
363			lines.push(geo::LineString::from_fb(line)?);
364		}
365		Ok(Self(lines))
366	}
367}
368
369impl ToFlatbuffers for geo::MultiPolygon {
370	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::MultiPolygon<'bldr>>;
371
372	#[inline]
373	fn to_fb<'bldr>(
374		&self,
375		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
376	) -> anyhow::Result<Self::Output<'bldr>> {
377		let mut polygons = Vec::with_capacity(self.0.len());
378		for polygon in &self.0 {
379			polygons.push(polygon.to_fb(builder)?);
380		}
381		let polygons_vector = builder.create_vector(&polygons);
382		Ok(proto_fb::MultiPolygon::create(
383			builder,
384			&proto_fb::MultiPolygonArgs {
385				polygons: Some(polygons_vector),
386			},
387		))
388	}
389}
390
391impl FromFlatbuffers for geo::MultiPolygon {
392	type Input<'a> = proto_fb::MultiPolygon<'a>;
393
394	#[inline]
395	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
396		let mut polygons = Vec::new();
397		for polygon in input.polygons().context("Polygons is not set")? {
398			polygons.push(geo::Polygon::from_fb(polygon)?);
399		}
400		Ok(Self(polygons))
401	}
402}