<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::str;

use resource_task::{Done, Payload, Metadata, LoadData, LoadResponse, LoaderTask, start_sending};

use serialize::base64::FromBase64;

use http::headers::test_utils::from_stream_with_str;
use http::headers::content_type::MediaType;
use url::{percent_decode, OtherSchemeData};

pub fn factory() -> LoaderTask {
    proc(url, start_chan) {
        // NB: we don't spawn a new task.
        // Hypothesis: data URLs are too small for parallel base64 etc. to be worth it.
        // Should be tested at some point.
        load(url, start_chan)
    }
}

fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
    let url = load_data.url;
    assert!("data" == url.scheme.as_slice());

    let mut metadata = Metadata::default(url.clone());

    // Split out content type and data.
    let mut scheme_data = match url.scheme_data {
        OtherSchemeData(scheme_data) => scheme_data,
        _ => fail!("Expected a non-relative scheme URL.")
    };
    match url.query {
        Some(query) => {
            scheme_data.push_str("?");
            scheme_data.push_str(query.as_slice());
        },
        None => ()
    }
    let parts: Vec<&str> = scheme_data.as_slice().splitn(',', 1).collect();
    if parts.len() != 2 {
        start_sending(start_chan, metadata).send(Done(Err("invalid data uri".to_string())));
        return;
    }

    // ";base64" must come at the end of the content type, per RFC 2397.
    // rust-http will fail to parse it because there's no =value part.
    let mut is_base64 = false;
    let mut ct_str = *parts.get(0);
    if ct_str.ends_with(";base64") {
        is_base64 = true;
        ct_str = ct_str.slice_to(ct_str.as_bytes().len() - 7);
    }

    // Parse the content type using rust-http.
    // FIXME: this can go into an infinite loop! (rust-http #25)
    let content_type: Option<MediaType> = from_stream_with_str(ct_str);
    metadata.set_content_type(&content_type);

    let progress_chan = start_sending(start_chan, metadata);
    let bytes = percent_decode(parts.get(1).as_bytes());

    if is_base64 {
        // See #1268
        let bytes = bytes.move_iter().filter(|&b| b != ' ' as u8).collect::<Vec<u8>>();
        // FIXME(#2877): use bytes.as_slice().from_base64() when we upgrade to a Rust version
        // that includes https://github.com/rust-lang/rust/pull/15810
        let fake_utf8 = unsafe { str::raw::from_utf8(bytes.as_slice()) };
        match fake_utf8.from_base64() {
            Err(..) => {
                progress_chan.send(Done(Err("non-base64 data uri".to_string())));
            }
            Ok(data) => {
                progress_chan.send(Payload(data));
                progress_chan.send(Done(Ok(())));
            }
        }
    } else {
        progress_chan.send(Payload(bytes));
        progress_chan.send(Done(Ok(())));
    }
}

#[cfg(test)]
fn assert_parse(url:          &'static str,
                content_type: Option<(String, String)>,
                charset:      Option<String>,
                data:         Option<Vec<u8>>) {
    use std::comm;
    use url::Url;

    let (start_chan, start_port) = comm::channel();
    load(LoadData::new(Url::parse(url).unwrap()), start_chan);

    let response = start_port.recv();
    assert_eq!(&response.metadata.content_type, &content_type);
    assert_eq!(&response.metadata.charset,      &charset);

    let progress = response.progress_port.recv();

    match data {
        None => {
            assert_eq!(progress, Done(Err("invalid data uri".to_string())));
        }
        Some(dat) => {
            assert_eq!(progress, Payload(dat));
            assert_eq!(response.progress_port.recv(), Done(Ok(())));
        }
    }
}

#[test]
fn empty_invalid() {
    assert_parse("data:", None, None, None);
}

#[test]
fn plain() {
    assert_parse("data:,hello%20world", None, None, Some(bytes!("hello world").iter().map(|&x| x).collect()));
}

#[test]
fn plain_ct() {
    assert_parse("data:text/plain,hello",
        Some(("text".to_string(), "plain".to_string())), None, Some(bytes!("hello").iter().map(|&x| x).collect()));
}

#[test]
fn plain_charset() {
    assert_parse("data:text/plain;charset=latin1,hello",
        Some(("text".to_string(), "plain".to_string())), Some("latin1".to_string()), Some(bytes!("hello").iter().map(|&x| x).collect()));
}

#[test]
fn base64() {
    assert_parse("data:;base64,C62+7w==", None, None, Some(vec!(0x0B, 0xAD, 0xBE, 0xEF)));
}

#[test]
fn base64_ct() {
    assert_parse("data:application/octet-stream;base64,C62+7w==",
        Some(("application".to_string(), "octet-stream".to_string())), None, Some(vec!(0x0B, 0xAD, 0xBE, 0xEF)));
}

#[test]
fn base64_charset() {
    assert_parse("data:text/plain;charset=koi8-r;base64,8PLl9+XkIO3l5Pfl5A==",
        Some(("text".to_string(), "plain".to_string())), Some("koi8-r".to_string()),
        Some(vec!(0xF0, 0xF2, 0xE5, 0xF7, 0xE5, 0xE4, 0x20, 0xED, 0xE5, 0xE4, 0xF7, 0xE5, 0xE4)));
}
<commit_msg>fixup! Ignore spaces in base64 data URLs. Fix #1268.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::str;

use resource_task::{Done, Payload, Metadata, LoadData, LoadResponse, LoaderTask, start_sending};

use serialize::base64::FromBase64;

use http::headers::test_utils::from_stream_with_str;
use http::headers::content_type::MediaType;
use url::{percent_decode, OtherSchemeData};

pub fn factory() -> LoaderTask {
    proc(url, start_chan) {
        // NB: we don't spawn a new task.
        // Hypothesis: data URLs are too small for parallel base64 etc. to be worth it.
        // Should be tested at some point.
        load(url, start_chan)
    }
}

fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
    let url = load_data.url;
    assert!("data" == url.scheme.as_slice());

    let mut metadata = Metadata::default(url.clone());

    // Split out content type and data.
    let mut scheme_data = match url.scheme_data {
        OtherSchemeData(scheme_data) => scheme_data,
        _ => fail!("Expected a non-relative scheme URL.")
    };
    match url.query {
        Some(query) => {
            scheme_data.push_str("?");
            scheme_data.push_str(query.as_slice());
        },
        None => ()
    }
    let parts: Vec<&str> = scheme_data.as_slice().splitn(',', 1).collect();
    if parts.len() != 2 {
        start_sending(start_chan, metadata).send(Done(Err("invalid data uri".to_string())));
        return;
    }

    // ";base64" must come at the end of the content type, per RFC 2397.
    // rust-http will fail to parse it because there's no =value part.
    let mut is_base64 = false;
    let mut ct_str = *parts.get(0);
    if ct_str.ends_with(";base64") {
        is_base64 = true;
        ct_str = ct_str.slice_to(ct_str.as_bytes().len() - 7);
    }

    // Parse the content type using rust-http.
    // FIXME: this can go into an infinite loop! (rust-http #25)
    let content_type: Option<MediaType> = from_stream_with_str(ct_str);
    metadata.set_content_type(&content_type);

    let progress_chan = start_sending(start_chan, metadata);
    let bytes = percent_decode(parts.get(1).as_bytes());

    if is_base64 {
        // FIXME(#2909): It’s unclear what to do with non-alphabet characters,
        // but Acid 3 apparently depends on spaces being ignored.
        let bytes = bytes.move_iter().filter(|&b| b != ' ' as u8).collect::<Vec<u8>>();
        // FIXME(#2877): use bytes.as_slice().from_base64() when we upgrade to a Rust version
        // that includes https://github.com/rust-lang/rust/pull/15810
        let fake_utf8 = unsafe { str::raw::from_utf8(bytes.as_slice()) };
        match fake_utf8.from_base64() {
            Err(..) => {
                progress_chan.send(Done(Err("non-base64 data uri".to_string())));
            }
            Ok(data) => {
                progress_chan.send(Payload(data));
                progress_chan.send(Done(Ok(())));
            }
        }
    } else {
        progress_chan.send(Payload(bytes));
        progress_chan.send(Done(Ok(())));
    }
}

#[cfg(test)]
fn assert_parse(url:          &'static str,
                content_type: Option<(String, String)>,
                charset:      Option<String>,
                data:         Option<Vec<u8>>) {
    use std::comm;
    use url::Url;

    let (start_chan, start_port) = comm::channel();
    load(LoadData::new(Url::parse(url).unwrap()), start_chan);

    let response = start_port.recv();
    assert_eq!(&response.metadata.content_type, &content_type);
    assert_eq!(&response.metadata.charset,      &charset);

    let progress = response.progress_port.recv();

    match data {
        None => {
            assert_eq!(progress, Done(Err("invalid data uri".to_string())));
        }
        Some(dat) => {
            assert_eq!(progress, Payload(dat));
            assert_eq!(response.progress_port.recv(), Done(Ok(())));
        }
    }
}

#[test]
fn empty_invalid() {
    assert_parse("data:", None, None, None);
}

#[test]
fn plain() {
    assert_parse("data:,hello%20world", None, None, Some(bytes!("hello world").iter().map(|&x| x).collect()));
}

#[test]
fn plain_ct() {
    assert_parse("data:text/plain,hello",
        Some(("text".to_string(), "plain".to_string())), None, Some(bytes!("hello").iter().map(|&x| x).collect()));
}

#[test]
fn plain_charset() {
    assert_parse("data:text/plain;charset=latin1,hello",
        Some(("text".to_string(), "plain".to_string())), Some("latin1".to_string()), Some(bytes!("hello").iter().map(|&x| x).collect()));
}

