Skip to main content

surrealdb_types/flatbuffers/
primitives.rs

1use anyhow::Context;
2use chrono::{DateTime, Utc};
3use rust_decimal::Decimal;
4use surrealdb_protocol::fb::v1 as proto_fb;
5
6use super::{FromFlatbuffers, ToFlatbuffers};
7use crate::{Bytes, Duration, Uuid};
8
9impl ToFlatbuffers for bool {
10	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::BoolValue<'bldr>>;
11
12	#[inline]
13	fn to_fb<'bldr>(
14		&self,
15		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
16	) -> anyhow::Result<Self::Output<'bldr>> {
17		Ok(proto_fb::BoolValue::create(
18			builder,
19			&proto_fb::BoolValueArgs {
20				value: *self,
21			},
22		))
23	}
24}
25
26impl FromFlatbuffers for bool {
27	type Input<'a> = proto_fb::BoolValue<'a>;
28
29	#[inline]
30	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
31		Ok(input.value())
32	}
33}
34
35impl ToFlatbuffers for i64 {
36	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Int64Value<'bldr>>;
37
38	#[inline]
39	fn to_fb<'bldr>(
40		&self,
41		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
42	) -> anyhow::Result<Self::Output<'bldr>> {
43		Ok(proto_fb::Int64Value::create(
44			builder,
45			&proto_fb::Int64ValueArgs {
46				value: *self,
47			},
48		))
49	}
50}
51
52impl FromFlatbuffers for i64 {
53	type Input<'a> = proto_fb::Int64Value<'a>;
54
55	#[inline]
56	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
57		Ok(input.value())
58	}
59}
60
61impl ToFlatbuffers for u64 {
62	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::UInt64Value<'bldr>>;
63
64	#[inline]
65	fn to_fb<'bldr>(
66		&self,
67		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
68	) -> anyhow::Result<Self::Output<'bldr>> {
69		Ok(proto_fb::UInt64Value::create(
70			builder,
71			&proto_fb::UInt64ValueArgs {
72				value: *self,
73			},
74		))
75	}
76}
77
78impl FromFlatbuffers for u64 {
79	type Input<'a> = proto_fb::UInt64Value<'a>;
80
81	#[inline]
82	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
83		Ok(input.value())
84	}
85}
86
87impl ToFlatbuffers for f64 {
88	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Float64Value<'bldr>>;
89
90	#[inline]
91	fn to_fb<'bldr>(
92		&self,
93		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
94	) -> anyhow::Result<Self::Output<'bldr>> {
95		Ok(proto_fb::Float64Value::create(
96			builder,
97			&proto_fb::Float64ValueArgs {
98				value: *self,
99			},
100		))
101	}
102}
103
104impl FromFlatbuffers for f64 {
105	type Input<'a> = proto_fb::Float64Value<'a>;
106
107	#[inline]
108	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
109		Ok(input.value())
110	}
111}
112
113impl ToFlatbuffers for String {
114	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::StringValue<'bldr>>;
115
116	#[inline]
117	fn to_fb<'bldr>(
118		&self,
119		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
120	) -> anyhow::Result<Self::Output<'bldr>> {
121		let value = builder.create_string(self);
122		Ok(proto_fb::StringValue::create(
123			builder,
124			&proto_fb::StringValueArgs {
125				value: Some(value),
126			},
127		))
128	}
129}
130
131impl FromFlatbuffers for String {
132	type Input<'a> = proto_fb::StringValue<'a>;
133
134	#[inline]
135	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
136		let Some(value) = input.value() else {
137			return Err(anyhow::anyhow!("Missing string value"));
138		};
139		Ok(value.to_string())
140	}
141}
142
143impl ToFlatbuffers for Decimal {
144	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Decimal<'bldr>>;
145
146	#[inline]
147	fn to_fb<'bldr>(
148		&self,
149		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
150	) -> anyhow::Result<Self::Output<'bldr>> {
151		let value = builder.create_string(&self.to_string());
152		Ok(proto_fb::Decimal::create(
153			builder,
154			&proto_fb::DecimalArgs {
155				value: Some(value),
156			},
157		))
158	}
159}
160
161impl FromFlatbuffers for Decimal {
162	type Input<'a> = proto_fb::Decimal<'a>;
163
164	#[inline]
165	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
166		let Some(value_str) = input.value() else {
167			return Err(anyhow::anyhow!("Missing decimal string"));
168		};
169		value_str.parse::<Decimal>().context("Failed to parse decimal")
170	}
171}
172
173impl ToFlatbuffers for std::time::Duration {
174	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Duration<'bldr>>;
175
176	#[inline]
177	fn to_fb<'bldr>(
178		&self,
179		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
180	) -> anyhow::Result<Self::Output<'bldr>> {
181		Ok(proto_fb::Duration::create(
182			builder,
183			&proto_fb::DurationArgs {
184				seconds: self.as_secs(),
185				nanos: self.subsec_nanos(),
186			},
187		))
188	}
189}
190
191impl FromFlatbuffers for std::time::Duration {
192	type Input<'a> = proto_fb::Duration<'a>;
193
194	#[inline]
195	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
196		let seconds = input.seconds();
197		let nanos = input.nanos();
198		Ok(std::time::Duration::new(seconds, nanos))
199	}
200}
201
202impl ToFlatbuffers for Duration {
203	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Duration<'bldr>>;
204
205	#[inline]
206	fn to_fb<'bldr>(
207		&self,
208		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
209	) -> anyhow::Result<Self::Output<'bldr>> {
210		self.0.to_fb(builder)
211	}
212}
213
214impl FromFlatbuffers for Duration {
215	type Input<'a> = proto_fb::Duration<'a>;
216
217	#[inline]
218	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
219		let duration = std::time::Duration::from_fb(input)?;
220		Ok(Duration(duration))
221	}
222}
223
224impl ToFlatbuffers for DateTime<Utc> {
225	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Timestamp<'bldr>>;
226
227	#[inline]
228	fn to_fb<'bldr>(
229		&self,
230		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
231	) -> anyhow::Result<Self::Output<'bldr>> {
232		Ok(proto_fb::Timestamp::create(
233			builder,
234			&proto_fb::TimestampArgs {
235				seconds: self.timestamp(),
236				nanos: self.timestamp_subsec_nanos(),
237			},
238		))
239	}
240}
241
242impl FromFlatbuffers for DateTime<Utc> {
243	type Input<'a> = proto_fb::Timestamp<'a>;
244
245	#[inline]
246	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
247		let seconds = input.seconds();
248		let nanos = input.nanos();
249		DateTime::<Utc>::from_timestamp(seconds, nanos)
250			.ok_or_else(|| anyhow::anyhow!("Invalid timestamp format"))
251	}
252}
253
254impl ToFlatbuffers for Uuid {
255	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Uuid<'bldr>>;
256
257	#[inline]
258	fn to_fb<'bldr>(
259		&self,
260		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
261	) -> anyhow::Result<Self::Output<'bldr>> {
262		let bytes = builder.create_vector(self.0.as_bytes());
263		Ok(proto_fb::Uuid::create(
264			builder,
265			&proto_fb::UuidArgs {
266				bytes: Some(bytes),
267			},
268		))
269	}
270}
271
272impl FromFlatbuffers for Uuid {
273	type Input<'a> = proto_fb::Uuid<'a>;
274
275	#[inline]
276	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
277		let bytes_vector = input.bytes().ok_or_else(|| anyhow::anyhow!("Missing bytes in Uuid"))?;
278		uuid::Uuid::from_slice(bytes_vector.bytes())
279			.map(Uuid)
280			.map_err(|_| anyhow::anyhow!("Invalid UUID format"))
281	}
282}
283
284impl ToFlatbuffers for Bytes {
285	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Bytes<'bldr>>;
286
287	#[inline]
288	fn to_fb<'bldr>(
289		&self,
290		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
291	) -> anyhow::Result<Self::Output<'bldr>> {
292		let data = builder.create_vector(&self.0);
293		Ok(proto_fb::Bytes::create(
294			builder,
295			&proto_fb::BytesArgs {
296				value: Some(data),
297			},
298		))
299	}
300}
301
302impl FromFlatbuffers for Bytes {
303	type Input<'a> = proto_fb::Bytes<'a>;
304
305	#[inline]
306	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
307		let data = input.value().ok_or_else(|| anyhow::anyhow!("Missing value in Bytes"))?;
308		Ok(Bytes(::bytes::Bytes::copy_from_slice(data.bytes())))
309	}
310}