1use bumpalo::Bump;
5use datavalue::OwnedDataValue;
6
7use crate::Result;
8use crate::arena::DataValue;
9use crate::eval_input::sealed;
10use crate::{EvalInput, OwnedInput, ParsedData};
11
12#[derive(Debug, Clone, Default)]
53pub struct Roots<'r> {
54 parts: Vec<(&'r str, RootValue<'r>)>,
55}
56
57#[derive(Debug, Clone, Copy)]
60pub struct RootValue<'r>(Part<'r>);
61
62#[derive(Debug, Clone, Copy)]
63enum Part<'r> {
64 Owned(&'r OwnedDataValue),
65 #[cfg(feature = "serde_json")]
66 Json(&'r serde_json::Value),
67 Parsed(&'r ParsedData),
68 Arena(&'r DataValue<'r>),
69}
70
71impl<'r> From<&'r OwnedDataValue> for RootValue<'r> {
72 fn from(v: &'r OwnedDataValue) -> Self {
73 RootValue(Part::Owned(v))
74 }
75}
76
77#[cfg(feature = "serde_json")]
78impl<'r> From<&'r serde_json::Value> for RootValue<'r> {
79 fn from(v: &'r serde_json::Value) -> Self {
80 RootValue(Part::Json(v))
81 }
82}
83
84impl<'r> From<&'r ParsedData> for RootValue<'r> {
85 fn from(v: &'r ParsedData) -> Self {
86 RootValue(Part::Parsed(v))
87 }
88}
89
90impl<'r> From<&'r DataValue<'r>> for RootValue<'r> {
91 fn from(v: &'r DataValue<'r>) -> Self {
92 RootValue(Part::Arena(v))
93 }
94}
95
96impl<'r> RootValue<'r> {
97 fn view_in<'a>(self, arena: &'a Bump) -> DataValue<'a>
100 where
101 'r: 'a,
102 {
103 match self.0 {
104 Part::Owned(v) => v.view_in(arena),
105 #[cfg(feature = "serde_json")]
106 Part::Json(v) => crate::arena::value_to_data(v, arena),
107 Part::Parsed(v) => *v.value(),
108 Part::Arena(v) => *v,
109 }
110 }
111
112 fn project_in<'a>(self, under: &crate::projection::Projection, arena: &'a Bump) -> DataValue<'a>
114 where
115 'r: 'a,
116 {
117 match self.0 {
118 Part::Owned(v) => under.owned(v, arena),
119 #[cfg(feature = "serde_json")]
120 Part::Json(v) => under.serde(v, arena),
121 Part::Parsed(v) => *v.value(),
123 Part::Arena(v) => *v,
124 }
125 }
126
127 fn to_owned_value(self) -> OwnedDataValue {
128 match self.0 {
129 Part::Owned(v) => v.clone(),
130 #[cfg(feature = "serde_json")]
131 Part::Json(v) => crate::serde_bridge::owned_from_serde(v),
132 Part::Parsed(v) => v.value().to_owned(),
133 Part::Arena(v) => v.to_owned(),
134 }
135 }
136}
137
138impl<'r> Roots<'r> {
139 pub fn new() -> Self {
141 Roots { parts: Vec::new() }
142 }
143
144 #[must_use = "`root` returns the extended `Roots`"]
146 pub fn root(mut self, name: &'r str, value: impl Into<RootValue<'r>>) -> Self {
147 self.insert(name, value);
148 self
149 }
150
151 pub fn insert(&mut self, name: &'r str, value: impl Into<RootValue<'r>>) {
153 let value = value.into();
154 match self.parts.iter_mut().find(|(n, _)| *n == name) {
155 Some((_, slot)) => *slot = value,
156 None => self.parts.push((name, value)),
157 }
158 }
159
160 pub fn names(&self) -> impl Iterator<Item = &'r str> + '_ {
162 self.parts.iter().map(|(name, _)| *name)
163 }
164
165 pub fn len(&self) -> usize {
167 self.parts.len()
168 }
169
170 pub fn is_empty(&self) -> bool {
172 self.parts.is_empty()
173 }
174
175 fn view_in<'a>(&self, arena: &'a Bump) -> &'a DataValue<'a>
178 where
179 'r: 'a,
180 {
181 let fields = arena.alloc_slice_fill_iter(
182 self.parts
183 .iter()
184 .map(|(name, value)| (*name, value.view_in(arena))),
185 );
186 arena.alloc(DataValue::Object(fields))
187 }
188
189 #[inline]
192 fn arena_for<'a>(
193 &self,
194 logic: &crate::Logic,
195 engine: &crate::Engine,
196 arena: &'a Bump,
197 ) -> &'a DataValue<'a>
198 where
199 'r: 'a,
200 {
201 match logic.projection_for(engine) {
202 Some(projection) => self.projected_in(projection, arena),
203 None => self.view_in(arena),
204 }
205 }
206
207 fn projected_in<'a>(
210 &self,
211 projection: &crate::projection::Projection,
212 arena: &'a Bump,
213 ) -> &'a DataValue<'a>
214 where
215 'r: 'a,
216 {
217 let mut kept = bumpalo::collections::Vec::with_capacity_in(self.parts.len(), arena);
218 for (name, value) in &self.parts {
219 if let Some(under) = projection.under(name) {
220 kept.push((*name, value.project_in(under, arena)));
221 }
222 }
223 arena.alloc(DataValue::Object(kept.into_bump_slice()))
224 }
225
226 fn to_owned_value(&self) -> OwnedDataValue {
227 OwnedDataValue::Object(
228 self.parts
229 .iter()
230 .map(|(name, value)| (name.to_string(), value.to_owned_value()))
231 .collect(),
232 )
233 }
234}
235
236impl<'r, V: Into<RootValue<'r>>, const N: usize> From<[(&'r str, V); N]> for Roots<'r> {
237 fn from(parts: [(&'r str, V); N]) -> Self {
238 parts.into_iter().collect()
239 }
240}
241
242impl<'r, V: Into<RootValue<'r>>> FromIterator<(&'r str, V)> for Roots<'r> {
243 fn from_iter<I: IntoIterator<Item = (&'r str, V)>>(iter: I) -> Self {
244 let mut roots = Roots::new();
245 for (name, value) in iter {
246 roots.insert(name, value);
247 }
248 roots
249 }
250}
251
252impl<'r, V: Into<RootValue<'r>>> Extend<(&'r str, V)> for Roots<'r> {
253 fn extend<I: IntoIterator<Item = (&'r str, V)>>(&mut self, iter: I) {
254 for (name, value) in iter {
255 self.insert(name, value);
256 }
257 }
258}
259
260impl sealed::Sealed for &Roots<'_> {}
263impl<'a, 'r: 'a> EvalInput<'a> for &'a Roots<'r> {
264 #[inline]
265 fn into_arena_value(self, arena: &'a Bump) -> Result<&'a DataValue<'a>> {
266 Ok(self.view_in(arena))
267 }
268
269 #[inline]
270 fn into_arena_for(
271 self,
272 logic: &crate::Logic,
273 engine: &crate::Engine,
274 arena: &'a Bump,
275 ) -> Result<&'a DataValue<'a>> {
276 Ok(self.arena_for(logic, engine, arena))
277 }
278}
279
280impl sealed::Sealed for Roots<'_> {}
281impl<'a, 'r: 'a> EvalInput<'a> for Roots<'r> {
282 #[inline]
283 fn into_arena_value(self, arena: &'a Bump) -> Result<&'a DataValue<'a>> {
284 Ok(self.view_in(arena))
285 }
286
287 #[inline]
288 fn into_arena_for(
289 self,
290 logic: &crate::Logic,
291 engine: &crate::Engine,
292 arena: &'a Bump,
293 ) -> Result<&'a DataValue<'a>> {
294 Ok(self.arena_for(logic, engine, arena))
295 }
296}
297
298impl sealed::LendArena for &Roots<'_> {
299 #[inline]
300 fn lend_arena<R>(
301 self,
302 f: impl for<'a> FnOnce(&'a DataValue<'a>, &'a Bump) -> Result<R>,
303 ) -> Result<R> {
304 let arena = sealed::one_shot_arena();
305 let data = self.view_in(&arena);
306 f(data, &arena)
307 }
308
309 #[inline]
310 fn lend_arena_for<R>(
311 self,
312 logic: &crate::Logic,
313 engine: &crate::Engine,
314 f: impl for<'a> FnOnce(&'a DataValue<'a>, &'a Bump) -> Result<R>,
315 ) -> Result<R> {
316 let arena = sealed::one_shot_arena();
317 let data = self.arena_for(logic, engine, &arena);
318 f(data, &arena)
319 }
320}
321impl OwnedInput for &Roots<'_> {
322 fn into_owned_input(self) -> Result<OwnedDataValue> {
323 Ok(self.to_owned_value())
324 }
325}
326
327impl sealed::LendArena for Roots<'_> {
328 #[inline]
329 fn lend_arena<R>(
330 self,
331 f: impl for<'a> FnOnce(&'a DataValue<'a>, &'a Bump) -> Result<R>,
332 ) -> Result<R> {
333 (&self).lend_arena(f)
334 }
335
336 #[inline]
337 fn lend_arena_for<R>(
338 self,
339 logic: &crate::Logic,
340 engine: &crate::Engine,
341 f: impl for<'a> FnOnce(&'a DataValue<'a>, &'a Bump) -> Result<R>,
342 ) -> Result<R> {
343 (&self).lend_arena_for(logic, engine, f)
344 }
345}
346impl OwnedInput for Roots<'_> {
347 fn into_owned_input(self) -> Result<OwnedDataValue> {
348 Ok(self.to_owned_value())
349 }
350}