<commit_before>#![deny(warnings)]

//! A library to drive web browsers using the webdriver
//! interface.

use std::convert::From;
use std::io::Read;
use std::io;
use std::fmt::{self, Debug};

extern crate hyper;
use hyper::client::*;
use hyper::Url;

extern crate serde;
use serde::Serialize;
use serde::de::DeserializeOwned;

extern crate serde_json;
pub use serde_json::Value as JsonValue;

#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate log;

#[macro_use]
extern crate derive_builder;

extern crate rand;

pub mod messages;
use messages::*;

pub mod firefox;

#[derive(Debug)]
pub enum Error {
    FailedToLaunchDriver,
    InvalidUrl,
    ConnectionError,
    Io(io::Error),
    JsonDecodeError(serde_json::Error),
    WebDriverError(WebDriverError),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::FailedToLaunchDriver => write!(f, "Unable to start browser driver"),
            Error::InvalidUrl => write!(f, "Invalid URL"),
            Error::ConnectionError => write!(f, "Error connecting to browser"),
            Error::Io(ref err) => write!(f, "{}", err),
            Error::JsonDecodeError(ref s) => write!(f, "Received invalid response from browser: {}", s),
            Error::WebDriverError(ref err) => write!(f, "Error: {}", err.message),
        }
    }
}

impl From<hyper::Error> for Error {
    fn from(_: hyper::Error) -> Error {
        Error::ConnectionError
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl From<serde_json::Error> for Error {
    fn from(e: serde_json::Error) -> Error {
        Error::JsonDecodeError(e)
    }
}

pub trait Driver {
    /// The url used to connect to this driver
    fn url(&self) -> &str;
    /// Start a session for this driver
    fn session(self) -> Result<DriverSession, Error> where Self : Sized + 'static {
        DriverSession::create_session(Box::new(self))
    }
}

/// A driver using a pre-existing WebDriver HTTP URL.
#[derive(Builder)]
#[builder(field(private))]
pub struct HttpDriver {
    #[builder(setter(into))]
    url: String,
}

impl Driver for HttpDriver {
    fn url(&self) -> &str { &self.url }
}

/// Wrapper around the hyper Client, that handles Json encoding and URL construction
struct HttpClient {
    baseurl: Url,
    http: Client,
}

impl HttpClient {
    pub fn new(baseurl: Url) -> Self {
        HttpClient {
            baseurl: baseurl,
            http: Client::new(),
        }
    }

    pub fn decode<D: DeserializeOwned + Debug>(res: &mut Response) -> Result<D, Error> {
        let mut data = String::new();
        try!(res.read_to_string(&mut data));
        debug!("result status: {}\n\
                body: '{}'", res.status, data);

        if !res.status.is_success() {
            let err: Value<WebDriverError> = try!(serde_json::from_str(&data));
            trace!("deserialize error result: {:#?}", err);
            return Err(Error::WebDriverError(err.value));
        }
        let response = serde_json::from_str(&data);
        trace!("deserialize result: {:#?}", response);
        Ok(response?)
    }

    pub fn get<D: DeserializeOwned + Debug>(&self, path: &str) -> Result<D, Error> {
        let url = try!(self.baseurl.join(path)
                           .map_err(|_| Error::InvalidUrl));
        debug!("GET {}", url);
        let mut res = try!(self.http.get(url)
                            .send());
        Self::decode(&mut res)
    }

    pub fn delete<D: DeserializeOwned + Debug>(&self, path: &str) -> Result<D, Error> {
        let url = try!(self.baseurl.join(path)
                           .map_err(|_| Error::InvalidUrl));
        debug!("DELETE {}", url);
        let mut res = try!(self.http.delete(url)
                            .send());
        Self::decode(&mut res)
    }

    pub fn post<D: DeserializeOwned + Debug, E: Serialize>(&self, path: &str, body: &E) -> Result<D, Error> {
        let url = try!(self.baseurl.join(path)
                           .map_err(|_| Error::InvalidUrl));
        let body_str = try!(serde_json::to_string(body));
        debug!("POST url: {}\n\
                body: {}", url, body_str);
        let mut res = try!(self.http.post(url)
                            .body(&body_str)
                            .send());
        Self::decode(&mut res)
    }
}

/// A WebDriver session.
///
/// By default the session is removed on `Drop`
pub struct DriverSession {
    driver: Box<Driver>,
    client: HttpClient,
    session_id: String,
    drop_session: bool,
}

impl DriverSession {
    /// Create a new session with the driver.
    pub fn create_session(driver: Box<Driver>)
    -> Result<DriverSession, Error>
    {
        let baseurl = Url::parse(driver.url())
                          .map_err(|_| Error::InvalidUrl)?;
        let client = HttpClient::new(baseurl);
        info!("Creating session at {}", client.baseurl);
        let sess = try!(Self::new_session(&client, &NewSessionCmd::new()));
        info!("Session {} created", sess.sessionId);
        Ok(DriverSession {
            driver: driver,
            client: client,
            session_id: sess.sessionId,
            drop_session: true,
        })
    }

    /// Use an existing session
    pub fn attach(url: &str, session_id: &str) -> Result<DriverSession, Error> {
        let driver = Box::new(HttpDriver {
            url: url.to_owned(),
        });
        let baseurl = try!(Url::parse(url).map_err(|_| Error::InvalidUrl));
        let mut s = DriverSession {
            driver: driver,
            client: HttpClient::new(baseurl),
            session_id: session_id.to_owned(),
            // This starts as false to avoid triggering the deletion call in Drop
            // if an error occurs
            drop_session: false,
        };
        info!("Connecting to session at {} with id {}", url, session_id);

        // FIXME /status would be preferable here to test the connection, but
        // it does not seem to work for the current geckodriver

        // We can fetch any value for the session to verify it exists.
        // The page URL will work.
        let _ = s.get_current_url()?;

        info!("Connected to existing session {}", s.session_id);
        // The session exists, enable session deletion on Drop
        s.drop_session = true;
        Ok(s)
    }

    pub fn session_id(&self) -> &str {
        &self.session_id
    }

    /// Whether to remove the session on Drop, the default is true
    pub fn drop_session(&mut self, drop: bool) {
        self.drop_session = drop;
    }

    /// Create a new webdriver session
    fn new_session(client: &HttpClient, params: &NewSessionCmd) -> Result<Session, Error> {
        let resp: Value<Session> = try!(client.post("/session", &params));
        Ok(resp.value)
    }

    /// Navigate to the given URL
    pub fn go(&self, url: &str) -> Result<(), Error> {
        let params = GoCmd { url: url.to_string() };
        let _: Empty = try!(self.client.post(&format!("/session/{}/url", &self.session_id), &params));
        Ok(())
    }

    pub fn get_current_url(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/url", self.session_id)));
        Ok(v.value)
    }

    pub fn back(&self) -> Result<(), Error> {
        let _: Empty = try!(self.client.post(&format!("/session/{}/back", self.session_id), &Empty {}));
        Ok(())
    }

    pub fn forward(&self) -> Result<(), Error> {
        let _: Empty = try!(self.client.post(&format!("/session/{}/forward", self.session_id), &Empty {}));
        Ok(())
    }

    pub fn refresh(&self) -> Result<(), Error> {
        let _: Empty = try!(self.client.post(&format!("/session/{}/refresh", self.session_id), &Empty {}));
        Ok(())
    }

    pub fn get_page_source(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/source", self.session_id)));
        Ok(v.value)
    }

    pub fn get_title(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/title", self.session_id)));
        Ok(v.value)
    }

    /// Get all cookies
    pub fn get_cookies(&self) -> Result<Vec<Cookie>, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/cookie", self.session_id)));
        Ok(v.value)
    }

    pub fn get_window_handle(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/window", self.session_id)));
        Ok(v.value)
    }

    pub fn switch_window(&mut self, handle: &str) -> Result<(), Error> {
        let _: Empty = try!(self.client.post(&format!("/session/{}/window", self.session_id), &SwitchWindowCmd::from(handle)));
        Ok(())
    }

    pub fn close_window(&mut self) -> Result<(), Error> {
        let _: Empty = try!(self.client.delete(&format!("/session/{}/window", self.session_id)));
        Ok(())
    }

    pub fn get_window_handles(&self) -> Result<Vec<String>, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/window/handles", self.session_id)));
        Ok(v.value)
    }

    pub fn find_element(&self, selector: &str, strategy: LocationStrategy) -> Result<Element, Error> {
        let cmd = FindElementCmd { using: strategy, value: selector};
        let v: Value<ElementReference> = try!(self.client.post(&format!("/session/{}/element", self.session_id), &cmd));
        Ok(Element::new(self, v.value.reference))
    }

    pub fn find_elements(&self, selector: &str, strategy: LocationStrategy) -> Result<Vec<Element>, Error> {
        let cmd = FindElementCmd { using: strategy, value: selector};
        let mut v: Value<Vec<ElementReference>> = try!(self.client.post(&format!("/session/{}/elements", self.session_id), &cmd));

        let mut elems = Vec::new();
        while let Some(er) = v.value.pop() {
            elems.push(Element::new(self, er.reference))
        }
        Ok(elems)
    }

    pub fn execute(&self, script: ExecuteCmd) -> Result<JsonValue, Error> {
        let v: Value<JsonValue> = try!(self.client.post(&format!("/session/{}/execute/sync", self.session_id), &script));
        Ok(v.value)
    }

    pub fn execute_async(&self, script: ExecuteCmd) -> Result<JsonValue, Error> {
        let v: Value<JsonValue> = try!(self.client.post(&format!("/session/{}/execute/async", self.session_id), &script));
        Ok(v.value)
    }

    pub fn switch_to_frame(&self, handle: JsonValue) -> Result<(), Error> {
        let _: Empty = try!(self.client.post(&format!("/session/{}/frame", self.session_id), &SwitchFrameCmd::from(handle)));
        Ok(())
    }
}

impl Drop for DriverSession {
    fn drop(&mut self) {
        if self.drop_session {
            let _: Result<Empty,_> = self.client.delete(&format!("/session/{}", self.session_id));
        }
    }
}

pub struct Element<'a> {
    session: &'a DriverSession,
    reference: String,
}

impl<'a> Element<'a> {
    fn new(s: &'a DriverSession, reference: String) -> Self {
        Element { session: s, reference: reference }
    }

    pub fn attribute(&self, name: &str) -> Result<String, Error> {
        let v: Value<_> = try!(self.session.client.get(&format!("/session/{}/element/{}/attribute/{}", self.session.session_id(), self.reference, name)));
        Ok(v.value)
    }

//    pub fn property(&self, name: &str) -> Result<String, Error> {
//        let v: Value<_> = try!(self.client.get(&format!("/session/{}/element/{}/property/{}", self.session_id, el.reference, name)));
//        Ok(v.value)
//    }

    pub fn css_value(&self, name: &str) -> Result<String, Error> {
        let v: Value<_> = try!(self.session.client.get(&format!("/session/{}/element/{}/css/{}", self.session.session_id(), self.reference, name)));
        Ok(v.value)
    }

    pub fn text(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.session.client.get(&format!("/session/{}/element/{}/text", self.session.session_id(), self.reference)));
        Ok(v.value)
    }

    /// Returns the tag name for this element
    pub fn name(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.session.client.get(&format!("/session/{}/element/{}/name", self.session.session_id(), self.reference)));
        Ok(v.value)
    }

    pub fn reference(&self) -> Result<JsonValue, Error> {
        serde_json::to_value(&ElementReference::from_str(&self.reference))
            .map_err(|err| Error::from(err))
    }

    /// Gets the `innerHTML` javascript attribute for this element. Some drivers can get
    /// this using regular attributes, in others it does not work. This method gets it
    /// executing a bit of javascript.
    pub fn inner_html(&self) -> Result<JsonValue, Error> {
        let script = ExecuteCmd {
            script: "return arguments[0].innerHTML;".to_owned(),
            args: vec![self.reference()?],
        };
        self.session.execute(script)
    }

    pub fn outer_html(&self) -> Result<JsonValue, Error> {
        let script = ExecuteCmd {
            script: "return arguments[0].outerHTML;".to_owned(),
            args: vec![self.reference()?],
        };
        self.session.execute(script)
    }
}