#[test]
fn base64() {
    assert_parse("data:;base64,C62+7w==", None, None, Some(vec!(0x0B, 0xAD, 0xBE, 0xEF)));
}

#[test]
fn base64_ct() {
    assert_parse("data:application/octet-stream;base64,C62+7w==",
        Some(("application".to_string(), "octet-stream".to_string())), None, Some(vec!(0x0B, 0xAD, 0xBE, 0xEF)));
}

#[test]
fn base64_charset() {
    assert_parse("data:text/plain;charset=koi8-r;base64,8PLl9+XkIO3l5Pfl5A==",
        Some(("text".to_string(), "plain".to_string())), Some("koi8-r".to_string()),
        Some(vec!(0xF0, 0xF2, 0xE5, 0xF7, 0xE5, 0xE4, 0x20, 0xED, 0xE5, 0xE4, 0xF7, 0xE5, 0xE4)));
}
<|endoftext|>


<commit_before>//! Crate ruma_api contains core types used to define the requests and responses for each endpoint
//! in the various [Matrix](https://matrix.org) API specifications.
//! These types can be shared by client and server code for all Matrix APIs.
//!
//! When implementing a new Matrix API, each endpoint has a type that implements `Endpoint`, plus
//! the necessary associated types.
//! An implementation of `Endpoint` contains all the information about the HTTP method, the path and
//! input parameters for requests, and the structure of a successful response.
//! Such types can then be used by client code to make requests, and by server code to fulfill
//! those requests.
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]
#![feature(try_from)]

extern crate futures;
extern crate http;
#[cfg(test)]
extern crate ruma_identifiers;
#[cfg(test)]
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde_urlencoded;

use std::convert::TryInto;
use std::io;

use futures::future::FutureFrom;
use http::{Method, Request, Response, StatusCode};

/// A Matrix API endpoint.
pub trait Endpoint<T, U> {
    /// Data needed to make a request to the endpoint.
    type Request: TryInto<Request<T>, Error = Error>;
    /// Data returned from the endpoint.
    type Response: FutureFrom<Response<U>, Error = Error>;

    /// Metadata about the endpoint.
    const METADATA: Metadata;
}

/// An error when converting an `Endpoint::Request` to a `http::Request` or a `http::Response` to
/// an `Endpoint::Response`.
#[derive(Debug)]
pub enum Error {
    /// An HTTP error.
    Http(http::Error),
    /// A I/O error.
    Io(io::Error),
    /// A Serde JSON error.
    SerdeJson(serde_json::Error),
    /// A Serde URL encoding error.
    SerdeUrlEncoded(serde_urlencoded::ser::Error),
    /// An HTTP status code indicating error.
    StatusCode(StatusCode),
}

impl From<http::Error> for Error {
    fn from(error: http::Error) -> Self {
        Error::Http(error)
    }
}

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

impl From<serde_json::Error> for Error {
    fn from(error: serde_json::Error) -> Self {
        Error::SerdeJson(error)
    }
}

impl From<serde_urlencoded::ser::Error> for Error {
    fn from(error: serde_urlencoded::ser::Error) -> Self {
        Error::SerdeUrlEncoded(error)
    }
}

/// Metadata about an API endpoint.
#[derive(Clone, Debug)]
pub struct Metadata {
    /// A human-readable description of the endpoint.
    pub description: &'static str,
    /// The HTTP method used by this endpoint.
    pub method: Method,
    /// A unique identifier for this endpoint.
    pub name: &'static str,
    /// The path of this endpoint's URL, with variable names where path parameters should be filled
    /// in during a request.
    pub path: &'static str,
    /// Whether or not this endpoint is rate limited by the server.
    pub rate_limited: bool,
    /// Whether or not the server requires an authenticated user for this endpoint.
    pub requires_authentication: bool,
}

#[cfg(test)]
mod tests {
    /// PUT /_matrix/client/r0/directory/room/:room_alias
    pub mod create {
        use std::convert::TryFrom;

        use futures::future::{err, ok, FutureFrom, FutureResult};
        use http::method::Method;
        use http::{Request as HttpRequest, Response as HttpResponse};
        use ruma_identifiers::{RoomAliasId, RoomId};
        use serde_json;

        use super::super::{Endpoint as ApiEndpoint, Error, Metadata};

        #[derive(Debug)]
        pub struct Endpoint;

        impl ApiEndpoint<Vec<u8>, Vec<u8>> for Endpoint {
            type Request = Request;
            type Response = Response;

            const METADATA: Metadata = Metadata {
                description: "Add an alias to a room.",
                method: Method::PUT,
                name: "create_alias",
                path: "/_matrix/client/r0/directory/room/:room_alias",
                rate_limited: false,
                requires_authentication: true,
            };
        }

        /// A request to create a new room alias.
        #[derive(Debug)]
        pub struct Request {
            pub room_id: RoomId,         // body
            pub room_alias: RoomAliasId, // path
        }

        #[derive(Debug, Serialize)]
        struct RequestBody {
            room_id: RoomId,
        }

        impl TryFrom<Request> for HttpRequest<Vec<u8>> {
            type Error = Error;

            fn try_from(request: Request) -> Result<HttpRequest<Vec<u8>>, Self::Error> {
                let metadata = Endpoint::METADATA;

                let path = metadata
                    .path
                    .to_string()
                    .replace(":room_alias", &request.room_alias.to_string());

                let request_body = RequestBody {
                    room_id: request.room_id,
                };

                let http_request = HttpRequest::builder()
                    .method(metadata.method)
                    .uri(path.as_ref())
                    .body(serde_json::to_vec(&request_body).map_err(Error::from)?)?;

                Ok(http_request)
            }
        }

        /// The response to a request to create a new room alias.
        pub struct Response;

        impl FutureFrom<HttpResponse<Vec<u8>>> for Response {
            type Future = FutureResult<Self, Self::Error>;
            type Error = Error;

            fn future_from(
                http_response: HttpResponse<Vec<u8>>,
            ) -> FutureResult<Self, Self::Error> {
                if http_response.status().is_success() {
                    ok(Response)
                } else {
                    err(Error::StatusCode(http_response.status().clone()))
                }
            }
        }
    }
}
<commit_msg>Add a nonexhaustive variant to Error.<commit_after>//! Crate ruma_api contains core types used to define the requests and responses for each endpoint
//! in the various [Matrix](https://matrix.org) API specifications.
//! These types can be shared by client and server code for all Matrix APIs.
//!
//! When implementing a new Matrix API, each endpoint has a type that implements `Endpoint`, plus
//! the necessary associated types.
//! An implementation of `Endpoint` contains all the information about the HTTP method, the path and
//! input parameters for requests, and the structure of a successful response.
//! Such types can then be used by client code to make requests, and by server code to fulfill
//! those requests.
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]
#![feature(try_from)]

extern crate futures;
extern crate http;
#[cfg(test)]
extern crate ruma_identifiers;
#[cfg(test)]
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde_urlencoded;

use std::convert::TryInto;
use std::io;

use futures::future::FutureFrom;
use http::{Method, Request, Response, StatusCode};

/// A Matrix API endpoint.
pub trait Endpoint<T, U> {
    /// Data needed to make a request to the endpoint.
    type Request: TryInto<Request<T>, Error = Error>;
    /// Data returned from the endpoint.
    type Response: FutureFrom<Response<U>, Error = Error>;

    /// Metadata about the endpoint.
    const METADATA: Metadata;
}

/// An error when converting an `Endpoint::Request` to a `http::Request` or a `http::Response` to
/// an `Endpoint::Response`.
#[derive(Debug)]
pub enum Error {
    /// An HTTP error.
    Http(http::Error),
    /// A I/O error.
    Io(io::Error),
    /// A Serde JSON error.
    SerdeJson(serde_json::Error),
    /// A Serde URL encoding error.
    SerdeUrlEncoded(serde_urlencoded::ser::Error),
    /// An HTTP status code indicating error.
    StatusCode(StatusCode),
    /// Standard hack to prevent exhaustive matching.
    /// This will be replaced by the #[non_exhaustive] feature when available.
    #[doc(hidden)]
    __Nonexhaustive,
}

impl From<http::Error> for Error {
    fn from(error: http::Error) -> Self {
        Error::Http(error)
    }
}

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

impl From<serde_json::Error> for Error {
    fn from(error: serde_json::Error) -> Self {
        Error::SerdeJson(error)
    }
}

impl From<serde_urlencoded::ser::Error> for Error {
    fn from(error: serde_urlencoded::ser::Error) -> Self {
        Error::SerdeUrlEncoded(error)
    }
}

/// Metadata about an API endpoint.
#[derive(Clone, Debug)]
pub struct Metadata {
    /// A human-readable description of the endpoint.
    pub description: &'static str,
    /// The HTTP method used by this endpoint.
    pub method: Method,
    /// A unique identifier for this endpoint.
    pub name: &'static str,
    /// The path of this endpoint's URL, with variable names where path parameters should be filled
    /// in during a request.
    pub path: &'static str,
    /// Whether or not this endpoint is rate limited by the server.
    pub rate_limited: bool,
    /// Whether or not the server requires an authenticated user for this endpoint.
    pub requires_authentication: bool,
}

#[cfg(test)]
mod tests {
    /// PUT /_matrix/client/r0/directory/room/:room_alias
    pub mod create {
        use std::convert::TryFrom;

        use futures::future::{err, ok, FutureFrom, FutureResult};
        use http::method::Method;
        use http::{Request as HttpRequest, Response as HttpResponse};
        use ruma_identifiers::{RoomAliasId, RoomId};
        use serde_json;

        use super::super::{Endpoint as ApiEndpoint, Error, Metadata};

        #[derive(Debug)]
        pub struct Endpoint;

