Blame testing/webdriver/src/actions.rs

Packit f0b94e
use command::Parameters;
Packit f0b94e
use common::{Nullable, WebElement};
Packit f0b94e
use error::{WebDriverResult, WebDriverError, ErrorStatus};
Packit f0b94e
use rustc_serialize::json::{ToJson, Json};
Packit f0b94e
use unicode_segmentation::UnicodeSegmentation;
Packit f0b94e
use std::collections::BTreeMap;
Packit f0b94e
use std::default::Default;
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub struct ActionSequence {
Packit f0b94e
    pub id: Nullable<String>,
Packit f0b94e
    pub actions: ActionsType
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for ActionSequence {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<ActionSequence> {
Packit f0b94e
        let data = try_opt!(body.as_object(),
Packit f0b94e
                            ErrorStatus::InvalidArgument,
Packit f0b94e
                            "Actions chain was not an object");
Packit f0b94e
Packit f0b94e
        let type_name = try_opt!(try_opt!(data.get("type"),
Packit f0b94e
                                          ErrorStatus::InvalidArgument,
Packit f0b94e
                                          "Missing type parameter").as_string(),
Packit f0b94e
                                 ErrorStatus::InvalidArgument,
Packit f0b94e
                                 "Parameter ;type' was not a string");
Packit f0b94e
Packit f0b94e
        let id = match data.get("id") {
Packit f0b94e
            Some(x) => Some(try_opt!(x.as_string(),
Packit f0b94e
                                     ErrorStatus::InvalidArgument,
Packit f0b94e
                                     "Parameter 'id' was not a string").to_owned()),
Packit f0b94e
            None => None
Packit f0b94e
        };
Packit f0b94e
Packit f0b94e
Packit f0b94e
        // Note that unlike the spec we get the pointer parameters in ActionsType::from_json
Packit f0b94e
Packit f0b94e
        let actions = match type_name {
Packit f0b94e
            "none" | "key" | "pointer" => try!(ActionsType::from_json(&body)),
Packit f0b94e
            _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
Packit f0b94e
                                                "Invalid action type"))
Packit f0b94e
        };
Packit f0b94e
Packit f0b94e
        Ok(ActionSequence {
Packit f0b94e
            id: id.into(),
Packit f0b94e
            actions: actions
Packit f0b94e
        })
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for ActionSequence {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        let mut data: BTreeMap<String, Json> = BTreeMap::new();
Packit f0b94e
        data.insert("id".into(), self.id.to_json());
Packit f0b94e
        let (action_type, actions) = match self.actions {
Packit f0b94e
            ActionsType::Null(ref actions) => {
Packit f0b94e
                ("none",
Packit f0b94e
                 actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>())
Packit f0b94e
            }
Packit f0b94e
            ActionsType::Key(ref actions) => {
Packit f0b94e
                ("key",
Packit f0b94e
                 actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>())
Packit f0b94e
            }
Packit f0b94e
            ActionsType::Pointer(ref parameters, ref actions) => {
Packit f0b94e
                data.insert("parameters".into(), parameters.to_json());
Packit f0b94e
                ("pointer",
Packit f0b94e
                 actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>())
Packit f0b94e
            }
Packit f0b94e
        };
Packit f0b94e
        data.insert("type".into(), action_type.to_json());
Packit f0b94e
        data.insert("actions".into(), actions.to_json());
Packit f0b94e
        Json::Object(data)
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub enum ActionsType {
Packit f0b94e
    Null(Vec<NullActionItem>),
Packit f0b94e
    Key(Vec<KeyActionItem>),
Packit f0b94e
    Pointer(PointerActionParameters, Vec<PointerActionItem>)
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for ActionsType {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<ActionsType> {
Packit f0b94e
        // These unwraps are OK as long as this is only called from ActionSequence::from_json
Packit f0b94e
        let data = body.as_object().expect("Body should be a JSON Object");
Packit f0b94e
        let actions_type = body.find("type").and_then(|x| x.as_string()).expect("Type should be a string");
Packit f0b94e
        let actions_chain = try_opt!(try_opt!(data.get("actions"),
Packit f0b94e
                                              ErrorStatus::InvalidArgument,
Packit f0b94e
                                              "Missing actions parameter").as_array(),
Packit f0b94e
                                     ErrorStatus::InvalidArgument,
Packit f0b94e
                                     "Parameter 'actions' was not an array");
Packit f0b94e
        match actions_type {
Packit f0b94e
            "none" => {
Packit f0b94e
                let mut actions = Vec::with_capacity(actions_chain.len());
Packit f0b94e
                for action_body in actions_chain.iter() {
Packit f0b94e
                    actions.push(try!(NullActionItem::from_json(action_body)));
Packit f0b94e
                };
Packit f0b94e
                Ok(ActionsType::Null(actions))
Packit f0b94e
            },
Packit f0b94e
            "key" => {
Packit f0b94e
                let mut actions = Vec::with_capacity(actions_chain.len());
Packit f0b94e
                for action_body in actions_chain.iter() {
Packit f0b94e
                    actions.push(try!(KeyActionItem::from_json(action_body)));
Packit f0b94e
                };
Packit f0b94e
                Ok(ActionsType::Key(actions))
Packit f0b94e
            },
Packit f0b94e
            "pointer" => {
Packit f0b94e
                let mut actions = Vec::with_capacity(actions_chain.len());
Packit f0b94e
                let parameters = match data.get("parameters") {
Packit f0b94e
                    Some(x) => try!(PointerActionParameters::from_json(x)),
Packit f0b94e
                    None => Default::default()
Packit f0b94e
                };
Packit f0b94e
Packit f0b94e
                for action_body in actions_chain.iter() {
Packit f0b94e
                    actions.push(try!(PointerActionItem::from_json(action_body)));
Packit f0b94e
                }
Packit f0b94e
                Ok(ActionsType::Pointer(parameters, actions))
Packit f0b94e
            }
Packit f0b94e
            _ => panic!("Got unexpected action type after checking type")
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub enum PointerType {
Packit f0b94e
    Mouse,
Packit f0b94e
    Pen,
Packit f0b94e
    Touch,
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for PointerType {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<PointerType> {
Packit f0b94e
        match body.as_string() {
Packit f0b94e
            Some("mouse") => Ok(PointerType::Mouse),
Packit f0b94e
            Some("pen") => Ok(PointerType::Pen),
Packit f0b94e
            Some("touch") => Ok(PointerType::Touch),
Packit f0b94e
            Some(_) => Err(WebDriverError::new(
Packit f0b94e
                ErrorStatus::InvalidArgument,
Packit f0b94e
                "Unsupported pointer type"
Packit f0b94e
            )),
Packit f0b94e
            None => Err(WebDriverError::new(
Packit f0b94e
                ErrorStatus::InvalidArgument,
Packit f0b94e
                "Pointer type was not a string"
Packit f0b94e
            ))
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for PointerType {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        match *self {
Packit f0b94e
            PointerType::Mouse => "mouse".to_json(),
Packit f0b94e
            PointerType::Pen => "pen".to_json(),
Packit f0b94e
            PointerType::Touch => "touch".to_json(),
Packit f0b94e
        }.to_json()
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Default for PointerType {
Packit f0b94e
    fn default() -> PointerType {
Packit f0b94e
        PointerType::Mouse
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, Default, PartialEq)]
Packit f0b94e
pub struct PointerActionParameters {
Packit f0b94e
    pub pointer_type: PointerType
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for PointerActionParameters {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<PointerActionParameters> {
Packit f0b94e
        let data = try_opt!(body.as_object(),
Packit f0b94e
                            ErrorStatus::InvalidArgument,
Packit f0b94e
                            "Parameter 'parameters' was not an object");
Packit f0b94e
        let pointer_type = match data.get("pointerType") {
Packit f0b94e
            Some(x) => try!(PointerType::from_json(x)),
Packit f0b94e
            None => PointerType::default()
Packit f0b94e
        };
Packit f0b94e
        Ok(PointerActionParameters {
Packit f0b94e
            pointer_type: pointer_type
Packit f0b94e
        })
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for PointerActionParameters {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        let mut data = BTreeMap::new();
Packit f0b94e
        data.insert("pointerType".to_owned(),
Packit f0b94e
                    self.pointer_type.to_json());
Packit f0b94e
        Json::Object(data)
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub enum NullActionItem {
Packit f0b94e
    General(GeneralAction)
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for NullActionItem {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<NullActionItem> {
Packit f0b94e
        let data = try_opt!(body.as_object(),
Packit f0b94e
                            ErrorStatus::InvalidArgument,
Packit f0b94e
                            "Actions chain was not an object");
Packit f0b94e
        let type_name = try_opt!(
Packit f0b94e
            try_opt!(data.get("type"),
Packit f0b94e
                     ErrorStatus::InvalidArgument,
Packit f0b94e
                     "Missing 'type' parameter").as_string(),
Packit f0b94e
            ErrorStatus::InvalidArgument,
Packit f0b94e
            "Parameter 'type' was not a string");
Packit f0b94e
        match type_name {
Packit f0b94e
            "pause" => Ok(NullActionItem::General(
Packit f0b94e
                try!(GeneralAction::from_json(body)))),
Packit f0b94e
            _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
Packit f0b94e
                                                "Invalid type attribute"))
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for NullActionItem {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        match self {
Packit f0b94e
            &NullActionItem::General(ref x) => x.to_json(),
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub enum KeyActionItem {
Packit f0b94e
    General(GeneralAction),
Packit f0b94e
    Key(KeyAction)
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for KeyActionItem {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<KeyActionItem> {
Packit f0b94e
        let data = try_opt!(body.as_object(),
Packit f0b94e
                            ErrorStatus::InvalidArgument,
Packit f0b94e
                            "Key action item was not an object");
Packit f0b94e
        let type_name = try_opt!(
Packit f0b94e
            try_opt!(data.get("type"),
Packit f0b94e
                     ErrorStatus::InvalidArgument,
Packit f0b94e
                     "Missing 'type' parameter").as_string(),
Packit f0b94e
            ErrorStatus::InvalidArgument,
Packit f0b94e
            "Parameter 'type' was not a string");
Packit f0b94e
        match type_name {
Packit f0b94e
            "pause" => Ok(KeyActionItem::General(
Packit f0b94e
                try!(GeneralAction::from_json(body)))),
Packit f0b94e
            _ => Ok(KeyActionItem::Key(
Packit f0b94e
                try!(KeyAction::from_json(body))))
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for KeyActionItem {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        match *self {
Packit f0b94e
            KeyActionItem::General(ref x) => x.to_json(),
Packit f0b94e
            KeyActionItem::Key(ref x) => x.to_json()
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub enum PointerActionItem {
Packit f0b94e
    General(GeneralAction),
Packit f0b94e
    Pointer(PointerAction)
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for PointerActionItem {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<PointerActionItem> {
Packit f0b94e
        let data = try_opt!(body.as_object(),
Packit f0b94e
                            ErrorStatus::InvalidArgument,
Packit f0b94e
                            "Pointer action item was not an object");
Packit f0b94e
        let type_name = try_opt!(
Packit f0b94e
            try_opt!(data.get("type"),
Packit f0b94e
                     ErrorStatus::InvalidArgument,
Packit f0b94e
                     "Missing 'type' parameter").as_string(),
Packit f0b94e
            ErrorStatus::InvalidArgument,
Packit f0b94e
            "Parameter 'type' was not a string");
Packit f0b94e
Packit f0b94e
        match type_name {
Packit f0b94e
            "pause" => Ok(PointerActionItem::General(try!(GeneralAction::from_json(body)))),
Packit f0b94e
            _ => Ok(PointerActionItem::Pointer(try!(PointerAction::from_json(body))))
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for PointerActionItem {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        match self {
Packit f0b94e
            &PointerActionItem::General(ref x) => x.to_json(),
Packit f0b94e
            &PointerActionItem::Pointer(ref x) => x.to_json()
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub enum GeneralAction {
Packit f0b94e
    Pause(PauseAction)
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for GeneralAction {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<GeneralAction> {
Packit f0b94e
        match body.find("type").and_then(|x| x.as_string()) {
Packit f0b94e
            Some("pause") => Ok(GeneralAction::Pause(try!(PauseAction::from_json(body)))),
Packit f0b94e
            _ => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
Packit f0b94e
                                         "Invalid or missing type attribute"))
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for GeneralAction {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        match self {
Packit f0b94e
            &GeneralAction::Pause(ref x) => x.to_json()
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub struct PauseAction {
Packit f0b94e
    pub duration: u64
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for PauseAction {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<PauseAction> {
Packit f0b94e
        let default = Json::U64(0);
Packit f0b94e
        Ok(PauseAction {
Packit f0b94e
            duration: try_opt!(body.find("duration").unwrap_or(&default).as_u64(),
Packit f0b94e
                               ErrorStatus::InvalidArgument,
Packit f0b94e
                               "Parameter 'duration' was not a positive integer")
Packit f0b94e
        })
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for PauseAction {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        let mut data = BTreeMap::new();
Packit f0b94e
        data.insert("type".to_owned(),
Packit f0b94e
                    "pause".to_json());
Packit f0b94e
        data.insert("duration".to_owned(),
Packit f0b94e
                    self.duration.to_json());
Packit f0b94e
        Json::Object(data)
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub enum KeyAction {
Packit f0b94e
    Up(KeyUpAction),
Packit f0b94e
    Down(KeyDownAction)
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for KeyAction {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<KeyAction> {
Packit f0b94e
        match body.find("type").and_then(|x| x.as_string()) {
Packit f0b94e
            Some("keyDown") => Ok(KeyAction::Down(try!(KeyDownAction::from_json(body)))),
Packit f0b94e
            Some("keyUp") => Ok(KeyAction::Up(try!(KeyUpAction::from_json(body)))),
Packit f0b94e
            Some(_) | None => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
Packit f0b94e
                                                      "Invalid type attribute value for key action"))
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for KeyAction {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        match self {
Packit f0b94e
            &KeyAction::Down(ref x) => x.to_json(),
Packit f0b94e
            &KeyAction::Up(ref x) => x.to_json(),
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
fn validate_key_value(value_str: &str) -> WebDriverResult<String> {
Packit f0b94e
    let mut graphemes = value_str.graphemes(true);
Packit f0b94e
    let value = if let Some(g) = graphemes.next() {
Packit f0b94e
        g
Packit f0b94e
    } else {
Packit f0b94e
        return Err(WebDriverError::new(
Packit f0b94e
            ErrorStatus::InvalidArgument,
Packit f0b94e
            "Parameter 'value' was an empty string"))
Packit f0b94e
    };
Packit f0b94e
    if graphemes.next().is_some() {
Packit f0b94e
        return Err(WebDriverError::new(
Packit f0b94e
            ErrorStatus::InvalidArgument,
Packit f0b94e
            "Parameter 'value' contained multiple graphemes"))
Packit f0b94e
    };
Packit f0b94e
    Ok(value.to_string())
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub struct KeyUpAction {
Packit f0b94e
    pub value: String
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for KeyUpAction {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<KeyUpAction> {
Packit f0b94e
        let value_str = try_opt!(
Packit f0b94e
                try_opt!(body.find("value"),
Packit f0b94e
                         ErrorStatus::InvalidArgument,
Packit f0b94e
                         "Missing value parameter").as_string(),
Packit f0b94e
                ErrorStatus::InvalidArgument,
Packit f0b94e
            "Parameter 'value' was not a string");
Packit f0b94e
Packit f0b94e
        let value = try!(validate_key_value(value_str));
Packit f0b94e
        Ok(KeyUpAction {
Packit f0b94e
            value: value
Packit f0b94e
        })
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for KeyUpAction {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        let mut data = BTreeMap::new();
Packit f0b94e
        data.insert("type".to_owned(),
Packit f0b94e
                    "keyUp".to_json());
Packit f0b94e
        data.insert("value".to_string(),
Packit f0b94e
                    self.value.to_string().to_json());
Packit f0b94e
        Json::Object(data)
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub struct KeyDownAction {
Packit f0b94e
    pub value: String
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for KeyDownAction {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<KeyDownAction> {
Packit f0b94e
        let value_str = try_opt!(
Packit f0b94e
                try_opt!(body.find("value"),
Packit f0b94e
                         ErrorStatus::InvalidArgument,
Packit f0b94e
                         "Missing value parameter").as_string(),
Packit f0b94e
                ErrorStatus::InvalidArgument,
Packit f0b94e
            "Parameter 'value' was not a string");
Packit f0b94e
        let value = try!(validate_key_value(value_str));
Packit f0b94e
        Ok(KeyDownAction {
Packit f0b94e
            value: value
Packit f0b94e
        })
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for KeyDownAction {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        let mut data = BTreeMap::new();
Packit f0b94e
        data.insert("type".to_owned(),
Packit f0b94e
                    "keyDown".to_json());
Packit f0b94e
        data.insert("value".to_owned(),
Packit f0b94e
                    self.value.to_string().to_json());
Packit f0b94e
        Json::Object(data)
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub enum PointerOrigin {
Packit f0b94e
    Viewport,
Packit f0b94e
    Pointer,
Packit f0b94e
    Element(WebElement),
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for PointerOrigin {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<PointerOrigin> {
Packit f0b94e
        match *body {
Packit f0b94e
            Json::String(ref x) => {
Packit f0b94e
                match &**x {
Packit f0b94e
                    "viewport" => Ok(PointerOrigin::Viewport),
Packit f0b94e
                    "pointer" => Ok(PointerOrigin::Pointer),
Packit f0b94e
                    _ => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
Packit f0b94e
                                                 "Unknown pointer origin"))
Packit f0b94e
                }
Packit f0b94e
            },
Packit f0b94e
            Json::Object(_) => Ok(PointerOrigin::Element(try!(WebElement::from_json(body)))),
Packit f0b94e
            _ => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
Packit f0b94e
                        "Pointer origin was not a string or an object"))
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for PointerOrigin {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        match *self {
Packit f0b94e
            PointerOrigin::Viewport => "viewport".to_json(),
Packit f0b94e
            PointerOrigin::Pointer => "pointer".to_json(),
Packit f0b94e
            PointerOrigin::Element(ref x) => x.to_json(),
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Default for PointerOrigin {
Packit f0b94e
    fn default() -> PointerOrigin {
Packit f0b94e
        PointerOrigin::Viewport
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub enum PointerAction {
Packit f0b94e
    Up(PointerUpAction),
Packit f0b94e
    Down(PointerDownAction),
Packit f0b94e
    Move(PointerMoveAction),
Packit f0b94e
    Cancel
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for PointerAction {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<PointerAction> {
Packit f0b94e
        match body.find("type").and_then(|x| x.as_string()) {
Packit f0b94e
            Some("pointerUp") => Ok(PointerAction::Up(try!(PointerUpAction::from_json(body)))),
Packit f0b94e
            Some("pointerDown") => Ok(PointerAction::Down(try!(PointerDownAction::from_json(body)))),
Packit f0b94e
            Some("pointerMove") => Ok(PointerAction::Move(try!(PointerMoveAction::from_json(body)))),
Packit f0b94e
            Some("pointerCancel") => Ok(PointerAction::Cancel),
Packit f0b94e
            Some(_) | None => Err(WebDriverError::new(
Packit f0b94e
                ErrorStatus::InvalidArgument,
Packit f0b94e
                "Missing or invalid type argument for pointer action"))
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for PointerAction {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        match self {
Packit f0b94e
            &PointerAction::Down(ref x) => x.to_json(),
Packit f0b94e
            &PointerAction::Up(ref x) => x.to_json(),
Packit f0b94e
            &PointerAction::Move(ref x) => x.to_json(),
Packit f0b94e
            &PointerAction::Cancel => {
Packit f0b94e
                let mut data = BTreeMap::new();
Packit f0b94e
                data.insert("type".to_owned(),
Packit f0b94e
                            "pointerCancel".to_json());
Packit f0b94e
                Json::Object(data)
Packit f0b94e
            }
Packit f0b94e
        }
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub struct PointerUpAction {
Packit f0b94e
    pub button: u64,
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for PointerUpAction {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<PointerUpAction> {
Packit f0b94e
        let button = try_opt!(
Packit f0b94e
            try_opt!(body.find("button"),
Packit f0b94e
                     ErrorStatus::InvalidArgument,
Packit f0b94e
                     "Missing button parameter").as_u64(),
Packit f0b94e
            ErrorStatus::InvalidArgument,
Packit f0b94e
            "Parameter 'button' was not a positive integer");
Packit f0b94e
Packit f0b94e
        Ok(PointerUpAction {
Packit f0b94e
            button: button
Packit f0b94e
        })
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for PointerUpAction {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        let mut data = BTreeMap::new();
Packit f0b94e
        data.insert("type".to_owned(),
Packit f0b94e
                    "pointerUp".to_json());
Packit f0b94e
        data.insert("button".to_owned(), self.button.to_json());
Packit f0b94e
        Json::Object(data)
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub struct PointerDownAction {
Packit f0b94e
    pub button: u64,
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for PointerDownAction {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<PointerDownAction> {
Packit f0b94e
        let button = try_opt!(
Packit f0b94e
            try_opt!(body.find("button"),
Packit f0b94e
                     ErrorStatus::InvalidArgument,
Packit f0b94e
                     "Missing button parameter").as_u64(),
Packit f0b94e
            ErrorStatus::InvalidArgument,
Packit f0b94e
            "Parameter 'button' was not a positive integer");
Packit f0b94e
Packit f0b94e
        Ok(PointerDownAction {
Packit f0b94e
            button: button
Packit f0b94e
        })
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for PointerDownAction {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        let mut data = BTreeMap::new();
Packit f0b94e
        data.insert("type".to_owned(),
Packit f0b94e
                    "pointerDown".to_json());
Packit f0b94e
        data.insert("button".to_owned(), self.button.to_json());
Packit f0b94e
        Json::Object(data)
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
#[derive(Debug, PartialEq)]
Packit f0b94e
pub struct PointerMoveAction {
Packit f0b94e
    pub duration: Nullable<u64>,
Packit f0b94e
    pub origin: PointerOrigin,
Packit f0b94e
    pub x: Nullable<i64>,
Packit f0b94e
    pub y: Nullable<i64>
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl Parameters for PointerMoveAction {
Packit f0b94e
    fn from_json(body: &Json) -> WebDriverResult<PointerMoveAction> {
Packit f0b94e
        let duration = match body.find("duration") {
Packit f0b94e
            Some(duration) => Some(try_opt!(duration.as_u64(),
Packit f0b94e
                                            ErrorStatus::InvalidArgument,
Packit f0b94e
                                            "Parameter 'duration' was not a positive integer")),
Packit f0b94e
            None => None
Packit f0b94e
Packit f0b94e
        };
Packit f0b94e
Packit f0b94e
        let origin = match body.find("origin") {
Packit f0b94e
            Some(o) => try!(PointerOrigin::from_json(o)),
Packit f0b94e
            None => PointerOrigin::default()
Packit f0b94e
        };
Packit f0b94e
Packit f0b94e
        let x = match body.find("x") {
Packit f0b94e
            Some(x) => {
Packit f0b94e
                Some(try_opt!(x.as_i64(),
Packit f0b94e
                              ErrorStatus::InvalidArgument,
Packit f0b94e
                              "Parameter 'x' was not an integer"))
Packit f0b94e
            },
Packit f0b94e
            None => None
Packit f0b94e
        };
Packit f0b94e
Packit f0b94e
        let y = match body.find("y") {
Packit f0b94e
            Some(y) => {
Packit f0b94e
                Some(try_opt!(y.as_i64(),
Packit f0b94e
                              ErrorStatus::InvalidArgument,
Packit f0b94e
                              "Parameter 'y' was not an integer"))
Packit f0b94e
            },
Packit f0b94e
            None => None
Packit f0b94e
        };
Packit f0b94e
Packit f0b94e
        Ok(PointerMoveAction {
Packit f0b94e
            duration: duration.into(),
Packit f0b94e
            origin: origin.into(),
Packit f0b94e
            x: x.into(),
Packit f0b94e
            y: y.into(),
Packit f0b94e
        })
Packit f0b94e
    }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
impl ToJson for PointerMoveAction {
Packit f0b94e
    fn to_json(&self) -> Json {
Packit f0b94e
        let mut data = BTreeMap::new();
Packit f0b94e
        data.insert("type".to_owned(), "pointerMove".to_json());
Packit f0b94e
        if self.duration.is_value() {
Packit f0b94e
            data.insert("duration".to_owned(),
Packit f0b94e
                        self.duration.to_json());
Packit f0b94e
        }
Packit f0b94e
Packit f0b94e
        data.insert("origin".to_owned(), self.origin.to_json());
Packit f0b94e
Packit f0b94e
        if self.x.is_value() {
Packit f0b94e
            data.insert("x".to_owned(), self.x.to_json());
Packit f0b94e
        }
Packit f0b94e
        if self.y.is_value() {
Packit f0b94e
            data.insert("y".to_owned(), self.y.to_json());
Packit f0b94e
        }
Packit f0b94e
        Json::Object(data)
Packit f0b94e
    }
Packit f0b94e
}