/// Switch the context of the current session to the given frame reference.
///
/// This structure implements Drop, and restores the session context
/// to the current top level window.
pub struct FrameContext<'a> {
    session: &'a DriverSession,
}

impl<'a> FrameContext<'a> {
    pub fn new(session: &'a DriverSession, frameref: JsonValue) -> Result<FrameContext<'a>, Error> {
        session.switch_to_frame(frameref)?;
        Ok(FrameContext { session: session })
    }
}

impl<'a> Drop for FrameContext<'a> {
    fn drop(&mut self) {
        let _ = self.session.switch_to_frame(JsonValue::Null);
    }
}
<commit_msg>find_elements no longer reverses order of elements<commit_after>#![deny(warnings)]

//! A library to drive web browsers using the webdriver
//! interface.

use std::convert::From;
use std::io::Read;
use std::io;
use std::fmt::{self, Debug};

extern crate hyper;
use hyper::client::*;
use hyper::Url;

extern crate serde;
use serde::Serialize;
use serde::de::DeserializeOwned;

extern crate serde_json;
pub use serde_json::Value as JsonValue;

#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate log;

#[macro_use]
extern crate derive_builder;

extern crate rand;

pub mod messages;
use messages::*;

pub mod firefox;

#[derive(Debug)]
pub enum Error {
    FailedToLaunchDriver,
    InvalidUrl,
    ConnectionError,
    Io(io::Error),
    JsonDecodeError(serde_json::Error),
    WebDriverError(WebDriverError),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::FailedToLaunchDriver => write!(f, "Unable to start browser driver"),
            Error::InvalidUrl => write!(f, "Invalid URL"),
            Error::ConnectionError => write!(f, "Error connecting to browser"),
            Error::Io(ref err) => write!(f, "{}", err),
            Error::JsonDecodeError(ref s) => write!(f, "Received invalid response from browser: {}", s),
            Error::WebDriverError(ref err) => write!(f, "Error: {}", err.message),
        }
    }
}

impl From<hyper::Error> for Error {
    fn from(_: hyper::Error) -> Error {
        Error::ConnectionError
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl From<serde_json::Error> for Error {
    fn from(e: serde_json::Error) -> Error {
        Error::JsonDecodeError(e)
    }
}

pub trait Driver {
    /// The url used to connect to this driver
    fn url(&self) -> &str;
    /// Start a session for this driver
    fn session(self) -> Result<DriverSession, Error> where Self : Sized + 'static {
        DriverSession::create_session(Box::new(self))
    }
}

/// A driver using a pre-existing WebDriver HTTP URL.
#[derive(Builder)]
#[builder(field(private))]
pub struct HttpDriver {
    #[builder(setter(into))]
    url: String,
}

impl Driver for HttpDriver {
    fn url(&self) -> &str { &self.url }
}

/// Wrapper around the hyper Client, that handles Json encoding and URL construction
struct HttpClient {
    baseurl: Url,
    http: Client,
}

impl HttpClient {
    pub fn new(baseurl: Url) -> Self {
        HttpClient {
            baseurl: baseurl,
            http: Client::new(),
        }
    }

    pub fn decode<D: DeserializeOwned + Debug>(res: &mut Response) -> Result<D, Error> {
        let mut data = String::new();
        try!(res.read_to_string(&mut data));
        debug!("result status: {}\n\
                body: '{}'", res.status, data);

        if !res.status.is_success() {
            let err: Value<WebDriverError> = try!(serde_json::from_str(&data));
            trace!("deserialize error result: {:#?}", err);
            return Err(Error::WebDriverError(err.value));
        }
        let response = serde_json::from_str(&data);
        trace!("deserialize result: {:#?}", response);
        Ok(response?)
    }

    pub fn get<D: DeserializeOwned + Debug>(&self, path: &str) -> Result<D, Error> {
        let url = try!(self.baseurl.join(path)
                           .map_err(|_| Error::InvalidUrl));
        debug!("GET {}", url);
        let mut res = try!(self.http.get(url)
                            .send());
        Self::decode(&mut res)
    }

    pub fn delete<D: DeserializeOwned + Debug>(&self, path: &str) -> Result<D, Error> {
        let url = try!(self.baseurl.join(path)
                           .map_err(|_| Error::InvalidUrl));
        debug!("DELETE {}", url);
        let mut res = try!(self.http.delete(url)
                            .send());
        Self::decode(&mut res)
    }

    pub fn post<D: DeserializeOwned + Debug, E: Serialize>(&self, path: &str, body: &E) -> Result<D, Error> {
        let url = try!(self.baseurl.join(path)
                           .map_err(|_| Error::InvalidUrl));
        let body_str = try!(serde_json::to_string(body));
        debug!("POST url: {}\n\
                body: {}", url, body_str);
        let mut res = try!(self.http.post(url)
                            .body(&body_str)
                            .send());
        Self::decode(&mut res)
    }
}

/// A WebDriver session.
///
/// By default the session is removed on `Drop`
pub struct DriverSession {
    driver: Box<Driver>,
    client: HttpClient,
    session_id: String,
    drop_session: bool,
}

impl DriverSession {
    /// Create a new session with the driver.
    pub fn create_session(driver: Box<Driver>)
    -> Result<DriverSession, Error>
    {
        let baseurl = Url::parse(driver.url())
                          .map_err(|_| Error::InvalidUrl)?;
        let client = HttpClient::new(baseurl);
        info!("Creating session at {}", client.baseurl);
        let sess = try!(Self::new_session(&client, &NewSessionCmd::new()));
        info!("Session {} created", sess.sessionId);
        Ok(DriverSession {
            driver: driver,
            client: client,
            session_id: sess.sessionId,
            drop_session: true,
        })
    }

    /// Use an existing session
    pub fn attach(url: &str, session_id: &str) -> Result<DriverSession, Error> {
        let driver = Box::new(HttpDriver {
            url: url.to_owned(),
        });
        let baseurl = try!(Url::parse(url).map_err(|_| Error::InvalidUrl));
        let mut s = DriverSession {
            driver: driver,
            client: HttpClient::new(baseurl),
            session_id: session_id.to_owned(),
            // This starts as false to avoid triggering the deletion call in Drop
            // if an error occurs
            drop_session: false,
        };
        info!("Connecting to session at {} with id {}", url, session_id);

        // FIXME /status would be preferable here to test the connection, but
        // it does not seem to work for the current geckodriver

        // We can fetch any value for the session to verify it exists.
        // The page URL will work.
        let _ = s.get_current_url()?;

        info!("Connected to existing session {}", s.session_id);
        // The session exists, enable session deletion on Drop
        s.drop_session = true;
        Ok(s)
    }

    pub fn session_id(&self) -> &str {
        &self.session_id
    }

    /// Whether to remove the session on Drop, the default is true
    pub fn drop_session(&mut self, drop: bool) {
        self.drop_session = drop;
    }

    /// Create a new webdriver session
    fn new_session(client: &HttpClient, params: &NewSessionCmd) -> Result<Session, Error> {
        let resp: Value<Session> = try!(client.post("/session", &params));
        Ok(resp.value)
    }

    /// Navigate to the given URL
    pub fn go(&self, url: &str) -> Result<(), Error> {
        let params = GoCmd { url: url.to_string() };
        let _: Empty = try!(self.client.post(&format!("/session/{}/url", &self.session_id), &params));
        Ok(())
    }

    pub fn get_current_url(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/url", self.session_id)));
        Ok(v.value)
    }

    pub fn back(&self) -> Result<(), Error> {
        let _: Empty = try!(self.client.post(&format!("/session/{}/back", self.session_id), &Empty {}));
        Ok(())
    }

    pub fn forward(&self) -> Result<(), Error> {
        let _: Empty = try!(self.client.post(&format!("/session/{}/forward", self.session_id), &Empty {}));
        Ok(())
    }

    pub fn refresh(&self) -> Result<(), Error> {
        let _: Empty = try!(self.client.post(&format!("/session/{}/refresh", self.session_id), &Empty {}));
        Ok(())
    }

    pub fn get_page_source(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/source", self.session_id)));
        Ok(v.value)
    }

    pub fn get_title(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/title", self.session_id)));
        Ok(v.value)
    }

    /// Get all cookies
    pub fn get_cookies(&self) -> Result<Vec<Cookie>, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/cookie", self.session_id)));
        Ok(v.value)
    }

    pub fn get_window_handle(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/window", self.session_id)));
        Ok(v.value)
    }

    pub fn switch_window(&mut self, handle: &str) -> Result<(), Error> {
        let _: Empty = try!(self.client.post(&format!("/session/{}/window", self.session_id), &SwitchWindowCmd::from(handle)));
        Ok(())
    }

    pub fn close_window(&mut self) -> Result<(), Error> {
        let _: Empty = try!(self.client.delete(&format!("/session/{}/window", self.session_id)));
        Ok(())
    }

    pub fn get_window_handles(&self) -> Result<Vec<String>, Error> {
        let v: Value<_> = try!(self.client.get(&format!("/session/{}/window/handles", self.session_id)));
        Ok(v.value)
    }

    pub fn find_element(&self, selector: &str, strategy: LocationStrategy) -> Result<Element, Error> {
        let cmd = FindElementCmd { using: strategy, value: selector};
        let v: Value<ElementReference> = try!(self.client.post(&format!("/session/{}/element", self.session_id), &cmd));
        Ok(Element::new(self, v.value.reference))
    }

    pub fn find_elements(&self, selector: &str, strategy: LocationStrategy) -> Result<Vec<Element>, Error> {
        let cmd = FindElementCmd { using: strategy, value: selector};
        let v: Value<Vec<ElementReference>> = try!(self.client.post(&format!("/session/{}/elements", self.session_id), &cmd));

        Ok(v.value.into_iter().map(|er| Element::new(self, er.reference)).collect())
    }

    pub fn execute(&self, script: ExecuteCmd) -> Result<JsonValue, Error> {
        let v: Value<JsonValue> = try!(self.client.post(&format!("/session/{}/execute/sync", self.session_id), &script));
        Ok(v.value)
    }

    pub fn execute_async(&self, script: ExecuteCmd) -> Result<JsonValue, Error> {
        let v: Value<JsonValue> = try!(self.client.post(&format!("/session/{}/execute/async", self.session_id), &script));
        Ok(v.value)
    }

    pub fn switch_to_frame(&self, handle: JsonValue) -> Result<(), Error> {
        let _: Empty = try!(self.client.post(&format!("/session/{}/frame", self.session_id), &SwitchFrameCmd::from(handle)));
        Ok(())
    }
}

impl Drop for DriverSession {
    fn drop(&mut self) {
        if self.drop_session {
            let _: Result<Empty,_> = self.client.delete(&format!("/session/{}", self.session_id));
        }
    }
}

pub struct Element<'a> {
    session: &'a DriverSession,
    reference: String,
}

impl<'a> Element<'a> {
    fn new(s: &'a DriverSession, reference: String) -> Self {
        Element { session: s, reference: reference }
    }

    pub fn attribute(&self, name: &str) -> Result<String, Error> {
        let v: Value<_> = try!(self.session.client.get(&format!("/session/{}/element/{}/attribute/{}", self.session.session_id(), self.reference, name)));
        Ok(v.value)
    }

//    pub fn property(&self, name: &str) -> Result<String, Error> {
//        let v: Value<_> = try!(self.client.get(&format!("/session/{}/element/{}/property/{}", self.session_id, el.reference, name)));
//        Ok(v.value)
//    }