        impl ApiEndpoint<Vec<u8>, Vec<u8>> for Endpoint {
            type Request = Request;
            type Response = Response;

            const METADATA: Metadata = Metadata {
                description: "Add an alias to a room.",
                method: Method::PUT,
                name: "create_alias",
                path: "/_matrix/client/r0/directory/room/:room_alias",
                rate_limited: false,
                requires_authentication: true,
            };
        }

        /// A request to create a new room alias.
        #[derive(Debug)]
        pub struct Request {
            pub room_id: RoomId,         // body
            pub room_alias: RoomAliasId, // path
        }

        #[derive(Debug, Serialize)]
        struct RequestBody {
            room_id: RoomId,
        }

        impl TryFrom<Request> for HttpRequest<Vec<u8>> {
            type Error = Error;

            fn try_from(request: Request) -> Result<HttpRequest<Vec<u8>>, Self::Error> {
                let metadata = Endpoint::METADATA;

                let path = metadata
                    .path
                    .to_string()
                    .replace(":room_alias", &request.room_alias.to_string());

                let request_body = RequestBody {
                    room_id: request.room_id,
                };

                let http_request = HttpRequest::builder()
                    .method(metadata.method)
                    .uri(path.as_ref())
                    .body(serde_json::to_vec(&request_body).map_err(Error::from)?)?;

                Ok(http_request)
            }
        }

        /// The response to a request to create a new room alias.
        pub struct Response;

        impl FutureFrom<HttpResponse<Vec<u8>>> for Response {
            type Future = FutureResult<Self, Self::Error>;
            type Error = Error;

            fn future_from(
                http_response: HttpResponse<Vec<u8>>,
            ) -> FutureResult<Self, Self::Error> {
                if http_response.status().is_success() {
                    ok(Response)
                } else {
                    err(Error::StatusCode(http_response.status().clone()))
                }
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>os specific clean<commit_after><|endoftext|>


<commit_before><commit_msg>Add Adapter pattern in Rust<commit_after>/*
 * Adapter Design Pattern
 * http://joshldavis.com/design-patterns/adapter/
 */

/*
 * Core Trait that defines a basic Rocket Ship
 */
trait RocketShip {
    fn turn_on(&self);
    fn turn_off(&self);
    fn blast_off(&self);
    fn fly(&self);
}

/*
 * Basic struct for a NASA Ship
 */
struct NASAShip;

/*
 * Implement RocketShip trait to add functionality to NASAShip
 */
impl RocketShip for NASAShip {
    fn turn_on(&self) {
        println("NASA Ship is turning on.")
    }

    fn turn_off(&self) {
        println("NASA Ship is turning off.")
    }

    fn blast_off(&self) {
        println("NASA Ship is blasting off.")
    }

    fn fly(&self) {
        println("NASA Ship is flying away.")
    }
}

/*
 * Uh oh, here is our problem. It's the amazingly advanced SpaceX ship that our
 * astronaut doesn't know how to pilot.
 */
trait SpaceXShip {
    fn ignition(&self);
    fn on(&self);
    fn off(&self);
    fn launch(&self);
    fn fly(&self);
}

struct SpaceXDragon;

impl SpaceXShip for SpaceXDragon {
    fn ignition(&self) {
        println("Turning Dragon's ignition.")
    }

    fn on(&self) {
        println("Turning on the Dragon.")
    }

    fn off(&self) {
        println("Turing off the Dragon.")
    }

    fn launch(&self) {
        println("Launching the Dragon")
    }

    fn fly(&self) {
        println("The Dragon is flying away.")
    }
}

struct SpaceXAdapter {
    ship: SpaceXDragon
}

impl RocketShip for SpaceXAdapter {
    fn turn_on(&self) {
        self.ship.ignition();
        self.ship.on();
    }

    fn turn_off(&self) {
        self.ship.off();
    }

    fn blast_off(&self) {
        self.ship.launch();
    }

    fn fly(&self) {
        self.ship.fly();
    }
}

fn pilot<S: RocketShip>(ship: &S) {
    ship.turn_on();
    ship.blast_off();
    ship.fly();
    ship.turn_off();
    print("\n");
}

fn main() {
    let saturn5 = NASAShip;

    // Let's fly our NASAShip
    println("Piloting the Saturn 5.");
    pilot(&saturn5);

    let dragon = SpaceXDragon;

    // Uh oh, our pilot function doesn't recognize this ship...
    // println("Piloting the Dragon.");
    // pilot(&dragon); <-- Gives a compile time error.

    // Let's Adapt our SpaceXDragon ship
    let dragon_adapter = SpaceXAdapter {
        ship: dragon
    };

    // Now we can pilot the Dragon!
    println("Piloting the Dragon Adapter.");
    pilot(&dragon_adapter);
}
<|endoftext|>


<commit_before><commit_msg>Got grid generation working for day 13, taking checkpoint before trying to solve pathfinding.<commit_after><|endoftext|>


<commit_before><commit_msg>add skeleton for deck struct<commit_after><|endoftext|>


<commit_before><commit_msg>Creating 'safe' (native) rust wrappers around unsafe FFI<commit_after><|endoftext|>


<commit_before><commit_msg>Move a square in any direction on the screen.<commit_after><|endoftext|>


<commit_before><commit_msg>Put a mirror transform in main pipeline.<commit_after><|endoftext|>


<commit_before><commit_msg>Codeforces 764B<commit_after>macro_rules! read_line {
    ($v:ident) => {
        let mut temp = String::new();
        std::io::stdin().read_line(&mut temp).unwrap();
        let $v = temp;
    };
    (var, $t:ty, $($v:ident), *) => {
        read_line!(input_line);
        let mut iter = parse_token!($t, input_line);
        $(
            let $v = iter.next().unwrap();
        )*
    };
    (vec, $t:ty, $v:ident) => {
        read_line!(input_line);
        let iter = parse_token!($t, input_line);
        let $v: Vec<$t> = iter.collect();
    };
    ($($v:ident; $t:ty), *) => {
        read_line!(input_line);
        let mut iter = input_line.split_whitespace();
        $(
            let $v: $t = iter.next().unwrap().parse().unwrap();
        )*
    };
}

macro_rules! parse_token {
    ($t:ty, $e:expr) => {
        $e.split_whitespace().map(|x| x.parse::<$t>().unwrap());
    };
}

fn main() {
    read_line!(cube_count;usize);
    read_line!(vec,i32,cubes);
    let mid = cube_count / 2;
    for i in 0..cube_count {
        let mut reversed = true;
        if i < mid {
            reversed = i % 2 == 0;
        } else {
            reversed = (cube_count - 1 - i) % 2 == 0;
        }
        if reversed {
            print!("{} ", cubes[cube_count - 1 - i]);
        } else {
            print!("{} ", cubes[i]);
        }
    }
}<|endoftext|>


<commit_before><commit_msg>Make program print contents of file passed by command line<commit_after><|endoftext|>


<commit_before><commit_msg>Set ion as a process group<commit_after><|endoftext|>


<commit_before><commit_msg>:art: Change the location of config file<commit_after><|endoftext|>


<commit_before><commit_msg>Implemented a simple Hello World example<commit_after>extern crate pancurses;

use pancurses::{initscr, printw, refresh, endwin};

fn main() {
    let window = initscr();
    printw("Hello Rust");
    refresh();
    window.getch();
    endwin();
}
<|endoftext|>


<commit_before><commit_msg>Chore(trash): fix another import warning<commit_after><|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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.

use std::cmp::Ordering;

use syntax::ast::{self, Visibility, Attribute, MetaItem, MetaItem_};
use syntax::codemap::{CodeMap, Span, BytePos};
use syntax::abi;

use Indent;
use comment::FindUncommented;
use rewrite::{Rewrite, RewriteContext};

use SKIP_ANNOTATION;

// Computes the length of a string's last line, minus offset.
#[inline]
pub fn extra_offset(text: &str, offset: Indent) -> usize {
    match text.rfind('\n') {
        // 1 for newline character
        Some(idx) => text.len() - idx - 1 - offset.width(),
        None => text.len(),
    }
}

#[inline]
pub fn span_after(original: Span, needle: &str, codemap: &CodeMap) -> BytePos {
    let snippet = codemap.span_to_snippet(original).unwrap();
    let offset = snippet.find_uncommented(needle).unwrap() + needle.len();

    original.lo + BytePos(offset as u32)
}

#[inline]
pub fn span_after_last(original: Span, needle: &str, codemap: &CodeMap) -> BytePos {
    let snippet = codemap.span_to_snippet(original).unwrap();
    let mut offset = 0;

    while let Some(additional_offset) = snippet[offset..].find_uncommented(needle) {
        offset += additional_offset + needle.len();
    }

    original.lo + BytePos(offset as u32)
}

#[inline]
pub fn format_visibility(vis: Visibility) -> &'static str {
    match vis {
        Visibility::Public => "pub ",
        Visibility::Inherited => "",
    }
}

#[inline]
pub fn format_unsafety(unsafety: ast::Unsafety) -> &'static str {
    match unsafety {
        ast::Unsafety::Unsafe => "unsafe ",
        ast::Unsafety::Normal => "",
    }
}

#[inline]
pub fn format_mutability(mutability: ast::Mutability) -> &'static str {
    match mutability {
        ast::Mutability::MutMutable => "mut ",
        ast::Mutability::MutImmutable => "",
    }
}

#[inline]
// FIXME(#451): include "C"?
pub fn format_abi(abi: abi::Abi) -> String {
    format!("extern {} ", abi)
}

// The width of the first line in s.
#[inline]
pub fn first_line_width(s: &str) -> usize {
    match s.find('\n') {
        Some(n) => n,
        None => s.len(),
    }
}

// The width of the last line in s.
#[inline]
pub fn last_line_width(s: &str) -> usize {
    match s.rfind('\n') {
        Some(n) => s.len() - n - 1,
        None => s.len(),
    }
}

#[inline]
fn is_skip(meta_item: &MetaItem) -> bool {
    match meta_item.node {
        MetaItem_::MetaWord(ref s) => *s == SKIP_ANNOTATION,
        MetaItem_::MetaList(ref s, ref l) => *s == "cfg_attr" && l.len() == 2 && is_skip(&l[1]),
        _ => false,
    }
}

#[inline]
pub fn contains_skip(attrs: &[Attribute]) -> bool {
    attrs.iter().any(|a| is_skip(&a.node.value))
}

// Find the end of a TyParam
#[inline]
pub fn end_typaram(typaram: &ast::TyParam) -> BytePos {
    typaram.bounds
           .last()
           .map(|bound| {
               match *bound {
                   ast::RegionTyParamBound(ref lt) => lt.span,
                   ast::TraitTyParamBound(ref prt, _) => prt.span,
               }
           })
           .unwrap_or(typaram.span)
           .hi
}

#[inline]
pub fn semicolon_for_expr(expr: &ast::Expr) -> bool {
    match expr.node {
        ast::Expr_::ExprRet(..) |
        ast::Expr_::ExprAgain(..) |
        ast::Expr_::ExprBreak(..) => true,
        _ => false,
    }
}

#[inline]
pub fn semicolon_for_stmt(stmt: &ast::Stmt) -> bool {
    match stmt.node {
        ast::Stmt_::StmtSemi(ref expr, _) => {
            match expr.node {
                ast::Expr_::ExprWhile(..) |
                ast::Expr_::ExprWhileLet(..) |
                ast::Expr_::ExprLoop(..) |
                ast::Expr_::ExprForLoop(..) => false,
                _ => true,
            }
        }
        ast::Stmt_::StmtExpr(..) => false,
        _ => true,
    }
}

#[inline]
pub fn trim_newlines(input: &str) -> &str {
    match input.find(|c| c != '\n' && c != '\r') {
        Some(start) => {
            let end = input.rfind(|c| c != '\n' && c != '\r').unwrap_or(0) + 1;
            &input[start..end]
        }
        None => "",
    }
}

#[inline]
#[cfg(target_pointer_width="64")]
// Based on the trick layed out at
// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
pub fn round_up_to_power_of_two(mut x: usize) -> usize {
    x = x.wrapping_sub(1);
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    x |= x >> 32;
    x.wrapping_add(1)
}

#[inline]
#[cfg(target_pointer_width="32")]
pub fn round_up_to_power_of_two(mut x: usize) -> usize {
    x = x.wrapping_sub(1);
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    x.wrapping_add(1)
}

// Macro for deriving implementations of Decodable for enums
#[macro_export]
macro_rules! impl_enum_decodable {
    ( $e:ident, $( $x:ident ),* ) => {
        impl ::rustc_serialize::Decodable for $e {
            fn decode<D: ::rustc_serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
                let s = try!(d.read_str());
                match &*s {
                    $(
                        stringify!($x) => Ok($e::$x),
                    )*
                    _ => Err(d.error("Bad variant")),
                }
            }
        }

        impl ::std::str::FromStr for $e {
            type Err = &'static str;

            fn from_str(s: &str) -> Result<Self, Self::Err> {
                match &*s {
                    $(
                        stringify!($x) => Ok($e::$x),
                    )*
                    _ => Err("Bad variant"),
                }
            }
        }

        impl ::config::ConfigType for $e {
            fn get_variant_names() -> String {
                let mut variants = Vec::new();
                $(
                    variants.push(stringify!($x));
                )*
                format!("[{}]", variants.join("|"))
            }
        }
    };
}

