use std::collections::{BTreeMap, HashMap};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::de;
use serde_json::Value;
use ::error::EsError;
use ::operations::common::OptionVal;
#[derive(Debug, Serialize, Deserialize)]
pub enum DurationUnit {
Month,
Week,
Day,
Hour,
Minute,
Second,
Millisecond
}
impl ToString for DurationUnit {
fn to_string(&self) -> String {
match *self {
DurationUnit::Month => "M",
DurationUnit::Week => "w",
DurationUnit::Day => "d",
DurationUnit::Hour => "h",
DurationUnit::Minute => "m",
DurationUnit::Second => "s",
DurationUnit::Millisecond => "ms"
}.to_owned()
}
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Duration {
amt: i64,
unit: DurationUnit
}
impl Duration {
pub fn new(amt: i64, unit: DurationUnit) -> Duration {
Duration {
amt: amt,
unit: unit
}
}
pub fn months(amt: i64) -> Duration {
Duration::new(amt, DurationUnit::Month)
}
pub fn weeks(amt: i64) -> Duration {
Duration::new(amt, DurationUnit::Week)
}
pub fn days(amt: i64) -> Duration {
Duration::new(amt, DurationUnit::Day)
}
pub fn hours(amt: i64) -> Duration {
Duration::new(amt, DurationUnit::Hour)
}
pub fn minutes(amt: i64) -> Duration {
Duration::new(amt, DurationUnit::Minute)
}
pub fn seconds(amt: i64) -> Duration {
Duration::new(amt, DurationUnit::Second)
}
pub fn milliseconds(amt: i64) -> Duration {
Duration::new(amt, DurationUnit::Millisecond)
}
}
impl ToString for Duration {
fn to_string(&self) -> String {
format!("{}{}", self.amt, self.unit.to_string())
}
}
impl<'a> From<&'a Duration> for OptionVal {
fn from(from: &'a Duration) -> OptionVal {
OptionVal(from.to_string())
}
}
from_exp!(Duration, OptionVal, from, OptionVal(from.to_string()));
#[derive(Debug)]
pub enum Location {
LatLon(f64, f64),
GeoHash(String)
}
impl Default for Location {
fn default() -> Location {
Location::LatLon(0f64, 0f64)
}
}
impl Deserialize for Location {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer {
let mut raw_location = try!(HashMap::<String, f64>::deserialize(deserializer));
Ok(Location::LatLon(
raw_location.remove("lat").unwrap(),
raw_location.remove("lon").unwrap()
))
}
}
from_exp!((f64, f64), Location, from, Location::LatLon(from.0, from.1));
from!(String, Location, GeoHash);
impl Serialize for Location {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer {
match self {
&Location::LatLon(lat, lon) => {
let mut d = BTreeMap::new();
d.insert("lat", lat);
d.insert("lon", lon);
d.serialize(serializer)
},
&Location::GeoHash(ref geo_hash) => {
geo_hash.serialize(serializer)
}
}
}
}
#[derive(Debug)]
pub enum GeoBox {
Corners(Location, Location),
Vertices(f64, f64, f64, f64)
}
impl Default for GeoBox {
fn default() -> Self {
GeoBox::Vertices(0f64, 0f64, 0f64, 0f64)
}
}
impl Deserialize for GeoBox {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer {
let mut raw_geo_box = try!(HashMap::<String, Location>::deserialize(deserializer));
Ok(GeoBox::Corners(
raw_geo_box.remove("top_left").unwrap(),
raw_geo_box.remove("bottom_right").unwrap()
))
}
}
from_exp!((Location, Location), GeoBox, from, GeoBox::Corners(from.0, from.1));
from_exp!(((f64, f64), (f64, f64)),
GeoBox,
from,
GeoBox::Corners(Location::LatLon({from.0}.0, {from.0}.1),
Location::LatLon({from.1}.0, {from.1}.1)));
from_exp!((f64, f64, f64, f64),
GeoBox,
from,
GeoBox::Vertices(from.0, from.1, from.2, from.3));
impl Serialize for GeoBox {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer {
use self::GeoBox::*;
match self {
&Corners(ref top_left, ref bottom_right) => {
let mut d = BTreeMap::new();
d.insert("top_left", top_left);
d.insert("bottom_right", bottom_right);
d.serialize(serializer)
},
&Vertices(top, left, bottom, right) => {
let mut d = BTreeMap::new();
d.insert("top", top);
d.insert("left", left);
d.insert("bottom", bottom);
d.insert("right", right);
d.serialize(serializer)
}
}
}
}
#[derive(Debug)]
pub enum OneOrMany<T> {
One(T),
Many(Vec<T>)
}
impl<T: Default> Default for OneOrMany<T> {
fn default() -> Self {
OneOrMany::One(Default::default())
}
}
impl<T> Serialize for OneOrMany<T>
where T: Serialize {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer {
match self {
&OneOrMany::One(ref t) => t.serialize(serializer),
&OneOrMany::Many(ref t) => t.serialize(serializer)
}
}
}
impl<T> From<T> for OneOrMany<T> {
fn from(from: T) -> OneOrMany<T> {
OneOrMany::One(from)
}
}
impl<T> From<Vec<T>> for OneOrMany<T> {
fn from(from: Vec<T>) -> OneOrMany<T> {
OneOrMany::Many(from)
}
}
#[derive(Debug)]
pub enum DistanceType {
SloppyArc,
Arc,
Plane
}
impl Serialize for DistanceType {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer {
match self {
&DistanceType::SloppyArc => "sloppy_arc",
&DistanceType::Arc => "arc",
&DistanceType::Plane => "plane"
}.serialize(serializer)
}
}
#[derive(Debug)]
pub enum DistanceUnit {
Mile,
Yard,
Feet,
Inch,
Kilometer,
Meter,
Centimeter,
Millimeter,
NauticalMile
}
impl Default for DistanceUnit {
fn default() -> DistanceUnit {
DistanceUnit::Kilometer
}
}
impl ToString for DistanceUnit {
fn to_string(&self) -> String {
match *self {
DistanceUnit::Mile => "mi",
DistanceUnit::Yard => "yd",
DistanceUnit::Feet => "ft",
DistanceUnit::Inch => "in",
DistanceUnit::Kilometer => "km",
DistanceUnit::Meter => "m",
DistanceUnit::Centimeter => "cm",
DistanceUnit::Millimeter => "mm",
DistanceUnit::NauticalMile => "NM"
}.to_owned()
}
}
impl Serialize for DistanceUnit {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer {
self.to_string().serialize(serializer)
}
}
#[derive(Debug, Default)]
pub struct Distance {
amt: f64,
unit: DistanceUnit
}
impl Distance {
pub fn new(amt: f64, unit: DistanceUnit) -> Distance {
Distance {
amt: amt,
unit: unit
}
}
}
impl Serialize for Distance {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer {
format!("{}{}", self.amt, self.unit.to_string()).serialize(serializer)
}
}
pub trait JsonPotential {
fn to_json_val(&self) -> JsonVal;
}
macro_rules! json_potential {
($t:ty) => (
impl JsonPotential for $t {
fn to_json_val(&self) -> JsonVal {
(*self).into()
}
}
)
}
impl<'a> JsonPotential for &'a str {
fn to_json_val(&self) -> JsonVal {
(*self).into()
}
}
json_potential!(i64);
json_potential!(i32);
json_potential!(u64);
json_potential!(u32);
json_potential!(f64);
json_potential!(f32);
json_potential!(bool);
#[derive(Debug)]
pub enum JsonVal {
String(String),
I64(i64),
U64(u64),
F64(f64),
Boolean(bool)
}
impl JsonVal {
pub fn from(from: &Value) -> Result<Self, EsError> {
use serde_json::Value::*;
Ok(match from {
&String(ref string) => JsonVal::String(string.clone()),
&Bool(b) => JsonVal::Boolean(b),
&I64(i) => JsonVal::I64(i),
&U64(u) => JsonVal::U64(u),
&F64(f) => JsonVal::F64(f),
_ => return Err(EsError::EsError(format!("Not a JsonVal: {:?}",
from)))
})
}
}
impl Default for JsonVal {
fn default() -> Self {
JsonVal::String(Default::default())
}
}
impl Serialize for JsonVal {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer {
match self {
&JsonVal::String(ref s) => s.serialize(serializer),
&JsonVal::I64(i) => i.serialize(serializer),
&JsonVal::U64(u) => u.serialize(serializer),
&JsonVal::F64(f) => f.serialize(serializer),
&JsonVal::Boolean(b) => b.serialize(serializer)
}
}
}
impl Deserialize for JsonVal {
fn deserialize<D>(deserializer: &mut D) -> Result<JsonVal, D::Error>
where D: Deserializer {
deserializer.deserialize(JsonValVisitor)
}
}
struct JsonValVisitor;
impl de::Visitor for JsonValVisitor {
type Value = JsonVal;
fn visit_string<E>(&mut self, s: String) -> Result<JsonVal, E>
where E: de::Error {
Ok(JsonVal::String(s))
}
fn visit_i64<E>(&mut self, i: i64) -> Result<JsonVal, E>
where E: de::Error {
Ok(JsonVal::I64(i))
}
fn visit_u64<E>(&mut self, u: u64) -> Result<JsonVal, E>
where E: de::Error {
Ok(JsonVal::U64(u))
}
fn visit_f64<E>(&mut self, f: f64) -> Result<JsonVal, E>
where E: de::Error {
Ok(JsonVal::F64(f))
}
fn visit_bool<E>(&mut self, b: bool) -> Result<JsonVal, E>
where E: de::Error {
Ok(JsonVal::Boolean(b))
}
}
from!(String, JsonVal, String);
impl<'a> From<&'a str> for JsonVal {
fn from(from: &'a str) -> JsonVal {
JsonVal::String(from.to_owned())
}
}
from_exp!(f32, JsonVal, from, JsonVal::F64(from as f64));
from!(f64, JsonVal, F64);
from_exp!(i32, JsonVal, from, JsonVal::I64(from as i64));
from!(i64, JsonVal, I64);
from_exp!(u32, JsonVal, from, JsonVal::U64(from as u64));
from!(u64, JsonVal, U64);
from!(bool, JsonVal, Boolean);
impl<'a> From<&'a Value> for JsonVal {
fn from(from: &'a Value) -> Self {
use serde_json::Value::*;
match from {
&String(ref s) => JsonVal::String(s.clone()),
&F64(f) => JsonVal::F64(f),
&I64(f) => JsonVal::I64(f),
&U64(f) => JsonVal::U64(f),
&Bool(b) => JsonVal::Boolean(b),
_ => panic!("Not a String, F64, I64, U64 or Boolean")
}
}
}