    pub fn css_value(&self, name: &str) -> Result<String, Error> {
        let v: Value<_> = try!(self.session.client.get(&format!("/session/{}/element/{}/css/{}", self.session.session_id(), self.reference, name)));
        Ok(v.value)
    }

    pub fn text(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.session.client.get(&format!("/session/{}/element/{}/text", self.session.session_id(), self.reference)));
        Ok(v.value)
    }

    /// Returns the tag name for this element
    pub fn name(&self) -> Result<String, Error> {
        let v: Value<_> = try!(self.session.client.get(&format!("/session/{}/element/{}/name", self.session.session_id(), self.reference)));
        Ok(v.value)
    }

    pub fn reference(&self) -> Result<JsonValue, Error> {
        serde_json::to_value(&ElementReference::from_str(&self.reference))
            .map_err(|err| Error::from(err))
    }

    /// Gets the `innerHTML` javascript attribute for this element. Some drivers can get
    /// this using regular attributes, in others it does not work. This method gets it
    /// executing a bit of javascript.
    pub fn inner_html(&self) -> Result<JsonValue, Error> {
        let script = ExecuteCmd {
            script: "return arguments[0].innerHTML;".to_owned(),
            args: vec![self.reference()?],
        };
        self.session.execute(script)
    }

    pub fn outer_html(&self) -> Result<JsonValue, Error> {
        let script = ExecuteCmd {
            script: "return arguments[0].outerHTML;".to_owned(),
            args: vec![self.reference()?],
        };
        self.session.execute(script)
    }
}

/// Switch the context of the current session to the given frame reference.
///
/// This structure implements Drop, and restores the session context
/// to the current top level window.
pub struct FrameContext<'a> {
    session: &'a DriverSession,
}

impl<'a> FrameContext<'a> {
    pub fn new(session: &'a DriverSession, frameref: JsonValue) -> Result<FrameContext<'a>, Error> {
        session.switch_to_frame(frameref)?;
        Ok(FrameContext { session: session })
    }
}

impl<'a> Drop for FrameContext<'a> {
    fn drop(&mut self) {
        let _ = self.session.switch_to_frame(JsonValue::Null);
    }
}
<|endoftext|>


<commit_before>use core::mem::{transmute};

/// Value that is in rax after multiboot jumps to our entry point
pub const SIGNATURE_RAX: u64 = 0x2BADB002;

#[derive(Debug)]
pub enum MemType {
    RAM = 1,
    Unusable = 2,
}

pub struct Multiboot<'a> {
    header: &'a MultibootHeader,
    paddr_to_vaddr: fn(u64) -> u64,
}

#[derive(Debug)]
#[repr(packed)]
struct MultibootHeader {
    flags: u32,

    mem_lower: u32,
    mem_upper: u32,

    boot_device: u32,
    cmdline: u32,

    mods_count: u32,
    mods_addr: u32,

    elf_symbols: ElfSymbols,

    mmap_length: u32,
    mmap_addr: u32,
}

#[derive(Debug)]
#[repr(packed)]
struct MemEntry {
    size: u32,
    base_addr: u64,
    length: u64,
    mtype: u32
}

#[derive(Debug)]
#[repr(packed)]
struct ElfSymbols {
    num: u32,
    size: u32,
    addr: u32,
    shndx: u32,
}

impl<'a> Multiboot<'a> {

    /// Initializes the multiboot structure
    pub fn new(mboot_ptr: u64, paddr_to_vaddr: fn(paddr: u64) -> u64) -> Multiboot<'a> {
        let header = paddr_to_vaddr(mboot_ptr);
        let mb: &MultibootHeader = unsafe { transmute::<u64, &MultibootHeader>(header) };

        Multiboot { header: mb, paddr_to_vaddr: paddr_to_vaddr }
    }

    /// Discovers all memory region in the multiboot memory map
    pub fn find_memory(&'a self, discovery_callback: fn(base: u64, length: u64, MemType))
    {
        let paddr_to_vaddr = self.paddr_to_vaddr;

        let mut current = self.header.mmap_addr;
        let end = self.header.mmap_addr + self.header.mmap_length;
        while current < end
        {
            let memory_region: &MemEntry = unsafe { transmute::<u64, &MemEntry>(paddr_to_vaddr(current as u64)) };

            let mtype = match memory_region.mtype {
                1 => MemType::RAM,
                2 => MemType::Unusable,
                _ => MemType::Unusable
            };

            discovery_callback(memory_region.base_addr, memory_region.length, mtype);
            current += memory_region.size + 4;
        }
    }

}<commit_msg>Ensure no_std.<commit_after>#![feature(no_std)]
#![feature(core)]
extern crate core;

use core::mem::{transmute};

/// Value that is in rax after multiboot jumps to our entry point
pub const SIGNATURE_RAX: u64 = 0x2BADB002;

#[derive(Debug)]
pub enum MemType {
    RAM = 1,
    Unusable = 2,
}

pub struct Multiboot<'a> {
    header: &'a MultibootHeader,
    paddr_to_vaddr: fn(u64) -> u64,
}

#[derive(Debug)]
#[repr(packed)]
struct MultibootHeader {
    flags: u32,

    mem_lower: u32,
    mem_upper: u32,

    boot_device: u32,
    cmdline: u32,

    mods_count: u32,
    mods_addr: u32,

    elf_symbols: ElfSymbols,

    mmap_length: u32,
    mmap_addr: u32,
}

#[derive(Debug)]
#[repr(packed)]
struct MemEntry {
    size: u32,
    base_addr: u64,
    length: u64,
    mtype: u32
}

#[derive(Debug)]
#[repr(packed)]
struct ElfSymbols {
    num: u32,
    size: u32,
    addr: u32,
    shndx: u32,
}

impl<'a> Multiboot<'a> {

    /// Initializes the multiboot structure
    pub fn new(mboot_ptr: u64, paddr_to_vaddr: fn(paddr: u64) -> u64) -> Multiboot<'a> {
        let header = paddr_to_vaddr(mboot_ptr);
        let mb: &MultibootHeader = unsafe { transmute::<u64, &MultibootHeader>(header) };

        Multiboot { header: mb, paddr_to_vaddr: paddr_to_vaddr }
    }

    /// Discovers all memory region in the multiboot memory map
    pub fn find_memory(&'a self, discovery_callback: fn(base: u64, length: u64, MemType))
    {
        let paddr_to_vaddr = self.paddr_to_vaddr;

        let mut current = self.header.mmap_addr;
        let end = self.header.mmap_addr + self.header.mmap_length;
        while current < end
        {
            let memory_region: &MemEntry = unsafe { transmute::<u64, &MemEntry>(paddr_to_vaddr(current as u64)) };

            let mtype = match memory_region.mtype {
                1 => MemType::RAM,
                2 => MemType::Unusable,
                _ => MemType::Unusable
            };

            discovery_callback(memory_region.base_addr, memory_region.length, mtype);
            current += memory_region.size + 4;
        }
    }

}
<|endoftext|>


<commit_before>#![doc(html_root_url = "http://www.rust-ci.org/tari/vorbisfile.rs/doc/libvorbisfile/")]

#![deny(dead_code, missing_docs)]
#![feature(unsafe_destructor)]

//! Ogg Vorbis file decoding, library bindings.

extern crate libc;
use libc::{c_void, c_int, c_long, size_t};

use std::c_str::CString;
use std::mem;
use std::str;
use std::ptr;
use std::raw;
use std::slice::from_raw_mut_buf;

#[allow(dead_code, non_snake_case)]
mod ffi;

/// `OVError` or `T`.
pub type OVResult<T> = Result<T, OVError>;

/// Decode error.
#[deriving(Show, Clone)]
pub enum OVError {
    /// Reached end of file.
    EndOfStream,
    /// Encounted missing or corrupt data.
    ///
    /// Recovery from this error is usually automatic and is returned for
    /// informational purposes only.
    StreamInterrupted,
    /// I/O error while reading compressed data to decode.
    ReadError,
    /// Internal inconsistency in encode or decode state. Recovery impossible.
    InternalFault,
    /// Feature not implemented.
    NotImplemented,
    /// User passed an invalid argument to a function.
    InvalidArgument,
    /// Provided data is not recognized as Ogg Vorbis.
    NotVorbis,
    /// Provided data appears to be Ogg Vorbis but has a corrupt or
    /// indecipherable header.
    InvalidHeader,
    /// Bitstream format revision is not supported.
    UnsupportedVersion,
    /// The specified Vorbis link exists but is corrupt.
    CorruptLink,
    /// The stream is not seekable.
    NotSeekable,
}

impl std::error::Error for OVError {
    fn description(&self) -> &str {
        match *self {
            OVError::EndOfStream => "End of stream",
            OVError::StreamInterrupted => "Stream interrupted",
            OVError::ReadError => "Read error",
            OVError::InternalFault => "Internal library fault",
            OVError::NotImplemented => "Feature not implemented",
            OVError::InvalidArgument => "Invalid argument",
            OVError::NotVorbis => "Not a Vorbis stream",
            OVError::InvalidHeader => "Invalid Vorbis header",
            OVError::UnsupportedVersion => "Bitstream format revision not supported",
            OVError::CorruptLink => "Vorbis link is corrupt",
            OVError::NotSeekable => "Not seekable",
        }
    }
}

impl Copy for OVError { }

impl OVError {
    fn from_native(code: c_int) -> OVError {
        match code {
            ffi::OV_HOLE => OVError::StreamInterrupted,
            ffi::OV_EREAD => OVError::ReadError,
            ffi::OV_EFAULT => OVError::InternalFault,
            ffi::OV_EIMPL => OVError::NotImplemented,
            ffi::OV_EINVAL => OVError::InvalidArgument,
            ffi::OV_ENOTVORBIS => OVError::NotVorbis,
            ffi::OV_EBADHEADER => OVError::InvalidHeader,
            ffi::OV_EVERSION => OVError::UnsupportedVersion,
            ffi::OV_EBADLINK => OVError::CorruptLink,
            ffi::OV_ENOSEEK => OVError::NotSeekable,
            x => panic!("Unexpected OVError code: {}", x)
        }
    }
}

/// Ogg Vorbis file decoder.
pub struct VorbisFile<R> {
    src: R,
    decoder: ffi::OggVorbis_File,
    // Totally not 'static, but need a lifetime specifier to get a slice.
    channels: Vec<raw::Slice<f32>>,
}

/// File metadata
pub struct Comments<'a> {
    /// The Vorbis implementation that encoded the stream.
    pub vendor: CString,
    /// User-specified key-value pairs of the form KEY=VALUE.
    pub comments: Vec<&'a str>
}

#[allow(unused_variables)]
extern "C" fn seek(datasource: *mut c_void, offset: i64, whence: c_int) -> c_int {
    // TODO permit seeking
    -1
}
#[allow(unused_variables)]
extern "C" fn close(datasource: *mut c_void) -> c_int {
    // No need to do anything. VorbisFile owns the Reader we're using.
    0
}
#[allow(unused_variables)]
extern "C" fn tell(datasource: *mut c_void) -> c_long {
    // TODO permit seeking
    -1
}

// Don't expose ov_fopen and friends because that won't play nicely
// with non-libnative runtime.
impl<R: Reader> VorbisFile<R> {
    /// Ensures the FFI struct is consistent for callback invocation.
    ///
    /// Because the user may move this struct, the `datasource` pointer
    /// passed back to FFI callbacks might be invalidated. This function
    /// should be called before FFI actions that might fire callbacks to ensure
    /// the self-pointer is valid.
    fn callback_setup(&mut self) {
        let ds = self as *mut _ as *mut c_void;
        self.decoder.datasource = ds;
    }

