<commit_before>use std::fmt;

use chrono::{DateTime, Local};
use chrono_humanize::HumanTime;
use json::JsonValue;

// #[derive(Debug, Default)]
// pub struct Error {
//     pub detail: String,
// }
//
// #[derive(Debug)]
// pub struct CrateLinks {
//     pub owners: Option<String>,
//     pub reverse_dependencies: String,
//     pub version_downloads: String,
//     pub versions: Option<String>,
// }
//
// pub struct Crate {
//     pub created_at: String,
//     pub description: Option<String>,
//     pub documentation: Option<String>,
//     pub downloads: i32,
//     pub homepage: Option<String>,
//     pub id: String,
//     pub keywords: Option<Vec<String>>,
//     pub license: Option<String>,
//     pub links: CrateLinks,
//     pub max_version: String,
//     pub name: String,
//     pub repository: Option<String>,
//     pub updated_at: String,
//     pub versions: Option<Vec<u64>>,
// }
//
// #[derive(Debug)]
// pub struct Keyword {
//     pub crates_cnt: u64,
//     pub created_at: String,
//     pub id: String,
//     pub keyword: String,
// }
//
// #[derive(Debug)]
// pub struct VersionLinks {
//     pub authors: String,
//     pub dependencies: String,
//     pub version_downloads: String,
// }
//
// #[derive(Debug)]
// pub struct Version {
//     pub krate: String,
//     pub created_at: String,
//     pub dl_path: String,
//     pub downloads: i32,
//     pub features: HashMap<String, Vec<String>>,
//     pub id: i32,
//     pub links: VersionLinks,
//     pub num: String,
//     pub updated_at: String,
//     pub yanked: bool,
// }
//
// pub struct Reply {
//     pub errors: Error,
//     pub krate: Crate,
//     pub keywords: Vec<Keyword>,
//     pub versions: Vec<Version>,
// }

struct TimeStamp(Option<DateTime<Local>>);

impl<'a> From<&'a JsonValue> for TimeStamp {
    fn from(jv: &JsonValue) -> Self {
        let parse = |s: &str| s.parse::<DateTime<Local>>().ok();
        TimeStamp(jv.as_str().and_then(parse))
    }
}

impl fmt::Display for TimeStamp {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(ts) = self.0 {
            if f.alternate() {
                f.pad(&format!("{}", HumanTime::from(ts)))
            } else {
                f.pad(&format!("{}", ts.naive_local()))
            }
        } else {
            f.pad("")
        }
    }
}

pub struct Crate {
    krate: JsonValue,
    versions: JsonValue,
    keywords: JsonValue,
}

const FIELDS: [&'static str; 5] =
    ["description", "documentation", "homepage", "repository", "license"];

impl Crate {
    pub fn new(json: &JsonValue) -> Self {
        let mut krate = json["crate"].clone();
        // Fix up fields that may be absent

        for field in &FIELDS {
            if krate[*field].is_null() {
                krate[*field] = "".into();
            }
        }

        Crate {
            krate: krate,
            versions: json["versions"].clone(),
            keywords: json["keywords"].clone(),
        }
    }

    pub fn print_repository(&self, verbose: bool) -> String {
        if verbose {
            format!("{:<16}{}", "Repository:", self.krate["repository"])
        } else {
            format!("{}", self.krate["repository"])
        }
        // if let JsonValue::String(ref repository) = self.krate["repository"] {
        //     if verbose {
        //         format!("{:<16}{}", "Repository:", repository)
        //     } else {
        //         repository.clone()
        //     }
        // }
    }

    pub fn print_documentation(&self, verbose: bool) -> String {
        if verbose {
            format!("{:<16}{}", "Documentation:", self.krate["documentation"])
        } else {
            format!("{}", self.krate["documentation"])
        }
        // if let JsonValue::String(ref documentation) = self.krate["documentation"] {
        //     if verbose {
        //         format!("{:<16}{}", "Documentation:", documentation)
        //     } else {
        //         documentation.clone()
        //     }
        // }
    }

    pub fn print_downloads(&self, verbose: bool) -> String {
        if verbose {
            format!("{:<16}{}", "Downloads:", self.krate["downloads"])
        } else {
            format!("{}", self.krate["downloads"])
        }
        // if let JsonValue::Number(downloads) = self.krate["downloads"] {
        //     if verbose {
        //         format!("{:<16}{}", "Downloads:", downloads)
        //     } else {
        //         format!("{}", downloads)
        //     }
        // }
    }

    pub fn print_homepage(&self, verbose: bool) -> String {
        if verbose {
            format!("{:<16}{}", "Homepage:", self.krate["homepage"])
        } else {
            format!("{}", self.krate["homepage"])
        }
        // if let JsonValue::String(ref homepage) = self.krate["homepage"] {
        //     let fmt = if verbose {
        //         format!("{:<16}{}", "Homepage:", homepage)
        //     } else {
        //         homepage.clone()
        //     };
        //     println!("{}", fmt);
        // }
    }

    fn print_version(v: &JsonValue, verbose: bool) -> String {
        let created_at = TimeStamp::from(&v["created_at"]);
        let mut output = format!("{:<11}{:<#16}{:<11}", v["num"], created_at, v["downloads"]);

        if v["yanked"].as_bool() == Some(true) {
            output = output + "\t\t(yanked)";
        }

        if verbose {
            // Consider adding some more useful information in verbose mode
            output + "\n"
        } else {
            output + "\n"
        }
    }

    fn print_version_header(verbose: bool) -> String {
        let output = format!("{:<11}{:<#16}{:<11}\n", "VERSION", "RELEASED", "DOWNLOADS");
        if verbose {
            // Consider adding some more useful information in verbose mode
            output + "\n"
        } else {
            output + "\n"
        }
    }

    pub fn print_last_versions(&self, limit: usize, verbose: bool) -> String {
        let mut output = Crate::print_version_header(verbose);
        for version in self.versions.members().take(limit) {
            output = output + &Crate::print_version(version, verbose);
        }
        let length = self.versions.len();
        if limit < length {
            output = output + &format!("\n... use -VV to show all {} versions\n", length);
        }
        output
    }

    pub fn print_keywords(&self, verbose: bool) -> String {
        if verbose {
            format!("{:#}", self.keywords)
        } else {
            format!("{}", self.keywords)
        }
    }
}

impl fmt::Display for Crate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let created_at = TimeStamp::from(&self.krate["created_at"]);
        let updated_at = TimeStamp::from(&self.krate["updated_at"]);

        let keywords = self.krate["keywords"]
            .members()
            .filter_map(|jv| jv.as_str())
            .collect::<Vec<_>>();

        if f.alternate() {
            write!(f,
                   "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}",
                   format_args!("{:<16}{}", "Crate:", self.krate["name"]),
                   format_args!("{:<16}{}", "Version:", self.krate["max_version"]),
                   format_args!("{:<16}{}", "Description:", self.krate["description"]),
                   format_args!("{:<16}{}", "Downloads:", self.krate["downloads"]),
                   format_args!("{:<16}{}", "Homepage:", self.krate["homepage"]),
                   format_args!("{:<16}{}", "Documentation:", self.krate["documentation"]),
                   format_args!("{:<16}{}", "Repository:", self.krate["repository"]),
                   format_args!("{:<16}{}", "License:", self.krate["license"]),
                   format_args!("{:<16}{:?}", "Keywords:", keywords),
                   format_args!("{:<16}{}  ({:#})", "Created at:", created_at, created_at),
                   format_args!("{:<16}{}  ({:#})", "Updated at:", updated_at, updated_at))
        } else {
            let mut versions = String::new();
            for line in self.print_last_versions(5, false).lines() {
                versions = versions + "\n";
                if !line.is_empty() {
                    versions = versions + "  " + line;
                }
            }

            write!(f,
                   "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}",
                   format_args!("{:<16}{}", "Crate:", self.krate["name"]),
                   format_args!("{:<16}{}", "Version:", self.krate["max_version"]),
                   format_args!("{:<16}{}", "Description:", self.krate["description"]),
                   format_args!("{:<16}{}", "Downloads:", self.krate["downloads"]),
                   format_args!("{:<16}{}", "Homepage:", self.krate["homepage"]),
                   format_args!("{:<16}{}", "Documentation:", self.krate["documentation"]),
                   format_args!("{:<16}{}", "Repository:", self.krate["repository"]),
                   format_args!("{:<16}{:#}", "Last updated:", updated_at),
                   format_args!("{:<16}\n{}", "Version history:", versions))
        }
    }
}
<commit_msg>Fix timestamp parsing<commit_after>use std::fmt;

use chrono::{DateTime, Local, NaiveDateTime, TimeZone};
use chrono_humanize::HumanTime;
use json::JsonValue;

// #[derive(Debug, Default)]
// pub struct Error {
//     pub detail: String,
// }
//
// #[derive(Debug)]
// pub struct CrateLinks {
//     pub owners: Option<String>,
//     pub reverse_dependencies: String,
//     pub version_downloads: String,
//     pub versions: Option<String>,
// }
//
// pub struct Crate {
//     pub created_at: String,
//     pub description: Option<String>,
//     pub documentation: Option<String>,
//     pub downloads: i32,
//     pub homepage: Option<String>,
//     pub id: String,
//     pub keywords: Option<Vec<String>>,
//     pub license: Option<String>,
//     pub links: CrateLinks,
//     pub max_version: String,
//     pub name: String,
//     pub repository: Option<String>,
//     pub updated_at: String,
//     pub versions: Option<Vec<u64>>,
// }
//
// #[derive(Debug)]
// pub struct Keyword {
//     pub crates_cnt: u64,
//     pub created_at: String,
//     pub id: String,
//     pub keyword: String,
// }
//
// #[derive(Debug)]
// pub struct VersionLinks {
//     pub authors: String,
//     pub dependencies: String,
//     pub version_downloads: String,
// }
//
// #[derive(Debug)]
// pub struct Version {
//     pub krate: String,
//     pub created_at: String,
//     pub dl_path: String,
//     pub downloads: i32,
//     pub features: HashMap<String, Vec<String>>,
//     pub id: i32,
//     pub links: VersionLinks,
//     pub num: String,
//     pub updated_at: String,
//     pub yanked: bool,
// }
//
// pub struct Reply {
//     pub errors: Error,
//     pub krate: Crate,
//     pub keywords: Vec<Keyword>,
//     pub versions: Vec<Version>,
// }

struct TimeStamp(Option<DateTime<Local>>);

impl<'a> From<&'a JsonValue> for TimeStamp {
    fn from(jv: &JsonValue) -> Self {
        let parse_naive = |s: &str| s.parse::<NaiveDateTime>();
        let naive_to_local = |n: NaiveDateTime| Local.from_utc_datetime(&n);
        let parse_local = |s: &str| s.parse::<DateTime<Local>>();
        let parse = |s: &str| parse_local(s).or_else(|_| parse_naive(s).map(naive_to_local)).ok();
        TimeStamp(jv.as_str().and_then(parse))
    }
}

