1pub mod attributes;
2pub mod edges;
3pub mod nodes;
4pub mod values;
5
6use super::{
7 Lut, PyNodeIndex, attribute::PyGraphRecordAttribute, errors::PyGraphRecordError,
8 traits::DeepFrom, value::PyGraphRecordValue,
9};
10use crate::{
11 conversion_lut::ConversionLut,
12 graphrecord::querying::{
13 attributes::{
14 PyEdgeSingleAttributeWithoutIndexGroupOperand,
15 PyNodeSingleAttributeWithoutIndexGroupOperand,
16 },
17 edges::{PyEdgeIndexGroupOperand, PyEdgeIndicesGroupOperand},
18 nodes::{PyNodeIndexGroupOperand, PyNodeIndicesGroupOperand},
19 values::{
20 PyEdgeSingleValueWithoutIndexGroupOperand, PyNodeSingleValueWithoutIndexGroupOperand,
21 },
22 },
23};
24use attributes::{
25 PyEdgeAttributesTreeGroupOperand, PyEdgeAttributesTreeOperand,
26 PyEdgeMultipleAttributesWithIndexGroupOperand, PyEdgeMultipleAttributesWithIndexOperand,
27 PyEdgeMultipleAttributesWithoutIndexOperand, PyEdgeSingleAttributeWithIndexGroupOperand,
28 PyEdgeSingleAttributeWithIndexOperand, PyEdgeSingleAttributeWithoutIndexOperand,
29 PyNodeAttributesTreeGroupOperand, PyNodeAttributesTreeOperand,
30 PyNodeMultipleAttributesWithIndexGroupOperand, PyNodeMultipleAttributesWithIndexOperand,
31 PyNodeMultipleAttributesWithoutIndexOperand, PyNodeSingleAttributeWithIndexGroupOperand,
32 PyNodeSingleAttributeWithIndexOperand, PyNodeSingleAttributeWithoutIndexOperand,
33};
34use edges::{PyEdgeIndexOperand, PyEdgeIndicesOperand};
35use graphrecords_core::{
36 GraphRecord,
37 errors::{GraphRecordError, GraphRecordResult},
38 graphrecord::{
39 GraphRecordAttribute,
40 querying::{
41 ReturnOperand,
42 attributes::{
43 EdgeAttributesTreeOperand, EdgeMultipleAttributesWithIndexOperand,
44 EdgeMultipleAttributesWithoutIndexOperand, EdgeSingleAttributeWithIndexOperand,
45 EdgeSingleAttributeWithoutIndexOperand, NodeAttributesTreeOperand,
46 NodeMultipleAttributesWithIndexOperand, NodeMultipleAttributesWithoutIndexOperand,
47 NodeSingleAttributeWithIndexOperand, NodeSingleAttributeWithoutIndexOperand,
48 },
49 edges::{EdgeIndexOperand, EdgeIndicesOperand},
50 group_by::{GroupKey, GroupOperand},
51 nodes::{NodeIndexOperand, NodeIndicesOperand},
52 values::{
53 EdgeMultipleValuesWithIndexOperand, EdgeMultipleValuesWithoutIndexOperand,
54 EdgeSingleValueWithIndexOperand, EdgeSingleValueWithoutIndexOperand,
55 NodeMultipleValuesWithIndexOperand, NodeMultipleValuesWithoutIndexOperand,
56 NodeSingleValueWithIndexOperand, NodeSingleValueWithoutIndexOperand,
57 },
58 wrapper::{CardinalityWrapper, MatchMode, Wrapper},
59 },
60 },
61};
62use nodes::{PyNodeIndexOperand, PyNodeIndicesOperand};
63use pyo3::{
64 Borrowed, Bound, FromPyObject, IntoPyObject, IntoPyObjectExt, PyAny, PyErr, PyResult, Python,
65 pyclass,
66 types::{PyAnyMethods, PyList},
67};
68use std::collections::HashMap;
69use values::{
70 PyEdgeMultipleValuesWithIndexGroupOperand, PyEdgeMultipleValuesWithIndexOperand,
71 PyEdgeMultipleValuesWithoutIndexOperand, PyEdgeSingleValueWithIndexGroupOperand,
72 PyEdgeSingleValueWithIndexOperand, PyEdgeSingleValueWithoutIndexOperand,
73 PyNodeMultipleValuesWithIndexGroupOperand, PyNodeMultipleValuesWithIndexOperand,
74 PyNodeMultipleValuesWithoutIndexOperand, PyNodeSingleValueWithIndexGroupOperand,
75 PyNodeSingleValueWithIndexOperand, PyNodeSingleValueWithoutIndexOperand,
76};
77
78#[pyclass(frozen)]
79#[derive(Debug, Clone, Copy)]
80pub enum PyMatchMode {
81 Any,
82 All,
83}
84
85impl From<MatchMode> for PyMatchMode {
86 fn from(mode: MatchMode) -> Self {
87 match mode {
88 MatchMode::Any => Self::Any,
89 MatchMode::All => Self::All,
90 }
91 }
92}
93
94impl From<PyMatchMode> for MatchMode {
95 fn from(mode: PyMatchMode) -> Self {
96 match mode {
97 PyMatchMode::Any => Self::Any,
98 PyMatchMode::All => Self::All,
99 }
100 }
101}
102
103#[derive(Debug, Clone)]
104pub enum PyGroupKey {
105 NodeIndex(PyNodeIndex),
106 Value(PyGraphRecordValue),
107 OptionalValue(Option<PyGraphRecordValue>),
108 TupleKey((Box<Self>, Box<Self>)),
109}
110
111impl From<GroupKey<'_>> for PyGroupKey {
112 fn from(key: GroupKey<'_>) -> Self {
113 match key {
114 GroupKey::NodeIndex(index) => Self::NodeIndex(PyNodeIndex::from(index.clone())),
115 GroupKey::Value(value) => Self::Value(PyGraphRecordValue::from(value.clone())),
116 GroupKey::OptionalValue(value) => {
117 Self::OptionalValue(value.cloned().map(PyGraphRecordValue::from))
118 }
119 GroupKey::TupleKey((left, right)) => {
120 Self::TupleKey((Box::new(Self::from(*left)), Box::new(Self::from(*right))))
121 }
122 }
123 }
124}
125
126impl<'py> IntoPyObject<'py> for PyGroupKey {
127 type Target = pyo3::PyAny;
128 type Output = Bound<'py, Self::Target>;
129 type Error = PyErr;
130
131 fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
132 match self {
133 Self::NodeIndex(index) => index.into_pyobject(py),
134 Self::Value(value) => value.into_pyobject(py),
135 Self::OptionalValue(value) => value.into_pyobject(py),
136 Self::TupleKey((left, right)) => {
137 let left = left.into_pyobject(py)?;
138 let right = right.into_pyobject(py)?;
139 (left, right).into_bound_py_any(py)
140 }
141 }
142 }
143}
144
145pub enum PyReturnOperand {
146 NodeAttributesTree(PyNodeAttributesTreeOperand),
147 NodeAttributesTreeGroup(PyNodeAttributesTreeGroupOperand),
148 EdgeAttributesTree(PyEdgeAttributesTreeOperand),
149 EdgeAttributesTreeGroup(PyEdgeAttributesTreeGroupOperand),
150 NodeMultipleAttributesWithIndex(PyNodeMultipleAttributesWithIndexOperand),
151 NodeMultipleAttributesWithIndexGroup(PyNodeMultipleAttributesWithIndexGroupOperand),
152 NodeMultipleAttributesWithoutIndex(PyNodeMultipleAttributesWithoutIndexOperand),
153 EdgeMultipleAttributesWithIndex(PyEdgeMultipleAttributesWithIndexOperand),
154 EdgeMultipleAttributesWithIndexGroup(PyEdgeMultipleAttributesWithIndexGroupOperand),
155 EdgeMultipleAttributesWithoutIndex(PyEdgeMultipleAttributesWithoutIndexOperand),
156 NodeSingleAttributeWithIndex(PyNodeSingleAttributeWithIndexOperand),
157 NodeSingleAttributeWithIndexGroup(PyNodeSingleAttributeWithIndexGroupOperand),
158 NodeSingleAttributeWithoutIndex(PyNodeSingleAttributeWithoutIndexOperand),
159 NodeSingleAttributeWithoutIndexGroup(PyNodeSingleAttributeWithoutIndexGroupOperand),
160 EdgeSingleAttributeWithIndex(PyEdgeSingleAttributeWithIndexOperand),
161 EdgeSingleAttributeWithIndexGroup(PyEdgeSingleAttributeWithIndexGroupOperand),
162 EdgeSingleAttributeWithoutIndex(PyEdgeSingleAttributeWithoutIndexOperand),
163 EdgeSingleAttributeWithoutIndexGroup(PyEdgeSingleAttributeWithoutIndexGroupOperand),
164 EdgeIndices(PyEdgeIndicesOperand),
165 EdgeIndicesGroup(PyEdgeIndicesGroupOperand),
166 EdgeIndex(PyEdgeIndexOperand),
167 EdgeIndexGroup(PyEdgeIndexGroupOperand),
168 NodeIndices(PyNodeIndicesOperand),
169 NodeIndicesGroup(PyNodeIndicesGroupOperand),
170 NodeIndex(PyNodeIndexOperand),
171 NodeIndexGroup(PyNodeIndexGroupOperand),
172 NodeMultipleValuesWithIndex(PyNodeMultipleValuesWithIndexOperand),
173 NodeMultipleValuesWithIndexGroup(PyNodeMultipleValuesWithIndexGroupOperand),
174 NodeMultipleValuesWithoutIndex(PyNodeMultipleValuesWithoutIndexOperand),
175 EdgeMultipleValuesWithIndex(PyEdgeMultipleValuesWithIndexOperand),
176 EdgeMultipleValuesWithIndexGroup(PyEdgeMultipleValuesWithIndexGroupOperand),
177 EdgeMultipleValuesWithoutIndex(PyEdgeMultipleValuesWithoutIndexOperand),
178 NodeSingleValueWithIndex(PyNodeSingleValueWithIndexOperand),
179 NodeSingleValueWithIndexGroup(PyNodeSingleValueWithIndexGroupOperand),
180 NodeSingleValueWithoutIndex(PyNodeSingleValueWithoutIndexOperand),
181 NodeSingleValueWithoutIndexGroup(PyNodeSingleValueWithoutIndexGroupOperand),
182 EdgeSingleValueWithIndex(PyEdgeSingleValueWithIndexOperand),
183 EdgeSingleValueWithIndexGroup(PyEdgeSingleValueWithIndexGroupOperand),
184 EdgeSingleValueWithoutIndex(PyEdgeSingleValueWithoutIndexOperand),
185 EdgeSingleValueWithoutIndexGroup(PyEdgeSingleValueWithoutIndexGroupOperand),
186 Vector(Vec<Self>),
187}
188
189impl<'a> ReturnOperand<'a> for PyReturnOperand {
190 type ReturnValue = PyReturnValue<'a>;
191
192 #[allow(clippy::too_many_lines)]
193 fn evaluate(&self, graphrecord: &'a GraphRecord) -> GraphRecordResult<Self::ReturnValue> {
194 match self {
195 Self::NodeAttributesTree(operand) => operand
196 .evaluate(graphrecord)
197 .map(PyReturnValue::NodeAttributesTree),
198 Self::NodeAttributesTreeGroup(operand) => operand
199 .evaluate(graphrecord)
200 .map(PyReturnValue::NodeAttributesTreeGroup),
201 Self::EdgeAttributesTree(operand) => operand
202 .evaluate(graphrecord)
203 .map(PyReturnValue::EdgeAttributesTree),
204 Self::EdgeAttributesTreeGroup(operand) => operand
205 .evaluate(graphrecord)
206 .map(PyReturnValue::EdgeAttributesTreeGroup),
207 Self::NodeMultipleAttributesWithIndex(operand) => operand
208 .evaluate(graphrecord)
209 .map(PyReturnValue::NodeMultipleAttributesWithIndex),
210 Self::NodeMultipleAttributesWithIndexGroup(operand) => operand
211 .evaluate(graphrecord)
212 .map(PyReturnValue::NodeMultipleAttributesWithIndexGroup),
213 Self::NodeMultipleAttributesWithoutIndex(operand) => operand
214 .evaluate(graphrecord)
215 .map(PyReturnValue::NodeMultipleAttributesWithoutIndex),
216 Self::EdgeMultipleAttributesWithIndex(operand) => operand
217 .evaluate(graphrecord)
218 .map(PyReturnValue::EdgeMultipleAttributesWithIndex),
219 Self::EdgeMultipleAttributesWithIndexGroup(operand) => operand
220 .evaluate(graphrecord)
221 .map(PyReturnValue::EdgeMultipleAttributesWithIndexGroup),
222 Self::EdgeMultipleAttributesWithoutIndex(operand) => operand
223 .evaluate(graphrecord)
224 .map(PyReturnValue::EdgeMultipleAttributesWithoutIndex),
225 Self::NodeSingleAttributeWithIndex(operand) => operand
226 .evaluate(graphrecord)
227 .map(PyReturnValue::NodeSingleAttributeWithIndex),
228 Self::NodeSingleAttributeWithIndexGroup(operand) => operand
229 .evaluate(graphrecord)
230 .map(PyReturnValue::NodeSingleAttributeWithIndexGroup),
231 Self::NodeSingleAttributeWithoutIndex(operand) => operand
232 .evaluate(graphrecord)
233 .map(PyReturnValue::NodeSingleAttributeWithoutIndex),
234 Self::NodeSingleAttributeWithoutIndexGroup(operand) => operand
235 .evaluate(graphrecord)
236 .map(PyReturnValue::NodeSingleAttributeWithoutIndexGroup),
237 Self::EdgeSingleAttributeWithIndex(operand) => operand
238 .evaluate(graphrecord)
239 .map(PyReturnValue::EdgeSingleAttributeWithIndex),
240 Self::EdgeSingleAttributeWithIndexGroup(operand) => operand
241 .evaluate(graphrecord)
242 .map(PyReturnValue::EdgeSingleAttributeWithIndexGroup),
243 Self::EdgeSingleAttributeWithoutIndex(operand) => operand
244 .evaluate(graphrecord)
245 .map(PyReturnValue::EdgeSingleAttributeWithoutIndex),
246 Self::EdgeSingleAttributeWithoutIndexGroup(operand) => operand
247 .evaluate(graphrecord)
248 .map(PyReturnValue::EdgeSingleAttributeWithoutIndexGroup),
249 Self::EdgeIndices(operand) => operand
250 .evaluate(graphrecord)
251 .map(PyReturnValue::EdgeIndices),
252 Self::EdgeIndicesGroup(operand) => operand
253 .evaluate(graphrecord)
254 .map(PyReturnValue::EdgeIndicesGroup),
255 Self::EdgeIndex(operand) => operand.evaluate(graphrecord).map(PyReturnValue::EdgeIndex),
256 Self::EdgeIndexGroup(operand) => operand
257 .evaluate(graphrecord)
258 .map(PyReturnValue::EdgeIndexGroup),
259 Self::NodeIndices(operand) => operand
260 .evaluate(graphrecord)
261 .map(PyReturnValue::NodeIndices),
262 Self::NodeIndicesGroup(operand) => operand
263 .evaluate(graphrecord)
264 .map(PyReturnValue::NodeIndicesGroup),
265 Self::NodeIndex(operand) => operand.evaluate(graphrecord).map(PyReturnValue::NodeIndex),
266 Self::NodeIndexGroup(operand) => operand
267 .evaluate(graphrecord)
268 .map(PyReturnValue::NodeIndexGroup),
269 Self::NodeMultipleValuesWithIndex(operand) => operand
270 .evaluate(graphrecord)
271 .map(PyReturnValue::NodeMultipleValuesWithIndex),
272 Self::NodeMultipleValuesWithIndexGroup(operand) => operand
273 .evaluate(graphrecord)
274 .map(PyReturnValue::NodeMultipleValuesWithIndexGroup),
275 Self::NodeMultipleValuesWithoutIndex(operand) => operand
276 .evaluate(graphrecord)
277 .map(PyReturnValue::NodeMultipleValuesWithoutIndex),
278 Self::EdgeMultipleValuesWithIndex(operand) => operand
279 .evaluate(graphrecord)
280 .map(PyReturnValue::EdgeMultipleValuesWithIndex),
281 Self::EdgeMultipleValuesWithIndexGroup(operand) => operand
282 .evaluate(graphrecord)
283 .map(PyReturnValue::EdgeMultipleValuesWithIndexGroup),
284 Self::EdgeMultipleValuesWithoutIndex(operand) => operand
285 .evaluate(graphrecord)
286 .map(PyReturnValue::EdgeMultipleValuesWithoutIndex),
287 Self::NodeSingleValueWithIndex(operand) => operand
288 .evaluate(graphrecord)
289 .map(PyReturnValue::NodeSingleValueWithIndex),
290 Self::NodeSingleValueWithIndexGroup(operand) => operand
291 .evaluate(graphrecord)
292 .map(PyReturnValue::NodeSingleValueWithIndexGroup),
293 Self::NodeSingleValueWithoutIndex(operand) => operand
294 .evaluate(graphrecord)
295 .map(PyReturnValue::NodeSingleValueWithoutIndex),
296 Self::NodeSingleValueWithoutIndexGroup(operand) => operand
297 .evaluate(graphrecord)
298 .map(PyReturnValue::NodeSingleValueWithoutIndexGroup),
299 Self::EdgeSingleValueWithIndex(operand) => operand
300 .evaluate(graphrecord)
301 .map(PyReturnValue::EdgeSingleValueWithIndex),
302 Self::EdgeSingleValueWithIndexGroup(operand) => operand
303 .evaluate(graphrecord)
304 .map(PyReturnValue::EdgeSingleValueWithIndexGroup),
305 Self::EdgeSingleValueWithoutIndex(operand) => operand
306 .evaluate(graphrecord)
307 .map(PyReturnValue::EdgeSingleValueWithoutIndex),
308 Self::EdgeSingleValueWithoutIndexGroup(operand) => operand
309 .evaluate(graphrecord)
310 .map(PyReturnValue::EdgeSingleValueWithoutIndexGroup),
311 Self::Vector(operand) => operand
312 .iter()
313 .map(|item| item.evaluate(graphrecord))
314 .collect::<GraphRecordResult<Vec<_>>>()
315 .map(PyReturnValue::Vector),
316 }
317 }
318}
319
320static RETURNOPERAND_CONVERSION_LUT: Lut<PyReturnOperand> = ConversionLut::new();
321
322#[allow(clippy::unnecessary_wraps, clippy::too_many_lines)]
323pub(crate) fn convert_pyobject_to_pyreturnoperand(
324 ob: &Bound<'_, PyAny>,
325) -> PyResult<PyReturnOperand> {
326 fn convert_py_node_attributes_tree_operand(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
327 Ok(PyReturnOperand::NodeAttributesTree(
328 ob.extract::<PyNodeAttributesTreeOperand>()
329 .expect("Extraction must succeed"),
330 ))
331 }
332 fn convert_py_node_attributes_tree_group_operand(
333 ob: &Bound<'_, PyAny>,
334 ) -> PyResult<PyReturnOperand> {
335 Ok(PyReturnOperand::NodeAttributesTreeGroup(
336 ob.extract::<PyNodeAttributesTreeGroupOperand>()
337 .expect("Extraction must succeed"),
338 ))
339 }
340
341 fn convert_py_edge_attributes_tree_operand(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
342 Ok(PyReturnOperand::EdgeAttributesTree(
343 ob.extract::<PyEdgeAttributesTreeOperand>()
344 .expect("Extraction must succeed"),
345 ))
346 }
347
348 fn convert_py_edge_attributes_tree_group_operand(
349 ob: &Bound<'_, PyAny>,
350 ) -> PyResult<PyReturnOperand> {
351 Ok(PyReturnOperand::EdgeAttributesTreeGroup(
352 ob.extract::<PyEdgeAttributesTreeGroupOperand>()
353 .expect("Extraction must succeed"),
354 ))
355 }
356
357 fn convert_py_node_multiple_attributes_with_index_operand(
358 ob: &Bound<'_, PyAny>,
359 ) -> PyResult<PyReturnOperand> {
360 Ok(PyReturnOperand::NodeMultipleAttributesWithIndex(
361 ob.extract::<PyNodeMultipleAttributesWithIndexOperand>()
362 .expect("Extraction must succeed"),
363 ))
364 }
365
366 fn convert_py_node_multiple_attributes_with_index_group_operand(
367 ob: &Bound<'_, PyAny>,
368 ) -> PyResult<PyReturnOperand> {
369 Ok(PyReturnOperand::NodeMultipleAttributesWithIndexGroup(
370 ob.extract::<PyNodeMultipleAttributesWithIndexGroupOperand>()
371 .expect("Extraction must succeed"),
372 ))
373 }
374
375 fn convert_py_node_multiple_attributes_without_index_operand(
376 ob: &Bound<'_, PyAny>,
377 ) -> PyResult<PyReturnOperand> {
378 Ok(PyReturnOperand::NodeMultipleAttributesWithoutIndex(
379 ob.extract::<PyNodeMultipleAttributesWithoutIndexOperand>()
380 .expect("Extraction must succeed"),
381 ))
382 }
383
384 fn convert_py_edge_multiple_attributes_with_index_operand(
385 ob: &Bound<'_, PyAny>,
386 ) -> PyResult<PyReturnOperand> {
387 Ok(PyReturnOperand::EdgeMultipleAttributesWithIndex(
388 ob.extract::<PyEdgeMultipleAttributesWithIndexOperand>()
389 .expect("Extraction must succeed"),
390 ))
391 }
392
393 fn convert_py_edge_multiple_attributes_with_index_group_operand(
394 ob: &Bound<'_, PyAny>,
395 ) -> PyResult<PyReturnOperand> {
396 Ok(PyReturnOperand::EdgeMultipleAttributesWithIndexGroup(
397 ob.extract::<PyEdgeMultipleAttributesWithIndexGroupOperand>()
398 .expect("Extraction must succeed"),
399 ))
400 }
401
402 fn convert_py_edge_multiple_attributes_without_index_operand(
403 ob: &Bound<'_, PyAny>,
404 ) -> PyResult<PyReturnOperand> {
405 Ok(PyReturnOperand::EdgeMultipleAttributesWithoutIndex(
406 ob.extract::<PyEdgeMultipleAttributesWithoutIndexOperand>()
407 .expect("Extraction must succeed"),
408 ))
409 }
410
411 fn convert_py_node_single_attribute_with_index_operand(
412 ob: &Bound<'_, PyAny>,
413 ) -> PyResult<PyReturnOperand> {
414 Ok(PyReturnOperand::NodeSingleAttributeWithIndex(
415 ob.extract::<PyNodeSingleAttributeWithIndexOperand>()
416 .expect("Extraction must succeed"),
417 ))
418 }
419
420 fn convert_py_node_single_attribute_with_index_group_operand(
421 ob: &Bound<'_, PyAny>,
422 ) -> PyResult<PyReturnOperand> {
423 Ok(PyReturnOperand::NodeSingleAttributeWithIndexGroup(
424 ob.extract::<PyNodeSingleAttributeWithIndexGroupOperand>()
425 .expect("Extraction must succeed"),
426 ))
427 }
428
429 fn convert_py_node_single_attribute_without_index_operand(
430 ob: &Bound<'_, PyAny>,
431 ) -> PyResult<PyReturnOperand> {
432 Ok(PyReturnOperand::NodeSingleAttributeWithoutIndex(
433 ob.extract::<PyNodeSingleAttributeWithoutIndexOperand>()
434 .expect("Extraction must succeed"),
435 ))
436 }
437
438 fn convert_py_node_single_attribute_without_index_group_operand(
439 ob: &Bound<'_, PyAny>,
440 ) -> PyResult<PyReturnOperand> {
441 Ok(PyReturnOperand::NodeSingleAttributeWithoutIndexGroup(
442 ob.extract::<PyNodeSingleAttributeWithoutIndexGroupOperand>()
443 .expect("Extraction must succeed"),
444 ))
445 }
446
447 fn convert_py_edge_single_attribute_with_index_operand(
448 ob: &Bound<'_, PyAny>,
449 ) -> PyResult<PyReturnOperand> {
450 Ok(PyReturnOperand::EdgeSingleAttributeWithIndex(
451 ob.extract::<PyEdgeSingleAttributeWithIndexOperand>()
452 .expect("Extraction must succeed"),
453 ))
454 }
455
456 fn convert_py_edge_single_attribute_with_index_group_operand(
457 ob: &Bound<'_, PyAny>,
458 ) -> PyResult<PyReturnOperand> {
459 Ok(PyReturnOperand::EdgeSingleAttributeWithIndexGroup(
460 ob.extract::<PyEdgeSingleAttributeWithIndexGroupOperand>()
461 .expect("Extraction must succeed"),
462 ))
463 }
464
465 fn convert_py_edge_single_attribute_without_index_operand(
466 ob: &Bound<'_, PyAny>,
467 ) -> PyResult<PyReturnOperand> {
468 Ok(PyReturnOperand::EdgeSingleAttributeWithoutIndex(
469 ob.extract::<PyEdgeSingleAttributeWithoutIndexOperand>()
470 .expect("Extraction must succeed"),
471 ))
472 }
473
474 fn convert_py_edge_single_attribute_without_index_group_operand(
475 ob: &Bound<'_, PyAny>,
476 ) -> PyResult<PyReturnOperand> {
477 Ok(PyReturnOperand::EdgeSingleAttributeWithoutIndexGroup(
478 ob.extract::<PyEdgeSingleAttributeWithoutIndexGroupOperand>()
479 .expect("Extraction must succeed"),
480 ))
481 }
482
483 fn convert_py_edge_indices_operand(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
484 Ok(PyReturnOperand::EdgeIndices(
485 ob.extract::<PyEdgeIndicesOperand>()
486 .expect("Extraction must succeed"),
487 ))
488 }
489
490 fn convert_py_edge_indices_group_operand(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
491 Ok(PyReturnOperand::EdgeIndicesGroup(
492 ob.extract::<PyEdgeIndicesGroupOperand>()
493 .expect("Extraction must succeed"),
494 ))
495 }
496
497 fn convert_py_edge_index_operand(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
498 Ok(PyReturnOperand::EdgeIndex(
499 ob.extract::<PyEdgeIndexOperand>()
500 .expect("Extraction must succeed"),
501 ))
502 }
503
504 fn convert_py_edge_index_group_operand(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
505 Ok(PyReturnOperand::EdgeIndexGroup(
506 ob.extract::<PyEdgeIndexGroupOperand>()
507 .expect("Extraction must succeed"),
508 ))
509 }
510
511 fn convert_py_node_indices_operand(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
512 Ok(PyReturnOperand::NodeIndices(
513 ob.extract::<PyNodeIndicesOperand>()
514 .expect("Extraction must succeed"),
515 ))
516 }
517
518 fn convert_py_node_indices_group_operand(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
519 Ok(PyReturnOperand::NodeIndicesGroup(
520 ob.extract::<PyNodeIndicesGroupOperand>()
521 .expect("Extraction must succeed"),
522 ))
523 }
524
525 fn convert_py_node_index_operand(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
526 Ok(PyReturnOperand::NodeIndex(
527 ob.extract::<PyNodeIndexOperand>()
528 .expect("Extraction must succeed"),
529 ))
530 }
531
532 fn convert_py_node_index_group_operand(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
533 Ok(PyReturnOperand::NodeIndexGroup(
534 ob.extract::<PyNodeIndexGroupOperand>()
535 .expect("Extraction must succeed"),
536 ))
537 }
538
539 fn convert_py_node_multiple_values_with_index_operand(
540 ob: &Bound<'_, PyAny>,
541 ) -> PyResult<PyReturnOperand> {
542 Ok(PyReturnOperand::NodeMultipleValuesWithIndex(
543 ob.extract::<PyNodeMultipleValuesWithIndexOperand>()
544 .expect("Extraction must succeed"),
545 ))
546 }
547
548 fn convert_py_node_multiple_values_with_index_group_operand(
549 ob: &Bound<'_, PyAny>,
550 ) -> PyResult<PyReturnOperand> {
551 Ok(PyReturnOperand::NodeMultipleValuesWithIndexGroup(
552 ob.extract::<PyNodeMultipleValuesWithIndexGroupOperand>()
553 .expect("Extraction must succeed"),
554 ))
555 }
556
557 fn convert_py_node_multiple_values_without_index_operand(
558 ob: &Bound<'_, PyAny>,
559 ) -> PyResult<PyReturnOperand> {
560 Ok(PyReturnOperand::NodeMultipleValuesWithoutIndex(
561 ob.extract::<PyNodeMultipleValuesWithoutIndexOperand>()
562 .expect("Extraction must succeed"),
563 ))
564 }
565
566 fn convert_py_edge_multiple_values_with_index_operand(
567 ob: &Bound<'_, PyAny>,
568 ) -> PyResult<PyReturnOperand> {
569 Ok(PyReturnOperand::EdgeMultipleValuesWithIndex(
570 ob.extract::<PyEdgeMultipleValuesWithIndexOperand>()
571 .expect("Extraction must succeed"),
572 ))
573 }
574
575 fn convert_py_edge_multiple_values_with_index_group_operand(
576 ob: &Bound<'_, PyAny>,
577 ) -> PyResult<PyReturnOperand> {
578 Ok(PyReturnOperand::EdgeMultipleValuesWithIndexGroup(
579 ob.extract::<PyEdgeMultipleValuesWithIndexGroupOperand>()
580 .expect("Extraction must succeed"),
581 ))
582 }
583
584 fn convert_py_edge_multiple_values_without_index_operand(
585 ob: &Bound<'_, PyAny>,
586 ) -> PyResult<PyReturnOperand> {
587 Ok(PyReturnOperand::EdgeMultipleValuesWithoutIndex(
588 ob.extract::<PyEdgeMultipleValuesWithoutIndexOperand>()
589 .expect("Extraction must succeed"),
590 ))
591 }
592
593 fn convert_py_node_single_value_with_index_operand(
594 ob: &Bound<'_, PyAny>,
595 ) -> PyResult<PyReturnOperand> {
596 Ok(PyReturnOperand::NodeSingleValueWithIndex(
597 ob.extract::<PyNodeSingleValueWithIndexOperand>()
598 .expect("Extraction must succeed"),
599 ))
600 }
601
602 fn convert_py_node_single_value_with_index_group_operand(
603 ob: &Bound<'_, PyAny>,
604 ) -> PyResult<PyReturnOperand> {
605 Ok(PyReturnOperand::NodeSingleValueWithIndexGroup(
606 ob.extract::<PyNodeSingleValueWithIndexGroupOperand>()
607 .expect("Extraction must succeed"),
608 ))
609 }
610
611 fn convert_py_node_single_value_without_index_operand(
612 ob: &Bound<'_, PyAny>,
613 ) -> PyResult<PyReturnOperand> {
614 Ok(PyReturnOperand::NodeSingleValueWithoutIndex(
615 ob.extract::<PyNodeSingleValueWithoutIndexOperand>()
616 .expect("Extraction must succeed"),
617 ))
618 }
619
620 fn convert_py_node_single_value_without_index_group_operand(
621 ob: &Bound<'_, PyAny>,
622 ) -> PyResult<PyReturnOperand> {
623 Ok(PyReturnOperand::NodeSingleValueWithoutIndexGroup(
624 ob.extract::<PyNodeSingleValueWithoutIndexGroupOperand>()
625 .expect("Extraction must succeed"),
626 ))
627 }
628
629 fn convert_py_edge_single_value_with_index_operand(
630 ob: &Bound<'_, PyAny>,
631 ) -> PyResult<PyReturnOperand> {
632 Ok(PyReturnOperand::EdgeSingleValueWithIndex(
633 ob.extract::<PyEdgeSingleValueWithIndexOperand>()
634 .expect("Extraction must succeed"),
635 ))
636 }
637
638 fn convert_py_edge_single_value_with_index_group_operand(
639 ob: &Bound<'_, PyAny>,
640 ) -> PyResult<PyReturnOperand> {
641 Ok(PyReturnOperand::EdgeSingleValueWithIndexGroup(
642 ob.extract::<PyEdgeSingleValueWithIndexGroupOperand>()
643 .expect("Extraction must succeed"),
644 ))
645 }
646
647 fn convert_py_edge_single_value_without_index_operand(
648 ob: &Bound<'_, PyAny>,
649 ) -> PyResult<PyReturnOperand> {
650 Ok(PyReturnOperand::EdgeSingleValueWithoutIndex(
651 ob.extract::<PyEdgeSingleValueWithoutIndexOperand>()
652 .expect("Extraction must succeed"),
653 ))
654 }
655
656 fn convert_py_edge_single_value_without_index_group_operand(
657 ob: &Bound<'_, PyAny>,
658 ) -> PyResult<PyReturnOperand> {
659 Ok(PyReturnOperand::EdgeSingleValueWithoutIndexGroup(
660 ob.extract::<PyEdgeSingleValueWithoutIndexGroupOperand>()
661 .expect("Extraction must succeed"),
662 ))
663 }
664
665 fn convert_py_list(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
666 Ok(PyReturnOperand::Vector(
667 ob.extract::<Vec<PyReturnOperand>>()?,
668 ))
669 }
670
671 fn throw_error(ob: &Bound<'_, PyAny>) -> PyResult<PyReturnOperand> {
672 Err(
673 PyGraphRecordError::from(GraphRecordError::ConversionError(format!(
674 "Failed to convert {ob} into query ReturnOperand",
675 )))
676 .into(),
677 )
678 }
679
680 let type_pointer = ob.get_type_ptr() as usize;
681
682 let conversion_function = RETURNOPERAND_CONVERSION_LUT.get_or_insert(type_pointer, || {
683 if ob.is_instance_of::<PyNodeAttributesTreeOperand>() {
684 convert_py_node_attributes_tree_operand
685 } else if ob.is_instance_of::<PyNodeAttributesTreeGroupOperand>() {
686 convert_py_node_attributes_tree_group_operand
687 } else if ob.is_instance_of::<PyEdgeAttributesTreeOperand>() {
688 convert_py_edge_attributes_tree_operand
689 } else if ob.is_instance_of::<PyEdgeAttributesTreeGroupOperand>() {
690 convert_py_edge_attributes_tree_group_operand
691 } else if ob.is_instance_of::<PyNodeMultipleAttributesWithIndexOperand>() {
692 convert_py_node_multiple_attributes_with_index_operand
693 } else if ob.is_instance_of::<PyNodeMultipleAttributesWithIndexGroupOperand>() {
694 convert_py_node_multiple_attributes_with_index_group_operand
695 } else if ob.is_instance_of::<PyNodeMultipleAttributesWithoutIndexOperand>() {
696 convert_py_node_multiple_attributes_without_index_operand
697 } else if ob.is_instance_of::<PyEdgeMultipleAttributesWithIndexOperand>() {
698 convert_py_edge_multiple_attributes_with_index_operand
699 } else if ob.is_instance_of::<PyEdgeMultipleAttributesWithIndexGroupOperand>() {
700 convert_py_edge_multiple_attributes_with_index_group_operand
701 } else if ob.is_instance_of::<PyEdgeMultipleAttributesWithoutIndexOperand>() {
702 convert_py_edge_multiple_attributes_without_index_operand
703 } else if ob.is_instance_of::<PyNodeSingleAttributeWithIndexOperand>() {
704 convert_py_node_single_attribute_with_index_operand
705 } else if ob.is_instance_of::<PyNodeSingleAttributeWithIndexGroupOperand>() {
706 convert_py_node_single_attribute_with_index_group_operand
707 } else if ob.is_instance_of::<PyNodeSingleAttributeWithoutIndexOperand>() {
708 convert_py_node_single_attribute_without_index_operand
709 } else if ob.is_instance_of::<PyNodeSingleAttributeWithoutIndexGroupOperand>() {
710 convert_py_node_single_attribute_without_index_group_operand
711 } else if ob.is_instance_of::<PyEdgeSingleAttributeWithIndexOperand>() {
712 convert_py_edge_single_attribute_with_index_operand
713 } else if ob.is_instance_of::<PyEdgeSingleAttributeWithIndexGroupOperand>() {
714 convert_py_edge_single_attribute_with_index_group_operand
715 } else if ob.is_instance_of::<PyEdgeSingleAttributeWithoutIndexOperand>() {
716 convert_py_edge_single_attribute_without_index_operand
717 } else if ob.is_instance_of::<PyEdgeSingleAttributeWithoutIndexGroupOperand>() {
718 convert_py_edge_single_attribute_without_index_group_operand
719 } else if ob.is_instance_of::<PyEdgeIndicesOperand>() {
720 convert_py_edge_indices_operand
721 } else if ob.is_instance_of::<PyEdgeIndicesGroupOperand>() {
722 convert_py_edge_indices_group_operand
723 } else if ob.is_instance_of::<PyEdgeIndexOperand>() {
724 convert_py_edge_index_operand
725 } else if ob.is_instance_of::<PyEdgeIndexGroupOperand>() {
726 convert_py_edge_index_group_operand
727 } else if ob.is_instance_of::<PyNodeIndicesOperand>() {
728 convert_py_node_indices_operand
729 } else if ob.is_instance_of::<PyNodeIndicesGroupOperand>() {
730 convert_py_node_indices_group_operand
731 } else if ob.is_instance_of::<PyNodeIndexOperand>() {
732 convert_py_node_index_operand
733 } else if ob.is_instance_of::<PyNodeIndexGroupOperand>() {
734 convert_py_node_index_group_operand
735 } else if ob.is_instance_of::<PyNodeMultipleValuesWithIndexOperand>() {
736 convert_py_node_multiple_values_with_index_operand
737 } else if ob.is_instance_of::<PyNodeMultipleValuesWithIndexGroupOperand>() {
738 convert_py_node_multiple_values_with_index_group_operand
739 } else if ob.is_instance_of::<PyNodeMultipleValuesWithoutIndexOperand>() {
740 convert_py_node_multiple_values_without_index_operand
741 } else if ob.is_instance_of::<PyEdgeMultipleValuesWithIndexOperand>() {
742 convert_py_edge_multiple_values_with_index_operand
743 } else if ob.is_instance_of::<PyEdgeMultipleValuesWithIndexGroupOperand>() {
744 convert_py_edge_multiple_values_with_index_group_operand
745 } else if ob.is_instance_of::<PyEdgeMultipleValuesWithoutIndexOperand>() {
746 convert_py_edge_multiple_values_without_index_operand
747 } else if ob.is_instance_of::<PyNodeSingleValueWithIndexOperand>() {
748 convert_py_node_single_value_with_index_operand
749 } else if ob.is_instance_of::<PyNodeSingleValueWithIndexGroupOperand>() {
750 convert_py_node_single_value_with_index_group_operand
751 } else if ob.is_instance_of::<PyNodeSingleValueWithoutIndexOperand>() {
752 convert_py_node_single_value_without_index_operand
753 } else if ob.is_instance_of::<PyNodeSingleValueWithoutIndexGroupOperand>() {
754 convert_py_node_single_value_without_index_group_operand
755 } else if ob.is_instance_of::<PyEdgeSingleValueWithIndexOperand>() {
756 convert_py_edge_single_value_with_index_operand
757 } else if ob.is_instance_of::<PyEdgeSingleValueWithIndexGroupOperand>() {
758 convert_py_edge_single_value_with_index_group_operand
759 } else if ob.is_instance_of::<PyEdgeSingleValueWithoutIndexOperand>() {
760 convert_py_edge_single_value_without_index_operand
761 } else if ob.is_instance_of::<PyEdgeSingleValueWithoutIndexGroupOperand>() {
762 convert_py_edge_single_value_without_index_group_operand
763 } else if ob.is_instance_of::<PyList>() {
764 convert_py_list
765 } else {
766 throw_error
767 }
768 });
769
770 conversion_function(ob)
771}
772
773impl FromPyObject<'_, '_> for PyReturnOperand {
774 type Error = PyErr;
775
776 fn extract(ob: Borrowed<'_, '_, PyAny>) -> PyResult<Self> {
777 convert_pyobject_to_pyreturnoperand(&ob)
778 }
779}
780
781pub enum PyReturnValue<'a> {
782 NodeAttributesTree(<Wrapper<NodeAttributesTreeOperand> as ReturnOperand<'a>>::ReturnValue),
783 NodeAttributesTreeGroup(<Wrapper<GroupOperand<NodeAttributesTreeOperand>> as ReturnOperand<'a>>::ReturnValue),
784 EdgeAttributesTree(<Wrapper<EdgeAttributesTreeOperand> as ReturnOperand<'a>>::ReturnValue),
785 EdgeAttributesTreeGroup(<Wrapper<GroupOperand<EdgeAttributesTreeOperand>> as ReturnOperand<'a>>::ReturnValue),
786 NodeMultipleAttributesWithIndex(
787 <Wrapper<NodeMultipleAttributesWithIndexOperand> as ReturnOperand<'a>>::ReturnValue,
788 ),
789 NodeMultipleAttributesWithIndexGroup(
790 <Wrapper<GroupOperand<NodeMultipleAttributesWithIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
791 ),
792 NodeMultipleAttributesWithoutIndex(
793 <Wrapper<NodeMultipleAttributesWithoutIndexOperand> as ReturnOperand<'a>>::ReturnValue,
794 ),
795 EdgeMultipleAttributesWithIndex(
796 <Wrapper<EdgeMultipleAttributesWithIndexOperand> as ReturnOperand<'a>>::ReturnValue,
797 ),
798 EdgeMultipleAttributesWithIndexGroup(
799 <Wrapper<GroupOperand<EdgeMultipleAttributesWithIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
800 ),
801 EdgeMultipleAttributesWithoutIndex(
802 <Wrapper<EdgeMultipleAttributesWithoutIndexOperand> as ReturnOperand<'a>>::ReturnValue,
803 ),
804 NodeSingleAttributeWithIndex(
805 <Wrapper<NodeSingleAttributeWithIndexOperand> as ReturnOperand<'a>>::ReturnValue,
806 ),
807 NodeSingleAttributeWithIndexGroup(
808 <Wrapper<GroupOperand<NodeSingleAttributeWithIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
809 ),
810 NodeSingleAttributeWithoutIndex(
811 <Wrapper<NodeSingleAttributeWithoutIndexOperand> as ReturnOperand<'a>>::ReturnValue,
812 ),
813 NodeSingleAttributeWithoutIndexGroup(
814 <Wrapper<GroupOperand<NodeSingleAttributeWithoutIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
815 ),
816 EdgeSingleAttributeWithIndex(
817 <Wrapper<EdgeSingleAttributeWithIndexOperand> as ReturnOperand<'a>>::ReturnValue,
818 ),
819 EdgeSingleAttributeWithIndexGroup(
820 <Wrapper<GroupOperand<EdgeSingleAttributeWithIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
821 ),
822 EdgeSingleAttributeWithoutIndex(
823 <Wrapper<EdgeSingleAttributeWithoutIndexOperand> as ReturnOperand<'a>>::ReturnValue,
824 ),
825 EdgeSingleAttributeWithoutIndexGroup(
826 <Wrapper<GroupOperand<EdgeSingleAttributeWithoutIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
827 ),
828 EdgeIndices(<Wrapper<EdgeIndicesOperand> as ReturnOperand<'a>>::ReturnValue),
829 EdgeIndicesGroup(<Wrapper<GroupOperand<EdgeIndicesOperand>> as ReturnOperand<'a>>::ReturnValue),
830 EdgeIndex(<Wrapper<EdgeIndexOperand> as ReturnOperand<'a>>::ReturnValue),
831 EdgeIndexGroup(<Wrapper<GroupOperand<EdgeIndexOperand>> as ReturnOperand<'a>>::ReturnValue),
832 NodeIndices(<Wrapper<NodeIndicesOperand> as ReturnOperand<'a>>::ReturnValue),
833 NodeIndicesGroup(<Wrapper<GroupOperand<NodeIndicesOperand>> as ReturnOperand<'a>>::ReturnValue),
834 NodeIndex(<Wrapper<NodeIndexOperand> as ReturnOperand<'a>>::ReturnValue),
835 NodeIndexGroup(<Wrapper<GroupOperand<NodeIndexOperand>> as ReturnOperand<'a>>::ReturnValue),
836 NodeMultipleValuesWithIndex(
837 <Wrapper<NodeMultipleValuesWithIndexOperand> as ReturnOperand<'a>>::ReturnValue,
838 ),
839 NodeMultipleValuesWithIndexGroup(
840 <Wrapper<GroupOperand<NodeMultipleValuesWithIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
841 ),
842 NodeMultipleValuesWithoutIndex(
843 <Wrapper<NodeMultipleValuesWithoutIndexOperand> as ReturnOperand<'a>>::ReturnValue,
844 ),
845 EdgeMultipleValuesWithIndex(
846 <Wrapper<EdgeMultipleValuesWithIndexOperand> as ReturnOperand<'a>>::ReturnValue,
847 ),
848 EdgeMultipleValuesWithIndexGroup(
849 <Wrapper<GroupOperand<EdgeMultipleValuesWithIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
850 ),
851 EdgeMultipleValuesWithoutIndex(
852 <Wrapper<EdgeMultipleValuesWithoutIndexOperand> as ReturnOperand<'a>>::ReturnValue,
853 ),
854 NodeSingleValueWithIndex(
855 <Wrapper<NodeSingleValueWithIndexOperand> as ReturnOperand<'a>>::ReturnValue,
856 ),
857 NodeSingleValueWithIndexGroup(
858 <Wrapper<GroupOperand<NodeSingleValueWithIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
859 ),
860 NodeSingleValueWithoutIndex(
861 <Wrapper<NodeSingleValueWithoutIndexOperand> as ReturnOperand<'a>>::ReturnValue,
862 ),
863 NodeSingleValueWithoutIndexGroup(
864 <Wrapper<GroupOperand<NodeSingleValueWithoutIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
865 ),
866 EdgeSingleValueWithIndex(
867 <Wrapper<EdgeSingleValueWithIndexOperand> as ReturnOperand<'a>>::ReturnValue,
868 ),
869 EdgeSingleValueWithIndexGroup(
870 <Wrapper<GroupOperand<EdgeSingleValueWithIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
871 ),
872 EdgeSingleValueWithoutIndex(
873 <Wrapper<EdgeSingleValueWithoutIndexOperand> as ReturnOperand<'a>>::ReturnValue,
874 ),
875 EdgeSingleValueWithoutIndexGroup(
876 <Wrapper<GroupOperand<EdgeSingleValueWithoutIndexOperand>> as ReturnOperand<'a>>::ReturnValue,
877 ),
878 Vector(Vec<Self>),
879}
880
881impl<'py> IntoPyObject<'py> for PyReturnValue<'_> {
882 type Target = PyAny;
883 type Output = Bound<'py, Self::Target>;
884 type Error = PyErr;
885
886 #[allow(clippy::too_many_lines)]
887 fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
888 match self {
889 PyReturnValue::NodeAttributesTree(iterator) => iterator
890 .map(|item| {
891 (
892 PyNodeIndex::from(item.0.clone()),
893 Vec::<PyGraphRecordAttribute>::deep_from(item.1),
894 )
895 })
896 .collect::<HashMap<_, _>>()
897 .into_bound_py_any(py),
898 PyReturnValue::NodeAttributesTreeGroup(iterator) => iterator
899 .map(|(key, items)| {
900 (
901 PyGroupKey::from(key),
902 items
903 .map(|item| {
904 (
905 PyNodeIndex::from(item.0.clone()),
906 Vec::<PyGraphRecordAttribute>::deep_from(item.1),
907 )
908 })
909 .collect::<HashMap<_, _>>(),
910 )
911 })
912 .collect::<Vec<_>>()
913 .into_bound_py_any(py),
914 PyReturnValue::EdgeAttributesTree(iterator) => iterator
915 .map(|item| (item.0, Vec::<PyGraphRecordAttribute>::deep_from(item.1)))
916 .collect::<HashMap<_, _>>()
917 .into_bound_py_any(py),
918 PyReturnValue::EdgeAttributesTreeGroup(iterator) => iterator
919 .map(|(key, items)| {
920 (
921 PyGroupKey::from(key),
922 items
923 .map(|item| (item.0, Vec::<PyGraphRecordAttribute>::deep_from(item.1)))
924 .collect::<HashMap<_, _>>(),
925 )
926 })
927 .collect::<Vec<_>>()
928 .into_bound_py_any(py),
929 PyReturnValue::NodeMultipleAttributesWithIndex(iterator) => iterator
930 .map(|item| {
931 (
932 PyNodeIndex::from(item.0.clone()),
933 PyGraphRecordAttribute::from(item.1),
934 )
935 })
936 .collect::<HashMap<_, _>>()
937 .into_bound_py_any(py),
938 PyReturnValue::NodeMultipleAttributesWithIndexGroup(iterator) => iterator
939 .map(|(key, items)| {
940 (
941 PyGroupKey::from(key),
942 items
943 .map(|item| {
944 (
945 PyNodeIndex::from(item.0.clone()),
946 PyGraphRecordAttribute::from(item.1),
947 )
948 })
949 .collect::<HashMap<_, _>>(),
950 )
951 })
952 .collect::<Vec<_>>()
953 .into_bound_py_any(py),
954 PyReturnValue::NodeMultipleAttributesWithoutIndex(iterator)
955 | PyReturnValue::EdgeMultipleAttributesWithoutIndex(iterator)
956 | PyReturnValue::NodeIndices(iterator) => iterator
957 .map(PyGraphRecordAttribute::from)
958 .collect::<Vec<_>>()
959 .into_bound_py_any(py),
960 PyReturnValue::EdgeMultipleAttributesWithIndex(iterator) => iterator
961 .map(|item| (item.0, PyGraphRecordAttribute::from(item.1)))
962 .collect::<HashMap<_, _>>()
963 .into_bound_py_any(py),
964 PyReturnValue::EdgeMultipleAttributesWithIndexGroup(iterator) => iterator
965 .map(|(key, items)| {
966 (
967 PyGroupKey::from(key),
968 items
969 .map(|item| (item.0, PyGraphRecordAttribute::from(item.1)))
970 .collect::<HashMap<_, _>>(),
971 )
972 })
973 .collect::<Vec<_>>()
974 .into_bound_py_any(py),
975 PyReturnValue::NodeSingleAttributeWithIndex(attribute) => attribute
976 .map(|item| {
977 (
978 PyGraphRecordAttribute::from(item.0.clone()),
979 PyGraphRecordAttribute::from(item.1),
980 )
981 })
982 .into_bound_py_any(py),
983 PyReturnValue::NodeSingleAttributeWithIndexGroup(attribute) => attribute
984 .map(|(key, items)| {
985 (
986 PyGroupKey::from(key),
987 items.map(|item| {
988 (
989 PyGraphRecordAttribute::from(item.0.clone()),
990 PyGraphRecordAttribute::from(item.1),
991 )
992 }),
993 )
994 })
995 .collect::<Vec<_>>()
996 .into_bound_py_any(py),
997 PyReturnValue::NodeSingleAttributeWithoutIndex(attribute)
998 | PyReturnValue::EdgeSingleAttributeWithoutIndex(attribute) => attribute
999 .map(PyGraphRecordAttribute::from)
1000 .into_bound_py_any(py),
1001 PyReturnValue::NodeSingleAttributeWithoutIndexGroup(attribute) => attribute
1002 .map(|(key, item)| {
1003 (
1004 PyGroupKey::from(key),
1005 item.map(PyGraphRecordAttribute::from),
1006 )
1007 })
1008 .collect::<Vec<_>>()
1009 .into_bound_py_any(py),
1010 PyReturnValue::EdgeSingleAttributeWithIndex(attribute) => attribute
1011 .map(|item| (item.0, PyGraphRecordAttribute::from(item.1)))
1012 .into_bound_py_any(py),
1013 PyReturnValue::EdgeSingleAttributeWithIndexGroup(attribute) => attribute
1014 .map(|(key, items)| {
1015 (
1016 PyGroupKey::from(key),
1017 items.map(|item| (item.0, PyGraphRecordAttribute::from(item.1))),
1018 )
1019 })
1020 .collect::<Vec<_>>()
1021 .into_bound_py_any(py),
1022 PyReturnValue::EdgeSingleAttributeWithoutIndexGroup(attribute) => attribute
1023 .map(|(key, item)| {
1024 (
1025 PyGroupKey::from(key),
1026 item.map(PyGraphRecordAttribute::from),
1027 )
1028 })
1029 .collect::<Vec<_>>()
1030 .into_bound_py_any(py),
1031 PyReturnValue::EdgeIndices(iterator) => {
1032 iterator.collect::<Vec<_>>().into_bound_py_any(py)
1033 }
1034 PyReturnValue::EdgeIndicesGroup(iterator) => iterator
1035 .map(|(key, iterator)| (PyGroupKey::from(key), iterator.collect::<Vec<_>>()))
1036 .collect::<Vec<_>>()
1037 .into_bound_py_any(py),
1038 PyReturnValue::EdgeIndex(index) => index.into_bound_py_any(py),
1039 PyReturnValue::EdgeIndexGroup(index) => index
1040 .map(|(key, index)| (PyGroupKey::from(key), index))
1041 .collect::<Vec<_>>()
1042 .into_bound_py_any(py),
1043 PyReturnValue::NodeIndicesGroup(iterator) => iterator
1044 .map(|(key, iterator)| {
1045 (
1046 PyGroupKey::from(key),
1047 iterator
1048 .map(PyGraphRecordAttribute::from)
1049 .collect::<Vec<_>>(),
1050 )
1051 })
1052 .collect::<Vec<_>>()
1053 .into_bound_py_any(py),
1054 PyReturnValue::NodeIndex(index) => {
1055 Option::<PyNodeIndex>::deep_from(index).into_bound_py_any(py)
1056 }
1057 PyReturnValue::NodeIndexGroup(index) => index
1058 .map(|(key, index)| {
1059 (
1060 PyGroupKey::from(key),
1061 Option::<PyNodeIndex>::deep_from(index),
1062 )
1063 })
1064 .collect::<Vec<_>>()
1065 .into_bound_py_any(py),
1066 PyReturnValue::NodeMultipleValuesWithIndex(iterator) => iterator
1067 .map(|item| {
1068 (
1069 PyNodeIndex::from(item.0.clone()),
1070 PyGraphRecordValue::from(item.1),
1071 )
1072 })
1073 .collect::<HashMap<_, _>>()
1074 .into_bound_py_any(py),
1075 PyReturnValue::NodeMultipleValuesWithIndexGroup(iterator) => iterator
1076 .map(|(key, items)| {
1077 (
1078 PyGroupKey::from(key),
1079 items
1080 .map(|item| {
1081 (
1082 PyNodeIndex::from(item.0.clone()),
1083 PyGraphRecordValue::from(item.1),
1084 )
1085 })
1086 .collect::<HashMap<_, _>>(),
1087 )
1088 })
1089 .collect::<Vec<_>>()
1090 .into_bound_py_any(py),
1091 PyReturnValue::NodeMultipleValuesWithoutIndex(iterator)
1092 | PyReturnValue::EdgeMultipleValuesWithoutIndex(iterator) => iterator
1093 .map(PyGraphRecordValue::from)
1094 .collect::<Vec<_>>()
1095 .into_bound_py_any(py),
1096 PyReturnValue::EdgeMultipleValuesWithIndex(iterator) => iterator
1097 .map(|item| (item.0, PyGraphRecordValue::from(item.1)))
1098 .collect::<HashMap<_, _>>()
1099 .into_bound_py_any(py),
1100 PyReturnValue::EdgeMultipleValuesWithIndexGroup(iterator) => iterator
1101 .map(|(key, items)| {
1102 (
1103 PyGroupKey::from(key),
1104 items
1105 .map(|item| (item.0, PyGraphRecordValue::from(item.1)))
1106 .collect::<HashMap<_, _>>(),
1107 )
1108 })
1109 .collect::<Vec<_>>()
1110 .into_bound_py_any(py),
1111 PyReturnValue::NodeSingleValueWithIndex(value) => value
1112 .map(|item| {
1113 (
1114 PyGraphRecordAttribute::from(item.0.clone()),
1115 PyGraphRecordValue::from(item.1),
1116 )
1117 })
1118 .into_bound_py_any(py),
1119 PyReturnValue::NodeSingleValueWithIndexGroup(value) => value
1120 .map(|(key, items)| {
1121 (
1122 PyGroupKey::from(key),
1123 items.map(|item| {
1124 (
1125 PyGraphRecordAttribute::from(item.0.clone()),
1126 PyGraphRecordValue::from(item.1),
1127 )
1128 }),
1129 )
1130 })
1131 .collect::<Vec<_>>()
1132 .into_bound_py_any(py),
1133 PyReturnValue::NodeSingleValueWithoutIndex(value)
1134 | PyReturnValue::EdgeSingleValueWithoutIndex(value) => {
1135 value.map(PyGraphRecordValue::from).into_bound_py_any(py)
1136 }
1137 PyReturnValue::NodeSingleValueWithoutIndexGroup(value) => value
1138 .map(|(key, item)| (PyGroupKey::from(key), item.map(PyGraphRecordValue::from)))
1139 .collect::<Vec<_>>()
1140 .into_bound_py_any(py),
1141 PyReturnValue::EdgeSingleValueWithIndex(value) => value
1142 .map(|item| (item.0, PyGraphRecordValue::from(item.1)))
1143 .into_bound_py_any(py),
1144 PyReturnValue::EdgeSingleValueWithIndexGroup(value) => value
1145 .map(|(key, items)| {
1146 (
1147 PyGroupKey::from(key),
1148 items.map(|item| (item.0, PyGraphRecordValue::from(item.1))),
1149 )
1150 })
1151 .collect::<Vec<_>>()
1152 .into_bound_py_any(py),
1153 PyReturnValue::EdgeSingleValueWithoutIndexGroup(value) => value
1154 .map(|(key, item)| (PyGroupKey::from(key), item.map(PyGraphRecordValue::from)))
1155 .collect::<Vec<_>>()
1156 .into_bound_py_any(py),
1157 PyReturnValue::Vector(vector) => vector.into_bound_py_any(py),
1158 }
1159 }
1160}
1161
1162#[repr(transparent)]
1163pub struct PyGraphRecordAttributeCardinalityWrapper(CardinalityWrapper<GraphRecordAttribute>);
1164
1165impl From<CardinalityWrapper<GraphRecordAttribute>> for PyGraphRecordAttributeCardinalityWrapper {
1166 fn from(attribute: CardinalityWrapper<GraphRecordAttribute>) -> Self {
1167 Self(attribute)
1168 }
1169}
1170
1171impl From<PyGraphRecordAttributeCardinalityWrapper> for CardinalityWrapper<GraphRecordAttribute> {
1172 fn from(attribute: PyGraphRecordAttributeCardinalityWrapper) -> Self {
1173 attribute.0
1174 }
1175}
1176
1177impl FromPyObject<'_, '_> for PyGraphRecordAttributeCardinalityWrapper {
1178 type Error = PyErr;
1179
1180 fn extract(ob: Borrowed<'_, '_, PyAny>) -> PyResult<Self> {
1181 match ob.extract::<PyGraphRecordAttribute>() { Ok(attribute) => {
1182 Ok(CardinalityWrapper::Single(GraphRecordAttribute::from(attribute)).into())
1183 } _ => { match ob.extract::<Vec<PyGraphRecordAttribute>>() { Ok(attributes) => {
1184 Ok(CardinalityWrapper::from(
1185 attributes
1186 .into_iter()
1187 .map(GraphRecordAttribute::from)
1188 .collect::<Vec<_>>(),
1189 )
1190 .into())
1191 } _ => { match ob.extract::<(Vec<PyGraphRecordAttribute>, PyMatchMode)>() { Ok(attributes) => {
1192 Ok(CardinalityWrapper::from((
1193 attributes
1194 .0
1195 .into_iter()
1196 .map(GraphRecordAttribute::from)
1197 .collect::<Vec<_>>(),
1198 attributes.1.into(),
1199 ))
1200 .into())
1201 } _ => {
1202 Err(
1203 PyGraphRecordError::from(GraphRecordError::ConversionError(format!(
1204 "Failed to convert {} into GraphRecordAttribute, List[GraphRecordAttribute] or (List[GraphRecordAttribute], MatchMode)",
1205 ob.to_owned()
1206 )))
1207 .into(),
1208 )
1209 }}}}}}
1210 }
1211}
1212
1213type PyGroupCardinalityWrapper = PyGraphRecordAttributeCardinalityWrapper;