    /// Create a Ogg Vorbis decoder.
    pub fn new(src: R) -> OVResult<VorbisFile<R>> {
        let mut vf = VorbisFile {
            src: src,
            decoder: unsafe { mem::uninitialized() },
            channels: Vec::new()
        };
        let callbacks = ffi::ov_callbacks {
            read: VorbisFile::<R>::read,
            seek: seek,
            tell: tell,
            close: close,
        };

        let status = unsafe {
            ffi::ov_open_callbacks(&mut vf.src as *mut _ as *mut c_void,
                                   &mut vf.decoder as *mut _,
                                   ptr::null_mut(), 0, callbacks)
        };

        match status {
            0 => Ok(vf),
            f => {
                // Must not run the destructor. decoder is still uninitialized.
                // XXX if VorbisFile's Drop impl does more than freeing self.decoder,
                // this must also be updated.
                unsafe {
                    mem::forget(vf);
                }
                Err(OVError::from_native(f))
            }
        }
    }

    /// Gets the comment struct for the specified bitstream.
    ///
    /// For nonseekable streams, returns the comments for the current
    /// bitstream. Otherwise, specify bitstream -1 to get the current
    /// bitstream.
    pub fn comment<'a>(&'a mut self, link: int) -> Option<Comments<'a>> {
        let cm = unsafe {
            match ffi::ov_comment(&mut self.decoder, link as c_int).as_ref() {
                Some(r) => r,
                None => return None
            }
        };

        unsafe fn make_str<'a>(data: *const u8, len: uint) -> Option<&'a str> {
            let slice = raw::Slice {
                data: data,
                len: len
            };
            str::from_utf8(mem::transmute(slice))
        }

        Some(Comments {
            vendor: unsafe {
                CString::new(cm.vendor as *const _, false)
            },
            comments: unsafe {
                let mut v = Vec::with_capacity(cm.comments as uint);
                for i in range(0, (*cm).comments) {
                    let len = *cm.comment_lengths.offset(i as int);
                    match make_str(*cm.user_comments.offset(i as int) as *const _,
                                   len as uint) {
                        Some(s) => {
                            v.push(s);
                        }
                        None => {
                            // Ignore. Vorbis specifies all comment data is valid
                            // UTF-8, but we need to protect against invalid input
                        }
                    }
                }
                v
            }
        })
    }

    /// Decode a block of samples.
    ///
    /// The emitted values are a slice of channels, each containing an equal
    /// number of samples.
    pub fn decode<'a>(&'a mut self) -> OVResult<&'a mut [&'a mut [f32]]> {
        let max_samples = 4096;
        self.callback_setup();
        let mut sample_buffer: *mut *mut f32 = unsafe {
            mem::uninitialized()
        };
        let mut bitstream_idx: c_int = unsafe {
            mem::uninitialized()
        };

        let n_samples = unsafe {
            match ffi::ov_read_float(&mut self.decoder, &mut sample_buffer,
                                     max_samples, &mut bitstream_idx) {
                0 => {
                    return Err(OVError::EndOfStream);
                }
                x if x < 0 => {
                    return Err(OVError::from_native(x as c_int));
                }
                x => x
            }
        };
        let n_channels = unsafe {
            (*ffi::ov_info(&mut self.decoder, bitstream_idx)).channels
        };

        self.channels.truncate(0);
        for i in range(0, n_channels) {
            unsafe {
                let channel_buffer = *sample_buffer.offset(i as int);
                let channel_slice = raw::Slice::<f32> {
                    data: channel_buffer as *const f32,
                    len: n_samples as uint
                };
                self.channels.push(channel_slice);
            };
        }
        Ok(unsafe {
            mem::transmute(self.channels.as_slice())
        })
    }

    /// Read `nmemb` items into `ptr` of `size` bytes each.
    ///
    /// If 0 is returned, error status is implied by errno. If nonzero, there was
    /// a read error. Otherwise, reached EOF.
    extern "C" fn read(buffer: *mut c_void, size: size_t, nmemb: size_t,
                       datasource: *mut c_void) -> size_t {
        let vf: &mut VorbisFile<R> = unsafe { mem::transmute(datasource) };
        let ptr = buffer as *mut u8;

        for i in range(0, nmemb) {
            let more = unsafe {
                let bufp = ptr.offset(i as int);
                let buf = from_raw_mut_buf(&bufp, size as uint);
                match vf.src.read_at_least(size as uint, buf) {
                    Ok(_) => true,
                    // Assume errno is set under the covers.
                    Err(_) => false
                }
            };
            if !more {
                // Got error, which might be EOF.
                return i;
            }
        }
        // Completed successfully
        return nmemb;
    }
}

#[unsafe_destructor]
impl<R: Reader> Drop for VorbisFile<R> {
    fn drop(&mut self) {
        self.callback_setup();
        unsafe {
            ffi::ov_clear(&mut self.decoder);
        }
    }
}
<commit_msg>str::from_utf8 now returns Result<commit_after>#![doc(html_root_url = "http://www.rust-ci.org/tari/vorbisfile.rs/doc/libvorbisfile/")]

#![deny(dead_code, missing_docs)]
#![feature(unsafe_destructor)]

//! Ogg Vorbis file decoding, library bindings.

extern crate libc;
use libc::{c_void, c_int, c_long, size_t};

use std::c_str::CString;
use std::mem;
use std::str;
use std::ptr;
use std::raw;
use std::slice::from_raw_mut_buf;

#[allow(dead_code, non_snake_case)]
mod ffi;

/// `OVError` or `T`.
pub type OVResult<T> = Result<T, OVError>;

/// Decode error.
#[deriving(Show, Clone)]
pub enum OVError {
    /// Reached end of file.
    EndOfStream,
    /// Encounted missing or corrupt data.
    ///
    /// Recovery from this error is usually automatic and is returned for
    /// informational purposes only.
    StreamInterrupted,
    /// I/O error while reading compressed data to decode.
    ReadError,
    /// Internal inconsistency in encode or decode state. Recovery impossible.
    InternalFault,
    /// Feature not implemented.
    NotImplemented,
    /// User passed an invalid argument to a function.
    InvalidArgument,
    /// Provided data is not recognized as Ogg Vorbis.
    NotVorbis,
    /// Provided data appears to be Ogg Vorbis but has a corrupt or
    /// indecipherable header.
    InvalidHeader,
    /// Bitstream format revision is not supported.
    UnsupportedVersion,
    /// The specified Vorbis link exists but is corrupt.
    CorruptLink,
    /// The stream is not seekable.
    NotSeekable,
}

impl std::error::Error for OVError {
    fn description(&self) -> &str {
        match *self {
            OVError::EndOfStream => "End of stream",
            OVError::StreamInterrupted => "Stream interrupted",
            OVError::ReadError => "Read error",
            OVError::InternalFault => "Internal library fault",
            OVError::NotImplemented => "Feature not implemented",
            OVError::InvalidArgument => "Invalid argument",
            OVError::NotVorbis => "Not a Vorbis stream",
            OVError::InvalidHeader => "Invalid Vorbis header",
            OVError::UnsupportedVersion => "Bitstream format revision not supported",
            OVError::CorruptLink => "Vorbis link is corrupt",
            OVError::NotSeekable => "Not seekable",
        }
    }
}

impl Copy for OVError { }

impl OVError {
    fn from_native(code: c_int) -> OVError {
        match code {
            ffi::OV_HOLE => OVError::StreamInterrupted,
            ffi::OV_EREAD => OVError::ReadError,
            ffi::OV_EFAULT => OVError::InternalFault,
            ffi::OV_EIMPL => OVError::NotImplemented,
            ffi::OV_EINVAL => OVError::InvalidArgument,
            ffi::OV_ENOTVORBIS => OVError::NotVorbis,
            ffi::OV_EBADHEADER => OVError::InvalidHeader,
            ffi::OV_EVERSION => OVError::UnsupportedVersion,
            ffi::OV_EBADLINK => OVError::CorruptLink,
            ffi::OV_ENOSEEK => OVError::NotSeekable,
            x => panic!("Unexpected OVError code: {}", x)
        }
    }
}

/// Ogg Vorbis file decoder.
pub struct VorbisFile<R> {
    src: R,
    decoder: ffi::OggVorbis_File,
    // Totally not 'static, but need a lifetime specifier to get a slice.
    channels: Vec<raw::Slice<f32>>,
}

/// File metadata
pub struct Comments<'a> {
    /// The Vorbis implementation that encoded the stream.
    pub vendor: CString,
    /// User-specified key-value pairs of the form KEY=VALUE.
    pub comments: Vec<&'a str>
}

#[allow(unused_variables)]
extern "C" fn seek(datasource: *mut c_void, offset: i64, whence: c_int) -> c_int {
    // TODO permit seeking
    -1
}
#[allow(unused_variables)]
extern "C" fn close(datasource: *mut c_void) -> c_int {
    // No need to do anything. VorbisFile owns the Reader we're using.
    0
}
#[allow(unused_variables)]
extern "C" fn tell(datasource: *mut c_void) -> c_long {
    // TODO permit seeking
    -1
}

// Don't expose ov_fopen and friends because that won't play nicely
// with non-libnative runtime.
impl<R: Reader> VorbisFile<R> {
    /// Ensures the FFI struct is consistent for callback invocation.
    ///
    /// Because the user may move this struct, the `datasource` pointer
    /// passed back to FFI callbacks might be invalidated. This function
    /// should be called before FFI actions that might fire callbacks to ensure
    /// the self-pointer is valid.
    fn callback_setup(&mut self) {
        let ds = self as *mut _ as *mut c_void;
        self.decoder.datasource = ds;
    }

    /// Create a Ogg Vorbis decoder.
    pub fn new(src: R) -> OVResult<VorbisFile<R>> {
        let mut vf = VorbisFile {
            src: src,
            decoder: unsafe { mem::uninitialized() },
            channels: Vec::new()
        };
        let callbacks = ffi::ov_callbacks {
            read: VorbisFile::<R>::read,
            seek: seek,
            tell: tell,
            close: close,
        };

        let status = unsafe {
            ffi::ov_open_callbacks(&mut vf.src as *mut _ as *mut c_void,
                                   &mut vf.decoder as *mut _,
                                   ptr::null_mut(), 0, callbacks)
        };

        match status {
            0 => Ok(vf),
            f => {
                // Must not run the destructor. decoder is still uninitialized.
                // XXX if VorbisFile's Drop impl does more than freeing self.decoder,
                // this must also be updated.
                unsafe {
                    mem::forget(vf);
                }
                Err(OVError::from_native(f))
            }
        }
    }