impl fmt::Display for TimeStamp {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(ts) = self.0 {
            if f.alternate() {
                f.pad(&format!("{}", HumanTime::from(ts)))
            } else {
                f.pad(&format!("{}", ts.naive_local()))
            }
        } else {
            f.pad("")
        }
    }
}

pub struct Crate {
    krate: JsonValue,
    versions: JsonValue,
    keywords: JsonValue,
}

const FIELDS: [&'static str; 5] =
    ["description", "documentation", "homepage", "repository", "license"];

impl Crate {
    pub fn new(json: &JsonValue) -> Self {
        let mut krate = json["crate"].clone();
        // Fix up fields that may be absent

        for field in &FIELDS {
            if krate[*field].is_null() {
                krate[*field] = "".into();
            }
        }

        Crate {
            krate: krate,
            versions: json["versions"].clone(),
            keywords: json["keywords"].clone(),
        }
    }

    pub fn print_repository(&self, verbose: bool) -> String {
        if verbose {
            format!("{:<16}{}", "Repository:", self.krate["repository"])
        } else {
            format!("{}", self.krate["repository"])
        }
        // if let JsonValue::String(ref repository) = self.krate["repository"] {
        //     if verbose {
        //         format!("{:<16}{}", "Repository:", repository)
        //     } else {
        //         repository.clone()
        //     }
        // }
    }

    pub fn print_documentation(&self, verbose: bool) -> String {
        if verbose {
            format!("{:<16}{}", "Documentation:", self.krate["documentation"])
        } else {
            format!("{}", self.krate["documentation"])
        }
        // if let JsonValue::String(ref documentation) = self.krate["documentation"] {
        //     if verbose {
        //         format!("{:<16}{}", "Documentation:", documentation)
        //     } else {
        //         documentation.clone()
        //     }
        // }
    }

    pub fn print_downloads(&self, verbose: bool) -> String {
        if verbose {
            format!("{:<16}{}", "Downloads:", self.krate["downloads"])
        } else {
            format!("{}", self.krate["downloads"])
        }
        // if let JsonValue::Number(downloads) = self.krate["downloads"] {
        //     if verbose {
        //         format!("{:<16}{}", "Downloads:", downloads)
        //     } else {
        //         format!("{}", downloads)
        //     }
        // }
    }

    pub fn print_homepage(&self, verbose: bool) -> String {
        if verbose {
            format!("{:<16}{}", "Homepage:", self.krate["homepage"])
        } else {
            format!("{}", self.krate["homepage"])
        }
        // if let JsonValue::String(ref homepage) = self.krate["homepage"] {
        //     let fmt = if verbose {
        //         format!("{:<16}{}", "Homepage:", homepage)
        //     } else {
        //         homepage.clone()
        //     };
        //     println!("{}", fmt);
        // }
    }

    fn print_version(v: &JsonValue, verbose: bool) -> String {
        let created_at = TimeStamp::from(&v["created_at"]);
        let mut output = format!("{:<11}{:<#16}{:<11}", v["num"], created_at, v["downloads"]);

        if v["yanked"].as_bool() == Some(true) {
            output = output + "\t\t(yanked)";
        }

        if verbose {
            // Consider adding some more useful information in verbose mode
            output + "\n"
        } else {
            output + "\n"
        }
    }

    fn print_version_header(verbose: bool) -> String {
        let output = format!("{:<11}{:<#16}{:<11}\n", "VERSION", "RELEASED", "DOWNLOADS");
        if verbose {
            // Consider adding some more useful information in verbose mode
            output + "\n"
        } else {
            output + "\n"
        }
    }

    pub fn print_last_versions(&self, limit: usize, verbose: bool) -> String {
        let mut output = Crate::print_version_header(verbose);
        for version in self.versions.members().take(limit) {
            output = output + &Crate::print_version(version, verbose);
        }
        let length = self.versions.len();
        if limit < length {
            output = output + &format!("\n... use -VV to show all {} versions\n", length);
        }
        output
    }

    pub fn print_keywords(&self, verbose: bool) -> String {
        if verbose {
            format!("{:#}", self.keywords)
        } else {
            format!("{}", self.keywords)
        }
    }
}

impl fmt::Display for Crate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let created_at = TimeStamp::from(&self.krate["created_at"]);
        let updated_at = TimeStamp::from(&self.krate["updated_at"]);

        let keywords = self.krate["keywords"]
            .members()
            .filter_map(|jv| jv.as_str())
            .collect::<Vec<_>>();

        if f.alternate() {
            write!(f,
                   "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}",
                   format_args!("{:<16}{}", "Crate:", self.krate["name"]),
                   format_args!("{:<16}{}", "Version:", self.krate["max_version"]),
                   format_args!("{:<16}{}", "Description:", self.krate["description"]),
                   format_args!("{:<16}{}", "Downloads:", self.krate["downloads"]),
                   format_args!("{:<16}{}", "Homepage:", self.krate["homepage"]),
                   format_args!("{:<16}{}", "Documentation:", self.krate["documentation"]),
                   format_args!("{:<16}{}", "Repository:", self.krate["repository"]),
                   format_args!("{:<16}{}", "License:", self.krate["license"]),
                   format_args!("{:<16}{:?}", "Keywords:", keywords),
                   format_args!("{:<16}{}  ({:#})", "Created at:", created_at, created_at),
                   format_args!("{:<16}{}  ({:#})", "Updated at:", updated_at, updated_at))
        } else {
            let mut versions = String::new();
            for line in self.print_last_versions(5, false).lines() {
                versions = versions + "\n";
                if !line.is_empty() {
                    versions = versions + "  " + line;
                }
            }

            write!(f,
                   "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}",
                   format_args!("{:<16}{}", "Crate:", self.krate["name"]),
                   format_args!("{:<16}{}", "Version:", self.krate["max_version"]),
                   format_args!("{:<16}{}", "Description:", self.krate["description"]),
                   format_args!("{:<16}{}", "Downloads:", self.krate["downloads"]),
                   format_args!("{:<16}{}", "Homepage:", self.krate["homepage"]),
                   format_args!("{:<16}{}", "Documentation:", self.krate["documentation"]),
                   format_args!("{:<16}{}", "Repository:", self.krate["repository"]),
                   format_args!("{:<16}{:#}", "Last updated:", updated_at),
                   format_args!("{:<16}\n{}", "Version history:", versions))
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! Rpc protocol errors

use crate::peer_manager::PeerManagerError;
use anyhow::anyhow;
use diem_types::PeerId;
use futures::channel::{mpsc, oneshot};
use std::io;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum RpcError {
    #[error("Error: {0:?}")]
    Error(#[from] anyhow::Error),

    #[error("IO error: {0}")]
    IoError(#[from] io::Error),

    #[error("Bcs error: {0:?}")]
    BcsError(#[from] bcs::Error),

    #[error("Failed to open substream, not connected with peer: {0}")]
    NotConnected(PeerId),

    #[error("Received invalid rpc response message")]
    InvalidRpcResponse,

    #[error("Received unexpected rpc response message; expected remote to half-close.")]
    UnexpectedRpcResponse,

    #[error("Received unexpected rpc request message; expected remote to half-close.")]
    UnexpectedRpcRequest,

    #[error("Application layer unexpectedly dropped response channel")]
    UnexpectedResponseChannelCancel,

    #[error("Error in application layer handling rpc request: {0:?}")]
    ApplicationError(anyhow::Error),

    #[error("Error sending on mpsc channel: {0:?}")]
    MpscSendError(#[from] mpsc::SendError),

    #[error("Too many pending RPCs: {0}")]
    TooManyPending(u32),

    #[error("Rpc timed out")]
    TimedOut,
}

impl From<PeerManagerError> for RpcError {
    fn from(err: PeerManagerError) -> Self {
        match err {
            PeerManagerError::NotConnected(peer_id) => RpcError::NotConnected(peer_id),
            PeerManagerError::IoError(err) => RpcError::IoError(err),
            err => RpcError::Error(anyhow!(err)),
        }
    }
}
impl From<oneshot::Canceled> for RpcError {
    fn from(_: oneshot::Canceled) -> Self {
        RpcError::UnexpectedResponseChannelCancel
    }
}

impl From<tokio::time::error::Elapsed> for RpcError {
    fn from(_err: tokio::time::error::Elapsed) -> RpcError {
        RpcError::TimedOut
    }
}
<commit_msg>[network] Remove unused RpcError variants<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! Rpc protocol errors

use crate::peer_manager::PeerManagerError;
use anyhow::anyhow;
use diem_types::PeerId;
use futures::channel::{mpsc, oneshot};
use std::io;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum RpcError {
    #[error("Error: {0:?}")]
    Error(#[from] anyhow::Error),

    #[error("IO error: {0}")]
    IoError(#[from] io::Error),

    #[error("Bcs error: {0:?}")]
    BcsError(#[from] bcs::Error),

    #[error("Not connected with peer: {0}")]
    NotConnected(PeerId),

    #[error("Received invalid rpc response message")]
    InvalidRpcResponse,

    #[error("Application layer unexpectedly dropped response channel")]
    UnexpectedResponseChannelCancel,

    #[error("Error in application layer handling rpc request: {0:?}")]
    ApplicationError(anyhow::Error),

    #[error("Error sending on mpsc channel, connection likely shutting down: {0:?}")]
    MpscSendError(#[from] mpsc::SendError),

    #[error("Too many pending RPCs: {0}")]
    TooManyPending(u32),

    #[error("Rpc timed out")]
    TimedOut,
}

impl From<PeerManagerError> for RpcError {
    fn from(err: PeerManagerError) -> Self {
        match err {
            PeerManagerError::NotConnected(peer_id) => RpcError::NotConnected(peer_id),
            PeerManagerError::IoError(err) => RpcError::IoError(err),
            err => RpcError::Error(anyhow!(err)),
        }
    }
}
impl From<oneshot::Canceled> for RpcError {
    fn from(_: oneshot::Canceled) -> Self {
        RpcError::UnexpectedResponseChannelCancel
    }
}

impl From<tokio::time::error::Elapsed> for RpcError {
    fn from(_err: tokio::time::error::Elapsed) -> RpcError {
        RpcError::TimedOut
    }
}
<|endoftext|>


<commit_before>use collections::vec::Vec;
use collections::btree_map::BTreeMap;
use collections::boxed::Box;
use alloc::arc::Arc;
use core::cell::RefCell;

use id::Id;
use scene::Scene;
use component::Component;

struct EntityData {
    depth: usize,
    scene: Option<Scene>,
    parent: Option<Entity>,
    children: Vec<Entity>,
    components: BTreeMap<Id, Box<Component>>,
}

#[derive(Clone)]
pub struct Entity {
    data: Arc<RefCell<EntityData>>,
}

impl Entity {

    pub fn new() -> Self {
        Entity {
            data: Arc::new(RefCell::new(EntityData {
                depth: 0,
                scene: None,
                parent: None,
                children: Vec::new(),
                components: BTreeMap::new(),
            }))
        }
    }

    pub fn depth(&self) -> usize {
        self.data.borrow().depth
    }

    pub fn scene(&self) -> Option<Scene> {
        match self.data.borrow().scene {
            Some(ref scene) => Some(scene.clone()),
            None => None,
        }
    }
    pub fn has_scene(&self) -> bool {
        match self.data.borrow().scene {
            Some(_) => true,
            None => false,
        }
    }

    pub fn parent(&self) -> Option<Entity> {
        match self.data.borrow().parent {
            Some(ref parent) => Some(parent.clone()),
            None => None,
        }
    }
    pub fn has_parent(&self) -> bool {
        match self.data.borrow().parent {
            Some(_) => true,
            None => false,
        }
    }

    pub fn add_child(&self, child: Entity) -> &Self {
        if *self != child {
            let parent = child.parent();
            if parent != None {
                parent.unwrap().remove_child(child.clone());
            }

            self.data.borrow_mut().children.push(child.clone());

            {
                let mut child_data = child.data.borrow_mut();
                child_data.depth = self.depth() + 1;
                child_data.parent = Some(self.clone());
            }
            child.update_children_depth();

            let scene = self.scene();
            if scene != None {
                scene.unwrap().add_entity(child.clone());
            }
        }
        self
    }
    pub fn has_child(&self, child: Entity) -> bool {
        let ref children = self.data.borrow().children;

        match children.iter().position(|c| *c == child) {
            Some(_) => true,
            None => false,
        }
    }
    pub fn remove_child(&self, child: Entity) -> &Self {
        let ref mut children = self.data.borrow_mut().children;

        match children.iter().position(|c| *c == child) {
            Some(i) => {
                {
                    let mut child_data = self.data.borrow_mut();
                    child_data.depth = 0;
                    child_data.parent = None;
                }
                child.update_children_depth();
                children.remove(i);
                self
            },
            None => self,
        }
    }

    pub fn add_component<T: Component + Clone>(&self, component: T) -> &Self {
        let ref mut components = self.data.borrow_mut().components;
        let id = Id::of::<T>();

        if !components.contains_key(&id) {
            component.set_entity(Some(self.clone()));
            components.insert(id, Box::new(component));
        }
        self
    }
    pub fn has_component<T: Component + Clone>(&self) -> bool {
        self.data.borrow().components.contains_key(&Id::of::<T>())
    }
    pub fn remove_component<T: Component + Clone>(&self) -> &Self {
        let ref mut components = self.data.borrow_mut().components;
        let id = Id::of::<T>();

        if components.contains_key(&id) {
            {
                let component = components.get(&Id::of::<T>()).unwrap();
                component.set_entity(None);
            }
            components.remove(&id);
        }
        self
    }
    pub fn get_component<T: Component + Clone>(&self) -> Option<T> {
        let ref components = self.data.borrow().components;
        let id = Id::of::<T>();

        if components.contains_key(&id) {
            let component = components.get(&id).unwrap().downcast_ref::<T>().unwrap();
            Some(component.clone())
        } else {
            None
        }
    }

    fn update_children_depth(&self) {
        let entity = self.data.borrow_mut();

        for child in entity.children.iter() {
            child.data.borrow_mut().depth = entity.depth + 1;
            child.update_children_depth()
        }
    }

    pub fn __set_scene(&self, scene: Scene) {
        let mut entity_data = self.data.borrow_mut();

        for child in entity_data.children.iter() {
            scene.add_entity(child.clone());
        }
        for (_, component) in entity_data.components.iter() {
            scene.__add_component(component);
        }

        entity_data.scene = Some(scene);
    }
    pub fn __remove_scene(&self, scene: Scene) {
        {
            let mut entity_data = self.data.borrow_mut();

            for child in entity_data.children.iter() {
                scene.remove_entity(child.clone());
            }
            for (_, component) in entity_data.components.iter() {
                scene.__remove_component(component);
            }

            entity_data.depth = 0;
            entity_data.scene = None;
            entity_data.parent = None;
        }
        self.update_children_depth();
    }
}

impl PartialEq<Entity> for Entity {
    fn eq(&self, other: &Entity) -> bool {
        (&*self.data.borrow() as *const _) == (&*other.data.borrow() as *const _)
    }
    fn ne(&self, other: &Entity) -> bool {
        !self.eq(other)
    }
}
<commit_msg>added child each method<commit_after>use collections::vec::Vec;
use collections::btree_map::BTreeMap;
use collections::boxed::Box;
use alloc::arc::Arc;
use core::cell::RefCell;

use id::Id;
use scene::Scene;
use component::Component;

struct EntityData {
    depth: usize,
    scene: Option<Scene>,
    parent: Option<Entity>,
    children: Vec<Entity>,
    components: BTreeMap<Id, Box<Component>>,
}

#[derive(Clone)]
pub struct Entity {
    data: Arc<RefCell<EntityData>>,
}

impl Entity {

    pub fn new() -> Self {
        Entity {
            data: Arc::new(RefCell::new(EntityData {
                depth: 0,
                scene: None,
                parent: None,
                children: Vec::new(),
                components: BTreeMap::new(),
            }))
        }
    }

    pub fn depth(&self) -> usize {
        self.data.borrow().depth
    }

    pub fn scene(&self) -> Option<Scene> {
        match self.data.borrow().scene {
            Some(ref scene) => Some(scene.clone()),
            None => None,
        }
    }
    pub fn has_scene(&self) -> bool {
        match self.data.borrow().scene {
            Some(_) => true,
            None => false,
        }
    }

    pub fn parent(&self) -> Option<Entity> {
        match self.data.borrow().parent {
            Some(ref parent) => Some(parent.clone()),
            None => None,
        }
    }
    pub fn has_parent(&self) -> bool {
        match self.data.borrow().parent {
            Some(_) => true,
            None => false,
        }
    }

    pub fn add_child(&self, child: Entity) -> &Self {
        if *self != child {
            let parent = child.parent();
            if parent != None {
                parent.unwrap().remove_child(child.clone());
            }

            self.data.borrow_mut().children.push(child.clone());

            {
                let mut child_data = child.data.borrow_mut();
                child_data.depth = self.depth() + 1;
                child_data.parent = Some(self.clone());
            }
            child.update_children_depth();

            let scene = self.scene();
            if scene != None {
                scene.unwrap().add_entity(child.clone());
            }
        }
        self
    }
    pub fn has_child(&self, child: Entity) -> bool {
        let ref children = self.data.borrow().children;

        match children.iter().position(|c| *c == child) {
            Some(_) => true,
            None => false,
        }
    }
    pub fn remove_child(&self, child: Entity) -> &Self {
        let ref mut children = self.data.borrow_mut().children;

        match children.iter().position(|c| *c == child) {
            Some(i) => {
                {
                    let mut child_data = self.data.borrow_mut();
                    child_data.depth = 0;
                    child_data.parent = None;
                }
                child.update_children_depth();
                children.remove(i);
                self
            },
            None => self,
        }
    }

    pub fn add_component<T: Component + Clone>(&self, component: T) -> &Self {
        let ref mut components = self.data.borrow_mut().components;
        let id = Id::of::<T>();

        if !components.contains_key(&id) {
            component.set_entity(Some(self.clone()));
            components.insert(id, Box::new(component));
        }
        self
    }
    pub fn has_component<T: Component + Clone>(&self) -> bool {
        self.data.borrow().components.contains_key(&Id::of::<T>())
    }
    pub fn remove_component<T: Component + Clone>(&self) -> &Self {
        let ref mut components = self.data.borrow_mut().components;
        let id = Id::of::<T>();

        if components.contains_key(&id) {
            {
                let component = components.get(&Id::of::<T>()).unwrap();
                component.set_entity(None);
            }
            components.remove(&id);
        }
        self
    }
    pub fn get_component<T: Component + Clone>(&self) -> Option<T> {
        let ref components = self.data.borrow().components;
        let id = Id::of::<T>();

        if components.contains_key(&id) {
            let component = components.get(&id).unwrap().downcast_ref::<T>().unwrap();
            Some(component.clone())
        } else {
            None
        }
    }

    pub fn each_child<F>(&self, func: F) where F: Fn(&Entity) {
        for child in self.data.borrow().children.iter() {
            func(child);
        }
    }

    fn update_children_depth(&self) {
        let entity = self.data.borrow_mut();

        for child in entity.children.iter() {
            child.data.borrow_mut().depth = entity.depth + 1;
            child.update_children_depth()
        }
    }

    pub fn __set_scene(&self, scene: Scene) {
        let mut entity_data = self.data.borrow_mut();

        for child in entity_data.children.iter() {
            scene.add_entity(child.clone());
        }
        for (_, component) in entity_data.components.iter() {
            scene.__add_component(component);
        }

        entity_data.scene = Some(scene);
    }
    pub fn __remove_scene(&self, scene: Scene) {
        {
            let mut entity_data = self.data.borrow_mut();

            for child in entity_data.children.iter() {
                scene.remove_entity(child.clone());
            }
            for (_, component) in entity_data.components.iter() {
                scene.__remove_component(component);
            }

            entity_data.depth = 0;
            entity_data.scene = None;
            entity_data.parent = None;
        }
        self.update_children_depth();
    }
}

impl PartialEq<Entity> for Entity {
    fn eq(&self, other: &Entity) -> bool {
        (&*self.data.borrow() as *const _) == (&*other.data.borrow() as *const _)
    }
    fn ne(&self, other: &Entity) -> bool {
        !self.eq(other)
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2015, The Rust-GNOME Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use ffi;
use libc::c_void;
use std::mem;

pub use self::event_type::EventType;
pub use self::owner_change::OwnerChange;
pub use self::setting_action::SettingAction;
pub use self::property_state::PropertyState;
pub use self::crossing_mode::CrossingMode;
pub use self::notify_type::NotifyType;
pub use self::scroll_direction::ScrollDirection;
pub use self::visibility_state::VisibilityState;

pub mod event_type {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum EventType {
        Nothing           = -1,
        Delete            = 0,
        Destroy           = 1,
        Expose            = 2,
        MotionNotify      = 3,
        ButtonPress       = 4,
        DoubleButtonPress = 5,
        TripleButtonPress = 6,
        ButtonRelease     = 7,
        KeyPress          = 8,
        KeyRelease        = 9,
        EnterNotify       = 10,
        LeaveNotify       = 11,
        FocusChange       = 12,
        Configure         = 13,
        Map               = 14,
        Unmap             = 15,
        PropertyNotify    = 16,
        SelectionClear    = 17,
        SelectionRequest  = 18,
        SelectionNotify   = 19,
        ProximityIn       = 20,
        ProximityOut      = 21,
        DragEnter         = 22,
        DragLeave         = 23,
        DragMotion        = 24,
        DragStatus        = 25,
        DropStart         = 26,
        DropFinished      = 27,
        ClientEvent       = 28,
        VisibilityNotify  = 29,
        Scroll            = 31,
        WindowState       = 32,
        Setting           = 33,
        OwnerChange       = 34,
        GrabBroken        = 35,
        Damage            = 36,
        TouchBegin        = 37,
        TouchUpdate       = 38,
        TouchEnd          = 39,
        TouchCancel       = 40
    }
}

pub trait Event: Sized {
    fn get_send_event(&self) -> bool {
        unsafe {
            let event_any : &EventAny = mem::transmute(self);
            event_any.send_event == 0
        }
    }
}

#[repr(C)]
pub struct EventAny {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,
}

impl Event for EventAny {}

#[allow(dead_code)]
pub struct EventExpose {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub area : ffi::C_GdkRectangle,
    pub region : *mut c_void, //TODO cairo_region_t
    pub count : i8 /* If non-zero, how many more events follow. */
}

impl Event for EventExpose {}

#[allow(dead_code)]
pub struct EventVisibility{
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    state : ::VisibilityState
}

impl Event for EventVisibility {}

#[allow(dead_code)]
pub struct EventMotion {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    time : u32,
    x : f64,
    y : f64,
    axes : *mut f64,
    state : ::enums::modifier_type::ModifierType,
    is_hint : i16,
    device : *mut ::Device,
    x_root : f64,
    y_root : f64
}

impl Event for EventMotion {}

#[allow(dead_code)]
pub struct EventButton {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    time : u32,
    x : f64,
    y : f64,
    axes : *mut f64,
    state : ::enums::modifier_type::ModifierType,
    button : u32,
    device : *mut ::Device,
    x_root : f64,
    y_root : f64
}

impl Event for EventButton {}

#[allow(dead_code)]
pub struct EventTouch {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub sequence : *mut c_void, //::EventSequence
    pub emulating_pointer : i32, // boolean
    pub device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventTouch {}

#[allow(dead_code)]
pub struct EventScroll {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub direction : ::ScrollDirection,
    pub device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64,
    pub delta_x : f64,
    pub delta_y : f64
}

impl Event for EventScroll {}

#[allow(dead_code)]
pub struct EventKey {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub state : ::enums::modifier_type::ModifierType,
    pub keyval : u32,
    pub length : i32,
    pub string : *mut char,
    pub hardware_keycode : u16,
    pub group : u8,
    pub is_modifier: u32
}

impl Event for EventKey {}

#[allow(dead_code)]
pub struct EventCrossing {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub subwindow : ::Window,
    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub x_root : f64,
    pub y_root : f64,
    pub mode : ::CrossingMode,
    pub detail : ::NotifyType,
    pub focus : i32, // boolean
    pub state : ::enums::modifier_type::ModifierType
}

impl Event for EventCrossing {}

#[allow(dead_code)]
pub struct EventFocus {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    _in : i16
}

impl Event for EventFocus {}

#[allow(dead_code)]
pub struct EventConfigure {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub x : i32,
    pub y : i32,
    pub width : i32,
    pub height : i32
}

impl Event for EventConfigure {}

#[allow(dead_code)]
pub struct EventProperty {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    atom : ::Atom,
    time : u32,
    state : u32 //FIXME
}

impl Event for EventProperty {}

#[allow(dead_code)]
pub struct EventSelection {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub selection : ::Atom,
    pub target : ::Atom,
    pub property : ::Atom,
    pub time : u32,
    pub requestor : *mut ::Window
}

impl Event for EventSelection {}

#[allow(dead_code)]
pub struct EventOwnerChange {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub owner : *mut ::Window,
    pub reason : ::OwnerChange,
    pub selection : ::Atom,
    pub time : u32,
    pub selection_time : u32
}

impl Event for EventOwnerChange {}

#[allow(dead_code)]
pub struct EventProximity {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub device : *mut ::Device
}

impl Event for EventProximity {}

#[allow(dead_code)]
pub struct EventSetting {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub action : ::SettingAction,
    pub name : *mut char
}

impl Event for EventSetting {}

#[allow(dead_code)]
pub struct EventWindowState {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub changed_mask : ::WindowState,
    pub new_window_state : ::WindowState
}

impl Event for EventWindowState {}

#[allow(dead_code)]
pub struct EventGrabBroken {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub keyboard : i32, // boolean
    pub implicit : i32, // boolean
    pub grab_window : *mut ::Window
}

impl Event for EventGrabBroken  {}

#[allow(dead_code)]
pub struct EventDND {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub context : *mut c_void, //::DragContext
    pub time : u32,
    pub x_root : i16, //short
    pub y_root : i16  //short
}

impl Event for EventDND  {}

//Supporting types

pub mod visibility_state {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum VisibilityState{
        VisibilityUnobscured,
        VisibilityPartial,
        VisibilityFullyObscured
    }
}

pub mod scroll_direction {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum ScrollDirection{
        ScrollUp,
        ScrollDown,
        ScrollLeft,
        ScrollRight,
        ScrollSmooth
    }
}

pub mod notify_type {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum NotifyType{
        NotifyAncestor   = 0,
        NotifyVirtual    = 1,
        NotifyInferior   = 2,
        NotifyNonlinear  = 3,
        NotifyNonlinearVirtual  = 4,
        NotifyUnknown    = 5
    }
}

pub mod crossing_mode {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum CrossingMode{
        CrossingNormal,
        CrossingGrab,
        CrossingUngrab,
        CrossingGtkGrab,
        CrossingGtkUngrab,
        CrossingStateChanged,
        CrossingTouchBegin,
        CrossingTouchEnd,
        CrossingDeviceSwitch
    }
}

pub mod property_state {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum PropertyState{
        PropertyNewValue,
        PropertyDelete
    }
}

pub mod setting_action {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum SettingAction{
        SettingActionNew,
        SettingActionChanged,
        SettingActionDeleted
    }
}

pub mod owner_change {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum OwnerChange{
        OwnerChangeNewOwner,
        OwnerChangeDestroy,
        OwnerChangeClose
    }
}<commit_msg>Publish event members<commit_after>// Copyright 2013-2015, The Rust-GNOME Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use ffi;
use libc::c_void;
use std::mem;

pub use self::event_type::EventType;
pub use self::owner_change::OwnerChange;
pub use self::setting_action::SettingAction;
pub use self::property_state::PropertyState;
pub use self::crossing_mode::CrossingMode;
pub use self::notify_type::NotifyType;
pub use self::scroll_direction::ScrollDirection;
pub use self::visibility_state::VisibilityState;

pub mod event_type {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum EventType {
        Nothing           = -1,
        Delete            = 0,
        Destroy           = 1,
        Expose            = 2,
        MotionNotify      = 3,
        ButtonPress       = 4,
        DoubleButtonPress = 5,
        TripleButtonPress = 6,
        ButtonRelease     = 7,
        KeyPress          = 8,
        KeyRelease        = 9,
        EnterNotify       = 10,
        LeaveNotify       = 11,
        FocusChange       = 12,
        Configure         = 13,
        Map               = 14,
        Unmap             = 15,
        PropertyNotify    = 16,
        SelectionClear    = 17,
        SelectionRequest  = 18,
        SelectionNotify   = 19,
        ProximityIn       = 20,
        ProximityOut      = 21,
        DragEnter         = 22,
        DragLeave         = 23,
        DragMotion        = 24,
        DragStatus        = 25,
        DropStart         = 26,
        DropFinished      = 27,
        ClientEvent       = 28,
        VisibilityNotify  = 29,
        Scroll            = 31,
        WindowState       = 32,
        Setting           = 33,
        OwnerChange       = 34,
        GrabBroken        = 35,
        Damage            = 36,
        TouchBegin        = 37,
        TouchUpdate       = 38,
        TouchEnd          = 39,
        TouchCancel       = 40
    }
}

pub trait Event: Sized {
    fn get_send_event(&self) -> bool {
        unsafe {
            let event_any : &EventAny = mem::transmute(self);
            event_any.send_event == 0
        }
    }
}

#[repr(C)]
pub struct EventAny {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,
}

impl Event for EventAny {}

#[allow(dead_code)]
pub struct EventExpose {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub area : ffi::C_GdkRectangle,
    pub region : *mut c_void, //TODO cairo_region_t
    pub count : i8 /* If non-zero, how many more events follow. */
}

impl Event for EventExpose {}

#[allow(dead_code)]
pub struct EventVisibility{
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub state : ::VisibilityState
}

impl Event for EventVisibility {}

#[allow(dead_code)]
pub struct EventMotion {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub is_hint : i16,
    pub device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventMotion {}

#[allow(dead_code)]
pub struct EventButton {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub button : u32,
    pub device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventButton {}

#[allow(dead_code)]
pub struct EventTouch {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub sequence : *mut c_void, //::EventSequence
    pub emulating_pointer : i32, // boolean
    pub device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventTouch {}

#[allow(dead_code)]
pub struct EventScroll {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub state : ::enums::modifier_type::ModifierType,
    pub direction : ::ScrollDirection,
    pub device : *mut ::Device,
    pub x_root : f64,
    pub y_root : f64,
    pub delta_x : f64,
    pub delta_y : f64
}

impl Event for EventScroll {}

#[allow(dead_code)]
pub struct EventKey {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub state : ::enums::modifier_type::ModifierType,
    pub keyval : u32,
    pub length : i32,
    pub string : *mut char,
    pub hardware_keycode : u16,
    pub group : u8,
    pub is_modifier: u32
}

impl Event for EventKey {}

#[allow(dead_code)]
pub struct EventCrossing {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub subwindow : ::Window,
    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub x_root : f64,
    pub y_root : f64,
    pub mode : ::CrossingMode,
    pub detail : ::NotifyType,
    pub focus : i32, // boolean
    pub state : ::enums::modifier_type::ModifierType
}

impl Event for EventCrossing {}

#[allow(dead_code)]
pub struct EventFocus {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub _in : i16
}

impl Event for EventFocus {}

#[allow(dead_code)]
pub struct EventConfigure {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub x : i32,
    pub y : i32,
    pub width : i32,
    pub height : i32
}

impl Event for EventConfigure {}

#[allow(dead_code)]
pub struct EventProperty {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub atom : ::Atom,
    pub time : u32,
    pub state : u32 //FIXME
}

impl Event for EventProperty {}

#[allow(dead_code)]
pub struct EventSelection {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub selection : ::Atom,
    pub target : ::Atom,
    pub property : ::Atom,
    pub time : u32,
    pub requestor : *mut ::Window
}

impl Event for EventSelection {}

#[allow(dead_code)]
pub struct EventOwnerChange {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub owner : *mut ::Window,
    pub reason : ::OwnerChange,
    pub selection : ::Atom,
    pub time : u32,
    pub selection_time : u32
}

impl Event for EventOwnerChange {}

#[allow(dead_code)]
pub struct EventProximity {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub time : u32,
    pub device : *mut ::Device
}

impl Event for EventProximity {}

#[allow(dead_code)]
pub struct EventSetting {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub action : ::SettingAction,
    pub name : *mut char
}

impl Event for EventSetting {}

#[allow(dead_code)]
pub struct EventWindowState {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub changed_mask : ::WindowState,
    pub new_window_state : ::WindowState
}

impl Event for EventWindowState {}

#[allow(dead_code)]
pub struct EventGrabBroken {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub keyboard : i32, // boolean
    pub implicit : i32, // boolean
    pub grab_window : *mut ::Window
}

impl Event for EventGrabBroken  {}

#[allow(dead_code)]
pub struct EventDND {
    pub _type : ::EventType,
    pub window : *mut ::Window,
    send_event : i8,

    pub context : *mut c_void, //::DragContext
    pub time : u32,
    pub x_root : i16, //short
    pub y_root : i16  //short
}

impl Event for EventDND  {}

//Supporting types

pub mod visibility_state {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum VisibilityState{
        VisibilityUnobscured,
        VisibilityPartial,
        VisibilityFullyObscured
    }
}

pub mod scroll_direction {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum ScrollDirection{
        ScrollUp,
        ScrollDown,
        ScrollLeft,
        ScrollRight,
        ScrollSmooth
    }
}

pub mod notify_type {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum NotifyType{
        NotifyAncestor   = 0,
        NotifyVirtual    = 1,
        NotifyInferior   = 2,
        NotifyNonlinear  = 3,
        NotifyNonlinearVirtual  = 4,
        NotifyUnknown    = 5
    }
}

pub mod crossing_mode {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum CrossingMode{
        CrossingNormal,
        CrossingGrab,
        CrossingUngrab,
        CrossingGtkGrab,
        CrossingGtkUngrab,
        CrossingStateChanged,
        CrossingTouchBegin,
        CrossingTouchEnd,
        CrossingDeviceSwitch
    }
}

pub mod property_state {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum PropertyState{
        PropertyNewValue,
        PropertyDelete
    }
}

pub mod setting_action {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum SettingAction{
        SettingActionNew,
        SettingActionChanged,
        SettingActionDeleted
    }
}

pub mod owner_change {
    #[repr(C)]
    #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)]
    pub enum OwnerChange{
        OwnerChangeNewOwner,
        OwnerChangeDestroy,
        OwnerChangeClose
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use rpc_capnp::{message, return_};

use capnp::{MessageBuilder, MallocMessageBuilder, ReaderOptions};
use capnp::private::capability::{ClientHook};
use capnp::capability::{FromClientHook, Server};
use rpc::{RpcConnectionState, RpcEvent};
use capability::{LocalClient};

pub struct EzRpcClient {
    rpc_chan : ::std::sync::mpsc::Sender<RpcEvent>,
    tcp : ::std::net::TcpStream,
}

impl Drop for EzRpcClient {
    fn drop(&mut self) {
        self.rpc_chan.send(RpcEvent::Shutdown).is_ok();
        //self.tcp.close_read().is_ok();
    }
}

struct EmptyCap;

impl Server for EmptyCap {
    fn dispatch_call(&mut self, _interface_id : u64, _method_id : u16,
                     context : ::capnp::capability::CallContext<::capnp::any_pointer::Reader,
                                                                ::capnp::any_pointer::Builder>) {
        context.fail("Attempted to call a method on an empty capability.".to_string());
    }
}

impl EzRpcClient {
    pub fn new(server_address : &str) -> ::std::io::Result<EzRpcClient> {
        let tcp = try!(::std::net::TcpStream::connect(server_address));

        let connection_state = RpcConnectionState::new();

        let empty_cap = Box::new(EmptyCap);
        let bootstrap = Box::new(LocalClient::new(empty_cap));

        let chan = connection_state.run(try!(tcp.try_clone()),
                                        try!(tcp.try_clone()),
                                        bootstrap,
                                        ReaderOptions::new());

        return Ok(EzRpcClient { rpc_chan : chan, tcp : tcp });
    }

    pub fn get_main<T : FromClientHook>(&mut self) -> T {
        let mut message = Box::new(MallocMessageBuilder::new_default());
        {
            message.init_root::<message::Builder>().init_bootstrap();
        }

        let (outgoing, answer_port, _question_port) = RpcEvent::new_outgoing(message);
        self.rpc_chan.send(RpcEvent::Outgoing(outgoing)).unwrap();

        let mut response_hook = answer_port.recv().unwrap();
        let message : message::Reader = response_hook.get().get_as().unwrap();
        let client = match message.which() {
            Ok(message::Return(Ok(ret))) => {
                match ret.which() {
                    Ok(return_::Results(Ok(payload))) => {
                        payload.get_content().get_as_capability::<T>().unwrap()
                    }
                    _ => { panic!() }
                }
            }
            _ => {panic!()}
        };

        return client;
    }
}

pub struct EzRpcServer {
     tcp_listener : ::std::net::TcpListener,
}

impl EzRpcServer {
    pub fn new(bind_address : &str) -> ::std::io::Result<EzRpcServer> {
        let tcp_listener = try!(::std::net::TcpListener::bind(bind_address));
        Ok(EzRpcServer { tcp_listener : tcp_listener  })
    }

    pub fn serve<'a>(self, bootstrap_interface : Box<Server + Send>) -> ::std::thread::JoinGuard<'a, ()> {
        ::std::thread::scoped(move || {
            let server = self;
            let bootstrap_interface = Box::new(LocalClient::new(bootstrap_interface));
            for stream_result in server.tcp_listener.incoming() {
                let bootstrap_interface = bootstrap_interface.copy();
                let tcp = stream_result.unwrap();
                ::std::thread::spawn(move || {
                    let connection_state = RpcConnectionState::new();
                    let _rpc_chan = connection_state.run(
                        tcp.try_clone().unwrap(),
                        tcp,
                        bootstrap_interface,
                        ReaderOptions::new());
                });
            }
        })
    }
}

<commit_msg>Generalize the type of address in EzRpcClient and EzRpcServer<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use rpc_capnp::{message, return_};

use capnp::{MessageBuilder, MallocMessageBuilder, ReaderOptions};
use capnp::private::capability::{ClientHook};
use capnp::capability::{FromClientHook, Server};
use rpc::{RpcConnectionState, RpcEvent};
use capability::{LocalClient};

pub struct EzRpcClient {
    rpc_chan : ::std::sync::mpsc::Sender<RpcEvent>,
    tcp : ::std::net::TcpStream,
}

impl Drop for EzRpcClient {
    fn drop(&mut self) {
        self.rpc_chan.send(RpcEvent::Shutdown).is_ok();
        //self.tcp.close_read().is_ok();
    }
}

struct EmptyCap;

impl Server for EmptyCap {
    fn dispatch_call(&mut self, _interface_id : u64, _method_id : u16,
                     context : ::capnp::capability::CallContext<::capnp::any_pointer::Reader,
                                                                ::capnp::any_pointer::Builder>) {
        context.fail("Attempted to call a method on an empty capability.".to_string());
    }
}

impl EzRpcClient {
    pub fn new<A: ::std::net::ToSocketAddrs>(server_address : A) -> ::std::io::Result<EzRpcClient> {
        let tcp = try!(::std::net::TcpStream::connect(server_address));

        let connection_state = RpcConnectionState::new();

        let empty_cap = Box::new(EmptyCap);
        let bootstrap = Box::new(LocalClient::new(empty_cap));

        let chan = connection_state.run(try!(tcp.try_clone()),
                                        try!(tcp.try_clone()),
                                        bootstrap,
                                        ReaderOptions::new());

        return Ok(EzRpcClient { rpc_chan : chan, tcp : tcp });
    }

    pub fn get_main<T : FromClientHook>(&mut self) -> T {
        let mut message = Box::new(MallocMessageBuilder::new_default());
        {
            message.init_root::<message::Builder>().init_bootstrap();
        }

        let (outgoing, answer_port, _question_port) = RpcEvent::new_outgoing(message);
        self.rpc_chan.send(RpcEvent::Outgoing(outgoing)).unwrap();

        let mut response_hook = answer_port.recv().unwrap();
        let message : message::Reader = response_hook.get().get_as().unwrap();
        let client = match message.which() {
            Ok(message::Return(Ok(ret))) => {
                match ret.which() {
                    Ok(return_::Results(Ok(payload))) => {
                        payload.get_content().get_as_capability::<T>().unwrap()
                    }
                    _ => { panic!() }
                }
            }
            _ => {panic!()}
        };

        return client;
    }
}

pub struct EzRpcServer {
     tcp_listener : ::std::net::TcpListener,
}

impl EzRpcServer {
    pub fn new<A: ::std::net::ToSocketAddrs>(bind_address : A) -> ::std::io::Result<EzRpcServer> {
        let tcp_listener = try!(::std::net::TcpListener::bind(bind_address));
        Ok(EzRpcServer { tcp_listener : tcp_listener  })
    }

    pub fn serve<'a>(self, bootstrap_interface : Box<Server + Send>) -> ::std::thread::JoinGuard<'a, ()> {
        ::std::thread::scoped(move || {
            let server = self;
            let bootstrap_interface = Box::new(LocalClient::new(bootstrap_interface));
            for stream_result in server.tcp_listener.incoming() {
                let bootstrap_interface = bootstrap_interface.copy();
                let tcp = stream_result.unwrap();
                ::std::thread::spawn(move || {
                    let connection_state = RpcConnectionState::new();
                    let _rpc_chan = connection_state.run(
                        tcp.try_clone().unwrap(),
                        tcp,
                        bootstrap_interface,
                        ReaderOptions::new());
                });
            }
        })
    }
}

<|endoftext|>


<commit_before>// Copyright 2014-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.

/// The set of user configurable options for compiling zero or more regexes.
#[derive(Clone, Debug)]
#[allow(missing_docs)]
pub struct RegexOptions {
    pub pats: Vec<String>,
    pub size_limit: usize,
    pub dfa_size_limit: usize,
    pub case_insensitive: bool,
    pub multi_line: bool,
    pub dot_matches_new_line: bool,
    pub swap_greed: bool,
    pub ignore_whitespace: bool,
    pub unicode: bool,
}

impl Default for RegexOptions {
    fn default() -> Self {
        RegexOptions {
            pats: vec![],
            size_limit: 10 * (1<<20),
            dfa_size_limit: 2 * (1<<20),
            case_insensitive: false,
            multi_line: false,
            dot_matches_new_line: false,
            swap_greed: false,
            ignore_whitespace: false,
            unicode: true,
        }
    }
}

macro_rules! define_builder {
    ($name:ident, $regex_mod:ident, $only_utf8:expr) => {
        pub mod $name {
            use error::Error;
            use exec::ExecBuilder;
            use super::RegexOptions;

            use $regex_mod::Regex;

/// A configurable builder for a regular expression.
///
/// A builder can be used to configure how the regex is built, for example, by
/// setting the default flags (which can be overridden in the expression
/// itself) or setting various limits.
pub struct RegexBuilder(RegexOptions);

impl RegexBuilder {
    /// Create a new regular expression builder with the given pattern.
    ///
    /// If the pattern is invalid, then an error will be returned when
    /// `compile` is called.
    pub fn new(pattern: &str) -> RegexBuilder {
        let mut builder = RegexBuilder(RegexOptions::default());
        builder.0.pats.push(pattern.to_owned());
        builder
    }

    /// Consume the builder and compile the regular expression.
    ///
    /// Note that calling `as_str` on the resulting `Regex` will produce the
    /// pattern given to `new` verbatim. Notably, it will not incorporate any
    /// of the flags set on this builder.
    pub fn build(&self) -> Result<Regex, Error> {
        ExecBuilder::new_options(self.0.clone())
            .only_utf8($only_utf8)
            .build()
            .map(Regex::from)
    }

    /// Set the value for the case insensitive (`i`) flag.
    pub fn case_insensitive(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.case_insensitive = yes;
        self
    }

    /// Set the value for the multi-line matching (`m`) flag.
    pub fn multi_line(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.multi_line = yes;
        self
    }

    /// Set the value for the any character (`s`) flag, where in `.` matches
    /// anything when `s` is set and matches anything except for new line when
    /// it is not set (the default).
    ///
    /// N.B. "matches anything" means "any byte" for `regex::bytes::Regex`
    /// expressions and means "any Unicode scalar value" for `regex::Regex`
    /// expressions.
    pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.dot_matches_new_line = yes;
        self
    }

    /// Set the value for the greedy swap (`U`) flag.
    pub fn swap_greed(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.swap_greed = yes;
        self
    }

    /// Set the value for the ignore whitespace (`x`) flag.
    pub fn ignore_whitespace(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.ignore_whitespace = yes;
        self
    }

    /// Set the value for the Unicode (`u`) flag.
    pub fn unicode(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.unicode = yes;
        self
    }

    /// Set the approximate size limit of the compiled regular expression.
    ///
    /// This roughly corresponds to the number of bytes occupied by a single
    /// compiled program. If the program exceeds this number, then a
    /// compilation error is returned.
    pub fn size_limit(&mut self, limit: usize) -> &mut RegexBuilder {
        self.0.size_limit = limit;
        self
    }

    /// Set the approximate size of the cache used by the DFA.
    ///
    /// This roughly corresponds to the number of bytes that the DFA will
    /// use while searching.
    ///
    /// Note that this is a *per thread* limit. There is no way to set a global
    /// limit. In particular, if a regex is used from multiple threads
    /// simulanteously, then each thread may use up to the number of bytes
    /// specified here.
    pub fn dfa_size_limit(&mut self, limit: usize) -> &mut RegexBuilder {
        self.0.dfa_size_limit = limit;
        self
    }
}
        }
    }
}

define_builder!(bytes, re_bytes, false);
define_builder!(unicode, re_unicode, true);

macro_rules! define_set_builder {
    ($name:ident, $regex_mod:ident, $only_utf8:expr) => {
        pub mod $name {
            use error::Error;
            use exec::ExecBuilder;
            use super::RegexOptions;

            use re_set::$regex_mod::RegexSet;

/// A configurable builder for a set of regular expressions.
///
/// A builder can be used to configure how the regexes are built, for example,
/// by setting the default flags (which can be overridden in the expression
/// itself) or setting various limits.
pub struct RegexSetBuilder(RegexOptions);

impl RegexSetBuilder {
    /// Create a new regular expression builder with the given pattern.
    ///
    /// If the pattern is invalid, then an error will be returned when
    /// `compile` is called.
    pub fn new<I, S>(patterns: I) -> RegexSetBuilder
            where S: AsRef<str>, I: IntoIterator<Item=S> {
        let mut builder = RegexSetBuilder(RegexOptions::default());
        for pat in patterns {
            builder.0.pats.push(pat.as_ref().to_owned());
        }
        builder
    }

    /// Consume the builder and compile the regular expressions into a set.
    pub fn build(&self) -> Result<RegexSet, Error> {
        ExecBuilder::new_options(self.0.clone())
            .only_utf8($only_utf8)
            .build()
            .map(RegexSet::from)
    }

    /// Set the value for the case insensitive (`i`) flag.
    pub fn case_insensitive(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.case_insensitive = yes;
        self
    }

    /// Set the value for the multi-line matching (`m`) flag.
    pub fn multi_line(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.multi_line = yes;
        self
    }

    /// Set the value for the any character (`s`) flag, where in `.` matches
    /// anything when `s` is set and matches anything except for new line when
    /// it is not set (the default).
    ///
    /// N.B. "matches anything" means "any byte" for `regex::bytes::RegexSet`
    /// expressions and means "any Unicode scalar value" for `regex::RegexSet`
    /// expressions.
    pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.dot_matches_new_line = yes;
        self
    }

    /// Set the value for the greedy swap (`U`) flag.
    pub fn swap_greed(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.swap_greed = yes;
        self
    }

    /// Set the value for the ignore whitespace (`x`) flag.
    pub fn ignore_whitespace(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.ignore_whitespace = yes;
        self
    }

    /// Set the value for the Unicode (`u`) flag.
    pub fn unicode(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.unicode = yes;
        self
    }

    /// Set the approximate size limit of the compiled regular expression.
    ///
    /// This roughly corresponds to the number of bytes occupied by a single
    /// compiled program. If the program exceeds this number, then a
    /// compilation error is returned.
    pub fn size_limit(&mut self, limit: usize) -> &mut RegexSetBuilder {
        self.0.size_limit = limit;
        self
    }

    /// Set the approximate size of the cache used by the DFA.
    ///
    /// This roughly corresponds to the number of bytes that the DFA will
    /// use while searching.
    ///
    /// Note that this is a *per thread* limit. There is no way to set a global
    /// limit. In particular, if a regex is used from multiple threads
    /// simulanteously, then each thread may use up to the number of bytes
    /// specified here.
    pub fn dfa_size_limit(&mut self, limit: usize) -> &mut RegexSetBuilder {
        self.0.dfa_size_limit = limit;
        self
    }
}
        }
    }
}

define_set_builder!(set_bytes, bytes, false);
define_set_builder!(set_unicode, unicode, true);
<commit_msg>Fix docs for renaming of `RegexBuilder::build`.<commit_after>// Copyright 2014-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.

/// The set of user configurable options for compiling zero or more regexes.
#[derive(Clone, Debug)]
#[allow(missing_docs)]
pub struct RegexOptions {
    pub pats: Vec<String>,
    pub size_limit: usize,
    pub dfa_size_limit: usize,
    pub case_insensitive: bool,
    pub multi_line: bool,
    pub dot_matches_new_line: bool,
    pub swap_greed: bool,
    pub ignore_whitespace: bool,
    pub unicode: bool,
}

impl Default for RegexOptions {
    fn default() -> Self {
        RegexOptions {
            pats: vec![],
            size_limit: 10 * (1<<20),
            dfa_size_limit: 2 * (1<<20),
            case_insensitive: false,
            multi_line: false,
            dot_matches_new_line: false,
            swap_greed: false,
            ignore_whitespace: false,
            unicode: true,
        }
    }
}

macro_rules! define_builder {
    ($name:ident, $regex_mod:ident, $only_utf8:expr) => {
        pub mod $name {
            use error::Error;
            use exec::ExecBuilder;
            use super::RegexOptions;

            use $regex_mod::Regex;

/// A configurable builder for a regular expression.
///
/// A builder can be used to configure how the regex is built, for example, by
/// setting the default flags (which can be overridden in the expression
/// itself) or setting various limits.
pub struct RegexBuilder(RegexOptions);

impl RegexBuilder {
    /// Create a new regular expression builder with the given pattern.
    ///
    /// If the pattern is invalid, then an error will be returned when
    /// `build` is called.
    pub fn new(pattern: &str) -> RegexBuilder {
        let mut builder = RegexBuilder(RegexOptions::default());
        builder.0.pats.push(pattern.to_owned());
        builder
    }

    /// Consume the builder and compile the regular expression.
    ///
    /// Note that calling `as_str` on the resulting `Regex` will produce the
    /// pattern given to `new` verbatim. Notably, it will not incorporate any
    /// of the flags set on this builder.
    pub fn build(&self) -> Result<Regex, Error> {
        ExecBuilder::new_options(self.0.clone())
            .only_utf8($only_utf8)
            .build()
            .map(Regex::from)
    }

    /// Set the value for the case insensitive (`i`) flag.
    pub fn case_insensitive(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.case_insensitive = yes;
        self
    }

    /// Set the value for the multi-line matching (`m`) flag.
    pub fn multi_line(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.multi_line = yes;
        self
    }

    /// Set the value for the any character (`s`) flag, where in `.` matches
    /// anything when `s` is set and matches anything except for new line when
    /// it is not set (the default).
    ///
    /// N.B. "matches anything" means "any byte" for `regex::bytes::Regex`
    /// expressions and means "any Unicode scalar value" for `regex::Regex`
    /// expressions.
    pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.dot_matches_new_line = yes;
        self
    }

    /// Set the value for the greedy swap (`U`) flag.
    pub fn swap_greed(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.swap_greed = yes;
        self
    }

    /// Set the value for the ignore whitespace (`x`) flag.
    pub fn ignore_whitespace(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.ignore_whitespace = yes;
        self
    }

    /// Set the value for the Unicode (`u`) flag.
    pub fn unicode(&mut self, yes: bool) -> &mut RegexBuilder {
        self.0.unicode = yes;
        self
    }

    /// Set the approximate size limit of the compiled regular expression.
    ///
    /// This roughly corresponds to the number of bytes occupied by a single
    /// compiled program. If the program exceeds this number, then a
    /// compilation error is returned.
    pub fn size_limit(&mut self, limit: usize) -> &mut RegexBuilder {
        self.0.size_limit = limit;
        self
    }

    /// Set the approximate size of the cache used by the DFA.
    ///
    /// This roughly corresponds to the number of bytes that the DFA will
    /// use while searching.
    ///
    /// Note that this is a *per thread* limit. There is no way to set a global
    /// limit. In particular, if a regex is used from multiple threads
    /// simulanteously, then each thread may use up to the number of bytes
    /// specified here.
    pub fn dfa_size_limit(&mut self, limit: usize) -> &mut RegexBuilder {
        self.0.dfa_size_limit = limit;
        self
    }
}
        }
    }
}

define_builder!(bytes, re_bytes, false);
define_builder!(unicode, re_unicode, true);

macro_rules! define_set_builder {
    ($name:ident, $regex_mod:ident, $only_utf8:expr) => {
        pub mod $name {
            use error::Error;
            use exec::ExecBuilder;
            use super::RegexOptions;

            use re_set::$regex_mod::RegexSet;

/// A configurable builder for a set of regular expressions.
///
/// A builder can be used to configure how the regexes are built, for example,
/// by setting the default flags (which can be overridden in the expression
/// itself) or setting various limits.
pub struct RegexSetBuilder(RegexOptions);

impl RegexSetBuilder {
    /// Create a new regular expression builder with the given pattern.
    ///
    /// If the pattern is invalid, then an error will be returned when
    /// `build` is called.
    pub fn new<I, S>(patterns: I) -> RegexSetBuilder
            where S: AsRef<str>, I: IntoIterator<Item=S> {
        let mut builder = RegexSetBuilder(RegexOptions::default());
        for pat in patterns {
            builder.0.pats.push(pat.as_ref().to_owned());
        }
        builder
    }

    /// Consume the builder and compile the regular expressions into a set.
    pub fn build(&self) -> Result<RegexSet, Error> {
        ExecBuilder::new_options(self.0.clone())
            .only_utf8($only_utf8)
            .build()
            .map(RegexSet::from)
    }

    /// Set the value for the case insensitive (`i`) flag.
    pub fn case_insensitive(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.case_insensitive = yes;
        self
    }

    /// Set the value for the multi-line matching (`m`) flag.
    pub fn multi_line(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.multi_line = yes;
        self
    }

    /// Set the value for the any character (`s`) flag, where in `.` matches
    /// anything when `s` is set and matches anything except for new line when
    /// it is not set (the default).
    ///
    /// N.B. "matches anything" means "any byte" for `regex::bytes::RegexSet`
    /// expressions and means "any Unicode scalar value" for `regex::RegexSet`
    /// expressions.
    pub fn dot_matches_new_line(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.dot_matches_new_line = yes;
        self
    }

    /// Set the value for the greedy swap (`U`) flag.
    pub fn swap_greed(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.swap_greed = yes;
        self
    }

    /// Set the value for the ignore whitespace (`x`) flag.
    pub fn ignore_whitespace(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.ignore_whitespace = yes;
        self
    }

    /// Set the value for the Unicode (`u`) flag.
    pub fn unicode(&mut self, yes: bool) -> &mut RegexSetBuilder {
        self.0.unicode = yes;
        self
    }

    /// Set the approximate size limit of the compiled regular expression.
    ///
    /// This roughly corresponds to the number of bytes occupied by a single
    /// compiled program. If the program exceeds this number, then a
    /// compilation error is returned.
    pub fn size_limit(&mut self, limit: usize) -> &mut RegexSetBuilder {
        self.0.size_limit = limit;
        self
    }

    /// Set the approximate size of the cache used by the DFA.
    ///
    /// This roughly corresponds to the number of bytes that the DFA will
    /// use while searching.
    ///
    /// Note that this is a *per thread* limit. There is no way to set a global
    /// limit. In particular, if a regex is used from multiple threads
    /// simulanteously, then each thread may use up to the number of bytes
    /// specified here.
    pub fn dfa_size_limit(&mut self, limit: usize) -> &mut RegexSetBuilder {
        self.0.dfa_size_limit = limit;
        self
    }
}
        }
    }
}

define_set_builder!(set_bytes, bytes, false);
define_set_builder!(set_unicode, unicode, true);
<|endoftext|>


<commit_before>use std::mem;
use libc::{uint32_t, c_void};

pub use sys::timer as ll;

pub fn get_ticks() -> uint {
    unsafe { ll::SDL_GetTicks() as uint }
}

pub fn get_performance_counter() -> u64 {
    unsafe { ll::SDL_GetPerformanceCounter() }
}

pub fn get_performance_frequency() -> u64 {
    unsafe { ll::SDL_GetPerformanceFrequency() }
}

pub fn delay(ms: uint) {
    unsafe { ll::SDL_Delay(ms as u32) }
}

pub struct Timer<'a> {
    delay: uint,
    raw: ll::SDL_TimerID,
    closure: &'a Box<FnMut() -> uint + 'a>,
}

impl<'a> Timer<'a> {
    pub fn new(delay: uint, callback: &'a Box<FnMut() -> uint + 'a>) -> Timer<'a> {
        Timer { delay: delay, raw: 0, closure: callback }
    }

    pub fn start(&mut self) {
        unsafe {
            let timer_id = ll::SDL_AddTimer(
                    self.delay as u32,
                    Some(c_timer_callback as
                        extern "C" fn (
                            _interval: uint32_t,
                            param: *const c_void
                        ) -> uint32_t),
                    mem::transmute(self.closure)
                );
            self.raw = timer_id;
        }
    }

    pub fn remove(&mut self) -> bool {
        let ret = unsafe { ll::SDL_RemoveTimer(self.raw) };
        if self.raw != 0 {
            self.raw = 0
        }
        ret == 1
    }
}

#[unsafe_destructor]
impl<'a> Drop for Timer<'a> {
    fn drop(&mut self) {
        let ret = unsafe { ll::SDL_RemoveTimer(self.raw) };
        if ret != 1 {
            println!("error dropping timer {}, maybe already removed.", self.raw);
        }
    }
}

extern "C" fn c_timer_callback(_interval: uint32_t, param: *const c_void) -> uint32_t {
    let f: &mut Box<FnMut() -> uint> = unsafe { mem::transmute(param) };
    (*f)() as uint32_t
}

#[test]
fn test_timer_1() {
    use std::sync::{Arc, Mutex};

    let local_num: Arc<Mutex<u32>> = Arc::new(Mutex::new(0));
    let timer_num = local_num.clone();
    {
        let f: Box<FnMut() -> uint> = box |&mut:| {
            let mut num = timer_num.lock().unwrap();
            *num = *num + 1;
            10
        };
        let mut timer = Timer::new(10, &f);
        timer.start();
        delay(100);
        let num = local_num.lock().unwrap();
        assert!(*num == 9);
    }

    // Check that timer has stopped
    delay(100);
    let num = local_num.lock().unwrap();
    assert!(*num == 9);
}

#[test]
fn test_timer_2() {
    // Check that the closure lives long enough outside the block where
    // the timer was started.
    let f: Box<FnMut() -> uint> = box |&:| { 0 };
    let _ = {
        let mut timer = Timer::new(1000, &f);
        timer.start();
        timer
    };
    delay(200);
    delay(200);
    delay(200);
    delay(200);
    delay(200);
    delay(200);
}
<commit_msg>Use SDL timers with C functions<commit_after>use libc::{uint32_t, c_void};

pub use sys::timer as ll;

pub fn get_ticks() -> uint {
    unsafe { ll::SDL_GetTicks() as uint }
}

pub fn get_performance_counter() -> u64 {
    unsafe { ll::SDL_GetPerformanceCounter() }
}

pub fn get_performance_frequency() -> u64 {
    unsafe { ll::SDL_GetPerformanceFrequency() }
}

pub fn delay(ms: uint) {
    unsafe { ll::SDL_Delay(ms as u32) }
}

pub type TimerCallback = extern "C" fn (interval: uint32_t, param: *const c_void) -> u32;

pub struct Timer {
    delay: uint,
    raw: ll::SDL_TimerID,
    callback: TimerCallback,
    param: *const c_void,
    remove_on_drop: bool,
}

impl Timer {
    pub fn new(delay: uint, callback: TimerCallback, param: *const c_void, remove_on_drop: bool) -> Timer {
        Timer { delay: delay, raw: 0, callback: callback, param: param, remove_on_drop: remove_on_drop }
    }

    pub fn start(&mut self) {
        unsafe {
            let timer_id = ll::SDL_AddTimer(self.delay as u32, Some(self.callback), self.param);
            self.raw = timer_id;
        }
    }

    pub fn remove(&mut self) -> bool {
        let ret = unsafe { ll::SDL_RemoveTimer(self.raw) };
        if self.raw != 0 {
            self.raw = 0
        }
        ret == 1
    }
}

#[unsafe_destructor]
impl Drop for Timer {
    fn drop(&mut self) {
        if self.remove_on_drop {
            let ret = unsafe { ll::SDL_RemoveTimer(self.raw) };
            if ret != 1 {
                println!("error dropping timer {}, maybe already removed.", self.raw);
            }
        }
    }
}

#[cfg(test)]
extern "C" fn test_timer_1_callback(_interval: uint32_t, param: *const c_void) -> uint32_t {
    use std::sync::{Arc, Mutex};
    use std::mem;

    let locked_num: &Arc<Mutex<u32>> = unsafe { mem::transmute(param) };
    let mut num = locked_num.lock().unwrap();
    *num = *num + 1;
    10
}

#[test]
fn test_timer_1() {
    use std::sync::{Arc, Mutex};
    use std::mem;

    let local_num: Arc<Mutex<u32>> = Arc::new(Mutex::new(0));
    let timer_num = local_num.clone();
    {
        let param = unsafe { mem::transmute(&timer_num) };
        let mut timer = Timer::new(10, test_timer_1_callback, param, true);
        timer.start();
        delay(100);
        let num = local_num.lock().unwrap();
        assert!(*num == 9);
    }

    // Check that timer has stopped
    delay(100);
    let num = local_num.lock().unwrap();
    assert!(*num == 9);
}

#[cfg(test)]
extern "C" fn test_timer_2_callback(_interval: uint32_t, _param: *const c_void) -> uint32_t {
    0
}

#[test]
fn test_timer_2() {
    use std::ptr;

    let _ = {
        let mut timer = Timer::new(1000, test_timer_2_callback, ptr::null(), true);
        timer.start();
        timer
    };
    delay(200);
    delay(200);
    delay(200);
    delay(200);
    delay(200);
    delay(200);
}
<|endoftext|>


<commit_before>use super::error::Error;
use super::wasm;
use std::env;
use std::fs;
use std::net::TcpListener;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use tiny_http::{Header, Response, Server};
use webbrowser;

macro_rules! resource {
    ($name: tt, $path: tt) => {
        #[cfg(TREE_SITTER_EMBED_WASM_BINDING)]
        fn $name(tree_sitter_dir: &Option<PathBuf>) -> Vec<u8> {
            if let Some(tree_sitter_dir) = tree_sitter_dir {
                fs::read(tree_sitter_dir.join($path)).unwrap()
            } else {
                include_bytes!(concat!("../../", $path)).to_vec()
            }
        }

        #[cfg(not(TREE_SITTER_EMBED_WASM_BINDING))]
        fn $name(tree_sitter_dir: &Option<PathBuf>) -> Vec<u8> {
            if let Some(tree_sitter_dir) = tree_sitter_dir {
                fs::read(tree_sitter_dir.join($path)).unwrap()
            } else {
                include_bytes!(concat!("../../", $path)).to_vec()
            }
        }
    };
}

macro_rules! posix_resource {
    ($name: tt, $path: tt) => {
        #[cfg(TREE_SITTER_EMBED_WASM_BINDING)]
        fn $name(tree_sitter_dir: &Option<PathBuf>) -> Vec<u8> {
            if let Some(tree_sitter_dir) = tree_sitter_dir {
                fs::read(tree_sitter_dir.join($path)).unwrap()
            } else {
                include_bytes!(concat!("../../", $path)).to_vec()
            }
        }

        #[cfg(not(TREE_SITTER_EMBED_WASM_BINDING))]
        fn $name(tree_sitter_dir: &Option<PathBuf>) -> Vec<u8> {
            if let Some(tree_sitter_dir) = tree_sitter_dir {
                fs::read(tree_sitter_dir.join($path)).unwrap()
            } else {
                Vec::new()
            }
        }
    };
}

resource!(get_main_html, "cli/src/web_ui.html");
resource!(get_playground_js, "docs/assets/js/playground.js");
posix_resource!(get_lib_js, "lib/binding_web/tree-sitter.js");
posix_resource!(get_lib_wasm, "lib/binding_web/tree-sitter.wasm");

pub fn serve(grammar_path: &Path, open_in_browser: bool) {
    let port = get_available_port().expect("Couldn't find an available port");
    let url = format!("127.0.0.1:{}", port);
    let server = Server::http(&url).expect("Failed to start web server");
    let grammar_name = wasm::get_grammar_name(&grammar_path.join("src"))
        .map_err(Error::wrap(|| "Failed to get wasm filename"))
        .unwrap();
    let wasm_filename = format!("tree-sitter-{}.wasm", grammar_name);
    let language_wasm = fs::read(grammar_path.join(&wasm_filename))
        .map_err(Error::wrap(|| {
            format!(
                "Failed to read {}. Run `tree-sitter build-wasm` first.",
                wasm_filename
            )
        }))
        .unwrap();
    if open_in_browser {
        if let Err(_) = webbrowser::open(&format!("http://127.0.0.1:{}", port)) {
            eprintln!("Failed to open '{}' in a web browser", url);
        }
    }

    let tree_sitter_dir = env::var("TREE_SITTER_BASE_DIR").map(PathBuf::from).ok();
    let main_html = String::from_utf8(get_main_html(&tree_sitter_dir))
        .unwrap()
        .replace("THE_LANGUAGE_NAME", &grammar_name)
        .into_bytes();
    let playground_js = get_playground_js(&tree_sitter_dir);
    let lib_js = get_lib_js(&tree_sitter_dir);
    let lib_wasm = get_lib_wasm(&tree_sitter_dir);

    let html_header = Header::from_str("Content-Type: text/html").unwrap();
    let js_header = Header::from_str("Content-Type: application/javascript").unwrap();
    let wasm_header = Header::from_str("Content-Type: application/wasm").unwrap();

    for request in server.incoming_requests() {
        let res = match request.url() {
            "/" => response(&main_html, &html_header),
            "/playground.js" => response(&playground_js, &js_header),
            "/tree-sitter-parser.wasm" => response(&language_wasm, &wasm_header),
            "/tree-sitter.js" => {
                if cfg!(windows) {
                    redirect("https://tree-sitter.github.io/tree-sitter.js")
                } else {
                    response(&lib_js, &js_header)
                }
            }
            "/tree-sitter.wasm" => {
                if cfg!(windows) {
                    redirect("https://tree-sitter.github.io/tree-sitter.wasm")
                } else {
                    response(&lib_wasm, &wasm_header)
                }
            }
            _ => response(b"Not found", &html_header).with_status_code(404),
        };
        request.respond(res).expect("Failed to write HTTP response");
    }
}

fn redirect<'a>(url: &'a str) -> Response<&'a [u8]> {
    Response::empty(302)
        .with_data("".as_bytes(), Some(0))
        .with_header(Header::from_bytes("Location", url.as_bytes()).unwrap())
}

fn response<'a>(data: &'a [u8], header: &Header) -> Response<&'a [u8]> {
    Response::empty(200)
        .with_data(data, Some(data.len()))
        .with_header(header.clone())
}

fn get_available_port() -> Option<u16> {
    (8000..12000).find(port_is_available)
}

fn port_is_available(port: &u16) -> bool {
    TcpListener::bind(("127.0.0.1", *port)).is_ok()
}
<commit_msg>Better naming.<commit_after>use super::error::Error;
use super::wasm;
use std::env;
use std::fs;
use std::net::TcpListener;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use tiny_http::{Header, Response, Server};
use webbrowser;

macro_rules! resource {
    ($name: tt, $path: tt) => {
        #[cfg(TREE_SITTER_EMBED_WASM_BINDING)]
        fn $name(tree_sitter_dir: &Option<PathBuf>) -> Vec<u8> {
            if let Some(tree_sitter_dir) = tree_sitter_dir {
                fs::read(tree_sitter_dir.join($path)).unwrap()
            } else {
                include_bytes!(concat!("../../", $path)).to_vec()
            }
        }

        #[cfg(not(TREE_SITTER_EMBED_WASM_BINDING))]
        fn $name(tree_sitter_dir: &Option<PathBuf>) -> Vec<u8> {
            if let Some(tree_sitter_dir) = tree_sitter_dir {
                fs::read(tree_sitter_dir.join($path)).unwrap()
            } else {
                include_bytes!(concat!("../../", $path)).to_vec()
            }
        }
    };
}

macro_rules! optional_resource {
    ($name: tt, $path: tt) => {
        #[cfg(TREE_SITTER_EMBED_WASM_BINDING)]
        fn $name(tree_sitter_dir: &Option<PathBuf>) -> Vec<u8> {
            if let Some(tree_sitter_dir) = tree_sitter_dir {
                fs::read(tree_sitter_dir.join($path)).unwrap()
            } else {
                include_bytes!(concat!("../../", $path)).to_vec()
            }
        }

        #[cfg(not(TREE_SITTER_EMBED_WASM_BINDING))]
        fn $name(tree_sitter_dir: &Option<PathBuf>) -> Vec<u8> {
            if let Some(tree_sitter_dir) = tree_sitter_dir {
                fs::read(tree_sitter_dir.join($path)).unwrap()
            } else {
                Vec::new()
            }
        }
    };
}

resource!(get_main_html, "cli/src/web_ui.html");
resource!(get_playground_js, "docs/assets/js/playground.js");
optional_resource!(get_lib_js, "lib/binding_web/tree-sitter.js");
optional_resource!(get_lib_wasm, "lib/binding_web/tree-sitter.wasm");

pub fn serve(grammar_path: &Path, open_in_browser: bool) {
    let port = get_available_port().expect("Couldn't find an available port");
    let url = format!("127.0.0.1:{}", port);
    let server = Server::http(&url).expect("Failed to start web server");
    let grammar_name = wasm::get_grammar_name(&grammar_path.join("src"))
        .map_err(Error::wrap(|| "Failed to get wasm filename"))
        .unwrap();
    let wasm_filename = format!("tree-sitter-{}.wasm", grammar_name);
    let language_wasm = fs::read(grammar_path.join(&wasm_filename))
        .map_err(Error::wrap(|| {
            format!(
                "Failed to read {}. Run `tree-sitter build-wasm` first.",
                wasm_filename
            )
        }))
        .unwrap();
    if open_in_browser {
        if let Err(_) = webbrowser::open(&format!("http://127.0.0.1:{}", port)) {
            eprintln!("Failed to open '{}' in a web browser", url);
        }
    }

    let tree_sitter_dir = env::var("TREE_SITTER_BASE_DIR").map(PathBuf::from).ok();
    let main_html = String::from_utf8(get_main_html(&tree_sitter_dir))
        .unwrap()
        .replace("THE_LANGUAGE_NAME", &grammar_name)
        .into_bytes();
    let playground_js = get_playground_js(&tree_sitter_dir);
    let lib_js = get_lib_js(&tree_sitter_dir);
    let lib_wasm = get_lib_wasm(&tree_sitter_dir);

    let html_header = Header::from_str("Content-Type: text/html").unwrap();
    let js_header = Header::from_str("Content-Type: application/javascript").unwrap();
    let wasm_header = Header::from_str("Content-Type: application/wasm").unwrap();

    for request in server.incoming_requests() {
        let res = match request.url() {
            "/" => response(&main_html, &html_header),
            "/playground.js" => response(&playground_js, &js_header),
            "/tree-sitter-parser.wasm" => response(&language_wasm, &wasm_header),
            "/tree-sitter.js" => {
                if cfg!(windows) {
                    redirect("https://tree-sitter.github.io/tree-sitter.js")
                } else {
                    response(&lib_js, &js_header)
                }
            }
            "/tree-sitter.wasm" => {
                if cfg!(windows) {
                    redirect("https://tree-sitter.github.io/tree-sitter.wasm")
                } else {
                    response(&lib_wasm, &wasm_header)
                }
            }
            _ => response(b"Not found", &html_header).with_status_code(404),
        };
        request.respond(res).expect("Failed to write HTTP response");
    }
}

fn redirect<'a>(url: &'a str) -> Response<&'a [u8]> {
    Response::empty(302)
        .with_data("".as_bytes(), Some(0))
        .with_header(Header::from_bytes("Location", url.as_bytes()).unwrap())
}

fn response<'a>(data: &'a [u8], header: &Header) -> Response<&'a [u8]> {
    Response::empty(200)
        .with_data(data, Some(data.len()))
        .with_header(header.clone())
}

fn get_available_port() -> Option<u16> {
    (8000..12000).find(port_is_available)
}

fn port_is_available(port: &u16) -> bool {
    TcpListener::bind(("127.0.0.1", *port)).is_ok()
}
<|endoftext|>