arthas 0.3.0

Arthas is an in-memory structure database.
Documentation

use std::cmp::Ordering;
use serde_json::Value;
use query::Order;


pub trait Math {
    fn eq(&self, &Value) -> bool;
    fn ne(&self, &Value) -> bool;
    fn gt(&self, &Value) -> bool;
    fn lt(&self, &Value) -> bool;
    fn ge(&self, &Value) -> bool;
    fn le(&self, &Value) -> bool;
    fn cmp(&self, &Value, order: &Order) -> Ordering;
    fn get_rate(&self, &Value) -> f64;
}

impl Math for Value {
    fn eq(&self, value: &Value) -> bool {
        thread_trace!("math eq, current: {:?}, find: {:?}", self, value);

        if self.is_number() && value.is_number() {
            self.get_f64() == value.get_f64()
        } else {
            self == value
        }
    }

    fn ne(&self, value: &Value) -> bool {
        thread_trace!("math ne, current: {:?}, find: {:?}", self, value);

        if self.is_number() && value.is_number() {
            self.get_f64() != value.get_f64()
        } else {
            self != value
        }
    }

    fn gt(&self, value: &Value) -> bool {
        thread_trace!("math gt, current: {:?}, find: {:?}", self, value);

        if self.is_number() && value.is_number() {
            self.get_f64() > value.get_f64()
        } else if self.is_string() && value.is_string() {
            self.get_str() > value.get_str()
        } else {
            panic!("Unsupported math type");
        }
    }

    fn lt(&self, value: &Value) -> bool {
        thread_trace!("math lt, current: {:?}, find: {:?}", self, value);

        if self.is_number() && value.is_number() {
            self.get_f64() < value.get_f64()
        } else if self.is_string() && value.is_string() {
            self.get_str() < value.get_str()
        } else {
            panic!("Unsupported math type");
        }
    }

    fn ge(&self, value: &Value) -> bool {
        thread_trace!("math ge, current: {:?}, find: {:?}", self, value);

        if self.is_number() && value.is_number() {
            self.get_f64() >= value.get_f64()
        } else if self.is_string() && value.is_string() {
            self.get_str() >= value.get_str()
        } else {
            panic!("Unsupported math type");
        }
    }

    fn le(&self, value: &Value) -> bool {
        thread_trace!("math le, current: {:?}, find: {:?}", self, value);

        if self.is_number() && value.is_number() {
            self.get_f64() <= value.get_f64()
        } else if self.is_string() && value.is_string() {
            self.get_str() <= value.get_str()
        } else {
            panic!("Unsupported math type");
        }
    }

    fn cmp(&self, value: &Value, order: &Order) -> Ordering {
        thread_trace!("math cmp, current: {:?}, find: {:?}", self, value);

        if let Order::Desc = *order {
            if Math::eq(self, value) {
                Ordering::Equal
            } else if Math::lt(self, value) {
                Ordering::Greater
            } else if Math::gt(self, value) {
                Ordering::Less
            } else {
                panic!("Unsupported math type");
            }
        } else if Math::eq(self, value) {
            Ordering::Equal
        } else if Math::lt(self, value) {
            Ordering::Less
        } else if Math::gt(self, value) {
            Ordering::Greater
        } else {
            panic!("Unsupported math type");
        }
    }

    fn get_rate(&self, other: &Value) -> f64 {
        if self.is_number() && other.is_number() {
            let n1 = self.get_f64();
            let n2 = other.get_f64();
            n2 / n1
        } else if self.is_string() && other.is_string() {
            let n1 = self.get_str().chars().map(|c| c as usize).fold(0, |a, b| a + b);
            let n2 = other.get_str().chars().map(|c| c as usize).fold(0, |a, b| a + b);
            n2 as f64 / n1 as f64
        } else {
            panic!("Unsupported math type");
        }
    }
}


trait Type {
    fn get_f64(&self) -> f64;
    fn get_string(&self) -> String;
    fn get_str(&self) -> &str;
    fn get_u64(&self) -> u64;
    fn get_i64(&self) -> i64;
    fn get_boolean(&self) -> bool;
    fn format(&self) -> String;
}

impl Type for Value {
    fn get_f64(&self) -> f64 {
        match *self {
            Value::Number(ref n) => n.as_f64().unwrap(),
            _ => panic!("not a number"),
        }
    }

    fn get_string(&self) -> String {
        self.as_str().unwrap().to_owned()
    }

    fn get_str(&self) -> &str {
        self.as_str().unwrap()
    }

    fn get_u64(&self) -> u64 {
        self.as_u64().unwrap()
    }

    fn get_i64(&self) -> i64 {
        self.as_i64().unwrap()
    }

    fn get_boolean(&self) -> bool {
        self.as_bool().unwrap()
    }

    fn format(&self) -> String {
        format!("{:?}", self)
    }
}