    /// Gets the comment struct for the specified bitstream.
    ///
    /// For nonseekable streams, returns the comments for the current
    /// bitstream. Otherwise, specify bitstream -1 to get the current
    /// bitstream.
    pub fn comment<'a>(&'a mut self, link: int) -> Option<Comments<'a>> {
        let cm = unsafe {
            match ffi::ov_comment(&mut self.decoder, link as c_int).as_ref() {
                Some(r) => r,
                None => return None
            }
        };

        unsafe fn make_str<'a>(data: *const u8, len: uint) -> Option<&'a str> {
            let slice = raw::Slice {
                data: data,
                len: len
            };
            str::from_utf8(mem::transmute(slice)).ok()
        }

        Some(Comments {
            vendor: unsafe {
                CString::new(cm.vendor as *const _, false)
            },
            comments: unsafe {
                let mut v = Vec::with_capacity(cm.comments as uint);
                for i in range(0, (*cm).comments) {
                    let len = *cm.comment_lengths.offset(i as int);
                    match make_str(*cm.user_comments.offset(i as int) as *const _,
                                   len as uint) {
                        Some(s) => {
                            v.push(s);
                        }
                        None => {
                            // Ignore. Vorbis specifies all comment data is valid
                            // UTF-8, but we need to protect against invalid input
                        }
                    }
                }
                v
            }
        })
    }

    /// Decode a block of samples.
    ///
    /// The emitted values are a slice of channels, each containing an equal
    /// number of samples.
    pub fn decode<'a>(&'a mut self) -> OVResult<&'a mut [&'a mut [f32]]> {
        let max_samples = 4096;
        self.callback_setup();
        let mut sample_buffer: *mut *mut f32 = unsafe {
            mem::uninitialized()
        };
        let mut bitstream_idx: c_int = unsafe {
            mem::uninitialized()
        };

        let n_samples = unsafe {
            match ffi::ov_read_float(&mut self.decoder, &mut sample_buffer,
                                     max_samples, &mut bitstream_idx) {
                0 => {
                    return Err(OVError::EndOfStream);
                }
                x if x < 0 => {
                    return Err(OVError::from_native(x as c_int));
                }
                x => x
            }
        };
        let n_channels = unsafe {
            (*ffi::ov_info(&mut self.decoder, bitstream_idx)).channels
        };

        self.channels.truncate(0);
        for i in range(0, n_channels) {
            unsafe {
                let channel_buffer = *sample_buffer.offset(i as int);
                let channel_slice = raw::Slice::<f32> {
                    data: channel_buffer as *const f32,
                    len: n_samples as uint
                };
                self.channels.push(channel_slice);
            };
        }
        Ok(unsafe {
            mem::transmute(self.channels.as_slice())
        })
    }

    /// Read `nmemb` items into `ptr` of `size` bytes each.
    ///
    /// If 0 is returned, error status is implied by errno. If nonzero, there was
    /// a read error. Otherwise, reached EOF.
    extern "C" fn read(buffer: *mut c_void, size: size_t, nmemb: size_t,
                       datasource: *mut c_void) -> size_t {
        let vf: &mut VorbisFile<R> = unsafe { mem::transmute(datasource) };
        let ptr = buffer as *mut u8;

        for i in range(0, nmemb) {
            let more = unsafe {
                let bufp = ptr.offset(i as int);
                let buf = from_raw_mut_buf(&bufp, size as uint);
                match vf.src.read_at_least(size as uint, buf) {
                    Ok(_) => true,
                    // Assume errno is set under the covers.
                    Err(_) => false
                }
            };
            if !more {
                // Got error, which might be EOF.
                return i;
            }
        }
        // Completed successfully
        return nmemb;
    }
}

#[unsafe_destructor]
impl<R: Reader> Drop for VorbisFile<R> {
    fn drop(&mut self) {
        self.callback_setup();
        unsafe {
            ffi::ov_clear(&mut self.decoder);
        }
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(regex_macros)]
extern crate regex;

use std::ops::Index;
use regex::Regex;

pub struct ReIdx(Regex);

impl ReIdx {
    pub fn new(re: Regex) -> ReIdx {
        ReIdx(re)
    }
}

impl Index<ReIdx> for str {
    type Output = str;
    fn index<'a>(&'a self, index: &ReIdx) -> &'a str {
        match index.0.find(self) {
            Some((start, end)) => &self[start..end],
            None => &self[..0]
        }
    }
}

#[test]
fn test_index_by_regex() {
    let re = ReIdx::new(regex!("^ab+"));
    assert_eq!("abb", &"abbcccdddd"[re]);
    assert_eq!("", &"acccdddd"[re]);
}
<commit_msg>stability markers<commit_after>#![feature(plugin)]
#![plugin(regex_macros)]
extern crate regex;

use std::ops::Index;
use regex::Regex;

#[stable(since="0.1.0")]
pub struct ReIdx(Regex);

#[unstable]
impl ReIdx {
    #[unstable]
    pub fn new(re: Regex) -> ReIdx {
        ReIdx(re)
    }
}

#[stable(since="0.1.0")]
impl Index<ReIdx> for str {
    type Output = str;
    fn index<'a>(&'a self, index: &ReIdx) -> &'a str {
        match index.0.find(self) {
            Some((start, end)) => &self[start..end],
            None => &self[..0]
        }
    }
}

#[test]
fn test_index_by_regex() {
    let re = ReIdx::new(regex!("^ab+"));
    assert_eq!("abb", &"abbcccdddd"[re]);
    assert_eq!("", &"acccdddd"[re]);
}
<|endoftext|>


<commit_before>// Copyright 2017 Daniel P. Clark & other digits Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
//
#![deny(missing_docs,trivial_casts,trivial_numeric_casts,
        missing_debug_implementations, missing_copy_implementations,
        unsafe_code,unstable_features,unused_import_braces,unused_qualifications)
]
//! # digits
//!
//! The digits crate is a linked list implementation of a score card flipper.  But
//! in this case it's with any characters you want and you can enumerate through
//! possibilities beyond the numeric limits intrinsic in basic numerc types like `u64`.
//!
//! Primary use case would be brute forcing character sequences.
extern crate base_custom;
use base_custom::BaseCustom;
use std::fmt;

/// # struct Digits
///
/// This struct acts similar to a full number with a custom numeric character base.
/// But the underlying implementation is a linked list where all the methods recurse
/// as far as need to to implement the operations.
#[derive(Clone)]
pub struct Digits<'a> {
  mapping: &'a BaseCustom<char>,
  digit: u64,
  left: Option<Box<Digits<'a>>>,
}

impl<'a> Digits<'a> {
  /// `new` creates a new Digits instance with the provided character set and value.
  ///
  /// The first parameter must be a BaseCustom object which defines and maps all values.
  /// The second parameter is a string value with all valid characters from the BaseCustom set.
  ///
  /// You can view the numbers current value at any time with `to_s()` or `to_string()`.
  pub fn new<S>(mapping: &'a BaseCustom<char>, number: S) -> Digits<'a>
  where S: Into<String> {
    let number = number.into();
    if number.is_empty() { return Digits { mapping: mapping, digit: 0, left: None }; };
    let (last, rest) = {
      let mut n = number.chars().rev();
      (n.next().unwrap(), n.rev().collect::<String>())
    };

    let continuation = {
      if rest.is_empty() {
        None
      } else {
        Some(Box::new(Digits::new(&mapping, rest)))
      }
    };
    Digits {
      mapping: mapping,
      digit: mapping.decimal(last.to_string()),
      left: continuation,
    }
  }

  /// `replicate` — alias for clone (useful for unboxing)
  pub fn replicate(self) -> Self { self.clone() }

  /// `propagate` creates a new number from the same underlying numeric base
  pub fn propagate<S>(&self, number: S) -> Self
  where S: Into<String> {
    Digits::new(self.mapping, number)
  }

  /// Gives the full value of all digits within the linked list as a String.
  pub fn to_s(&self) -> String {
    let num = self.mapping.gen(self.digit);
    match &self.left {
      &None => format!("{}", num),
      &Some(ref bx) => format!("{}{}", bx.to_s(), num),
    }
  }

  /// Gives the full value of all digits within the linked list as a String.
  pub fn to_string(&self) -> String {
    self.to_s()
  }

  // the way to recurse and process Digits
  fn head_tail(self) -> (u64, Option<Box<Self>>) {
    match self.left {
      Some(bx) => (self.digit, Some(bx)),
      None => (self.digit, None),
    }
  }

  // logic for setting left linked list continuation
  fn set_left(&mut self, d: Digits<'a>) {
    if d.is_end() {
      self.left = None;
    } else {
      self.left = Some(Box::new(d));
    }
  }

  /// `length` returns a `usize` of the total linked list length.
  pub fn length(&self) -> usize {
    match &self.left {
      &None => 1,
      &Some(ref l) => { l.length() + 1 }
    }
  }

  /// `zero` returns a Digits instance with value of zero and the current character mapping.
  pub fn zero(&self) -> Self {
    Digits::new_zero(self.mapping)
  }

  /// `new_zero` returns a Digits instance with value of zero and the current character mapping.
  pub fn new_zero(mapping: &'a BaseCustom<char>) -> Self {
    Digits { mapping: mapping, digit: 0, left: None }
  }

  /// `is_zero` returns bool value of if the number is zero
  pub fn is_zero(&self) -> bool {
    if self.digit != 0 { return false }
    match &self.left {
      &None => { true },
      &Some(ref bx) => { bx.is_zero() },
    }
  }

  /// `pinky` is the smallest digit.
  /// a.k.a. current digit in the linked list.
  /// a.k.a. the right most digit.
  /// This will be a char value for that digit.
  pub fn pinky(&self) -> char {
    self.mapping.char(self.digit as usize).unwrap()
  }

  /// `one` returns a Digits instance with value of one and the current character mapping.
  pub fn one(&self) -> Self {
    Digits::new_one(self.mapping)
  }

  /// `new_one` returns a Digits instance with value of one and the current character mapping.
  pub fn new_one(mapping: &'a BaseCustom<char>) -> Self {
    Digits { mapping: mapping, digit: 1, left: None }
  }

  // A non-consuming quick end check.
  // More efficient than calling `is_zero` when this applies.
  fn is_end(&self) -> bool {
    self.digit == 0 && match self.left { None => true, _ => false }
  }

  /// Add two Digits instances together.  The one the `add` method is called on
  /// must be mutable and modifies itself.  The other is consumed.
  ///
  /// Returns a clone of the updated `Self` as well.
  pub fn add(&mut self, other: Self) -> Self {
    assert!(self.mapping == other.mapping);
    if other.is_end() { return self.clone(); };
    let (last, rest) = other.head_tail();

    // sums current single digit
    let added = self.propagate(self.mapping.gen(last + self.digit));
    let (l, r) = added.head_tail();
    self.digit = l;

    // sums for left
    let mut intermediate = Digits::new_zero(self.mapping);
    if let Some(dg) = r { intermediate.add(dg.replicate()); }
    if let Some(dg) = rest { intermediate.add(dg.replicate()); }

    let current_left = match self.left.clone() {
      None => { Box::new(self.zero()) },
      Some(bx) => { bx },
    }.as_ref().clone();

    self.set_left( intermediate.add(current_left).clone() );
    self.clone()
  }

  /// Multiply two Digits instances together.  The one the `mul` method is called on
  /// must be mutable and modifies itself.  The other is consumed.
  ///
  /// Returns a clone of the updated `Self` as well.
  pub fn mul(&mut self, other: Self) -> Self {
    self.multiply(other, 0)
  }

  fn multiply(&mut self, other: Self, power_of_ten: u32) -> Self {
    println!("STILL DEBUGGING THIS!");
    let mut additives: Vec<Digits> = vec![];
    let mut position: u32 = power_of_ten;
    let mut o = Some(Box::new(other));
    loop {
      match o.clone() {
        Some(thing) => {
          let (dgt, tail) = thing.head_tail();
          o = tail;

          println!("{:?} * {:?} = {:?}", self.digit, dgt, self.digit * dgt);
          let mltply = self.propagate((self.digit * dgt * 10_u64.pow(position)).to_string());
          println!("{:?} {}", position, mltply.to_s());

          let mapping = self.mapping.clone();

          if let Some(ref mut bx) = self.left {
            additives.push(
              bx.clone().multiply(
                Digits::new(
                  mapping,
                  dgt.to_string()
                ),
                position + 1
              )
            );
          };

          if !mltply.is_zero() { additives.push( mltply ); }
        },
        None => break,
      }

      position += 1;
    }

    loop {
      match additives.pop() {
        Some(dg) => {
          self.add(dg);
        },
        None => break,
      }
    }

    self.clone()
  }
}

/// NODOC
pub trait Into<String> {
  /// NODOC
  fn into(self) -> String;
}

impl<'a> From<Digits<'a>> for String {
  fn from(d: Digits) -> String {
    d.to_s()
  }
}

impl<'a> Into<String> for Digits<'a> {
  fn into(self) -> String {
    self.to_s()
  }
}

impl Into<String> for String {
  fn into(self) -> String {
    self.clone()
  }
}

impl<'a> fmt::Display for Digits<'a> {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
   write!(f, "Digits<'a> — (Character: '{}', Decimal Value: {}{})",
     self.mapping.gen(self.digit), self.digit, {
       match self.left {
         None => "".to_string(),
         Some(ref l) => format!(", With Preceeding: '{}'", l.to_s()),
       }
     }
     )
  }
}