// Same as try!, but for Option
#[macro_export]
macro_rules! try_opt {
    ($expr:expr) => (match $expr {
        Some(val) => val,
        None => { return None; }
    })
}

// Wraps string-like values in an Option. Returns Some when the string adheres
// to the Rewrite constraints defined for the Rewrite trait and else otherwise.
pub fn wrap_str<S: AsRef<str>>(s: S, max_width: usize, width: usize, offset: Indent) -> Option<S> {
    {
        let snippet = s.as_ref();

        if !snippet.contains('\n') && snippet.len() > width {
            return None;
        } else {
            let mut lines = snippet.lines();

            // The caller of this function has already placed `offset`
            // characters on the first line.
            let first_line_max_len = try_opt!(max_width.checked_sub(offset.width()));
            if lines.next().unwrap().len() > first_line_max_len {
                return None;
            }

            // The other lines must fit within the maximum width.
            if lines.find(|line| line.len() > max_width).is_some() {
                return None;
            }

            // `width` is the maximum length of the last line, excluding
            // indentation.
            // A special check for the last line, since the caller may
            // place trailing characters on this line.
            if snippet.lines().rev().next().unwrap().len() > offset.width() + width {
                return None;
            }
        }
    }

    Some(s)
}

impl Rewrite for String {
    fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> {
        wrap_str(self, context.config.max_width, width, offset).map(ToOwned::to_owned)
    }
}

// Binary search in integer range. Returns the first Ok value returned by the
// callback.
// The callback takes an integer and returns either an Ok, or an Err indicating
// whether the `guess' was too high (Ordering::Less), or too low.
// This function is guaranteed to try to the hi value first.
pub fn binary_search<C, T>(mut lo: usize, mut hi: usize, callback: C) -> Option<T>
    where C: Fn(usize) -> Result<T, Ordering>
{
    let mut middle = hi;

    while lo <= hi {
        match callback(middle) {
            Ok(val) => return Some(val),
            Err(Ordering::Less) => {
                hi = middle - 1;
            }
            Err(..) => {
                lo = middle + 1;
            }
        }
        middle = (hi + lo) / 2;
    }

    None
}

#[test]
fn bin_search_test() {
    let closure = |i| {
        match i {
            4 => Ok(()),
            j if j > 4 => Err(Ordering::Less),
            j if j < 4 => Err(Ordering::Greater),
            _ => unreachable!(),
        }
    };

    assert_eq!(Some(()), binary_search(1, 10, &closure));
    assert_eq!(None, binary_search(1, 3, &closure));
    assert_eq!(Some(()), binary_search(0, 44, &closure));
    assert_eq!(Some(()), binary_search(4, 125, &closure));
    assert_eq!(None, binary_search(6, 100, &closure));
}

#[test]
fn power_rounding() {
    assert_eq!(0, round_up_to_power_of_two(0));
    assert_eq!(1, round_up_to_power_of_two(1));
    assert_eq!(64, round_up_to_power_of_two(33));
    assert_eq!(256, round_up_to_power_of_two(256));
}
<commit_msg>ignore case for config enums. Fixes #738<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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.

use std::cmp::Ordering;

use syntax::ast::{self, Visibility, Attribute, MetaItem, MetaItem_};
use syntax::codemap::{CodeMap, Span, BytePos};
use syntax::abi;

use Indent;
use comment::FindUncommented;
use rewrite::{Rewrite, RewriteContext};

use SKIP_ANNOTATION;

// Computes the length of a string's last line, minus offset.
#[inline]
pub fn extra_offset(text: &str, offset: Indent) -> usize {
    match text.rfind('\n') {
        // 1 for newline character
        Some(idx) => text.len() - idx - 1 - offset.width(),
        None => text.len(),
    }
}

#[inline]
pub fn span_after(original: Span, needle: &str, codemap: &CodeMap) -> BytePos {
    let snippet = codemap.span_to_snippet(original).unwrap();
    let offset = snippet.find_uncommented(needle).unwrap() + needle.len();

    original.lo + BytePos(offset as u32)
}

#[inline]
pub fn span_after_last(original: Span, needle: &str, codemap: &CodeMap) -> BytePos {
    let snippet = codemap.span_to_snippet(original).unwrap();
    let mut offset = 0;

    while let Some(additional_offset) = snippet[offset..].find_uncommented(needle) {
        offset += additional_offset + needle.len();
    }

    original.lo + BytePos(offset as u32)
}

#[inline]
pub fn format_visibility(vis: Visibility) -> &'static str {
    match vis {
        Visibility::Public => "pub ",
        Visibility::Inherited => "",
    }
}

#[inline]
pub fn format_unsafety(unsafety: ast::Unsafety) -> &'static str {
    match unsafety {
        ast::Unsafety::Unsafe => "unsafe ",
        ast::Unsafety::Normal => "",
    }
}

#[inline]
pub fn format_mutability(mutability: ast::Mutability) -> &'static str {
    match mutability {
        ast::Mutability::MutMutable => "mut ",
        ast::Mutability::MutImmutable => "",
    }
}

#[inline]
// FIXME(#451): include "C"?
pub fn format_abi(abi: abi::Abi) -> String {
    format!("extern {} ", abi)
}

// The width of the first line in s.
#[inline]
pub fn first_line_width(s: &str) -> usize {
    match s.find('\n') {
        Some(n) => n,
        None => s.len(),
    }
}

// The width of the last line in s.
#[inline]
pub fn last_line_width(s: &str) -> usize {
    match s.rfind('\n') {
        Some(n) => s.len() - n - 1,
        None => s.len(),
    }
}

#[inline]
fn is_skip(meta_item: &MetaItem) -> bool {
    match meta_item.node {
        MetaItem_::MetaWord(ref s) => *s == SKIP_ANNOTATION,
        MetaItem_::MetaList(ref s, ref l) => *s == "cfg_attr" && l.len() == 2 && is_skip(&l[1]),
        _ => false,
    }
}

