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
use std::str::FromStr; use std::cmp::PartialOrd; use std::fmt::{Display, Debug}; use super::Aggregate; use crate::{Headers, Row, error}; #[derive(Debug)] pub struct Max<T> { source: String, current: T, colname: String, default: T, } impl<T: Copy> Max<T> { pub fn new(colname: String, source: String, init: T) -> Max<T> { Max { source, colname, current: init, default: init, } } } impl<T> Aggregate for Max<T> where T: FromStr + PartialOrd + Display + Copy, { fn update(&mut self, headers: &Headers, row: &Row) -> error::Result<()> { match headers.get_field(row, &self.source) { Some(data) => { let val: T = data.parse().unwrap_or(self.default); if val > self.current { self.current = val; } Ok(()) }, None => Err(error::Error::ColumnNotFound(self.source.to_string())), } } fn value(&self) -> String { self.current.to_string() } fn colname(&self) -> &str { &self.colname } } #[cfg(test)] mod tests { use std::f64; use super::{Aggregate, Max}; use crate::{Row, error}; #[test] fn test_max() { let mut max = Max::new("new".into(), "a".into(), f64::NEG_INFINITY); let h = Row::from(vec!["a"]).into(); let r = Row::from(vec!["3.0"]); max.update(&h, &r).unwrap(); let r = Row::from(vec!["2"]); max.update(&h, &r).unwrap(); let r = Row::from(vec![".5"]); max.update(&h, &r).unwrap(); assert_eq!(max.value(), "3"); } #[test] fn test_missing_column() { let mut max = Max::new("new".into(), "a".into(), f64::NEG_INFINITY); let h = Row::from(vec!["b"]).into(); let r = Row::from(vec!["3.0"]); match max.update(&h, &r) { Err(error::Error::ColumnNotFound(val)) => assert_eq!(val, "a"), _ => panic!("Test failed"), } } #[test] fn test_value_error() { let mut max = Max::new("new".into(), "a".into(), f64::NEG_INFINITY); let h = Row::from(vec!["a"]).into(); let r = Row::from(vec!["chicken"]); max.update(&h, &r).unwrap(); assert_eq!(max.value(), "-inf"); } #[test] fn test_default() { let mut max = Max::new("new".into(), "a".into(), 1.0); let h = Row::from(vec!["a"]).into(); let r = Row::from(vec!["-1.0"]); max.update(&h, &r).unwrap(); let r = Row::from(vec!["0.0"]); max.update(&h, &r).unwrap(); let r = Row::from(vec!["pollo"]); max.update(&h, &r).unwrap(); assert_eq!(max.value(), "1"); } }