impl<'a> fmt::Debug for Digits<'a> {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{} with base: {:?}", self, self.mapping)
  }
}
<commit_msg>WOOHOO!!! I did it! Multiplication implemented.<commit_after>// Copyright 2017 Daniel P. Clark & other digits Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
//
#![deny(missing_docs,trivial_casts,trivial_numeric_casts,
        missing_debug_implementations, missing_copy_implementations,
        unsafe_code,unstable_features,unused_import_braces,unused_qualifications)
]
//! # digits
//!
//! The digits crate is a linked list implementation of a score card flipper.  But
//! in this case it's with any characters you want and you can enumerate through
//! possibilities beyond the numeric limits intrinsic in basic numerc types like `u64`.
//!
//! Primary use case would be brute forcing character sequences.
extern crate base_custom;
use base_custom::BaseCustom;
use std::fmt;

/// # struct Digits
///
/// This struct acts similar to a full number with a custom numeric character base.
/// But the underlying implementation is a linked list where all the methods recurse
/// as far as need to to implement the operations.
#[derive(Clone)]
pub struct Digits<'a> {
  mapping: &'a BaseCustom<char>,
  digit: u64,
  left: Option<Box<Digits<'a>>>,
}

impl<'a> Digits<'a> {
  /// `new` creates a new Digits instance with the provided character set and value.
  ///
  /// The first parameter must be a BaseCustom object which defines and maps all values.
  /// The second parameter is a string value with all valid characters from the BaseCustom set.
  ///
  /// You can view the numbers current value at any time with `to_s()` or `to_string()`.
  pub fn new<S>(mapping: &'a BaseCustom<char>, number: S) -> Digits<'a>
  where S: Into<String> {
    let number = number.into();
    if number.is_empty() { return Digits { mapping: mapping, digit: 0, left: None }; };
    let (last, rest) = {
      let mut n = number.chars().rev();
      (n.next().unwrap(), n.rev().collect::<String>())
    };

    let continuation = {
      if rest.is_empty() {
        None
      } else {
        Some(Box::new(Digits::new(&mapping, rest)))
      }
    };
    Digits {
      mapping: mapping,
      digit: mapping.decimal(last.to_string()),
      left: continuation,
    }
  }

  /// `replicate` — alias for clone (useful for unboxing)
  pub fn replicate(self) -> Self { self.clone() }

  /// `propagate` creates a new number from the same underlying numeric base
  pub fn propagate<S>(&self, number: S) -> Self
  where S: Into<String> {
    Digits::new(self.mapping, number)
  }

  /// Gives the full value of all digits within the linked list as a String.
  pub fn to_s(&self) -> String {
    let num = self.mapping.gen(self.digit);
    match &self.left {
      &None => format!("{}", num),
      &Some(ref bx) => format!("{}{}", bx.to_s(), num),
    }
  }

  /// Gives the full value of all digits within the linked list as a String.
  pub fn to_string(&self) -> String {
    self.to_s()
  }

  // the way to recurse and process Digits
  fn head_tail(self) -> (u64, Option<Box<Self>>) {
    match self.left {
      Some(bx) => (self.digit, Some(bx)),
      None => (self.digit, None),
    }
  }

  // logic for setting left linked list continuation
  fn set_left(&mut self, d: Digits<'a>) {
    if d.is_end() {
      self.left = None;
    } else {
      self.left = Some(Box::new(d));
    }
  }

  /// `length` returns a `usize` of the total linked list length.
  pub fn length(&self) -> usize {
    match &self.left {
      &None => 1,
      &Some(ref l) => { l.length() + 1 }
    }
  }

  /// `zero` returns a Digits instance with value of zero and the current character mapping.
  pub fn zero(&self) -> Self {
    Digits::new_zero(self.mapping)
  }

  /// `new_zero` returns a Digits instance with value of zero and the current character mapping.
  pub fn new_zero(mapping: &'a BaseCustom<char>) -> Self {
    Digits { mapping: mapping, digit: 0, left: None }
  }

  /// `is_zero` returns bool value of if the number is zero
  pub fn is_zero(&self) -> bool {
    if self.digit != 0 { return false }
    match &self.left {
      &None => { true },
      &Some(ref bx) => { bx.is_zero() },
    }
  }

  /// `pinky` is the smallest digit.
  /// a.k.a. current digit in the linked list.
  /// a.k.a. the right most digit.
  /// This will be a char value for that digit.
  pub fn pinky(&self) -> char {
    self.mapping.char(self.digit as usize).unwrap()
  }

  /// `one` returns a Digits instance with value of one and the current character mapping.
  pub fn one(&self) -> Self {
    Digits::new_one(self.mapping)
  }

  /// `new_one` returns a Digits instance with value of one and the current character mapping.
  pub fn new_one(mapping: &'a BaseCustom<char>) -> Self {
    Digits { mapping: mapping, digit: 1, left: None }
  }

  // A non-consuming quick end check.
  // More efficient than calling `is_zero` when this applies.
  fn is_end(&self) -> bool {
    self.digit == 0 && match self.left { None => true, _ => false }
  }

  /// Add two Digits instances together.  The one the `add` method is called on
  /// must be mutable and modifies itself.  The other is consumed.
  ///
  /// Returns a clone of the updated `Self` as well.
  pub fn add(&mut self, other: Self) -> Self {
    assert!(self.mapping == other.mapping);
    if other.is_end() { return self.clone(); };
    let (last, rest) = other.head_tail();

    // sums current single digit
    let added = self.propagate(self.mapping.gen(last + self.digit));
    let (l, r) = added.head_tail();
    self.digit = l;

    // sums for left
    let mut intermediate = Digits::new_zero(self.mapping);
    if let Some(dg) = r { intermediate.add(dg.replicate()); }
    if let Some(dg) = rest { intermediate.add(dg.replicate()); }

    let current_left = match self.left.clone() {
      None => { Box::new(self.zero()) },
      Some(bx) => { bx },
    }.as_ref().clone();

    self.set_left( intermediate.add(current_left).clone() );
    self.clone()
  }

  /// Multiply two Digits instances together.  The one the `mul` method is called on
  /// must be mutable and modifies itself.  The other is consumed.
  ///
  /// Returns a clone of the updated `Self` as well.
  pub fn mul(&mut self, other: Self) -> Self {
    self.multiply(other, 0)
  }

  fn multiply(&mut self, other: Self, power_of_ten: u32) -> Self {
    let mut additives: Vec<Digits> = vec![];
    let mut position: u32 = power_of_ten;
    let mut o = Some(Box::new(other));
    loop {
      match o.clone() {
        Some(thing) => {
          let (dgt, tail) = thing.head_tail();
          o = tail;

          let mltply = self.propagate((self.digit * dgt * 10_u64.pow(position)).to_string());

          let mapping = self.mapping.clone();

          if let Some(ref mut bx) = self.left {
            additives.push(
              bx.clone().multiply(
                Digits::new(
                  mapping,
                  self.mapping.gen(dgt).to_string()
                ),
                position + 1
              )
            );
          };

          if !mltply.is_zero() { additives.push( mltply ); }
        },
        None => break,
      }

      position += 1;
    }

    let mut result = self.zero();

    loop {
      match additives.pop() {
        Some(dg) => {
          println!("Adding: {}", dg.to_s());
          result.add(dg);
        },
        None => break,
      }
    }

    result
  }
}

/// NODOC
pub trait Into<String> {
  /// NODOC
  fn into(self) -> String;
}

impl<'a> From<Digits<'a>> for String {
  fn from(d: Digits) -> String {
    d.to_s()
  }
}

impl<'a> Into<String> for Digits<'a> {
  fn into(self) -> String {
    self.to_s()
  }
}

impl Into<String> for String {
  fn into(self) -> String {
    self.clone()
  }
}

impl<'a> fmt::Display for Digits<'a> {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
   write!(f, "Digits<'a> — (Character: '{}', Decimal Value: {}{})",
     self.mapping.gen(self.digit), self.digit, {
       match self.left {
         None => "".to_string(),
         Some(ref l) => format!(", With Preceeding: '{}'", l.to_s()),
       }
     }
     )
  }
}

impl<'a> fmt::Debug for Digits<'a> {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{} with base: {:?}", self, self.mapping)
  }
}
<|endoftext|>


<commit_before>//! Whatlang is a Rust library to detect(regonize) natural languages.
//! Apart from it, the library also recognizes scripts (writing system).
//! Every language and script are represented by determined list of enums.
//!
//! # Examples
//!
//! Using `detect` function:
//!
//! ```
//! use whatlang::{detect, Lang, Script};
//!
//! let text = "Ĉu vi ne volas eklerni Esperanton? Bonvolu! Estas unu de la plej bonaj aferoj!";
//! let info = detect(text).unwrap();
//! assert_eq!(info.lang(), Lang::Epo);
//! assert_eq!(info.script(), Script::Latin);
//!
//! // Confidence is in the range from 0 to 1.
//! assert_eq!(info.confidence(), 1.0);
//! assert!(info.is_reliable());
//! ```
//!
//! Using `Detector` with specified blacklist or whitelist:
//!
//! ```
//! use whatlang::{Detector, Lang};
//!
//! let whitelist = vec![Lang::Eng, Lang::Rus];
//!
//! // You can also create detector using with_blacklist function
//! let detector = Detector::with_whitelist(whitelist);
//! let lang = detector.detect_lang("There is no reason not to learn Esperanto.");
//! assert_eq!(lang, Some(Lang::Eng));
//!
mod constants;
mod detect;
mod detector;
mod error;
mod info;
mod lang;
mod options;
mod scripts;
mod trigrams;
mod utils;

pub use crate::detector::Detector;
pub use crate::info::Info;
pub use crate::lang::Lang;
pub use crate::options::Options;
pub use crate::scripts::Script;

pub use crate::detect::detect;
pub use crate::detect::detect_lang;
pub use crate::detect::detect_with_options;
pub use crate::scripts::detect_script;
<commit_msg>Add breaking test<commit_after>//! Whatlang is a Rust library to detect(regonize) natural languages.
//! Apart from it, the library also recognizes scripts (writing system).
//! Every language and script are represented by determined list of enums.
//!
//! # Examples
//!
//! Using `detect` function:
//!
//! ```
//! use whatlang::{detect, Lang, Script};
//!
//! let text = "Ĉu vi ne volas eklerni Esperanton? Bonvolu! Estas unu de la plej bonaj aferoj!";
//! let info = detect(text).unwrap();
//! assert_eq!(info.lang(), Lang::Epo);
//! assert_eq!(info.script(), Script::Latin);
//!
//! // Confidence is in the range from 0 to 1.
//! assert_eq!(info.confidence(), 1.0);
//! assert!(info.is_reliable());
//! ```
//!
//! Using `Detector` with specified blacklist or whitelist:
//!
//! ```
//! use whatlang::{Detector, Lang};
//!
//! let whitelist = vec![Lang::Eng, Lang::Rus];
//!
//! // You can also create detector using with_blacklist function
//! let detector = Detector::with_whitelist(whitelist);
//! let lang = detector.detect_lang("There is no reason not to learn Esperanto.");
//! assert_eq!(lang, Some(Lang::Eng));
//! ```
//!
//!
//! Breaking test (check CI):
//! ```
//! let lang = whatlang::detect_lang("Man soll weiterhin Deutsch lernen").unwrap();
//! assert_eq!(lang, whatlang::Lang::Rus);
//! ```
//!
mod constants;
mod detect;
mod detector;
mod error;
mod info;
mod lang;
mod options;
mod scripts;
mod trigrams;
mod utils;