#[inline]
pub fn contains_skip(attrs: &[Attribute]) -> bool {
    attrs.iter().any(|a| is_skip(&a.node.value))
}

// Find the end of a TyParam
#[inline]
pub fn end_typaram(typaram: &ast::TyParam) -> BytePos {
    typaram.bounds
           .last()
           .map(|bound| {
               match *bound {
                   ast::RegionTyParamBound(ref lt) => lt.span,
                   ast::TraitTyParamBound(ref prt, _) => prt.span,
               }
           })
           .unwrap_or(typaram.span)
           .hi
}

#[inline]
pub fn semicolon_for_expr(expr: &ast::Expr) -> bool {
    match expr.node {
        ast::Expr_::ExprRet(..) |
        ast::Expr_::ExprAgain(..) |
        ast::Expr_::ExprBreak(..) => true,
        _ => false,
    }
}

#[inline]
pub fn semicolon_for_stmt(stmt: &ast::Stmt) -> bool {
    match stmt.node {
        ast::Stmt_::StmtSemi(ref expr, _) => {
            match expr.node {
                ast::Expr_::ExprWhile(..) |
                ast::Expr_::ExprWhileLet(..) |
                ast::Expr_::ExprLoop(..) |
                ast::Expr_::ExprForLoop(..) => false,
                _ => true,
            }
        }
        ast::Stmt_::StmtExpr(..) => false,
        _ => true,
    }
}

#[inline]
pub fn trim_newlines(input: &str) -> &str {
    match input.find(|c| c != '\n' && c != '\r') {
        Some(start) => {
            let end = input.rfind(|c| c != '\n' && c != '\r').unwrap_or(0) + 1;
            &input[start..end]
        }
        None => "",
    }
}

#[inline]
#[cfg(target_pointer_width="64")]
// Based on the trick layed out at
// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
pub fn round_up_to_power_of_two(mut x: usize) -> usize {
    x = x.wrapping_sub(1);
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    x |= x >> 32;
    x.wrapping_add(1)
}

#[inline]
#[cfg(target_pointer_width="32")]
pub fn round_up_to_power_of_two(mut x: usize) -> usize {
    x = x.wrapping_sub(1);
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    x.wrapping_add(1)
}

// Macro for deriving implementations of Decodable for enums
#[macro_export]
macro_rules! impl_enum_decodable {
    ( $e:ident, $( $x:ident ),* ) => {
        impl ::rustc_serialize::Decodable for $e {
            fn decode<D: ::rustc_serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
                use std::ascii::AsciiExt;
                let s = try!(d.read_str());
                $(
                    if stringify!($x).eq_ignore_ascii_case(&s) {
                      return Ok($e::$x);
                    }
                )*
                Err(d.error("Bad variant"))
            }
        }

        impl ::std::str::FromStr for $e {
            type Err = &'static str;

            fn from_str(s: &str) -> Result<Self, Self::Err> {
                use std::ascii::AsciiExt;
                $(
                    if stringify!($x).eq_ignore_ascii_case(s) {
                        return Ok($e::$x);
                    }
                )*
                Err("Bad variant")
            }
        }

        impl ::config::ConfigType for $e {
            fn get_variant_names() -> String {
                let mut variants = Vec::new();
                $(
                    variants.push(stringify!($x));
                )*
                format!("[{}]", variants.join("|"))
            }
        }
    };
}

// Same as try!, but for Option
#[macro_export]
macro_rules! try_opt {
    ($expr:expr) => (match $expr {
        Some(val) => val,
        None => { return None; }
    })
}

// Wraps string-like values in an Option. Returns Some when the string adheres
// to the Rewrite constraints defined for the Rewrite trait and else otherwise.
pub fn wrap_str<S: AsRef<str>>(s: S, max_width: usize, width: usize, offset: Indent) -> Option<S> {
    {
        let snippet = s.as_ref();

        if !snippet.contains('\n') && snippet.len() > width {
            return None;
        } else {
            let mut lines = snippet.lines();

            // The caller of this function has already placed `offset`
            // characters on the first line.
            let first_line_max_len = try_opt!(max_width.checked_sub(offset.width()));
            if lines.next().unwrap().len() > first_line_max_len {
                return None;
            }

            // The other lines must fit within the maximum width.
            if lines.find(|line| line.len() > max_width).is_some() {
                return None;
            }

            // `width` is the maximum length of the last line, excluding
            // indentation.
            // A special check for the last line, since the caller may
            // place trailing characters on this line.
            if snippet.lines().rev().next().unwrap().len() > offset.width() + width {
                return None;
            }
        }
    }

    Some(s)
}

impl Rewrite for String {
    fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> {
        wrap_str(self, context.config.max_width, width, offset).map(ToOwned::to_owned)
    }
}

// Binary search in integer range. Returns the first Ok value returned by the
// callback.
// The callback takes an integer and returns either an Ok, or an Err indicating
// whether the `guess' was too high (Ordering::Less), or too low.
// This function is guaranteed to try to the hi value first.
pub fn binary_search<C, T>(mut lo: usize, mut hi: usize, callback: C) -> Option<T>
    where C: Fn(usize) -> Result<T, Ordering>
{
    let mut middle = hi;

    while lo <= hi {
        match callback(middle) {
            Ok(val) => return Some(val),
            Err(Ordering::Less) => {
                hi = middle - 1;
            }
            Err(..) => {
                lo = middle + 1;
            }
        }
        middle = (hi + lo) / 2;
    }

    None
}

#[test]
fn bin_search_test() {
    let closure = |i| {
        match i {
            4 => Ok(()),
            j if j > 4 => Err(Ordering::Less),
            j if j < 4 => Err(Ordering::Greater),
            _ => unreachable!(),
        }
    };

    assert_eq!(Some(()), binary_search(1, 10, &closure));
    assert_eq!(None, binary_search(1, 3, &closure));
    assert_eq!(Some(()), binary_search(0, 44, &closure));
    assert_eq!(Some(()), binary_search(4, 125, &closure));
    assert_eq!(None, binary_search(6, 100, &closure));
}

#[test]
fn power_rounding() {
    assert_eq!(0, round_up_to_power_of_two(0));
    assert_eq!(1, round_up_to_power_of_two(1));
    assert_eq!(64, round_up_to_power_of_two(33));
    assert_eq!(256, round_up_to_power_of_two(256));
}
<|endoftext|>


<commit_before><commit_msg>Problem: server command not implemented<commit_after><|endoftext|>


<commit_before><commit_msg>Add protoyping file<commit_after>use std::ops::Index;

trait Point
{}

struct Point1D
{
  x: usize,
}
mod abs
{
  pub trait Signal
  {
    type valueType;
    type pointType;
  }
}

trait Signal<T: abs::Signal> : Index<T::pointType>
{}

struct Signal1D<T>
{
  arr: Box<[T]>,
}

impl <T: Copy> Signal1D<T>
{
  fn new( init_value: T, size: usize) -> Signal1D<T>
  {
    let mut vec: Vec<T> = Vec::with_capacity(size);
    for _ in 0 .. size
    {
      vec.push(init_value);
    };
    Signal1D {arr: vec.into_boxed_slice()}
  }
}

impl <T> abs::Signal for Signal1D<T>
{
  type valueType = T;
  type pointType = Point1D;
}

impl <T> Signal<Signal1D<T>> for Signal1D<T> {}

impl <T> Index<Point1D> for Signal1D<T>
{
  type Output = T;
   fn index<'a>(&'a self, _index: Point1D) -> &'a T
   {
        &self.arr[_index.x]
   }
}

fn main()
{
  let a :Signal1D<i32> = Signal1D::new(0, 10);
  let b = Point1D{x:0};

  println!("{}", a[b]);

}
<|endoftext|>


<commit_before>use crate::core::compiler::RustcTargetData;
use crate::core::resolver::HasDevUnits;
use crate::core::{Shell, Workspace};
use crate::ops;
use crate::util::CargoResult;
use serde::Deserialize;
use std::collections::HashMap;
use std::ffi::OsString;
use std::path::Path;
use std::process::Command;

/// Strongly typed options for the `cargo doc` command.
#[derive(Debug)]
pub struct DocOptions {
    /// Whether to attempt to open the browser after compiling the docs
    pub open_result: bool,
    /// Options to pass through to the compiler
    pub compile_opts: ops::CompileOptions,
}

#[derive(Deserialize)]
struct CargoDocConfig {
    /// Browser to use to open docs. If this is unset, the value of the environment variable
    /// `BROWSER` will be used.
    browser: Option<String>,
}

