Skip to main content

surrealdb_types/flatbuffers/
collections.rs

1use std::collections::BTreeMap;
2
3use anyhow::Context;
4use surrealdb_protocol::fb::v1 as proto_fb;
5
6use super::{FromFlatbuffers, ToFlatbuffers};
7use crate::set::Set;
8use crate::{Array, Kind, Object, Value};
9
10impl ToFlatbuffers for BTreeMap<String, Kind> {
11	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::LiteralObject<'bldr>>;
12
13	#[inline]
14	fn to_fb<'bldr>(
15		&self,
16		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
17	) -> anyhow::Result<Self::Output<'bldr>> {
18		let entries: Vec<_> = self
19			.iter()
20			.map(|(key, kind)| -> anyhow::Result<_> {
21				let key_offset = builder.create_string(key);
22				let kind_offset = kind.to_fb(builder)?;
23				Ok(proto_fb::ObjectField::create(
24					builder,
25					&proto_fb::ObjectFieldArgs {
26						key: Some(key_offset),
27						kind: Some(kind_offset),
28					},
29				))
30			})
31			.collect::<anyhow::Result<Vec<_>>>()?;
32
33		let entries_vector = builder.create_vector(&entries);
34		Ok(proto_fb::LiteralObject::create(
35			builder,
36			&proto_fb::LiteralObjectArgs {
37				fields: Some(entries_vector),
38			},
39		))
40	}
41}
42
43impl FromFlatbuffers for BTreeMap<String, Kind> {
44	type Input<'a> = proto_fb::LiteralObject<'a>;
45
46	#[inline]
47	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
48		let mut map = BTreeMap::new();
49		if let Some(entries) = input.fields() {
50			for entry in entries {
51				let Some(key) = entry.key() else {
52					return Err(anyhow::anyhow!("Missing object field key"));
53				};
54				let Some(kind) = entry.kind() else {
55					return Err(anyhow::anyhow!("Missing object field kind"));
56				};
57				map.insert(key.to_string(), Kind::from_fb(kind)?);
58			}
59		}
60		Ok(map)
61	}
62}
63
64impl ToFlatbuffers for Object {
65	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Object<'bldr>>;
66
67	#[inline]
68	fn to_fb<'bldr>(
69		&self,
70		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
71	) -> anyhow::Result<Self::Output<'bldr>> {
72		let mut entries = Vec::with_capacity(self.0.len());
73		for (key, value) in &self.0 {
74			let key_fb = builder.create_string(key);
75			let value_fb = value.to_fb(builder)?;
76
77			let object_item = proto_fb::KeyValue::create(
78				builder,
79				&proto_fb::KeyValueArgs {
80					key: Some(key_fb),
81					value: Some(value_fb),
82				},
83			);
84
85			entries.push(object_item);
86		}
87		let entries_vector = builder.create_vector(&entries);
88		Ok(proto_fb::Object::create(
89			builder,
90			&proto_fb::ObjectArgs {
91				items: Some(entries_vector),
92			},
93		))
94	}
95}
96
97impl FromFlatbuffers for Object {
98	type Input<'a> = proto_fb::Object<'a>;
99
100	#[inline]
101	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
102		let mut map = BTreeMap::new();
103		let items = input.items().ok_or_else(|| anyhow::anyhow!("Missing items in Object"))?;
104		if items.is_empty() {
105			return Ok(Object(map));
106		}
107		for entry in items {
108			let key = entry.key().context("Missing key in Object entry")?.to_string();
109			let value = entry.value().context("Missing value in Object entry")?;
110			map.insert(key, Value::from_fb(value)?);
111		}
112		Ok(Object(map))
113	}
114}
115
116impl ToFlatbuffers for Array {
117	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Array<'bldr>>;
118
119	#[inline]
120	fn to_fb<'bldr>(
121		&self,
122		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
123	) -> anyhow::Result<Self::Output<'bldr>> {
124		let mut values = Vec::with_capacity(self.len());
125		for value in self.iter() {
126			values.push(value.to_fb(builder)?);
127		}
128		let values_vector = builder.create_vector(&values);
129		Ok(proto_fb::Array::create(
130			builder,
131			&proto_fb::ArrayArgs {
132				values: Some(values_vector),
133			},
134		))
135	}
136}
137
138impl FromFlatbuffers for Array {
139	type Input<'a> = proto_fb::Array<'a>;
140
141	#[inline]
142	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
143		let mut vec = Vec::new();
144		let values = input.values().context("Values is not set")?;
145		for value in values {
146			vec.push(Value::from_fb(value)?);
147		}
148		Ok(Array::from(vec))
149	}
150}
151
152impl ToFlatbuffers for Set {
153	type Output<'bldr> = flatbuffers::WIPOffset<proto_fb::Set<'bldr>>;
154
155	#[inline]
156	fn to_fb<'bldr>(
157		&self,
158		builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
159	) -> anyhow::Result<Self::Output<'bldr>> {
160		let mut values = Vec::with_capacity(self.len());
161		for value in self.iter() {
162			values.push(value.to_fb(builder)?);
163		}
164		let values_vector = builder.create_vector(&values);
165		Ok(proto_fb::Set::create(
166			builder,
167			&proto_fb::SetArgs {
168				values: Some(values_vector),
169			},
170		))
171	}
172}
173
174impl FromFlatbuffers for Set {
175	type Input<'a> = proto_fb::Set<'a>;
176
177	#[inline]
178	fn from_fb(input: Self::Input<'_>) -> anyhow::Result<Self> {
179		let mut set = Set::new();
180		let values = input.values().context("Values is not set")?;
181		for value in values {
182			set.insert(Value::from_fb(value)?);
183		}
184		Ok(set)
185	}
186}