1extern crate num_traits;
2
3use std::cmp::Ordering;
4use std::hash;
5use num_traits::ToPrimitive;
6
7pub use frequency::Frequencies;
8pub use minmax::MinMax;
9pub use online::{OnlineStats, stddev, variance, mean};
10pub use unsorted::{Unsorted, median, mode, modes};
11
12#[derive(Clone, PartialEq, PartialOrd)]
17struct Partial<T>(pub T);
18
19impl<T: PartialEq> Eq for Partial<T> {}
20
21impl<T: PartialOrd> Ord for Partial<T> {
22 fn cmp(&self, other: &Partial<T>) -> Ordering {
23 self.partial_cmp(other).unwrap_or(Ordering::Less)
24 }
25}
26
27impl<T: ToPrimitive> ToPrimitive for Partial<T> {
28 fn to_isize(&self) -> Option<isize> { self.0.to_isize() }
29 fn to_i8(&self) -> Option<i8> { self.0.to_i8() }
30 fn to_i16(&self) -> Option<i16> { self.0.to_i16() }
31 fn to_i32(&self) -> Option<i32> { self.0.to_i32() }
32 fn to_i64(&self) -> Option<i64> { self.0.to_i64() }
33
34 fn to_usize(&self) -> Option<usize> { self.0.to_usize() }
35 fn to_u8(&self) -> Option<u8> { self.0.to_u8() }
36 fn to_u16(&self) -> Option<u16> { self.0.to_u16() }
37 fn to_u32(&self) -> Option<u32> { self.0.to_u32() }
38 fn to_u64(&self) -> Option<u64> { self.0.to_u64() }
39
40 fn to_f32(&self) -> Option<f32> { self.0.to_f32() }
41 fn to_f64(&self) -> Option<f64> { self.0.to_f64() }
42}
43
44impl<T: hash::Hash> hash::Hash for Partial<T> {
45 fn hash<H: hash::Hasher>(&self, state: &mut H) { self.0.hash(state); }
46}
47
48pub trait Commute : Sized {
53 fn merge(&mut self, other: Self);
55
56 fn consume<I: Iterator<Item=Self>>(&mut self, other: I) {
58 for v in other {
59 self.merge(v);
60 }
61 }
62}
63
64pub fn merge_all<T: Commute, I: Iterator<Item=T>>(mut it: I) -> Option<T> {
68 match it.next() {
69 None => None,
70 Some(mut init) => { init.consume(it); Some(init) }
71 }
72}
73
74impl<T: Commute> Commute for Option<T> {
75 fn merge(&mut self, other: Option<T>) {
76 match *self {
77 None => { *self = other; }
78 Some(ref mut v1) => { other.map(|v2| v1.merge(v2)); }
79 }
80 }
81}
82
83impl<T: Commute, E> Commute for Result<T, E> {
84 fn merge(&mut self, other: Result<T, E>) {
85 if !self.is_err() && other.is_err() {
88 *self = other;
89 return;
90 }
91 match *self {
92 Err(_) => {},
93 Ok(ref mut v1) => {
94 match other {
95 Ok(v2) => { v1.merge(v2); }
96 Err(_) => { unreachable!(); }
100 }
101 }
102 }
103 }
104}
105
106impl<T: Commute> Commute for Vec<T> {
107 fn merge(&mut self, other: Vec<T>) {
108 assert_eq!(self.len(), other.len());
109 for (v1, v2) in self.iter_mut().zip(other.into_iter()) {
110 v1.merge(v2);
111 }
112 }
113}
114
115mod frequency;
116mod minmax;
117mod online;
118mod unsorted;
119
120#[cfg(test)]
121mod test {
122 use Commute;
123 use unsorted::Unsorted;
124
125 #[test]
126 fn options() {
127 let v1: Unsorted<usize> = vec![2, 1, 3, 2].into_iter().collect();
128 let v2: Unsorted<usize> = vec![5, 6, 5, 5].into_iter().collect();
129 let mut merged = Some(v1);
130 merged.merge(Some(v2));
131 assert_eq!(merged.unwrap().mode(), Some(5));
132 }
133}