1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
use crate::types::repr::Repr;
use crate::wrappers::prop::{PropHistories, PropHistory, PropValue, Props};
use num::cast::AsPrimitive;
use pyo3::prelude::*;
use raphtory::core as db_c;
use raphtory::db::view_api::BoxedIter;
use std::collections::HashMap;
use std::i64;
use std::iter::Sum;
use std::ops::Deref;

pub(crate) trait MeanExt<V>: Iterator<Item = V>
where
    V: AsPrimitive<f64> + Sum<V>,
{
    fn mean(self) -> f64
    where
        Self: Sized,
    {
        let mut count: usize = 0;
        let sum: V = self.inspect(|_| count += 1).sum();

        if count > 0 {
            sum.as_() / (count as f64)
        } else {
            0.0
        }
    }
}

impl<I: ?Sized + Iterator<Item = V>, V: AsPrimitive<f64> + Sum<V>> MeanExt<V> for I {}

py_iterator!(Float64Iter, f64);
py_float_iterable!(Float64Iterable, f64, Float64Iter);

py_iterator!(U64Iter, u64);
py_numeric_iterable!(U64Iterable, u64, U64Iter);
py_iterator!(NestedU64Iter, BoxedIter<u64>, U64Iter);
py_nested_numeric_iterable!(
    NestedU64Iterable,
    u64,
    NestedU64Iter,
    U64Iterable,
    OptionU64Iterable
);

py_iterator!(OptionU64Iter, Option<u64>);
py_iterable!(OptionU64Iterable, Option<u64>, Option<u64>, OptionU64Iter);
_py_ord_max_min_methods!(OptionU64Iterable, Option<u64>);

py_iterator!(I64Iter, i64);
py_numeric_iterable!(I64Iterable, i64, I64Iter);
py_iterator!(NestedI64Iter, BoxedIter<i64>, I64Iter);
py_nested_numeric_iterable!(
    NestedI64Iterable,
    i64,
    NestedI64Iter,
    I64Iterable,
    OptionI64Iterable
);

py_iterator!(OptionI64Iter, Option<i64>);
py_iterable!(OptionI64Iterable, Option<i64>, OptionI64Iter);
_py_ord_max_min_methods!(OptionI64Iterable, Option<i64>);
py_iterator!(OptionOptionI64Iter, Option<Option<i64>>);
py_iterable!(
    OptionOptionI64Iterable,
    Option<Option<i64>>,
    OptionOptionI64Iter
);
_py_ord_max_min_methods!(OptionOptionI64Iterable, Option<Option<i64>>);

py_iterator!(NestedOptionI64Iter, BoxedIter<Option<i64>>, OptionI64Iter);
py_nested_ordered_iterable!(
    NestedOptionI64Iterable,
    Option<i64>,
    NestedOptionI64Iter,
    OptionOptionI64Iterable
);

py_iterator!(UsizeIter, usize);
py_numeric_iterable!(UsizeIterable, usize, UsizeIter);
py_iterator!(OptionUsizeIter, Option<usize>);
py_ordered_iterable!(OptionUsizeIterable, Option<usize>, OptionUsizeIter);
py_iterator!(NestedUsizeIter, BoxedIter<usize>, UsizeIter);
py_nested_numeric_iterable!(
    NestedUsizeIterable,
    usize,
    NestedUsizeIter,
    UsizeIterable,
    OptionUsizeIterable
);

py_iterator!(BoolIter, bool);
py_iterable!(BoolIterable, bool, BoolIter);
py_iterator!(NestedBoolIter, BoxedIter<bool>, BoolIter);
py_nested_iterable!(NestedBoolIterable, bool, NestedBoolIter);

py_iterator!(StringIter, String);
py_iterable!(StringIterable, String, StringIter);
py_iterator!(NestedStringIter, BoxedIter<String>, StringIter);
py_nested_iterable!(NestedStringIterable, String, NestedStringIter);

py_iterator!(StringVecIter, Vec<String>);
py_iterable!(StringVecIterable, Vec<String>, StringVecIter);
py_iterator!(NestedStringVecIter, BoxedIter<Vec<String>>, StringVecIter);
py_nested_iterable!(NestedStringVecIterable, Vec<String>, NestedStringVecIter);

py_iterator!(OptionPropIter, Option<db_c::Prop>, PropValue);
py_iterable!(
    OptionPropIterable,
    Option<db_c::Prop>,
    PropValue,
    OptionPropIter
);
py_iterator!(
    NestedOptionPropIter,
    BoxedIter<Option<db_c::Prop>>,
    OptionPropIter
);
py_nested_iterable!(
    NestedOptionPropIterable,
    Option<db_c::Prop>,
    PropValue,
    NestedOptionPropIter
);

py_iterator!(PropHistoryIter, Vec<(i64, db_c::Prop)>, PropHistory);
py_iterable!(
    PropHistoryIterable,
    Vec<(i64, db_c::Prop)>,
    PropHistory,
    PropHistoryIter
);
py_iterator!(
    NestedPropHistoryIter,
    BoxedIter<Vec<(i64, db_c::Prop)>>,
    PropHistoryIter
);
py_nested_iterable!(
    NestedPropHistoryIterable,
    Vec<(i64, db_c::Prop)>,
    PropHistory,
    NestedPropHistoryIter
);

py_iterator!(PropsIter, HashMap<String, db_c::Prop>, Props);
py_iterable!(PropsIterable, HashMap<String, db_c::Prop>, Props, PropsIter);
py_iterator!(
    NestedPropsIter,
    BoxedIter<HashMap<String, db_c::Prop>>,
    PropsIter
);
py_nested_iterable!(NestedPropsIterable, HashMap<String, db_c::Prop>, Props, NestedPropsIter);

py_iterator!(PropHistoriesIter, HashMap<String, Vec<(i64, db_c::Prop)>>, PropHistories);
py_iterable!(PropHistoriesIterable, HashMap<String, Vec<(i64, db_c::Prop)>>, PropHistories, PropHistoriesIter);
py_iterator!(
    NestedPropHistoriesIter,
    BoxedIter<HashMap<String, Vec<(i64, db_c::Prop)>>>,
    PropHistoriesIter
);
py_nested_iterable!(NestedPropHistoriesIterable, HashMap<String, Vec<(i64, db_c::Prop)>>, PropHistories, NestedPropHistoriesIter);