1use crate::graphrecord::{errors::PyGraphRecordError, value::PyGraphRecordValue};
2use graphrecords_core::{
3 errors::GraphRecordError,
4 graphrecord::{
5 GraphRecordValue,
6 querying::{
7 DeepClone,
8 edges::EdgeOperand,
9 group_by::GroupOperand,
10 nodes::NodeOperand,
11 values::{
12 MultipleValuesComparisonOperand, MultipleValuesWithIndexOperand,
13 MultipleValuesWithoutIndexOperand, SingleValueComparisonOperand,
14 SingleValueWithIndexOperand, SingleValueWithoutIndexOperand,
15 },
16 wrapper::Wrapper,
17 },
18 },
19};
20use pyo3::{
21 Borrowed, Bound, FromPyObject, PyAny, PyErr, PyResult, pyclass, pymethods,
22 types::{PyAnyMethods, PyFunction},
23};
24use std::ops::Deref;
25
26#[repr(transparent)]
27pub struct PySingleValueComparisonOperand(SingleValueComparisonOperand);
28
29impl From<SingleValueComparisonOperand> for PySingleValueComparisonOperand {
30 fn from(operand: SingleValueComparisonOperand) -> Self {
31 Self(operand)
32 }
33}
34
35impl From<PySingleValueComparisonOperand> for SingleValueComparisonOperand {
36 fn from(operand: PySingleValueComparisonOperand) -> Self {
37 operand.0
38 }
39}
40
41impl FromPyObject<'_, '_> for PySingleValueComparisonOperand {
42 type Error = PyErr;
43
44 fn extract(ob: Borrowed<'_, '_, PyAny>) -> PyResult<Self> {
45 match ob.extract::<PyGraphRecordValue>() {
46 Ok(value) => Ok(SingleValueComparisonOperand::Value(value.into()).into()),
47 _ => match ob.extract::<PyNodeSingleValueWithIndexOperand>() {
48 Ok(operand) => Ok(Self(operand.0.into())),
49 _ => match ob.extract::<PyNodeSingleValueWithoutIndexOperand>() {
50 Ok(operand) => Ok(Self(operand.0.into())),
51 _ => match ob.extract::<PyEdgeSingleValueWithIndexOperand>() {
52 Ok(operand) => Ok(Self(operand.0.into())),
53 _ => match ob.extract::<PyEdgeSingleValueWithoutIndexOperand>() {
54 Ok(operand) => Ok(Self(operand.0.into())),
55 _ => Err(PyGraphRecordError::from(GraphRecordError::ConversionError(
56 format!(
57 "Failed to convert {} into GraphRecordValue or SingleValueOperand",
58 ob.to_owned()
59 ),
60 ))
61 .into()),
62 },
63 },
64 },
65 },
66 }
67 }
68}
69
70#[repr(transparent)]
71pub struct PyMultipleValuesComparisonOperand(MultipleValuesComparisonOperand);
72
73impl From<MultipleValuesComparisonOperand> for PyMultipleValuesComparisonOperand {
74 fn from(operand: MultipleValuesComparisonOperand) -> Self {
75 Self(operand)
76 }
77}
78
79impl From<PyMultipleValuesComparisonOperand> for MultipleValuesComparisonOperand {
80 fn from(operand: PyMultipleValuesComparisonOperand) -> Self {
81 operand.0
82 }
83}
84
85impl FromPyObject<'_, '_> for PyMultipleValuesComparisonOperand {
86 type Error = PyErr;
87
88 fn extract(ob: Borrowed<'_, '_, PyAny>) -> PyResult<Self> {
89 match ob.extract::<Vec<PyGraphRecordValue>>() {
90 Ok(values) => Ok(MultipleValuesComparisonOperand::Values(
91 values.into_iter().map(GraphRecordValue::from).collect(),
92 )
93 .into()),
94 _ => match ob.extract::<PyNodeMultipleValuesWithIndexOperand>() {
95 Ok(operand) => Ok(Self(operand.0.into())),
96 _ => match ob.extract::<PyNodeMultipleValuesWithoutIndexOperand>() {
97 Ok(operand) => Ok(Self(operand.0.into())),
98 _ => match ob.extract::<PyEdgeMultipleValuesWithIndexOperand>() {
99 Ok(operand) => Ok(Self(operand.0.into())),
100 _ => match ob.extract::<PyEdgeMultipleValuesWithoutIndexOperand>() {
101 Ok(operand) => Ok(Self(operand.0.into())),
102 _ => Err(PyGraphRecordError::from(GraphRecordError::ConversionError(
103 format!(
104 "Failed to convert {} into List[GraphRecordValue] or MultipleValuesOperand",
105 ob.to_owned()
106 ),
107 ))
108 .into()),
109 },
110 },
111 },
112 },
113 }
114 }
115}
116
117macro_rules! implement_multiple_values_operand {
118 ($name:ident, $kind:ident, $generic:ty, $py_single_value_with_index_operand:ty, $py_single_value_without_index_operand:ty) => {
119 #[pyclass(frozen)]
120 #[repr(transparent)]
121 #[derive(Clone)]
122 pub struct $name(Wrapper<$kind<$generic>>);
123
124 impl From<Wrapper<$kind<$generic>>> for $name {
125 fn from(operand: Wrapper<$kind<$generic>>) -> Self {
126 Self(operand)
127 }
128 }
129
130 impl From<$name> for Wrapper<$kind<$generic>> {
131 fn from(operand: $name) -> Self {
132 operand.0
133 }
134 }
135
136 impl Deref for $name {
137 type Target = Wrapper<$kind<$generic>>;
138
139 fn deref(&self) -> &Self::Target {
140 &self.0
141 }
142 }
143
144 #[pymethods]
145 impl $name {
146 pub fn max(&self) -> $py_single_value_with_index_operand {
147 self.0.max().into()
148 }
149
150 pub fn min(&self) -> $py_single_value_with_index_operand {
151 self.0.min().into()
152 }
153
154 pub fn mean(&self) -> $py_single_value_without_index_operand {
155 self.0.mean().into()
156 }
157
158 pub fn median(&self) -> $py_single_value_without_index_operand {
159 self.0.median().into()
160 }
161
162 pub fn mode(&self) -> $py_single_value_without_index_operand {
163 self.0.mode().into()
164 }
165
166 pub fn std(&self) -> $py_single_value_without_index_operand {
167 self.0.std().into()
168 }
169
170 pub fn var(&self) -> $py_single_value_without_index_operand {
171 self.0.var().into()
172 }
173
174 pub fn count(&self) -> $py_single_value_without_index_operand {
175 self.0.count().into()
176 }
177
178 pub fn sum(&self) -> $py_single_value_without_index_operand {
179 self.0.sum().into()
180 }
181
182 pub fn random(&self) -> $py_single_value_with_index_operand {
183 self.0.random().into()
184 }
185
186 pub fn greater_than(&self, value: PySingleValueComparisonOperand) {
187 self.0.greater_than(value);
188 }
189
190 pub fn greater_than_or_equal_to(&self, value: PySingleValueComparisonOperand) {
191 self.0.greater_than_or_equal_to(value);
192 }
193
194 pub fn less_than(&self, value: PySingleValueComparisonOperand) {
195 self.0.less_than(value);
196 }
197
198 pub fn less_than_or_equal_to(&self, value: PySingleValueComparisonOperand) {
199 self.0.less_than_or_equal_to(value);
200 }
201
202 pub fn equal_to(&self, value: PySingleValueComparisonOperand) {
203 self.0.equal_to(value);
204 }
205
206 pub fn not_equal_to(&self, value: PySingleValueComparisonOperand) {
207 self.0.not_equal_to(value);
208 }
209
210 pub fn starts_with(&self, value: PySingleValueComparisonOperand) {
211 self.0.starts_with(value);
212 }
213
214 pub fn ends_with(&self, value: PySingleValueComparisonOperand) {
215 self.0.ends_with(value);
216 }
217
218 pub fn contains(&self, value: PySingleValueComparisonOperand) {
219 self.0.contains(value);
220 }
221
222 pub fn is_in(&self, values: PyMultipleValuesComparisonOperand) {
223 self.0.is_in(values);
224 }
225
226 pub fn is_not_in(&self, values: PyMultipleValuesComparisonOperand) {
227 self.0.is_not_in(values);
228 }
229
230 pub fn add(&self, value: PySingleValueComparisonOperand) {
231 self.0.add(value);
232 }
233
234 pub fn sub(&self, value: PySingleValueComparisonOperand) {
235 self.0.sub(value);
236 }
237
238 pub fn mul(&self, value: PySingleValueComparisonOperand) {
239 self.0.mul(value);
240 }
241
242 pub fn div(&self, value: PySingleValueComparisonOperand) {
243 self.0.div(value);
244 }
245
246 pub fn pow(&self, value: PySingleValueComparisonOperand) {
247 self.0.pow(value);
248 }
249
250 pub fn r#mod(&self, value: PySingleValueComparisonOperand) {
251 self.0.r#mod(value);
252 }
253
254 pub fn round(&self) {
255 self.0.round();
256 }
257
258 pub fn ceil(&self) {
259 self.0.ceil();
260 }
261
262 pub fn floor(&self) {
263 self.0.floor();
264 }
265
266 pub fn abs(&self) {
267 self.0.abs();
268 }
269
270 pub fn sqrt(&self) {
271 self.0.sqrt();
272 }
273
274 pub fn trim(&self) {
275 self.0.trim();
276 }
277
278 pub fn trim_start(&self) {
279 self.0.trim_start();
280 }
281
282 pub fn trim_end(&self) {
283 self.0.trim_end();
284 }
285
286 pub fn lowercase(&self) {
287 self.0.lowercase();
288 }
289
290 pub fn uppercase(&self) {
291 self.0.uppercase();
292 }
293
294 pub fn slice(&self, start: usize, end: usize) {
295 self.0.slice(start, end);
296 }
297
298 pub fn is_string(&self) {
299 self.0.is_string();
300 }
301
302 pub fn is_int(&self) {
303 self.0.is_int();
304 }
305
306 pub fn is_float(&self) {
307 self.0.is_float();
308 }
309
310 pub fn is_bool(&self) {
311 self.0.is_bool();
312 }
313
314 pub fn is_datetime(&self) {
315 self.0.is_datetime();
316 }
317
318 pub fn is_duration(&self) {
319 self.0.is_duration();
320 }
321
322 pub fn is_null(&self) {
323 self.0.is_null();
324 }
325
326 pub fn is_max(&self) {
327 self.0.is_max();
328 }
329
330 pub fn is_min(&self) {
331 self.0.is_min();
332 }
333
334 pub fn either_or(&self, either: &Bound<'_, PyFunction>, or: &Bound<'_, PyFunction>) {
335 self.0.either_or(
336 |operand| {
337 either
338 .call1(($name::from(operand.clone()),))
339 .expect("Call must succeed");
340 },
341 |operand| {
342 or.call1(($name::from(operand.clone()),))
343 .expect("Call must succeed");
344 },
345 );
346 }
347
348 pub fn exclude(&self, query: &Bound<'_, PyFunction>) {
349 self.0.exclude(|operand| {
350 query
351 .call1(($name::from(operand.clone()),))
352 .expect("Call must succeed");
353 });
354 }
355
356 pub fn deep_clone(&self) -> $name {
357 self.0.deep_clone().into()
358 }
359 }
360 };
361}
362
363implement_multiple_values_operand!(
364 PyNodeMultipleValuesWithIndexOperand,
365 MultipleValuesWithIndexOperand,
366 NodeOperand,
367 PyNodeSingleValueWithIndexOperand,
368 PyNodeSingleValueWithoutIndexOperand
369);
370implement_multiple_values_operand!(
371 PyNodeMultipleValuesWithoutIndexOperand,
372 MultipleValuesWithoutIndexOperand,
373 NodeOperand,
374 PyNodeSingleValueWithoutIndexOperand,
375 PyNodeSingleValueWithoutIndexOperand
376);
377implement_multiple_values_operand!(
378 PyEdgeMultipleValuesWithIndexOperand,
379 MultipleValuesWithIndexOperand,
380 EdgeOperand,
381 PyEdgeSingleValueWithIndexOperand,
382 PyEdgeSingleValueWithoutIndexOperand
383);
384implement_multiple_values_operand!(
385 PyEdgeMultipleValuesWithoutIndexOperand,
386 MultipleValuesWithoutIndexOperand,
387 EdgeOperand,
388 PyEdgeSingleValueWithoutIndexOperand,
389 PyEdgeSingleValueWithoutIndexOperand
390);
391
392macro_rules! implement_multiple_values_grouped_operand {
393 ($name:ident, $ungrouped_name:ident, $kind:ident, $generic:ty, $py_single_value_with_index_operand:ty, $py_single_value_without_index_operand:ty) => {
394 #[pyclass(frozen)]
395 #[repr(transparent)]
396 #[derive(Clone)]
397 pub struct $name(Wrapper<GroupOperand<$kind<$generic>>>);
398
399 impl From<Wrapper<GroupOperand<$kind<$generic>>>> for $name {
400 fn from(operand: Wrapper<GroupOperand<$kind<$generic>>>) -> Self {
401 Self(operand)
402 }
403 }
404
405 impl From<$name> for Wrapper<GroupOperand<$kind<$generic>>> {
406 fn from(operand: $name) -> Self {
407 operand.0
408 }
409 }
410
411 impl Deref for $name {
412 type Target = Wrapper<GroupOperand<$kind<$generic>>>;
413
414 fn deref(&self) -> &Self::Target {
415 &self.0
416 }
417 }
418
419 #[pymethods]
420 impl $name {
421 pub fn max(&self) -> $py_single_value_with_index_operand {
422 self.0.max().into()
423 }
424
425 pub fn min(&self) -> $py_single_value_with_index_operand {
426 self.0.min().into()
427 }
428
429 pub fn mean(&self) -> $py_single_value_without_index_operand {
430 self.0.mean().into()
431 }
432
433 pub fn median(&self) -> $py_single_value_without_index_operand {
434 self.0.median().into()
435 }
436
437 pub fn mode(&self) -> $py_single_value_without_index_operand {
438 self.0.mode().into()
439 }
440
441 pub fn std(&self) -> $py_single_value_without_index_operand {
442 self.0.std().into()
443 }
444
445 pub fn var(&self) -> $py_single_value_without_index_operand {
446 self.0.var().into()
447 }
448
449 pub fn count(&self) -> $py_single_value_without_index_operand {
450 self.0.count().into()
451 }
452
453 pub fn sum(&self) -> $py_single_value_without_index_operand {
454 self.0.sum().into()
455 }
456
457 pub fn random(&self) -> $py_single_value_with_index_operand {
458 self.0.random().into()
459 }
460
461 pub fn greater_than(&self, value: PySingleValueComparisonOperand) {
462 self.0.greater_than(value);
463 }
464
465 pub fn greater_than_or_equal_to(&self, value: PySingleValueComparisonOperand) {
466 self.0.greater_than_or_equal_to(value);
467 }
468
469 pub fn less_than(&self, value: PySingleValueComparisonOperand) {
470 self.0.less_than(value);
471 }
472
473 pub fn less_than_or_equal_to(&self, value: PySingleValueComparisonOperand) {
474 self.0.less_than_or_equal_to(value);
475 }
476
477 pub fn equal_to(&self, value: PySingleValueComparisonOperand) {
478 self.0.equal_to(value);
479 }
480
481 pub fn not_equal_to(&self, value: PySingleValueComparisonOperand) {
482 self.0.not_equal_to(value);
483 }
484
485 pub fn starts_with(&self, value: PySingleValueComparisonOperand) {
486 self.0.starts_with(value);
487 }
488
489 pub fn ends_with(&self, value: PySingleValueComparisonOperand) {
490 self.0.ends_with(value);
491 }
492
493 pub fn contains(&self, value: PySingleValueComparisonOperand) {
494 self.0.contains(value);
495 }
496
497 pub fn is_in(&self, values: PyMultipleValuesComparisonOperand) {
498 self.0.is_in(values);
499 }
500
501 pub fn is_not_in(&self, values: PyMultipleValuesComparisonOperand) {
502 self.0.is_not_in(values);
503 }
504
505 pub fn add(&self, value: PySingleValueComparisonOperand) {
506 self.0.add(value);
507 }
508
509 pub fn sub(&self, value: PySingleValueComparisonOperand) {
510 self.0.sub(value);
511 }
512
513 pub fn mul(&self, value: PySingleValueComparisonOperand) {
514 self.0.mul(value);
515 }
516
517 pub fn div(&self, value: PySingleValueComparisonOperand) {
518 self.0.div(value);
519 }
520
521 pub fn pow(&self, value: PySingleValueComparisonOperand) {
522 self.0.pow(value);
523 }
524
525 pub fn r#mod(&self, value: PySingleValueComparisonOperand) {
526 self.0.r#mod(value);
527 }
528
529 pub fn round(&self) {
530 self.0.round();
531 }
532
533 pub fn ceil(&self) {
534 self.0.ceil();
535 }
536
537 pub fn floor(&self) {
538 self.0.floor();
539 }
540
541 pub fn abs(&self) {
542 self.0.abs();
543 }
544
545 pub fn sqrt(&self) {
546 self.0.sqrt();
547 }
548
549 pub fn trim(&self) {
550 self.0.trim();
551 }
552
553 pub fn trim_start(&self) {
554 self.0.trim_start();
555 }
556
557 pub fn trim_end(&self) {
558 self.0.trim_end();
559 }
560
561 pub fn lowercase(&self) {
562 self.0.lowercase();
563 }
564
565 pub fn uppercase(&self) {
566 self.0.uppercase();
567 }
568
569 pub fn slice(&self, start: usize, end: usize) {
570 self.0.slice(start, end);
571 }
572
573 pub fn is_string(&self) {
574 self.0.is_string();
575 }
576
577 pub fn is_int(&self) {
578 self.0.is_int();
579 }
580
581 pub fn is_float(&self) {
582 self.0.is_float();
583 }
584
585 pub fn is_bool(&self) {
586 self.0.is_bool();
587 }
588
589 pub fn is_datetime(&self) {
590 self.0.is_datetime();
591 }
592
593 pub fn is_duration(&self) {
594 self.0.is_duration();
595 }
596
597 pub fn is_null(&self) {
598 self.0.is_null();
599 }
600
601 pub fn is_max(&self) {
602 self.0.is_max();
603 }
604
605 pub fn is_min(&self) {
606 self.0.is_min();
607 }
608
609 pub fn either_or(&self, either: &Bound<'_, PyFunction>, or: &Bound<'_, PyFunction>) {
610 self.0.either_or(
611 |operand| {
612 either
613 .call1(($ungrouped_name::from(operand.clone()),))
614 .expect("Call must succeed");
615 },
616 |operand| {
617 or.call1(($ungrouped_name::from(operand.clone()),))
618 .expect("Call must succeed");
619 },
620 );
621 }
622
623 pub fn exclude(&self, query: &Bound<'_, PyFunction>) {
624 self.0.exclude(|operand| {
625 query
626 .call1(($ungrouped_name::from(operand.clone()),))
627 .expect("Call must succeed");
628 });
629 }
630
631 pub fn ungroup(&self) -> $ungrouped_name {
632 self.0.ungroup().into()
633 }
634
635 pub fn deep_clone(&self) -> $name {
636 self.0.deep_clone().into()
637 }
638 }
639 };
640}
641
642implement_multiple_values_grouped_operand!(
643 PyNodeMultipleValuesWithIndexGroupOperand,
644 PyNodeMultipleValuesWithIndexOperand,
645 MultipleValuesWithIndexOperand,
646 NodeOperand,
647 PyNodeSingleValueWithIndexGroupOperand,
648 PyNodeSingleValueWithoutIndexGroupOperand
649);
650implement_multiple_values_grouped_operand!(
651 PyEdgeMultipleValuesWithIndexGroupOperand,
652 PyEdgeMultipleValuesWithIndexOperand,
653 MultipleValuesWithIndexOperand,
654 EdgeOperand,
655 PyEdgeSingleValueWithIndexGroupOperand,
656 PyEdgeSingleValueWithoutIndexGroupOperand
657);
658
659macro_rules! implement_single_value_operand {
660 ($name:ident, $kind:ident, $generic:ty) => {
661 #[pyclass(frozen)]
662 #[repr(transparent)]
663 #[derive(Clone)]
664 pub struct $name(Wrapper<$kind<$generic>>);
665
666 impl From<Wrapper<$kind<$generic>>> for $name {
667 fn from(operand: Wrapper<$kind<$generic>>) -> Self {
668 Self(operand)
669 }
670 }
671
672 impl From<$name> for Wrapper<$kind<$generic>> {
673 fn from(operand: $name) -> Self {
674 operand.0
675 }
676 }
677
678 impl Deref for $name {
679 type Target = Wrapper<$kind<$generic>>;
680
681 fn deref(&self) -> &Self::Target {
682 &self.0
683 }
684 }
685
686 #[pymethods]
687 impl $name {
688 pub fn greater_than(&self, value: PySingleValueComparisonOperand) {
689 self.0.greater_than(value);
690 }
691
692 pub fn greater_than_or_equal_to(&self, value: PySingleValueComparisonOperand) {
693 self.0.greater_than_or_equal_to(value);
694 }
695
696 pub fn less_than(&self, value: PySingleValueComparisonOperand) {
697 self.0.less_than(value);
698 }
699
700 pub fn less_than_or_equal_to(&self, value: PySingleValueComparisonOperand) {
701 self.0.less_than_or_equal_to(value);
702 }
703
704 pub fn equal_to(&self, value: PySingleValueComparisonOperand) {
705 self.0.equal_to(value);
706 }
707
708 pub fn not_equal_to(&self, value: PySingleValueComparisonOperand) {
709 self.0.not_equal_to(value);
710 }
711
712 pub fn starts_with(&self, value: PySingleValueComparisonOperand) {
713 self.0.starts_with(value);
714 }
715
716 pub fn ends_with(&self, value: PySingleValueComparisonOperand) {
717 self.0.ends_with(value);
718 }
719
720 pub fn contains(&self, value: PySingleValueComparisonOperand) {
721 self.0.contains(value);
722 }
723
724 pub fn is_in(&self, values: PyMultipleValuesComparisonOperand) {
725 self.0.is_in(values);
726 }
727
728 pub fn is_not_in(&self, values: PyMultipleValuesComparisonOperand) {
729 self.0.is_not_in(values);
730 }
731
732 pub fn add(&self, value: PySingleValueComparisonOperand) {
733 self.0.add(value);
734 }
735
736 pub fn sub(&self, value: PySingleValueComparisonOperand) {
737 self.0.sub(value);
738 }
739
740 pub fn mul(&self, value: PySingleValueComparisonOperand) {
741 self.0.mul(value);
742 }
743
744 pub fn div(&self, value: PySingleValueComparisonOperand) {
745 self.0.div(value);
746 }
747
748 pub fn pow(&self, value: PySingleValueComparisonOperand) {
749 self.0.pow(value);
750 }
751
752 pub fn r#mod(&self, value: PySingleValueComparisonOperand) {
753 self.0.r#mod(value);
754 }
755
756 pub fn round(&self) {
757 self.0.round();
758 }
759
760 pub fn ceil(&self) {
761 self.0.ceil();
762 }
763
764 pub fn floor(&self) {
765 self.0.floor();
766 }
767
768 pub fn abs(&self) {
769 self.0.abs();
770 }
771
772 pub fn sqrt(&self) {
773 self.0.sqrt();
774 }
775
776 pub fn trim(&self) {
777 self.0.trim();
778 }
779
780 pub fn trim_start(&self) {
781 self.0.trim_start();
782 }
783
784 pub fn trim_end(&self) {
785 self.0.trim_end();
786 }
787
788 pub fn lowercase(&self) {
789 self.0.lowercase();
790 }
791
792 pub fn uppercase(&self) {
793 self.0.uppercase();
794 }
795
796 pub fn slice(&self, start: usize, end: usize) {
797 self.0.slice(start, end);
798 }
799
800 pub fn is_string(&self) {
801 self.0.is_string();
802 }
803
804 pub fn is_int(&self) {
805 self.0.is_int();
806 }
807
808 pub fn is_float(&self) {
809 self.0.is_float();
810 }
811
812 pub fn is_bool(&self) {
813 self.0.is_bool();
814 }
815
816 pub fn is_datetime(&self) {
817 self.0.is_datetime();
818 }
819
820 pub fn is_duration(&self) {
821 self.0.is_duration();
822 }
823
824 pub fn is_null(&self) {
825 self.0.is_null();
826 }
827
828 pub fn either_or(&self, either: &Bound<'_, PyFunction>, or: &Bound<'_, PyFunction>) {
829 self.0.either_or(
830 |operand| {
831 either
832 .call1(($name::from(operand.clone()),))
833 .expect("Call must succeed");
834 },
835 |operand| {
836 or.call1(($name::from(operand.clone()),))
837 .expect("Call must succeed");
838 },
839 );
840 }
841
842 pub fn exclude(&self, query: &Bound<'_, PyFunction>) {
843 self.0.exclude(|operand| {
844 query
845 .call1(($name::from(operand.clone()),))
846 .expect("Call must succeed");
847 });
848 }
849
850 pub fn deep_clone(&self) -> $name {
851 self.0.deep_clone().into()
852 }
853 }
854 };
855}
856
857implement_single_value_operand!(
858 PyNodeSingleValueWithIndexOperand,
859 SingleValueWithIndexOperand,
860 NodeOperand
861);
862implement_single_value_operand!(
863 PyEdgeSingleValueWithIndexOperand,
864 SingleValueWithIndexOperand,
865 EdgeOperand
866);
867implement_single_value_operand!(
868 PyNodeSingleValueWithoutIndexOperand,
869 SingleValueWithoutIndexOperand,
870 NodeOperand
871);
872implement_single_value_operand!(
873 PyEdgeSingleValueWithoutIndexOperand,
874 SingleValueWithoutIndexOperand,
875 EdgeOperand
876);
877
878macro_rules! implement_single_value_group_operand {
879 ($name:ident, $ungrouped_name:ident, $ungrouped_operand_name:ident, $kind:ident, $generic:ty) => {
880 #[pyclass(frozen)]
881 #[repr(transparent)]
882 #[derive(Clone)]
883 pub struct $name(Wrapper<GroupOperand<$kind<$generic>>>);
884
885 impl From<Wrapper<GroupOperand<$kind<$generic>>>> for $name {
886 fn from(operand: Wrapper<GroupOperand<$kind<$generic>>>) -> Self {
887 Self(operand)
888 }
889 }
890
891 impl From<$name> for Wrapper<GroupOperand<$kind<$generic>>> {
892 fn from(operand: $name) -> Self {
893 operand.0
894 }
895 }
896
897 impl Deref for $name {
898 type Target = Wrapper<GroupOperand<$kind<$generic>>>;
899
900 fn deref(&self) -> &Self::Target {
901 &self.0
902 }
903 }
904
905 #[pymethods]
906 impl $name {
907 pub fn greater_than(&self, value: PySingleValueComparisonOperand) {
908 self.0.greater_than(value);
909 }
910
911 pub fn greater_than_or_equal_to(&self, value: PySingleValueComparisonOperand) {
912 self.0.greater_than_or_equal_to(value);
913 }
914
915 pub fn less_than(&self, value: PySingleValueComparisonOperand) {
916 self.0.less_than(value);
917 }
918
919 pub fn less_than_or_equal_to(&self, value: PySingleValueComparisonOperand) {
920 self.0.less_than_or_equal_to(value);
921 }
922
923 pub fn equal_to(&self, value: PySingleValueComparisonOperand) {
924 self.0.equal_to(value);
925 }
926
927 pub fn not_equal_to(&self, value: PySingleValueComparisonOperand) {
928 self.0.not_equal_to(value);
929 }
930
931 pub fn starts_with(&self, value: PySingleValueComparisonOperand) {
932 self.0.starts_with(value);
933 }
934
935 pub fn ends_with(&self, value: PySingleValueComparisonOperand) {
936 self.0.ends_with(value);
937 }
938
939 pub fn contains(&self, value: PySingleValueComparisonOperand) {
940 self.0.contains(value);
941 }
942
943 pub fn is_in(&self, values: PyMultipleValuesComparisonOperand) {
944 self.0.is_in(values);
945 }
946
947 pub fn is_not_in(&self, values: PyMultipleValuesComparisonOperand) {
948 self.0.is_not_in(values);
949 }
950
951 pub fn add(&self, value: PySingleValueComparisonOperand) {
952 self.0.add(value);
953 }
954
955 pub fn sub(&self, value: PySingleValueComparisonOperand) {
956 self.0.sub(value);
957 }
958
959 pub fn mul(&self, value: PySingleValueComparisonOperand) {
960 self.0.mul(value);
961 }
962
963 pub fn div(&self, value: PySingleValueComparisonOperand) {
964 self.0.div(value);
965 }
966
967 pub fn pow(&self, value: PySingleValueComparisonOperand) {
968 self.0.pow(value);
969 }
970
971 pub fn r#mod(&self, value: PySingleValueComparisonOperand) {
972 self.0.r#mod(value);
973 }
974
975 pub fn round(&self) {
976 self.0.round();
977 }
978
979 pub fn ceil(&self) {
980 self.0.ceil();
981 }
982
983 pub fn floor(&self) {
984 self.0.floor();
985 }
986
987 pub fn abs(&self) {
988 self.0.abs();
989 }
990
991 pub fn sqrt(&self) {
992 self.0.sqrt();
993 }
994
995 pub fn trim(&self) {
996 self.0.trim();
997 }
998
999 pub fn trim_start(&self) {
1000 self.0.trim_start();
1001 }
1002
1003 pub fn trim_end(&self) {
1004 self.0.trim_end();
1005 }
1006
1007 pub fn lowercase(&self) {
1008 self.0.lowercase();
1009 }
1010
1011 pub fn uppercase(&self) {
1012 self.0.uppercase();
1013 }
1014
1015 pub fn slice(&self, start: usize, end: usize) {
1016 self.0.slice(start, end);
1017 }
1018
1019 pub fn is_string(&self) {
1020 self.0.is_string();
1021 }
1022
1023 pub fn is_int(&self) {
1024 self.0.is_int();
1025 }
1026
1027 pub fn is_float(&self) {
1028 self.0.is_float();
1029 }
1030
1031 pub fn is_bool(&self) {
1032 self.0.is_bool();
1033 }
1034
1035 pub fn is_datetime(&self) {
1036 self.0.is_datetime();
1037 }
1038
1039 pub fn is_duration(&self) {
1040 self.0.is_duration();
1041 }
1042
1043 pub fn is_null(&self) {
1044 self.0.is_null();
1045 }
1046
1047 pub fn either_or(&self, either: &Bound<'_, PyFunction>, or: &Bound<'_, PyFunction>) {
1048 self.0.either_or(
1049 |operand| {
1050 either
1051 .call1(($ungrouped_name::from(operand.clone()),))
1052 .expect("Call must succeed");
1053 },
1054 |operand| {
1055 or.call1(($ungrouped_name::from(operand.clone()),))
1056 .expect("Call must succeed");
1057 },
1058 );
1059 }
1060
1061 pub fn exclude(&self, query: &Bound<'_, PyFunction>) {
1062 self.0.exclude(|operand| {
1063 query
1064 .call1(($ungrouped_name::from(operand.clone()),))
1065 .expect("Call must succeed");
1066 });
1067 }
1068
1069 pub fn ungroup(&self) -> $ungrouped_operand_name {
1070 self.0.ungroup().into()
1071 }
1072
1073 pub fn deep_clone(&self) -> $name {
1074 self.0.deep_clone().into()
1075 }
1076 }
1077 };
1078}
1079
1080implement_single_value_group_operand!(
1081 PyNodeSingleValueWithIndexGroupOperand,
1082 PyNodeSingleValueWithIndexOperand,
1083 PyNodeMultipleValuesWithIndexOperand,
1084 SingleValueWithIndexOperand,
1085 NodeOperand
1086);
1087implement_single_value_group_operand!(
1088 PyEdgeSingleValueWithIndexGroupOperand,
1089 PyEdgeSingleValueWithIndexOperand,
1090 PyEdgeMultipleValuesWithIndexOperand,
1091 SingleValueWithIndexOperand,
1092 EdgeOperand
1093);
1094implement_single_value_group_operand!(
1095 PyNodeSingleValueWithoutIndexGroupOperand,
1096 PyNodeSingleValueWithoutIndexOperand,
1097 PyNodeMultipleValuesWithoutIndexOperand,
1098 SingleValueWithoutIndexOperand,
1099 NodeOperand
1100);
1101implement_single_value_group_operand!(
1102 PyEdgeSingleValueWithoutIndexGroupOperand,
1103 PyEdgeSingleValueWithoutIndexOperand,
1104 PyEdgeMultipleValuesWithoutIndexOperand,
1105 SingleValueWithoutIndexOperand,
1106 EdgeOperand
1107);