td-client 0.9.0

Rust Client Library for Treasure Data
Documentation
macro_rules! expected_err {
    ($json:expr, $item_name:expr, $type_name:expr) => {
        DecoderError::ExpectedError(
            format!("{} : {}", $item_name, $type_name).to_string(),
            format!("{:?}", $json),
        )
    };
}

macro_rules! pick_item_base {
    ($json:expr, $item_name:expr, $conv_func:ident, $type_name:expr) => {
        $json
            .find($item_name)
            .ok_or(DecoderError::MissingFieldError($item_name.to_string()))
            .and_then(|x| {
                x.$conv_func().ok_or(DecoderError::ExpectedError(
                    format!("{} : {}", $item_name, $type_name).to_string(),
                    format!("{:?}", x),
                ))
            })
    };
}

macro_rules! pick_item {
    ($json:expr, $item_name:expr, $conv_func:ident, $type_name:expr) => {
        pick_item_base!($json, $item_name, $conv_func, $type_name)?
    };
}

macro_rules! pick_string_item {
    ($json:expr, $item_name:expr) => {
        pick_item!($json, $item_name, as_string, "String").to_string();
    };
}

macro_rules! pick_timestamp_item {
    ($json:expr, $item_name:expr) => {
        TimeStamp::from_str(pick_item!($json, $item_name, as_string, "String"))?
    };
}

macro_rules! pick_u64_item {
    ($json:expr, $item_name:expr) => {
        pick_item!($json, $item_name, as_u64, "u64");
    };
}

#[allow(unused_macros)]
macro_rules! pick_array_string_item {
    ($json:expr, $item_name:expr) => {{
        let items: &Vec<json::Json> = pick_item!($json, $item_name, as_array, "Array");
        items
            .iter()
            .map(|j| {
                let result: Result<String, DecoderError> = j
                    .as_string()
                    .ok_or(DecoderError::ExpectedError(
                        "String".to_string(),
                        format!("{:?}", j),
                    ))
                    .and_then(|x| Ok(x.to_string()));
                result
            })
            .collect::<Result<Vec<String>, _>>()?
    }};
}

macro_rules! pick_opt_item {
    ($json:expr, $item_name:expr, $conv_func:ident, $type_name:expr) => {
        pick_item_base!($json, $item_name, $conv_func, $type_name).ok()
    };
}

macro_rules! pick_opt_string_item {
    ($json:expr, $item_name:expr) => {
        pick_opt_item!($json, $item_name, as_string, "String").map(|x| x.to_string())
    };
}

macro_rules! pick_opt_timestamp_item {
    ($json:expr, $item_name:expr) => {
        match pick_opt_item!($json, $item_name, as_string, "String") {
            Some("") => None,
            Some(x) => Some(TimeStamp::from_str(x)?),
            None => None,
        }
    };
}

macro_rules! pick_opt_u64_item {
    ($json:expr, $item_name:expr) => {
        pick_opt_item!($json, $item_name, as_u64, "u64");
    };
}

#[cfg(test)]
mod tests {
    use error::*;
    use model::*;
    use rustc_serialize::json::{DecoderError, Json};
    use std::str::FromStr;

    #[test]
    fn pick_string_item() {
        let j = Json::from_str(r#"{"x": "foo"}"#).unwrap();
        let r: Result<String, TreasureDataError> = (|| Ok(pick_string_item!(j, "x")))();
        assert_eq!(r.unwrap(), "foo".to_string());
    }

    #[test]
    fn pick_opt_string_item() {
        let j = Json::from_str(r#"{"x": "foo"}"#).unwrap();
        let r: Result<Option<String>, TreasureDataError> = (|| Ok(pick_opt_string_item!(j, "x")))();
        assert_eq!(r.unwrap(), Some("foo".to_string()));

        let j = Json::from_str(r#"{"y": "foo"}"#).unwrap();
        let r: Result<Option<String>, TreasureDataError> = (|| Ok(pick_opt_string_item!(j, "x")))();
        assert_eq!(r.unwrap(), None);
    }

    #[test]
    fn pick_timestamp_item() {
        let j = Json::from_str(r#"{"x": "2016-07-29 16:00:00 UTC"}"#).unwrap();
        let r: Result<TimeStamp, TreasureDataError> = (|| Ok(pick_timestamp_item!(j, "x")))();
        assert_eq!(
            r.unwrap(),
            TimeStamp::from_str("2016-07-29 16:00:00 UTC").unwrap()
        );
    }

    #[test]
    fn pick_opt_timestamp_item() {
        let j = Json::from_str(r#"{"x": "2016-07-29 16:00:00 UTC"}"#).unwrap();
        let r: Result<Option<TimeStamp>, TreasureDataError> =
            (|| Ok(pick_opt_timestamp_item!(j, "x")))();
        assert_eq!(
            r.unwrap(),
            Some(TimeStamp::from_str("2016-07-29 16:00:00 UTC").unwrap())
        );

        let j = Json::from_str(r#"{"y": "2016-07-29 16:00:00 UTC"}"#).unwrap();
        let r: Result<Option<TimeStamp>, TreasureDataError> =
            (|| Ok(pick_opt_timestamp_item!(j, "x")))();
        assert_eq!(r.unwrap(), None);

        let j = Json::from_str(r#"{"x": ""}"#).unwrap();
        let r: Result<Option<TimeStamp>, TreasureDataError> =
            (|| Ok(pick_opt_timestamp_item!(j, "x")))();
        assert_eq!(r.unwrap(), None);
    }
}