/// Main method for `cargo doc`.
pub fn doc(ws: &Workspace<'_>, options: &DocOptions) -> CargoResult<()> {
    let specs = options.compile_opts.spec.to_package_id_specs(ws)?;
    let target_data = RustcTargetData::new(ws, &options.compile_opts.build_config.requested_kinds)?;
    let ws_resolve = ops::resolve_ws_with_opts(
        ws,
        &target_data,
        &options.compile_opts.build_config.requested_kinds,
        &options.compile_opts.cli_features,
        &specs,
        HasDevUnits::No,
        crate::core::resolver::features::ForceAllTargets::No,
    )?;

    let ids = ws_resolve.targeted_resolve.specs_to_ids(&specs)?;
    let pkgs = ws_resolve.pkg_set.get_many(ids)?;

    let mut lib_names = HashMap::new();
    let mut bin_names = HashMap::new();
    let mut names = Vec::new();
    for package in &pkgs {
        for target in package.targets().iter().filter(|t| t.documented()) {
            if target.is_lib() {
                if let Some(prev) = lib_names.insert(target.crate_name(), package) {
                    anyhow::bail!(
                        "The library `{}` is specified by packages `{}` and \
                         `{}` but can only be documented once. Consider renaming \
                         or marking one of the targets as `doc = false`.",
                        target.crate_name(),
                        prev,
                        package
                    );
                }
            } else if let Some(prev) = bin_names.insert(target.crate_name(), package) {
                anyhow::bail!(
                    "The binary `{}` is specified by packages `{}` and \
                     `{}` but can be documented only once. Consider renaming \
                     or marking one of the targets as `doc = false`.",
                    target.crate_name(),
                    prev,
                    package
                );
            }
            names.push(target.crate_name());
        }
    }

    let open_kind = if options.open_result {
        Some(options.compile_opts.build_config.single_requested_kind()?)
    } else {
        None
    };

    let compilation = ops::compile(ws, &options.compile_opts)?;

    if let Some(kind) = open_kind {
        let name = match names.first() {
            Some(s) => s.to_string(),
            None => return Ok(()),
        };
        let path = compilation.root_output[&kind]
            .with_file_name("doc")
            .join(&name)
            .join("index.html");
        if path.exists() {
            let mut shell = ws.config().shell();
            shell.status("Opening", path.display())?;
            let cfg = ws.config().get::<CargoDocConfig>("cargo-doc")?;
            open_docs(&path, &mut shell, cfg.browser.map(|v| v.into()))?;
        }
    }

    Ok(())
}

fn open_docs(path: &Path, shell: &mut Shell, config_browser: Option<OsString>) -> CargoResult<()> {
    let browser = config_browser.or_else(|| std::env::var_os("BROWSER"));
    match browser {
        Some(browser) => {
            if let Err(e) = Command::new(&browser).arg(path).status() {
                shell.warn(format!(
                    "Couldn't open docs with {}: {}",
                    browser.to_string_lossy(),
                    e
                ))?;
            }
        }
        None => {
            if let Err(e) = opener::open(&path) {
                let e = e.into();
                crate::display_warning_with_error("couldn't open docs", &e, shell);
            }
        }
    };

    Ok(())
}
<commit_msg>Move browser setting to [doc], use PathAndArgs<commit_after>use crate::core::resolver::HasDevUnits;
use crate::core::{Shell, Workspace};
use crate::ops;
use crate::util::CargoResult;
use crate::{core::compiler::RustcTargetData, util::config::PathAndArgs};
use serde::Deserialize;
use std::path::Path;
use std::process::Command;
use std::{collections::HashMap, path::PathBuf};

/// Strongly typed options for the `cargo doc` command.
#[derive(Debug)]
pub struct DocOptions {
    /// Whether to attempt to open the browser after compiling the docs
    pub open_result: bool,
    /// Options to pass through to the compiler
    pub compile_opts: ops::CompileOptions,
}

#[derive(Deserialize)]
struct CargoDocConfig {
    /// Browser to use to open docs. If this is unset, the value of the environment variable
    /// `BROWSER` will be used.
    browser: Option<PathAndArgs>,
}

/// Main method for `cargo doc`.
pub fn doc(ws: &Workspace<'_>, options: &DocOptions) -> CargoResult<()> {
    let specs = options.compile_opts.spec.to_package_id_specs(ws)?;
    let target_data = RustcTargetData::new(ws, &options.compile_opts.build_config.requested_kinds)?;
    let ws_resolve = ops::resolve_ws_with_opts(
        ws,
        &target_data,
        &options.compile_opts.build_config.requested_kinds,
        &options.compile_opts.cli_features,
        &specs,
        HasDevUnits::No,
        crate::core::resolver::features::ForceAllTargets::No,
    )?;

    let ids = ws_resolve.targeted_resolve.specs_to_ids(&specs)?;
    let pkgs = ws_resolve.pkg_set.get_many(ids)?;

    let mut lib_names = HashMap::new();
    let mut bin_names = HashMap::new();
    let mut names = Vec::new();
    for package in &pkgs {
        for target in package.targets().iter().filter(|t| t.documented()) {
            if target.is_lib() {
                if let Some(prev) = lib_names.insert(target.crate_name(), package) {
                    anyhow::bail!(
                        "The library `{}` is specified by packages `{}` and \
                         `{}` but can only be documented once. Consider renaming \
                         or marking one of the targets as `doc = false`.",
                        target.crate_name(),
                        prev,
                        package
                    );
                }
            } else if let Some(prev) = bin_names.insert(target.crate_name(), package) {
                anyhow::bail!(
                    "The binary `{}` is specified by packages `{}` and \
                     `{}` but can be documented only once. Consider renaming \
                     or marking one of the targets as `doc = false`.",
                    target.crate_name(),
                    prev,
                    package
                );
            }
            names.push(target.crate_name());
        }
    }

    let open_kind = if options.open_result {
        Some(options.compile_opts.build_config.single_requested_kind()?)
    } else {
        None
    };

    let compilation = ops::compile(ws, &options.compile_opts)?;

    if let Some(kind) = open_kind {
        let name = match names.first() {
            Some(s) => s.to_string(),
            None => return Ok(()),
        };
        let path = compilation.root_output[&kind]
            .with_file_name("doc")
            .join(&name)
            .join("index.html");
        if path.exists() {
            let mut shell = ws.config().shell();
            shell.status("Opening", path.display())?;
            let cfg = ws.config().get::<CargoDocConfig>("doc")?;
            open_docs(
                &path,
                &mut shell,
                cfg.browser.map(|path_args| {
                    (path_args.path.resolve_program(&ws.config()), path_args.args)
                }),
            )?;
        }
    }

    Ok(())
}