pub use crate::detector::Detector;
pub use crate::info::Info;
pub use crate::lang::Lang;
pub use crate::options::Options;
pub use crate::scripts::Script;

pub use crate::detect::detect;
pub use crate::detect::detect_lang;
pub use crate::detect::detect_with_options;
pub use crate::scripts::detect_script;
<|endoftext|>


<commit_before>//! Wherein are contained methods for checking the current `state` of the terminal's property.

pub mod mouse;

use geometry::Size;
use terminal::KeyCode;
use bear_lib_terminal_sys as ffi;

pub fn size() -> Size {
	Size::new(ffi::state(ffi::TK_WIDTH), ffi::state(ffi::TK_HEIGHT));
}

pub fn key_pressed(key: KeyCode) -> bool {
	ffi::check(match key {
		KeyCode::A            => ffi::TK_A,
		KeyCode::B            => ffi::TK_B,
		KeyCode::C            => ffi::TK_C,
		KeyCode::D            => ffi::TK_D,
		KeyCode::E            => ffi::TK_E,
		KeyCode::F            => ffi::TK_F,
		KeyCode::G            => ffi::TK_G,
		KeyCode::H            => ffi::TK_H,
		KeyCode::I            => ffi::TK_I,
		KeyCode::J            => ffi::TK_J,
		KeyCode::K            => ffi::TK_K,
		KeyCode::L            => ffi::TK_L,
		KeyCode::M            => ffi::TK_M,
		KeyCode::N            => ffi::TK_N,
		KeyCode::O            => ffi::TK_O,
		KeyCode::P            => ffi::TK_P,
		KeyCode::Q            => ffi::TK_Q,
		KeyCode::R            => ffi::TK_R,
		KeyCode::S            => ffi::TK_S,
		KeyCode::T            => ffi::TK_T,
		KeyCode::U            => ffi::TK_U,
		KeyCode::V            => ffi::TK_V,
		KeyCode::W            => ffi::TK_W,
		KeyCode::X            => ffi::TK_X,
		KeyCode::Y            => ffi::TK_Y,
		KeyCode::Z            => ffi::TK_Z,
		KeyCode::Row1         => ffi::TK_1,
		KeyCode::Row2         => ffi::TK_2,
		KeyCode::Row3         => ffi::TK_3,
		KeyCode::Row4         => ffi::TK_4,
		KeyCode::Row5         => ffi::TK_5,
		KeyCode::Row6         => ffi::TK_6,
		KeyCode::Row7         => ffi::TK_7,
		KeyCode::Row8         => ffi::TK_8,
		KeyCode::Row9         => ffi::TK_9,
		KeyCode::Row0         => ffi::TK_0,
		KeyCode::Enter        => ffi::TK_ENTER,
		KeyCode::Escape       => ffi::TK_ESCAPE,
		KeyCode::Backspace    => ffi::TK_BACKSPACE,
		KeyCode::Tab          => ffi::TK_TAB,
		KeyCode::Space        => ffi::TK_SPACE,
		KeyCode::Minus        => ffi::TK_MINUS,
		KeyCode::Equals       => ffi::TK_EQUALS,
		KeyCode::LeftBracket  => ffi::TK_LBRACKET,
		KeyCode::RightBracket => ffi::TK_RBRACKET,
		KeyCode::Backslash    => ffi::TK_BACKSLASH,
		KeyCode::Semicolon    => ffi::TK_SEMICOLON,
		KeyCode::Apostrophe   => ffi::TK_APOSTROPHE,
		KeyCode::Grave        => ffi::TK_GRAVE,
		KeyCode::Comma        => ffi::TK_COMMA,
		KeyCode::Period       => ffi::TK_PERIOD,
		KeyCode::Slash        => ffi::TK_SLASH,
		KeyCode::F1           => ffi::TK_F1,
		KeyCode::F2           => ffi::TK_F2,
		KeyCode::F3           => ffi::TK_F3,
		KeyCode::F4           => ffi::TK_F4,
		KeyCode::F5           => ffi::TK_F5,
		KeyCode::F6           => ffi::TK_F6,
		KeyCode::F7           => ffi::TK_F7,
		KeyCode::F8           => ffi::TK_F8,
		KeyCode::F9           => ffi::TK_F9,
		KeyCode::F10          => ffi::TK_F10,
		KeyCode::F11          => ffi::TK_F11,
		KeyCode::F12          => ffi::TK_F12,
		KeyCode::Pause        => ffi::TK_PAUSE,
		KeyCode::Insert       => ffi::TK_INSERT,
		KeyCode::Home         => ffi::TK_HOME,
		KeyCode::PageUp       => ffi::TK_PAGEUP,
		KeyCode::Delete       => ffi::TK_DELETE,
		KeyCode::End          => ffi::TK_END,
		KeyCode::PageDown     => ffi::TK_PAGEDOWN,
		KeyCode::Right        => ffi::TK_RIGHT,
		KeyCode::Left         => ffi::TK_LEFT,
		KeyCode::Down         => ffi::TK_DOWN,
		KeyCode::Up           => ffi::TK_UP,
		KeyCode::NumDivide    => ffi::TK_KP_DIVIDE,
		KeyCode::NumMultiply  => ffi::TK_KP_MULTIPLY,
		KeyCode::NumMinus     => ffi::TK_KP_MINUS,
		KeyCode::NumPlus      => ffi::TK_KP_PLUS,
		KeyCode::NumEnter     => ffi::TK_KP_ENTER,
		KeyCode::Num1         => ffi::TK_KP_1,
		KeyCode::Num2         => ffi::TK_KP_2,
		KeyCode::Num3         => ffi::TK_KP_3,
		KeyCode::Num4         => ffi::TK_KP_4,
		KeyCode::Num5         => ffi::TK_KP_5,
		KeyCode::Num6         => ffi::TK_KP_6,
		KeyCode::Num7         => ffi::TK_KP_7,
		KeyCode::Num8         => ffi::TK_KP_8,
		KeyCode::Num9         => ffi::TK_KP_9,
		KeyCode::Num0         => ffi::TK_KP_0,
		KeyCode::NumPeriod    => ffi::TK_KP_PERIOD,
		KeyCode::MouseLeft    => ffi::TK_MOUSE_LEFT,
		KeyCode::MouseRight   => ffi::TK_MOUSE_RIGHT,
		KeyCode::MouseMiddle  => ffi::TK_MOUSE_MIDDLE,
		KeyCode::MouseFourth  => ffi::TK_MOUSE_X1,
		KeyCode::MouseFifth   => ffi::TK_MOUSE_X2,
	})
}
<commit_msg>Semicolons<commit_after>//! Wherein are contained methods for checking the current `state` of the terminal's property.

pub mod mouse;

use geometry::Size;
use terminal::KeyCode;
use bear_lib_terminal_sys as ffi;

pub fn size() -> Size {
	Size::new(ffi::state(ffi::TK_WIDTH), ffi::state(ffi::TK_HEIGHT))
}

pub fn key_pressed(key: KeyCode) -> bool {
	ffi::check(match key {
		KeyCode::A            => ffi::TK_A,
		KeyCode::B            => ffi::TK_B,
		KeyCode::C            => ffi::TK_C,
		KeyCode::D            => ffi::TK_D,
		KeyCode::E            => ffi::TK_E,
		KeyCode::F            => ffi::TK_F,
		KeyCode::G            => ffi::TK_G,
		KeyCode::H            => ffi::TK_H,
		KeyCode::I            => ffi::TK_I,
		KeyCode::J            => ffi::TK_J,
		KeyCode::K            => ffi::TK_K,
		KeyCode::L            => ffi::TK_L,
		KeyCode::M            => ffi::TK_M,
		KeyCode::N            => ffi::TK_N,
		KeyCode::O            => ffi::TK_O,
		KeyCode::P            => ffi::TK_P,
		KeyCode::Q            => ffi::TK_Q,
		KeyCode::R            => ffi::TK_R,
		KeyCode::S            => ffi::TK_S,
		KeyCode::T            => ffi::TK_T,
		KeyCode::U            => ffi::TK_U,
		KeyCode::V            => ffi::TK_V,
		KeyCode::W            => ffi::TK_W,
		KeyCode::X            => ffi::TK_X,
		KeyCode::Y            => ffi::TK_Y,
		KeyCode::Z            => ffi::TK_Z,
		KeyCode::Row1         => ffi::TK_1,
		KeyCode::Row2         => ffi::TK_2,
		KeyCode::Row3         => ffi::TK_3,
		KeyCode::Row4         => ffi::TK_4,
		KeyCode::Row5         => ffi::TK_5,
		KeyCode::Row6         => ffi::TK_6,
		KeyCode::Row7         => ffi::TK_7,
		KeyCode::Row8         => ffi::TK_8,
		KeyCode::Row9         => ffi::TK_9,
		KeyCode::Row0         => ffi::TK_0,
		KeyCode::Enter        => ffi::TK_ENTER,
		KeyCode::Escape       => ffi::TK_ESCAPE,
		KeyCode::Backspace    => ffi::TK_BACKSPACE,
		KeyCode::Tab          => ffi::TK_TAB,
		KeyCode::Space        => ffi::TK_SPACE,
		KeyCode::Minus        => ffi::TK_MINUS,
		KeyCode::Equals       => ffi::TK_EQUALS,
		KeyCode::LeftBracket  => ffi::TK_LBRACKET,
		KeyCode::RightBracket => ffi::TK_RBRACKET,
		KeyCode::Backslash    => ffi::TK_BACKSLASH,
		KeyCode::Semicolon    => ffi::TK_SEMICOLON,
		KeyCode::Apostrophe   => ffi::TK_APOSTROPHE,
		KeyCode::Grave        => ffi::TK_GRAVE,
		KeyCode::Comma        => ffi::TK_COMMA,
		KeyCode::Period       => ffi::TK_PERIOD,
		KeyCode::Slash        => ffi::TK_SLASH,
		KeyCode::F1           => ffi::TK_F1,
		KeyCode::F2           => ffi::TK_F2,
		KeyCode::F3           => ffi::TK_F3,
		KeyCode::F4           => ffi::TK_F4,
		KeyCode::F5           => ffi::TK_F5,
		KeyCode::F6           => ffi::TK_F6,
		KeyCode::F7           => ffi::TK_F7,
		KeyCode::F8           => ffi::TK_F8,
		KeyCode::F9           => ffi::TK_F9,
		KeyCode::F10          => ffi::TK_F10,
		KeyCode::F11          => ffi::TK_F11,
		KeyCode::F12          => ffi::TK_F12,
		KeyCode::Pause        => ffi::TK_PAUSE,
		KeyCode::Insert       => ffi::TK_INSERT,
		KeyCode::Home         => ffi::TK_HOME,
		KeyCode::PageUp       => ffi::TK_PAGEUP,
		KeyCode::Delete       => ffi::TK_DELETE,
		KeyCode::End          => ffi::TK_END,
		KeyCode::PageDown     => ffi::TK_PAGEDOWN,
		KeyCode::Right        => ffi::TK_RIGHT,
		KeyCode::Left         => ffi::TK_LEFT,
		KeyCode::Down         => ffi::TK_DOWN,
		KeyCode::Up           => ffi::TK_UP,
		KeyCode::NumDivide    => ffi::TK_KP_DIVIDE,
		KeyCode::NumMultiply  => ffi::TK_KP_MULTIPLY,
		KeyCode::NumMinus     => ffi::TK_KP_MINUS,
		KeyCode::NumPlus      => ffi::TK_KP_PLUS,
		KeyCode::NumEnter     => ffi::TK_KP_ENTER,
		KeyCode::Num1         => ffi::TK_KP_1,
		KeyCode::Num2         => ffi::TK_KP_2,
		KeyCode::Num3         => ffi::TK_KP_3,
		KeyCode::Num4         => ffi::TK_KP_4,
		KeyCode::Num5         => ffi::TK_KP_5,
		KeyCode::Num6         => ffi::TK_KP_6,
		KeyCode::Num7         => ffi::TK_KP_7,
		KeyCode::Num8         => ffi::TK_KP_8,
		KeyCode::Num9         => ffi::TK_KP_9,
		KeyCode::Num0         => ffi::TK_KP_0,
		KeyCode::NumPeriod    => ffi::TK_KP_PERIOD,
		KeyCode::MouseLeft    => ffi::TK_MOUSE_LEFT,
		KeyCode::MouseRight   => ffi::TK_MOUSE_RIGHT,
		KeyCode::MouseMiddle  => ffi::TK_MOUSE_MIDDLE,
		KeyCode::MouseFourth  => ffi::TK_MOUSE_X1,
		KeyCode::MouseFifth   => ffi::TK_MOUSE_X2,
	})
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;

pub struct Lock<'a, T: 'a> {
    opt_val: Option<T>,
    phantom_lock: PhantomData<&'a mut ()>
}

impl<'a, T: 'a> Lock<'a, T> {
    /// Creates an empty Lock<T> container.
    ///
    /// Needs to be stored in a binding (e.g. `let lock = Lock::new();`) to be useful.
    pub fn new() -> Self {
        Lock { opt_val: None, phantom_lock: PhantomData }
    }

    // Needs to be `&'a mut self`, as that makes the Lock's `'a` the same lifetime as the passed-in `&mut self`, causing it to refer to itself.
    // Taking `&mut self` instead of `&self` prevents another `Acceptor` from being created, which can help prevent confusion.
    pub fn lock<R, F: FnOnce(Acceptor<'a, T>) -> R>(&'a mut self, f: F) -> R {
        let acc = Acceptor::new(self);
        f(acc)
    }
}

