|
Packit |
f0b94e |
use rustc_serialize::{Encodable, Encoder};
|
|
Packit |
f0b94e |
use rustc_serialize::json::{Json, ToJson};
|
|
Packit |
f0b94e |
use std::collections::BTreeMap;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
use error::{WebDriverResult, WebDriverError, ErrorStatus};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
pub static ELEMENT_KEY: &'static str = "element-6066-11e4-a52e-4f735466cecf";
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Clone, Debug, PartialEq, RustcEncodable)]
|
|
Packit |
f0b94e |
pub struct Date(pub u64);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Date {
|
|
Packit |
f0b94e |
pub fn new(timestamp: u64) -> Date {
|
|
Packit |
f0b94e |
Date(timestamp)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for Date {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
let &Date(x) = self;
|
|
Packit |
f0b94e |
x.to_json()
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Clone, Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum Nullable<T: ToJson> {
|
|
Packit |
f0b94e |
Value(T),
|
|
Packit |
f0b94e |
Null
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl<T: ToJson> Nullable<T> {
|
|
Packit |
f0b94e |
pub fn is_null(&self) -> bool {
|
|
Packit |
f0b94e |
match *self {
|
|
Packit |
f0b94e |
Nullable::Value(_) => false,
|
|
Packit |
f0b94e |
Nullable::Null => true
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
pub fn is_value(&self) -> bool {
|
|
Packit |
f0b94e |
match *self {
|
|
Packit |
f0b94e |
Nullable::Value(_) => true,
|
|
Packit |
f0b94e |
Nullable::Null => false
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
pub fn map<F, U: ToJson>(self, f: F) -> Nullable<U>
|
|
Packit |
f0b94e |
where F: FnOnce(T) -> U {
|
|
Packit |
f0b94e |
match self {
|
|
Packit |
f0b94e |
Nullable::Value(val) => Nullable::Value(f(val)),
|
|
Packit |
f0b94e |
Nullable::Null => Nullable::Null
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl<T: ToJson> Nullable<T> {
|
|
Packit |
f0b94e |
//This is not very pretty
|
|
Packit |
f0b94e |
pub fn from_json<F: FnOnce(&Json) -> WebDriverResult<T>>(value: &Json, f: F) -> WebDriverResult<Nullable<T>> {
|
|
Packit |
f0b94e |
if value.is_null() {
|
|
Packit |
f0b94e |
Ok(Nullable::Null)
|
|
Packit |
f0b94e |
} else {
|
|
Packit |
f0b94e |
Ok(Nullable::Value(try!(f(value))))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl<T: ToJson> ToJson for Nullable<T> {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
match *self {
|
|
Packit |
f0b94e |
Nullable::Value(ref x) => x.to_json(),
|
|
Packit |
f0b94e |
Nullable::Null => Json::Null
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl<T: ToJson> Encodable for Nullable<T> {
|
|
Packit |
f0b94e |
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
|
Packit |
f0b94e |
match *self {
|
|
Packit |
f0b94e |
Nullable::Value(ref x) => x.to_json().encode(s),
|
|
Packit |
f0b94e |
Nullable::Null => s.emit_option_none()
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl<T: ToJson> Into<Option<T>> for Nullable<T> {
|
|
Packit |
f0b94e |
fn into(self) -> Option<T> {
|
|
Packit |
f0b94e |
match self {
|
|
Packit |
f0b94e |
Nullable::Value(val) => Some(val),
|
|
Packit |
f0b94e |
Nullable::Null => None
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl<T: ToJson> From<Option<T>> for Nullable<T> {
|
|
Packit |
f0b94e |
fn from(option: Option<T>) -> Nullable<T> {
|
|
Packit |
f0b94e |
match option {
|
|
Packit |
f0b94e |
Some(val) => Nullable::Value(val),
|
|
Packit |
f0b94e |
None => Nullable::Null,
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Clone, Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub struct WebElement {
|
|
Packit |
f0b94e |
pub id: String
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl WebElement {
|
|
Packit |
f0b94e |
pub fn new(id: String) -> WebElement {
|
|
Packit |
f0b94e |
WebElement {
|
|
Packit |
f0b94e |
id: id
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
pub fn from_json(data: &Json) -> WebDriverResult<WebElement> {
|
|
Packit |
f0b94e |
let object = try_opt!(data.as_object(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Could not convert webelement to object");
|
|
Packit |
f0b94e |
let id_value = try_opt!(object.get(ELEMENT_KEY),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Could not find webelement key");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let id = try_opt!(id_value.as_string(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Could not convert web element to string").to_string();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
Ok(WebElement::new(id))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for WebElement {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
let mut data = BTreeMap::new();
|
|
Packit |
f0b94e |
data.insert(ELEMENT_KEY.to_string(), self.id.to_json());
|
|
Packit |
f0b94e |
Json::Object(data)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl <T> From<T> for WebElement
|
|
Packit |
f0b94e |
where T: Into<String> {
|
|
Packit |
f0b94e |
fn from(data: T) -> WebElement {
|
|
Packit |
f0b94e |
WebElement::new(data.into())
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum FrameId {
|
|
Packit |
f0b94e |
Short(u16),
|
|
Packit |
f0b94e |
Element(WebElement),
|
|
Packit |
f0b94e |
Null
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl FrameId {
|
|
Packit |
f0b94e |
pub fn from_json(data: &Json) -> WebDriverResult<FrameId> {
|
|
Packit |
f0b94e |
match data {
|
|
Packit |
f0b94e |
&Json::U64(x) => {
|
|
Packit |
f0b94e |
if x > u16::max_value() as u64 || x < u16::min_value() as u64 {
|
|
Packit |
f0b94e |
return Err(WebDriverError::new(ErrorStatus::NoSuchFrame,
|
|
Packit |
f0b94e |
"frame id out of range"))
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
Ok(FrameId::Short(x as u16))
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
&Json::Null => Ok(FrameId::Null),
|
|
Packit |
f0b94e |
&Json::Object(_) => Ok(FrameId::Element(
|
|
Packit |
f0b94e |
try!(WebElement::from_json(data)))),
|
|
Packit |
f0b94e |
_ => Err(WebDriverError::new(ErrorStatus::NoSuchFrame,
|
|
Packit |
f0b94e |
"frame id has unexpected type"))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for FrameId {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
match *self {
|
|
Packit |
f0b94e |
FrameId::Short(x) => {
|
|
Packit |
f0b94e |
Json::U64(x as u64)
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
FrameId::Element(ref x) => {
|
|
Packit |
f0b94e |
Json::String(x.id.clone())
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
FrameId::Null => {
|
|
Packit |
f0b94e |
Json::Null
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum LocatorStrategy {
|
|
Packit |
f0b94e |
CSSSelector,
|
|
Packit |
f0b94e |
LinkText,
|
|
Packit |
f0b94e |
PartialLinkText,
|
|
Packit |
f0b94e |
TagName,
|
|
Packit |
f0b94e |
XPath,
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl LocatorStrategy {
|
|
Packit |
f0b94e |
pub fn from_json(body: &Json) -> WebDriverResult<LocatorStrategy> {
|
|
Packit |
f0b94e |
match try_opt!(body.as_string(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Expected locator strategy as string") {
|
|
Packit |
f0b94e |
"css selector" => Ok(LocatorStrategy::CSSSelector),
|
|
Packit |
f0b94e |
"link text" => Ok(LocatorStrategy::LinkText),
|
|
Packit |
f0b94e |
"partial link text" => Ok(LocatorStrategy::PartialLinkText),
|
|
Packit |
f0b94e |
"tag name" => Ok(LocatorStrategy::TagName),
|
|
Packit |
f0b94e |
"xpath" => Ok(LocatorStrategy::XPath),
|
|
Packit |
f0b94e |
x => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
format!("Unknown locator strategy {}", x)))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for LocatorStrategy {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
Json::String(match *self {
|
|
Packit |
f0b94e |
LocatorStrategy::CSSSelector => "css selector",
|
|
Packit |
f0b94e |
LocatorStrategy::LinkText => "link text",
|
|
Packit |
f0b94e |
LocatorStrategy::PartialLinkText => "partial link text",
|
|
Packit |
f0b94e |
LocatorStrategy::TagName => "tag name",
|
|
Packit |
f0b94e |
LocatorStrategy::XPath => "xpath"
|
|
Packit |
f0b94e |
}.to_string())
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|