fn open_docs(
    path: &Path,
    shell: &mut Shell,
    config_browser: Option<(PathBuf, Vec<String>)>,
) -> CargoResult<()> {
    let browser =
        config_browser.or_else(|| Some((PathBuf::from(std::env::var_os("BROWSER")?), Vec::new())));

    match browser {
        Some((browser, initial_args)) => {
            if let Err(e) = Command::new(&browser).args(initial_args).arg(path).status() {
                shell.warn(format!(
                    "Couldn't open docs with {}: {}",
                    browser.to_string_lossy(),
                    e
                ))?;
            }
        }
        None => {
            if let Err(e) = opener::open(&path) {
                let e = e.into();
                crate::display_warning_with_error("couldn't open docs", &e, shell);
            }
        }
    };

    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>Table driven tests (read/write, i32/i64)<commit_after><|endoftext|>


<commit_before><commit_msg>Add a fence method to combine wait and reset, which applies to all current uses<commit_after><|endoftext|>


<commit_before><commit_msg>Looking for a way to recognize EOF correctly.<commit_after>extern crate rand;

use rand::random;
use std::io::BufferedReader;
use std::io;

fn main() {
    println!("I'm thinking of a number between 1 and 100. Can you guess it?");
    let x = random();
    let mut reader = BufferedReader::new(io::stdin());
    while !reader.eof() {
        let line = reader.read_line().unwrap();
        let num = from_str::<int>(line.slice_to(line.len() - 1));
        match num {
            Some(number_string) => println!("Well, it was a number."),
            None                => println!("Doesn't count.")
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>docs(examples): add compaction_filter example code<commit_after>extern crate rocks;

use lazy_static::lazy_static;
use rocks::compaction_filter::{CompactionFilter, Decision, ValueType};
use rocks::merge_operator::{MergeOperationInput, MergeOperationOutput, MergeOperator};
use rocks::prelude::*;

pub struct MyMerge;

impl MergeOperator for MyMerge {
    fn full_merge(&self, merge_in: &MergeOperationInput, merge_out: &mut MergeOperationOutput) -> bool {
        if let Some(value) = merge_in.existing_value() {
            merge_out.assign(value);
        }
        for m in merge_in.operands() {
            eprintln!("Merge({:?})", String::from_utf8_lossy(m));
            // the compaction filter filters out bad values
            assert!(m != b"bad");
            merge_out.assign(m);
        }
        true
    }

    fn name(&self) -> &str {
        "MyMerge\0"
    }
}

#[derive(Debug, Default)]
pub struct MyFilter {
    count: usize,
    merge_count: usize,
}

impl CompactionFilter for MyFilter {
    // rust-rocks only impls the `FilterV2` API.
    fn filter(&mut self, _level: i32, key: &[u8], value_type: ValueType, existing_value: &[u8]) -> Decision {
        match value_type {
            ValueType::Value => {
                eprintln!("Filter({:?})", String::from_utf8_lossy(key));
                self.count += 1;
                Decision::Keep
            },
            ValueType::MergeOperand => {
                eprintln!("FilterMerge({:?})", String::from_utf8_lossy(key));
                self.merge_count += 1;
                if existing_value == b"bad" {
                    Decision::Remove
                } else {
                    Decision::Keep
                }
            },
        }
    }

    fn name(&self) -> &str {
        "MyFilterV2\0"
    }
}

lazy_static! {
    static ref MY_FILTER: MyFilter = MyFilter::default();
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    const DB_PATH: &str = "/tmp/rocksmergetest";

    let options = Options::default()
        .map_db_options(|opt| opt.create_if_missing(true))
        .map_cf_options(|opt| opt.merge_operator(Box::new(MyMerge)).compaction_filter(&*MY_FILTER));

    let db = DB::open(&options, DB_PATH)?;

    let wopts = WriteOptions::default_instance();
    db.merge(wopts, b"0", b"bad")?;
    db.merge(wopts, b"1", b"data1")?;
    db.merge(wopts, b"1", b"bad")?;
    db.merge(wopts, b"1", b"data2")?;
    db.merge(wopts, b"1", b"bad")?;
    db.merge(wopts, b"3", b"data3")?;

    db.compact_range(&CompactRangeOptions::default(), ..)?;

    println!("{:?}", &*MY_FILTER);

    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>Add test for #69312<commit_after>// build-pass

// Verify that the compiler doesn't ICE during const prop while evaluating the index operation.

#![allow(unconditional_panic)]

fn main() {
    let cols = [0u32; 0];
    cols[0];
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use url::Url;

use selectors::bloom::BloomFilter;
use selectors::matching::{SelectorMap, Rule};
use selectors::matching::DeclarationBlock as GenericDeclarationBlock;
use selectors::parser::PseudoElement;
use selectors::tree::TNode;
use util::resource_files::read_resource_file;
use util::smallvec::VecLike;

use legacy::PresentationalHintSynthesis;
use media_queries::Device;
use node::TElementAttributes;
use properties::{PropertyDeclaration, PropertyDeclarationBlock};
use stylesheets::{Stylesheet, CSSRuleIteratorExt, Origin};
use viewport::{ViewportConstraints, ViewportRuleCascade};

pub type DeclarationBlock = GenericDeclarationBlock<Vec<PropertyDeclaration>>;

pub struct Stylist {
    // List of stylesheets (including all media rules)
    stylesheets: Vec<Stylesheet>,

    // Device that the stylist is currently evaluating against.
    pub device: Device,

    // If true, a stylesheet has been added or the device has
    // changed, and the stylist needs to be updated.
    is_dirty: bool,

    // The current selector maps, after evaluating media
    // rules against the current device.
    element_map: PerPseudoElementSelectorMap,
    before_map: PerPseudoElementSelectorMap,
    after_map: PerPseudoElementSelectorMap,
    rules_source_order: usize,
}

impl Stylist {
    #[inline]
    pub fn new(device: Device) -> Stylist {
        let mut stylist = Stylist {
            stylesheets: vec!(),
            device: device,
            is_dirty: true,

            element_map: PerPseudoElementSelectorMap::new(),
            before_map: PerPseudoElementSelectorMap::new(),
            after_map: PerPseudoElementSelectorMap::new(),
            rules_source_order: 0,
        };
        // FIXME: Add iso-8859-9.css when the document’s encoding is ISO-8859-8.
        // FIXME: presentational-hints.css should be at author origin with zero specificity.
        //        (Does it make a difference?)
        for &filename in ["user-agent.css", "servo.css", "presentational-hints.css"].iter() {
            let ua_stylesheet = Stylesheet::from_bytes(
                &read_resource_file(&[filename]).unwrap(),
                Url::parse(&format!("chrome:///{:?}", filename)).unwrap(),
                None,
                None,
                Origin::UserAgent);
            stylist.add_stylesheet(ua_stylesheet);
        }
        stylist
    }

    pub fn constrain_viewport(&self) -> Option<ViewportConstraints> {
        let cascaded_rule = self.stylesheets.iter()
            .flat_map(|s| s.effective_rules(&self.device).viewport())
            .cascade();

        ViewportConstraints::maybe_new(self.device.viewport_size, &cascaded_rule)
    }

    pub fn update(&mut self) -> bool {
        if self.is_dirty {
            self.element_map = PerPseudoElementSelectorMap::new();
            self.before_map = PerPseudoElementSelectorMap::new();
            self.after_map = PerPseudoElementSelectorMap::new();
            self.rules_source_order = 0;

            for stylesheet in self.stylesheets.iter() {
                let (mut element_map, mut before_map, mut after_map) = match stylesheet.origin {
                    Origin::UserAgent => (
                        &mut self.element_map.user_agent,
                        &mut self.before_map.user_agent,
                        &mut self.after_map.user_agent,
                    ),
                    Origin::Author => (
                        &mut self.element_map.author,
                        &mut self.before_map.author,
                        &mut self.after_map.author,
                    ),
                    Origin::User => (
                        &mut self.element_map.user,
                        &mut self.before_map.user,
                        &mut self.after_map.user,
                    ),
                };
                let mut rules_source_order = self.rules_source_order;

                // Take apart the StyleRule into individual Rules and insert
                // them into the SelectorMap of that priority.
                macro_rules! append(
                    ($style_rule: ident, $priority: ident) => {
                        if $style_rule.declarations.$priority.len() > 0 {
                            for selector in $style_rule.selectors.iter() {
                                let map = match selector.pseudo_element {
                                    None => &mut element_map,
                                    Some(PseudoElement::Before) => &mut before_map,
                                    Some(PseudoElement::After) => &mut after_map,
                                };
                                map.$priority.insert(Rule {
                                        selector: selector.compound_selectors.clone(),
                                        declarations: DeclarationBlock {
                                            specificity: selector.specificity,
                                            declarations: $style_rule.declarations.$priority.clone(),
                                            source_order: rules_source_order,
                                        },
                                });
                            }
                        }
                    };
                );

                for style_rule in stylesheet.effective_rules(&self.device).style() {
                    append!(style_rule, normal);
                    append!(style_rule, important);
                    rules_source_order += 1;
                }
                self.rules_source_order = rules_source_order;
            }

            self.is_dirty = false;
            return true;
        }

        false
    }

    pub fn set_device(&mut self, device: Device) {
        let is_dirty = self.is_dirty || self.stylesheets.iter()
            .flat_map(|stylesheet| stylesheet.rules().media())
            .any(|media_rule| media_rule.evaluate(&self.device) != media_rule.evaluate(&device));

        self.device = device;
        self.is_dirty |= is_dirty;
    }

    pub fn add_quirks_mode_stylesheet(&mut self) {
        self.add_stylesheet(Stylesheet::from_bytes(
            &read_resource_file(&["quirks-mode.css"]).unwrap(),
            Url::parse("chrome:///quirks-mode.css").unwrap(),
            None,
            None,
            Origin::UserAgent))
    }

    pub fn add_stylesheet(&mut self, stylesheet: Stylesheet) {
        self.stylesheets.push(stylesheet);
        self.is_dirty = true;
    }

    /// Returns the applicable CSS declarations for the given element. This corresponds to
    /// `ElementRuleCollector` in WebKit.
    ///
    /// The returned boolean indicates whether the style is *shareable*; that is, whether the
    /// matched selectors are simple enough to allow the matching logic to be reduced to the logic
    /// in `css::matching::PrivateMatchMethods::candidate_element_allows_for_style_sharing`.
    pub fn push_applicable_declarations<'a,N,V>(
                                        &self,
                                        element: &N,
                                        parent_bf: &Option<Box<BloomFilter>>,
                                        style_attribute: Option<&PropertyDeclarationBlock>,
                                        pseudo_element: Option<PseudoElement>,
                                        applicable_declarations: &mut V)
                                        -> bool
                                        where N: TNode<'a>,
                                              N::Element: TElementAttributes<'a>,
                                              V: VecLike<DeclarationBlock> {
        assert!(!self.is_dirty);
        assert!(element.is_element());
        assert!(style_attribute.is_none() || pseudo_element.is_none(),
                "Style attributes do not apply to pseudo-elements");

        let map = match pseudo_element {
            None => &self.element_map,
            Some(PseudoElement::Before) => &self.before_map,
            Some(PseudoElement::After) => &self.after_map,
        };

        let mut shareable = true;

        // Step 1: Normal user-agent rules.
        map.user_agent.normal.get_all_matching_rules(element,
                                                     parent_bf,
                                                     applicable_declarations,
                                                     &mut shareable);

        // Step 2: Presentational hints.
        self.synthesize_presentational_hints_for_legacy_attributes(element,
                                                                   applicable_declarations,
                                                                   &mut shareable);

        // Step 3: User and author normal rules.
        map.user.normal.get_all_matching_rules(element,
                                               parent_bf,
                                               applicable_declarations,
                                               &mut shareable);
        map.author.normal.get_all_matching_rules(element,
                                                 parent_bf,
                                                 applicable_declarations,
                                                 &mut shareable);

        // Step 4: Normal style attributes.
        style_attribute.map(|sa| {
            shareable = false;
            applicable_declarations.push(
                GenericDeclarationBlock::from_declarations(sa.normal.clone()))
        });

        // Step 5: Author-supplied `!important` rules.
        map.author.important.get_all_matching_rules(element,
                                                    parent_bf,
                                                    applicable_declarations,
                                                    &mut shareable);

        // Step 6: `!important` style attributes.
        style_attribute.map(|sa| {
            shareable = false;
            applicable_declarations.push(
                GenericDeclarationBlock::from_declarations(sa.important.clone()))
        });

        // Step 7: User and UA `!important` rules.
        map.user.important.get_all_matching_rules(element,
                                                  parent_bf,
                                                  applicable_declarations,
                                                  &mut shareable);
        map.user_agent.important.get_all_matching_rules(element,
                                                        parent_bf,
                                                        applicable_declarations,
                                                        &mut shareable);

        shareable
    }

    pub fn is_dirty(&self) -> bool {
        self.is_dirty
    }
}

struct PerOriginSelectorMap {
    normal: SelectorMap<Vec<PropertyDeclaration>>,
    important: SelectorMap<Vec<PropertyDeclaration>>,
}

impl PerOriginSelectorMap {
    #[inline]
    fn new() -> PerOriginSelectorMap {
        PerOriginSelectorMap {
            normal: SelectorMap::new(),
            important: SelectorMap::new(),
        }
    }
}

struct PerPseudoElementSelectorMap {
    user_agent: PerOriginSelectorMap,
    author: PerOriginSelectorMap,
    user: PerOriginSelectorMap,
}

impl PerPseudoElementSelectorMap {
    #[inline]
    fn new() -> PerPseudoElementSelectorMap {
        PerPseudoElementSelectorMap {
            user_agent: PerOriginSelectorMap::new(),
            author: PerOriginSelectorMap::new(),
            user: PerOriginSelectorMap::new(),
        }
    }
}
<commit_msg>fix Stylist::new() to not panic when resources cannot be loaded<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use url::Url;

use selectors::bloom::BloomFilter;
use selectors::matching::{SelectorMap, Rule};
use selectors::matching::DeclarationBlock as GenericDeclarationBlock;
use selectors::parser::PseudoElement;
use selectors::tree::TNode;
use std::process;
use util::resource_files::read_resource_file;
use util::smallvec::VecLike;

use legacy::PresentationalHintSynthesis;
use media_queries::Device;
use node::TElementAttributes;
use properties::{PropertyDeclaration, PropertyDeclarationBlock};
use stylesheets::{Stylesheet, CSSRuleIteratorExt, Origin};
use viewport::{ViewportConstraints, ViewportRuleCascade};

pub type DeclarationBlock = GenericDeclarationBlock<Vec<PropertyDeclaration>>;

pub struct Stylist {
    // List of stylesheets (including all media rules)
    stylesheets: Vec<Stylesheet>,

    // Device that the stylist is currently evaluating against.
    pub device: Device,

    // If true, a stylesheet has been added or the device has
    // changed, and the stylist needs to be updated.
    is_dirty: bool,

    // The current selector maps, after evaluating media
    // rules against the current device.
    element_map: PerPseudoElementSelectorMap,
    before_map: PerPseudoElementSelectorMap,
    after_map: PerPseudoElementSelectorMap,
    rules_source_order: usize,
}

impl Stylist {
    #[inline]
    pub fn new(device: Device) -> Stylist {
        let mut stylist = Stylist {
            stylesheets: vec!(),
            device: device,
            is_dirty: true,

            element_map: PerPseudoElementSelectorMap::new(),
            before_map: PerPseudoElementSelectorMap::new(),
            after_map: PerPseudoElementSelectorMap::new(),
            rules_source_order: 0,
        };
        // FIXME: Add iso-8859-9.css when the document’s encoding is ISO-8859-8.
        // FIXME: presentational-hints.css should be at author origin with zero specificity.
        //        (Does it make a difference?)
        for &filename in ["user-agent.css", "servo.css", "presentational-hints.css"].iter() {
            match read_resource_file(&[filename]) {
                Ok(res) => {
                    let ua_stylesheet = Stylesheet::from_bytes(
                        &res,
                        Url::parse(&format!("chrome:///{:?}", filename)).unwrap(),
                        None,
                        None,
                        Origin::UserAgent);
                    stylist.add_stylesheet(ua_stylesheet);
                }
                Err(..) => {
                    error!("Stylist::new() failed at loading {}!", filename);
                    process::exit(1);
                }
            }
        }
        stylist
    }

    pub fn constrain_viewport(&self) -> Option<ViewportConstraints> {
        let cascaded_rule = self.stylesheets.iter()
            .flat_map(|s| s.effective_rules(&self.device).viewport())
            .cascade();

        ViewportConstraints::maybe_new(self.device.viewport_size, &cascaded_rule)
    }

    pub fn update(&mut self) -> bool {
        if self.is_dirty {
            self.element_map = PerPseudoElementSelectorMap::new();
            self.before_map = PerPseudoElementSelectorMap::new();
            self.after_map = PerPseudoElementSelectorMap::new();
            self.rules_source_order = 0;

            for stylesheet in self.stylesheets.iter() {
                let (mut element_map, mut before_map, mut after_map) = match stylesheet.origin {
                    Origin::UserAgent => (
                        &mut self.element_map.user_agent,
                        &mut self.before_map.user_agent,
                        &mut self.after_map.user_agent,
                    ),
                    Origin::Author => (
                        &mut self.element_map.author,
                        &mut self.before_map.author,
                        &mut self.after_map.author,
                    ),
                    Origin::User => (
                        &mut self.element_map.user,
                        &mut self.before_map.user,
                        &mut self.after_map.user,
                    ),
                };
                let mut rules_source_order = self.rules_source_order;

                // Take apart the StyleRule into individual Rules and insert
                // them into the SelectorMap of that priority.
                macro_rules! append(
                    ($style_rule: ident, $priority: ident) => {
                        if $style_rule.declarations.$priority.len() > 0 {
                            for selector in $style_rule.selectors.iter() {
                                let map = match selector.pseudo_element {
                                    None => &mut element_map,
                                    Some(PseudoElement::Before) => &mut before_map,
                                    Some(PseudoElement::After) => &mut after_map,
                                };
                                map.$priority.insert(Rule {
                                        selector: selector.compound_selectors.clone(),
                                        declarations: DeclarationBlock {
                                            specificity: selector.specificity,
                                            declarations: $style_rule.declarations.$priority.clone(),
                                            source_order: rules_source_order,
                                        },
                                });
                            }
                        }
                    };
                );

                for style_rule in stylesheet.effective_rules(&self.device).style() {
                    append!(style_rule, normal);
                    append!(style_rule, important);
                    rules_source_order += 1;
                }
                self.rules_source_order = rules_source_order;
            }

            self.is_dirty = false;
            return true;
        }

        false
    }

    pub fn set_device(&mut self, device: Device) {
        let is_dirty = self.is_dirty || self.stylesheets.iter()
            .flat_map(|stylesheet| stylesheet.rules().media())
            .any(|media_rule| media_rule.evaluate(&self.device) != media_rule.evaluate(&device));

        self.device = device;
        self.is_dirty |= is_dirty;
    }

    pub fn add_quirks_mode_stylesheet(&mut self) {
        self.add_stylesheet(Stylesheet::from_bytes(
            &read_resource_file(&["quirks-mode.css"]).unwrap(),
            Url::parse("chrome:///quirks-mode.css").unwrap(),
            None,
            None,
            Origin::UserAgent))
    }

    pub fn add_stylesheet(&mut self, stylesheet: Stylesheet) {
        self.stylesheets.push(stylesheet);
        self.is_dirty = true;
    }

    /// Returns the applicable CSS declarations for the given element. This corresponds to
    /// `ElementRuleCollector` in WebKit.
    ///
    /// The returned boolean indicates whether the style is *shareable*; that is, whether the
    /// matched selectors are simple enough to allow the matching logic to be reduced to the logic
    /// in `css::matching::PrivateMatchMethods::candidate_element_allows_for_style_sharing`.
    pub fn push_applicable_declarations<'a,N,V>(
                                        &self,
                                        element: &N,
                                        parent_bf: &Option<Box<BloomFilter>>,
                                        style_attribute: Option<&PropertyDeclarationBlock>,
                                        pseudo_element: Option<PseudoElement>,
                                        applicable_declarations: &mut V)
                                        -> bool
                                        where N: TNode<'a>,
                                              N::Element: TElementAttributes<'a>,
                                              V: VecLike<DeclarationBlock> {
        assert!(!self.is_dirty);
        assert!(element.is_element());
        assert!(style_attribute.is_none() || pseudo_element.is_none(),
                "Style attributes do not apply to pseudo-elements");

        let map = match pseudo_element {
            None => &self.element_map,
            Some(PseudoElement::Before) => &self.before_map,
            Some(PseudoElement::After) => &self.after_map,
        };

        let mut shareable = true;

        // Step 1: Normal user-agent rules.
        map.user_agent.normal.get_all_matching_rules(element,
                                                     parent_bf,
                                                     applicable_declarations,
                                                     &mut shareable);

        // Step 2: Presentational hints.
        self.synthesize_presentational_hints_for_legacy_attributes(element,
                                                                   applicable_declarations,
                                                                   &mut shareable);

        // Step 3: User and author normal rules.
        map.user.normal.get_all_matching_rules(element,
                                               parent_bf,
                                               applicable_declarations,
                                               &mut shareable);
        map.author.normal.get_all_matching_rules(element,
                                                 parent_bf,
                                                 applicable_declarations,
                                                 &mut shareable);

        // Step 4: Normal style attributes.
        style_attribute.map(|sa| {
            shareable = false;
            applicable_declarations.push(
                GenericDeclarationBlock::from_declarations(sa.normal.clone()))
        });

        // Step 5: Author-supplied `!important` rules.
        map.author.important.get_all_matching_rules(element,
                                                    parent_bf,
                                                    applicable_declarations,
                                                    &mut shareable);

        // Step 6: `!important` style attributes.
        style_attribute.map(|sa| {
            shareable = false;
            applicable_declarations.push(
                GenericDeclarationBlock::from_declarations(sa.important.clone()))
        });

        // Step 7: User and UA `!important` rules.
        map.user.important.get_all_matching_rules(element,
                                                  parent_bf,
                                                  applicable_declarations,
                                                  &mut shareable);
        map.user_agent.important.get_all_matching_rules(element,
                                                        parent_bf,
                                                        applicable_declarations,
                                                        &mut shareable);

        shareable
    }

    pub fn is_dirty(&self) -> bool {
        self.is_dirty
    }
}

struct PerOriginSelectorMap {
    normal: SelectorMap<Vec<PropertyDeclaration>>,
    important: SelectorMap<Vec<PropertyDeclaration>>,
}

impl PerOriginSelectorMap {
    #[inline]
    fn new() -> PerOriginSelectorMap {
        PerOriginSelectorMap {
            normal: SelectorMap::new(),
            important: SelectorMap::new(),
        }
    }
}

struct PerPseudoElementSelectorMap {
    user_agent: PerOriginSelectorMap,
    author: PerOriginSelectorMap,
    user: PerOriginSelectorMap,
}

impl PerPseudoElementSelectorMap {
    #[inline]
    fn new() -> PerPseudoElementSelectorMap {
        PerPseudoElementSelectorMap {
            user_agent: PerOriginSelectorMap::new(),
            author: PerOriginSelectorMap::new(),
            user: PerOriginSelectorMap::new(),
        }
    }
}
<|endoftext|>