pub struct Acceptor<'a, T: 'a> {
    mut_lock: &'a mut Lock<'a, T>
}

impl<'a, T: 'a> Acceptor<'a, T> {
    fn new(lock: &'a mut Lock<'a, T>) -> Self {
        Acceptor { mut_lock: lock }
    }

    pub fn fill(self, t: T) -> Handle<'a, T> {
        self.mut_lock.opt_val = Some(t);
        Handle { mut_lock: self.mut_lock }
    }

    pub fn fill_from<'b>(self, handle_t: Handle<'b, T>) -> Handle<'a, T> {
        let new = handle_t.mut_lock.opt_val.take().expect("Attempting to .fill_from() an emptied Handle!");
        self.fill(new)
    }
}

pub struct Handle<'a, T: 'a> {
    mut_lock: &'a mut Lock<'a, T>
}

impl<'a, T: 'a> std::ops::Deref for Handle<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        self.mut_lock.opt_val.as_ref().expect("Tried to deref() an emptied Handle!")
    }
}

impl <'a, T: 'a> std::ops::DerefMut for Handle<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        self.mut_lock.opt_val.as_mut().expect("Tried to deref_mut() an emptied Handle!")
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn it_works() {
        use super::*;
        let mut lock = Lock::new();
        let mut handle = lock.lock(|acc| acc.fill(0i32));
        assert_eq!(*handle, 0i32);
    }
}
<commit_msg>.lock() returns an Acceptor, instead of taking a closure.<commit_after>use std::marker::PhantomData;

pub struct Lock<'a, T: 'a> {
    opt_val: Option<T>,
    phantom_lock: PhantomData<&'a mut ()>
}

impl<'a, T: 'a> Lock<'a, T> {
    /// Creates an empty Lock<T> container.
    ///
    /// Needs to be stored in a binding (e.g. `let lock = Lock::new();`) to be useful.
    pub fn new() -> Self {
        Lock { opt_val: None, phantom_lock: PhantomData }
    }

    // Needs to be `&'a mut self`, as that makes the Lock's `'a` the same lifetime as the passed-in `&mut self`, causing it to refer to itself.
    // Taking `&mut self` instead of `&self` prevents another `Acceptor` from being created, which can help prevent confusion.
    pub fn lock(&'a mut self) -> Acceptor<'a, T> {
        Acceptor::new(self)
    }
}

pub struct Acceptor<'a, T: 'a> {
    mut_lock: &'a mut Lock<'a, T>
}

impl<'a, T: 'a> Acceptor<'a, T> {
    fn new(lock: &'a mut Lock<'a, T>) -> Self {
        Acceptor { mut_lock: lock }
    }

    pub fn fill(self, t: T) -> Handle<'a, T> {
        self.mut_lock.opt_val = Some(t);
        Handle { mut_lock: self.mut_lock }
    }

    pub fn fill_from<'b>(self, handle_t: Handle<'b, T>) -> Handle<'a, T> {
        let new = handle_t.mut_lock.opt_val.take().expect("Attempting to .fill_from() an emptied Handle!");
        self.fill(new)
    }
}

pub struct Handle<'a, T: 'a> {
    mut_lock: &'a mut Lock<'a, T>
}

impl<'a, T: 'a> std::ops::Deref for Handle<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        self.mut_lock.opt_val.as_ref().expect("Tried to deref() an emptied Handle!")
    }
}

impl <'a, T: 'a> std::ops::DerefMut for Handle<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        self.mut_lock.opt_val.as_mut().expect("Tried to deref_mut() an emptied Handle!")
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn it_works() {
        use super::*;
        let mut lock = Lock::new();
        let mut handle = lock.lock().fill(0i32);
        assert_eq!(*handle, 0i32);
    }
}
<|endoftext|>


<commit_before>// Copyright 2014-2015 The GeoRust Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate "rustc-serialize" as rustc_serialize;

pub use types::pos::Pos;

pub use types::ring::Ring;

pub use types::point::Point;
pub use types::multipoint::MultiPoint;

pub use types::linestring::LineString;
pub use types::multilinestring::MultiLineString;

pub use types::poly::Poly;
pub use types::polygon::Polygon;
pub use types::multipolygon::MultiPolygon;

pub use types::geometry::Geometry;
pub use types::geometrycollection::GeometryCollection;

pub use types::feature::Feature;
pub use types::featurecollection::FeatureCollection;

macro_rules! expect_string {
    ($value:expr) => (try!(
        match $value.as_string() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected string value")})
        }
    ))
}

macro_rules! expect_f64 {
    ($value:expr) => (try!(
        match $value.as_f64() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected f64 value")})
        }
    ))
}

macro_rules! expect_array {
    ($value:expr) => (try!(
        match $value.as_array() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected array value")})
        }
    ))
}

macro_rules! expect_object {
    ($value:expr) => (try!(
        match $value.as_object() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected object value")})
        }
    ))
}

macro_rules! expect_property {
    ($obj:expr, $name:expr, $desc:expr) => (
        match $obj.get($name) {
            Some(v) => v,
            None => return Err({use GeoJsonError; GeoJsonError::new($desc)}),
        };
    )
}

mod types;

#[derive(Copy)]
pub struct GeoJsonError {
    pub desc: &'static str,
}

impl GeoJsonError {
    pub fn new(desc: &'static str) -> GeoJsonError {
        return GeoJsonError{desc: desc};
    }
}

pub type GeoJsonResult<T> = Result<T, GeoJsonError>;
<commit_msg>Silence warnings, enable 'core' feature<commit_after>// Copyright 2014-2015 The GeoRust Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(core)]

extern crate "rustc-serialize" as rustc_serialize;

pub use types::pos::Pos;

pub use types::ring::Ring;

pub use types::point::Point;
pub use types::multipoint::MultiPoint;

pub use types::linestring::LineString;
pub use types::multilinestring::MultiLineString;

pub use types::poly::Poly;
pub use types::polygon::Polygon;
pub use types::multipolygon::MultiPolygon;

pub use types::geometry::Geometry;
pub use types::geometrycollection::GeometryCollection;

pub use types::feature::Feature;
pub use types::featurecollection::FeatureCollection;

macro_rules! expect_string {
    ($value:expr) => (try!(
        match $value.as_string() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected string value")})
        }
    ))
}

macro_rules! expect_f64 {
    ($value:expr) => (try!(
        match $value.as_f64() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected f64 value")})
        }
    ))
}

macro_rules! expect_array {
    ($value:expr) => (try!(
        match $value.as_array() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected array value")})
        }
    ))
}

macro_rules! expect_object {
    ($value:expr) => (try!(
        match $value.as_object() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected object value")})
        }
    ))
}

macro_rules! expect_property {
    ($obj:expr, $name:expr, $desc:expr) => (
        match $obj.get($name) {
            Some(v) => v,
            None => return Err({use GeoJsonError; GeoJsonError::new($desc)}),
        };
    )
}

mod types;

#[derive(Copy)]
pub struct GeoJsonError {
    pub desc: &'static str,
}

impl GeoJsonError {
    pub fn new(desc: &'static str) -> GeoJsonError {
        return GeoJsonError{desc: desc};
    }
}

pub type GeoJsonResult<T> = Result<T, GeoJsonError>;
<|endoftext|>


<commit_before>//! Point ABSTraction library in Rust.
//!
//! This library is inspired by [PDAL](http://www.pdal.io/), which provides both point abstraction
//! and a wide range of other abilitiles. **Pabst** hopes to keep its focus more narrow. We provide
//! source and sink abstractions for LiDAR point cloud file and stream formats. Other libraries
//! should be used to provide intermediate functionality.

#![deny(fat_ptr_transmutes, missing_copy_implementations, missing_debug_implementations, missing_docs, trivial_casts, trivial_numeric_casts, unsafe_code, unused_extern_crates, unused_import_braces, unused_qualifications, unused_results, variant_size_differences)]

extern crate las;
#[cfg(feature = "rxp")]
extern crate rivlib;
extern crate sdc;
#[cfg(feature = "sdf-convert")]
extern crate sdf;

pub mod error;
pub mod point;
pub mod source;
pub mod sink;

pub use error::Error;
pub use point::Point;
pub use source::Source;
pub use sink::Sink;

use std::result;

/// Our custom result type.
pub type Result<T> = result::Result<T, Error>;
<commit_msg>Re-export the open methods<commit_after>//! Point ABSTraction library in Rust.
//!
//! This library is inspired by [PDAL](http://www.pdal.io/), which provides both point abstraction
//! and a wide range of other abilitiles. **Pabst** hopes to keep its focus more narrow. We provide
//! source and sink abstractions for LiDAR point cloud file and stream formats. Other libraries
//! should be used to provide intermediate functionality.

#![deny(fat_ptr_transmutes, missing_copy_implementations, missing_debug_implementations, missing_docs, trivial_casts, trivial_numeric_casts, unsafe_code, unused_extern_crates, unused_import_braces, unused_qualifications, unused_results, variant_size_differences)]

extern crate las;
#[cfg(feature = "rxp")]
extern crate rivlib;
extern crate sdc;
#[cfg(feature = "sdf-convert")]
extern crate sdf;

pub mod error;
pub mod point;
pub mod source;
pub mod sink;

pub use error::Error;
pub use point::Point;
pub use source::{open_file_source, FileSource, Source};
pub use sink::{open_file_sink, FileSink, Sink};

use std::result;

/// Our custom result type.
pub type Result<T> = result::Result<T, Error>;
<|endoftext|>