<commit_before>#![warn(rust_2018_idioms)]

#[macro_use]
extern crate tracing;

use std::collections::hash_map::{Entry, HashMap};

use conduit::{box_error, Handler, HandlerResult, Method, RequestExt};
use route_recognizer::{Match, Params, Router};

#[derive(Default)]
pub struct RouteBuilder {
    routers: HashMap<Method, Router<WrappedHandler>>,
}

#[derive(Clone, Copy)]
pub struct RoutePattern(&'static str);

impl RoutePattern {
    pub fn pattern(&self) -> &str {
        self.0
    }
}

struct WrappedHandler {
    pattern: RoutePattern,
    handler: Box<dyn Handler>,
}

impl conduit::Handler for WrappedHandler {
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        self.handler.call(request)
    }
}

#[derive(Debug, thiserror::Error)]
pub enum RouterError {
    #[error("Invalid method")]
    UnknownMethod,
    #[error("Path not found")]
    PathNotFound,
}

impl RouteBuilder {
    pub fn new() -> Self {
        Self {
            routers: HashMap::new(),
        }
    }

    #[instrument(level = "trace", skip(self))]
    fn recognize<'a>(
        &'a self,
        method: &Method,
        path: &str,
    ) -> Result<Match<&WrappedHandler>, RouterError> {
        match self.routers.get(method) {
            Some(router) => router.recognize(path).or(Err(RouterError::PathNotFound)),
            None => Err(RouterError::UnknownMethod),
        }
    }

    #[instrument(level = "trace", skip(self, handler))]
    pub fn map<H: Handler>(
        &mut self,
        method: Method,
        pattern: &'static str,
        handler: H,
    ) -> &mut Self {
        {
            let router = match self.routers.entry(method) {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(Router::new()),
            };
            let wrapped_handler = WrappedHandler {
                pattern: RoutePattern(pattern),
                handler: Box::new(handler),
            };
            router.add(pattern, wrapped_handler);
        }
        self
    }

    pub fn get<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut Self {
        self.map(Method::GET, pattern, handler)
    }

    pub fn post<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut Self {
        self.map(Method::POST, pattern, handler)
    }

    pub fn put<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut Self {
        self.map(Method::PUT, pattern, handler)
    }

    pub fn delete<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut Self {
        self.map(Method::DELETE, pattern, handler)
    }

    pub fn head<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut Self {
        self.map(Method::HEAD, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    #[instrument(level = "trace", skip(self, request))]
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        let mut m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => {
                    info!("{}", e);
                    return Err(box_error(e));
                }
            }
        };

        // We don't have `pub` access to the fields to destructure `Params`, so swap with an empty
        // value to avoid an allocation.
        let mut params = Params::new();
        std::mem::swap(m.params_mut(), &mut params);

        let pattern = m.handler().pattern;
        debug!(pattern = pattern.0, "matching route handler found");

        {
            let extensions = request.mut_extensions();
            extensions.insert(pattern);
            extensions.insert(params);
        }

        let span = trace_span!("handler", pattern = pattern.0);
        span.in_scope(|| m.handler().call(request))
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a Params;
}

impl<'a> RequestParams<'a> for &'a (dyn RequestExt + 'a) {
    fn params(self) -> &'a Params {
        self.extensions().get::<Params>().expect("Missing params")
    }
}

#[cfg(test)]
mod tests {
    use super::{RequestParams, RouteBuilder, RoutePattern};

    use conduit::{Body, Handler, Method, Response, StatusCode};
    use conduit_test::{MockRequest, ResponseExt};

    lazy_static::lazy_static! {
        static ref TRACING: () = {
            tracing_subscriber::FmtSubscriber::builder()
                .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
                .with_span_events(tracing_subscriber::fmt::format::FmtSpan::FULL)
                .with_test_writer()
                .init();
        };
    }

    #[test]
    fn basic_get() {
        lazy_static::initialize(&TRACING);

        let router = test_router();
        let mut req = MockRequest::new(Method::GET, "/posts/1");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"1, GET, /posts/:id"[..]);
    }

    #[test]
    fn basic_post() {
        lazy_static::initialize(&TRACING);

        let router = test_router();
        let mut req = MockRequest::new(Method::POST, "/posts/10");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"10, POST, /posts/:id"[..]);
    }

    #[test]
    fn path_not_found() {
        lazy_static::initialize(&TRACING);

        let router = test_router();
        let mut req = MockRequest::new(Method::POST, "/nonexistent");
        let err = router.call(&mut req).err().unwrap();

        assert_eq!(err.to_string(), "Path not found");
    }

    #[test]
    fn unknown_method() {
        lazy_static::initialize(&TRACING);

        let router = test_router();
        let mut req = MockRequest::new(Method::DELETE, "/posts/1");
        let err = router.call(&mut req).err().unwrap();

        assert_eq!(err.to_string(), "Invalid method");
    }

    #[test]
    fn catch_all() {
        lazy_static::initialize(&TRACING);

        let mut router = RouteBuilder::new();
        router.get("/*", test_handler);

        let mut req = MockRequest::new(Method::GET, "/foo");
        let res = router.call(&mut req).expect("No response");
        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b", GET, /*"[..]);
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut dyn conduit::RequestExt) -> conduit::HttpResult {
        let res = vec![
            req.params().find("id").unwrap_or("").to_string(),
            format!("{:?}", req.method()),
            req.extensions()
                .get::<RoutePattern>()
                .unwrap()
                .pattern()
                .to_string(),
        ];

        let bytes = res.join(", ").into_bytes();
        Response::builder().body(Body::from_vec(bytes))
    }
}
<commit_msg>Fix clippy warnings<commit_after>#![warn(rust_2018_idioms)]

#[macro_use]
extern crate tracing;

use std::collections::hash_map::{Entry, HashMap};

use conduit::{box_error, Handler, HandlerResult, Method, RequestExt};
use route_recognizer::{Match, Params, Router};

#[derive(Default)]
pub struct RouteBuilder {
    routers: HashMap<Method, Router<WrappedHandler>>,
}

#[derive(Clone, Copy)]
pub struct RoutePattern(&'static str);

impl RoutePattern {
    pub fn pattern(&self) -> &str {
        self.0
    }
}

struct WrappedHandler {
    pattern: RoutePattern,
    handler: Box<dyn Handler>,
}

impl conduit::Handler for WrappedHandler {
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        self.handler.call(request)
    }
}

#[derive(Debug, thiserror::Error)]
pub enum RouterError {
    #[error("Invalid method")]
    UnknownMethod,
    #[error("Path not found")]
    PathNotFound,
}

impl RouteBuilder {
    pub fn new() -> Self {
        Self {
            routers: HashMap::new(),
        }
    }

    #[instrument(level = "trace", skip(self))]
    #[allow(clippy::suspicious_else_formatting)]
    fn recognize<'a>(
        &'a self,
        method: &Method,
        path: &str,
    ) -> Result<Match<&WrappedHandler>, RouterError> {
        match self.routers.get(method) {
            Some(router) => router.recognize(path).or(Err(RouterError::PathNotFound)),
            None => Err(RouterError::UnknownMethod),
        }
    }

    #[instrument(level = "trace", skip(self, handler))]
    pub fn map<H: Handler>(
        &mut self,
        method: Method,
        pattern: &'static str,
        handler: H,
    ) -> &mut Self {
        let router = match self.routers.entry(method) {
            Entry::Occupied(e) => e.into_mut(),
            Entry::Vacant(e) => e.insert(Router::new()),
        };
        let wrapped_handler = WrappedHandler {
            pattern: RoutePattern(pattern),
            handler: Box::new(handler),
        };
        router.add(pattern, wrapped_handler);
        self
    }

    pub fn get<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut Self {
        self.map(Method::GET, pattern, handler)
    }

    pub fn post<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut Self {
        self.map(Method::POST, pattern, handler)
    }

    pub fn put<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut Self {
        self.map(Method::PUT, pattern, handler)
    }

    pub fn delete<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut Self {
        self.map(Method::DELETE, pattern, handler)
    }

    pub fn head<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut Self {
        self.map(Method::HEAD, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    #[instrument(level = "trace", skip(self, request))]
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        let mut m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => {
                    info!("{}", e);
                    return Err(box_error(e));
                }
            }
        };

        // We don't have `pub` access to the fields to destructure `Params`, so swap with an empty
        // value to avoid an allocation.
        let mut params = Params::new();
        std::mem::swap(m.params_mut(), &mut params);

        let pattern = m.handler().pattern;
        debug!(pattern = pattern.0, "matching route handler found");

        let extensions = request.mut_extensions();
        extensions.insert(pattern);
        extensions.insert(params);

        let span = trace_span!("handler", pattern = pattern.0);
        span.in_scope(|| m.handler().call(request))
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a Params;
}

impl<'a> RequestParams<'a> for &'a (dyn RequestExt + 'a) {
    fn params(self) -> &'a Params {
        self.extensions().get::<Params>().expect("Missing params")
    }
}

#[cfg(test)]
mod tests {
    use super::{RequestParams, RouteBuilder, RoutePattern};

    use conduit::{Body, Handler, Method, Response, StatusCode};
    use conduit_test::{MockRequest, ResponseExt};

    lazy_static::lazy_static! {
        static ref TRACING: () = {
            tracing_subscriber::FmtSubscriber::builder()
                .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
                .with_span_events(tracing_subscriber::fmt::format::FmtSpan::FULL)
                .with_test_writer()
                .init();
        };
    }

    #[test]
    fn basic_get() {
        lazy_static::initialize(&TRACING);

        let router = test_router();
        let mut req = MockRequest::new(Method::GET, "/posts/1");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"1, GET, /posts/:id"[..]);
    }

    #[test]
    fn basic_post() {
        lazy_static::initialize(&TRACING);

        let router = test_router();
        let mut req = MockRequest::new(Method::POST, "/posts/10");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"10, POST, /posts/:id"[..]);
    }

    #[test]
    fn path_not_found() {
        lazy_static::initialize(&TRACING);

        let router = test_router();
        let mut req = MockRequest::new(Method::POST, "/nonexistent");
        let err = router.call(&mut req).err().unwrap();

        assert_eq!(err.to_string(), "Path not found");
    }

    #[test]
    fn unknown_method() {
        lazy_static::initialize(&TRACING);

        let router = test_router();
        let mut req = MockRequest::new(Method::DELETE, "/posts/1");
        let err = router.call(&mut req).err().unwrap();

        assert_eq!(err.to_string(), "Invalid method");
    }

    #[test]
    fn catch_all() {
        lazy_static::initialize(&TRACING);

        let mut router = RouteBuilder::new();
        router.get("/*", test_handler);

        let mut req = MockRequest::new(Method::GET, "/foo");
        let res = router.call(&mut req).expect("No response");
        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b", GET, /*"[..]);
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut dyn conduit::RequestExt) -> conduit::HttpResult {
        let res = vec![
            req.params().find("id").unwrap_or("").to_string(),
            format!("{:?}", req.method()),
            req.extensions()
                .get::<RoutePattern>()
                .unwrap()
                .pattern()
                .to_string(),
        ];

        let bytes = res.join(", ").into_bytes();
        Response::builder().body(Body::from_vec(bytes))
    }
}
<|endoftext|>


<commit_before>use std::{ffi::OsStr, fs, io, path, result::Result, string::ToString};

use syntax::print::pprust;
use syntax::{ast, source_map, visit};

use tree::{Tree, Visibility};

pub struct Config {
    pub include_orphans: bool,
    pub ignored_files: Vec<path::PathBuf>,
}

pub struct Builder<'a> {
    tree: Tree,
    path: Vec<String>,
    config: Config,
    source_map: &'a source_map::SourceMap,
}

impl<'a> Builder<'a> {
    pub fn new(config: Config, crate_name: String, source_map: &'a source_map::SourceMap) -> Self {
        let tree = Tree::new_crate(crate_name);
        Builder {
            tree,
            path: vec![],
            config,
            source_map,
        }
    }

    pub fn tree(&self) -> &Tree {
        &self.tree
    }

    fn find_orphan_candidates(
        path: &[String],
        ignored_paths: &[path::PathBuf],
    ) -> Result<Vec<String>, io::Error> {
        let mut dir_path = "./src/".to_string();
        for name in path.iter() {
            dir_path.push_str(name);
            dir_path.push_str("/");
        }
        fn is_mod(entry: &fs::DirEntry) -> bool {
            let path = entry.path();
            if path.is_file() {
                if path.extension().map_or(false, |ext| ext == "rs") {
                    return file_name(entry)
                        .map_or(false, |s| (s != "mod") && (s != "lib") && (s != "main"));
                }
            } else if path.join("mod.rs").exists() {
                return true;
            }
            false
        }
        fn file_name(entry: &fs::DirEntry) -> Option<String> {
            entry
                .path()
                .file_stem()
                .and_then(OsStr::to_str)
                .map(ToString::to_string)
        }
        Ok(fs::read_dir(&dir_path)?
            .filter_map(Result::ok)
            .filter(is_mod)
            .filter(|e| !ignored_paths.contains(&e.path()))
            .filter_map(|e| file_name(&e))
            .collect::<Vec<_>>())
    }

    fn sanitize_condition(condition: String) -> String {
        let words: Vec<&str> = condition.split_whitespace().collect();
        words.join(" ")
    }
}

impl<'a> visit::Visitor<'a> for Builder<'a> {
    fn visit_item(&mut self, item: &'a ast::Item) {
        let condition = item
            .attrs
            .iter()
            .find(|attr| attr.check_name("cfg"))
            .map(|attr| {
                self.source_map
                    .span_to_snippet(attr.span)
                    .map(Builder::sanitize_condition)
                    .unwrap_or_else(|_| "".to_string())
            });

        match item.node {
            ast::ItemKind::Mod(_) => {
                let name = item.ident.to_string();
                {
                    let tree = self.tree.subtree_at_path(&self.path).unwrap();
                    let visibility = if let ast::VisibilityKind::Public = item.vis.node {
                        Visibility::Public
                    } else {
                        Visibility::Private
                    };
                    tree.insert(Tree::new_module(name.clone(), visibility, condition));
                }
                self.path.push(name);
                visit::walk_item(self, item);
                let _ = self.path.pop();
            }
            ast::ItemKind::Use(ref use_tree) => {
                {
                    let tree = self.tree.subtree_at_path(&self.path).unwrap();
                    let visibility = if let ast::VisibilityKind::Public = item.vis.node {
                        Visibility::Public
                    } else {
                        Visibility::Private
                    };

                    add_use_tree(tree, visibility, "", use_tree);
                }

                visit::walk_item(self, item);
            }
            _ => {
                visit::walk_item(self, item);
            }
        }
    }

    fn visit_mod(
        &mut self,
        m: &'a ast::Mod,
        _s: source_map::Span,
        _attrs: &[ast::Attribute],
        _n: ast::NodeId,
    ) {
        visit::walk_mod(self, m);
        if !self.config.include_orphans {
            return;
        }
        let path = &self.path;
        if let Ok(candidates) = Builder::find_orphan_candidates(path, &self.config.ignored_files) {
            let tree = self.tree.subtree_at_path(path).unwrap();
            let names: Vec<_> = tree.subtree_names();
            for candidate in candidates {
                if !names.contains(&candidate) {
                    tree.insert(Tree::new_orphan(candidate.clone()));
                }
            }
        }
    }

    fn visit_mac(&mut self, mac: &ast::Mac) {
        visit::walk_mac(self, mac);
    }
}

fn add_use_tree(tree: &mut Tree, visibility: Visibility, prefix: &str, use_tree: &ast::UseTree) {
    let prefix = if prefix.is_empty() {
        String::new()
    } else {
        prefix.to_string()
    };

    match use_tree.kind {
        ast::UseTreeKind::Simple(_, ..) => {
            let path = pprust::path_to_string(&use_tree.prefix);
            if path != "self" {
                tree.insert_use((visibility, prefix + &path));
            } else {
                let mut prefix = prefix;
                let new_len = prefix.len() - 2;
                prefix.truncate(new_len);
                tree.insert_use((visibility, prefix));
            }
        }
        ast::UseTreeKind::Glob => {
            let mut use_path = if use_tree.prefix.segments.is_empty() {
                prefix
            } else {
                prefix + &pprust::path_to_string(&use_tree.prefix) + "::"
            };
            use_path += "*";
            tree.insert_use((visibility, use_path));
        }
        ast::UseTreeKind::Nested(ref items) => {
            let mut prefix = if use_tree.prefix.segments.is_empty() {
                prefix
            } else {
                prefix + &pprust::path_to_string(&use_tree.prefix) + "::"
            };
            for (sub_tree, _) in items {
                add_use_tree(tree, visibility, &prefix, sub_tree);
            }
        }
    }
}
<commit_msg>Use immutable local values in add_use_tree<commit_after>use std::{ffi::OsStr, fs, io, path, result::Result, string::ToString};

use syntax::print::pprust;
use syntax::{ast, source_map, visit};

use tree::{Tree, Visibility};

pub struct Config {
    pub include_orphans: bool,
    pub ignored_files: Vec<path::PathBuf>,
}

pub struct Builder<'a> {
    tree: Tree,
    path: Vec<String>,
    config: Config,
    source_map: &'a source_map::SourceMap,
}

impl<'a> Builder<'a> {
    pub fn new(config: Config, crate_name: String, source_map: &'a source_map::SourceMap) -> Self {
        let tree = Tree::new_crate(crate_name);
        Builder {
            tree,
            path: vec![],
            config,
            source_map,
        }
    }

    pub fn tree(&self) -> &Tree {
        &self.tree
    }

    fn find_orphan_candidates(
        path: &[String],
        ignored_paths: &[path::PathBuf],
    ) -> Result<Vec<String>, io::Error> {
        let mut dir_path = "./src/".to_string();
        for name in path.iter() {
            dir_path.push_str(name);
            dir_path.push_str("/");
        }
        fn is_mod(entry: &fs::DirEntry) -> bool {
            let path = entry.path();
            if path.is_file() {
                if path.extension().map_or(false, |ext| ext == "rs") {
                    return file_name(entry)
                        .map_or(false, |s| (s != "mod") && (s != "lib") && (s != "main"));
                }
            } else if path.join("mod.rs").exists() {
                return true;
            }
            false
        }
        fn file_name(entry: &fs::DirEntry) -> Option<String> {
            entry
                .path()
                .file_stem()
                .and_then(OsStr::to_str)
                .map(ToString::to_string)
        }
        Ok(fs::read_dir(&dir_path)?
            .filter_map(Result::ok)
            .filter(is_mod)
            .filter(|e| !ignored_paths.contains(&e.path()))
            .filter_map(|e| file_name(&e))
            .collect::<Vec<_>>())
    }

    fn sanitize_condition(condition: String) -> String {
        let words: Vec<&str> = condition.split_whitespace().collect();
        words.join(" ")
    }
}

impl<'a> visit::Visitor<'a> for Builder<'a> {
    fn visit_item(&mut self, item: &'a ast::Item) {
        let condition = item
            .attrs
            .iter()
            .find(|attr| attr.check_name("cfg"))
            .map(|attr| {
                self.source_map
                    .span_to_snippet(attr.span)
                    .map(Builder::sanitize_condition)
                    .unwrap_or_else(|_| "".to_string())
            });

        match item.node {
            ast::ItemKind::Mod(_) => {
                let name = item.ident.to_string();
                {
                    let tree = self.tree.subtree_at_path(&self.path).unwrap();
                    let visibility = if let ast::VisibilityKind::Public = item.vis.node {
                        Visibility::Public
                    } else {
                        Visibility::Private
                    };
                    tree.insert(Tree::new_module(name.clone(), visibility, condition));
                }
                self.path.push(name);
                visit::walk_item(self, item);
                let _ = self.path.pop();
            }
            ast::ItemKind::Use(ref use_tree) => {
                {
                    let tree = self.tree.subtree_at_path(&self.path).unwrap();
                    let visibility = if let ast::VisibilityKind::Public = item.vis.node {
                        Visibility::Public
                    } else {
                        Visibility::Private
                    };

                    add_use_tree(tree, visibility, "", use_tree);
                }

                visit::walk_item(self, item);
            }
            _ => {
                visit::walk_item(self, item);
            }
        }
    }

    fn visit_mod(
        &mut self,
        m: &'a ast::Mod,
        _s: source_map::Span,
        _attrs: &[ast::Attribute],
        _n: ast::NodeId,
    ) {
        visit::walk_mod(self, m);
        if !self.config.include_orphans {
            return;
        }
        let path = &self.path;
        if let Ok(candidates) = Builder::find_orphan_candidates(path, &self.config.ignored_files) {
            let tree = self.tree.subtree_at_path(path).unwrap();
            let names: Vec<_> = tree.subtree_names();
            for candidate in candidates {
                if !names.contains(&candidate) {
                    tree.insert(Tree::new_orphan(candidate.clone()));
                }
            }
        }
    }

    fn visit_mac(&mut self, mac: &ast::Mac) {
        visit::walk_mac(self, mac);
    }
}

fn add_use_tree(tree: &mut Tree, visibility: Visibility, prefix: &str, use_tree: &ast::UseTree) {
    let prefix = if prefix.is_empty() {
        String::new()
    } else {
        prefix.to_string()
    };

    match use_tree.kind {
        ast::UseTreeKind::Simple(_, ..) => {
            let path = pprust::path_to_string(&use_tree.prefix);
            if path != "self" {
                tree.insert_use((visibility, prefix + &path));
            } else {
                let mut prefix = prefix;
                let new_len = prefix.len() - 2;
                prefix.truncate(new_len);
                tree.insert_use((visibility, prefix));
            }
        }
        ast::UseTreeKind::Glob => {
            let use_path = if use_tree.prefix.segments.is_empty() {
                prefix + "*"
            } else {
                prefix + &pprust::path_to_string(&use_tree.prefix) + "::*"
            };
            tree.insert_use((visibility, use_path));
        }
        ast::UseTreeKind::Nested(ref items) => {
            let prefix_ = if use_tree.prefix.segments.is_empty() {
                prefix
            } else {
                prefix + &pprust::path_to_string(&use_tree.prefix) + "::"
            };
            for (sub_tree, _) in items {
                add_use_tree(tree, visibility, &prefix_, sub_tree);
            }
        }
    }
}
<|endoftext|>


<commit_before>use regex::Regex;
use std::sync::mpsc::channel;

use adapter::ChatAdapter;
use handler::MessageHandler;

/// The Chatbot is the central data structure of the chatbot platform. It contains a `run` method
/// which listens for messages from adapters and routes them to handlers. Any program which uses
/// chatbot will need to minimally create a Chatbot, add an adapter, add a handler, and call Chatbot
/// [`run`](chatbot/struct.Chatbot.html#method.run).
pub struct Chatbot {
    name: String,
    adapters: Vec<Box<ChatAdapter>>,
    handlers: Vec<Box<MessageHandler>>,
    addresser: Regex
}

impl Chatbot {
    /// Create a new chatbot instance.
    ///
    /// The name provided here will be used for message filtering and in handlers for whatever they
    /// want. You'll want to make your binding mutable so you can call `add_adapter` and
    /// `add_handler`.
    pub fn new(name: &str) -> Chatbot {
        let addresser_str = format!(r"^\s*@?{}[:,\s]\s*", name);
        let addresser = Regex::new(addresser_str.as_ref());

        Chatbot {
            name: name.to_owned(),
            adapters: Vec::new(),
            handlers: Vec::new(),
            addresser: addresser.unwrap()
        }
    }

    /// Return the name provided in initialization
    pub fn get_name(&self) -> &str {
        self.name.as_ref()
    }

    /// Return the regular expression of what the bot will be addressed by, if present
    pub fn get_addresser(&self) -> Option<&Regex> {
        self.addresser.as_ref()
    }

    /// Turns on the requirement of addressing the bot before a handler is triggered
    pub fn address_by_name(&mut self) {
        let addresser_str = format!(r"^\s*@?{}[:,\s]\s*", self.get_name());
        let addresser = Regex::new(addresser_str.as_ref());

        self.addresser = addresser.ok();
    }

    /// Add a ChatAdapter to the bot
    ///
    /// Add as many adapters as you like. The IncomingMessages sent by adapters are made available
    /// to all handlers regardless of how many adapters exist. The IncomingMessage.reply method
    /// makes sure the response is sent back to the adapter from whence the message came.
    pub fn add_adapter<T>(&mut self, adapter: T)
        where T: ChatAdapter + 'static
    {
        println!("Adding adapter {}", adapter.get_name());
        self.adapters.push(Box::new(adapter))
    }

    /// Add a MessageHandler to the bot
    ///
    /// The more handlers you have the more useful your bot becomes (for potentially loose
    /// definitions of useful :P). Check out the handler! macro for making simple handlers and also
    /// see the `MessageHandler` implementors section for a list of built in handlers.
    pub fn add_handler<T>(&mut self, handler: T)
        where T: MessageHandler + 'static
    {
        println!("Adding handler {}", handler.name());
        self.handlers.push(Box::new(handler))
    }

    /// Start processing messages
    ///
    /// Call process_events on all of the adapters and `recv` on the `IncomingMessage` channel.
    /// Distribute IncomingMessages to list of handlers.
    pub fn run(&self) {

        assert!(self.adapters.len() > 0);
        assert!(self.handlers.len() > 0);

        println!("Chatbot: {} adapters", self.adapters.len());
        println!("Chatbot: {} handlers", self.handlers.len());

        let (incoming_tx, incoming_rx) = channel();

        for adapter in &self.adapters {
            adapter.process_events(self, incoming_tx.clone());
        }

        loop {
            // Get message from adapter
            let msg = match incoming_rx.recv() {
                Ok(msg) => msg,
                Err(_) => break
            };

            // Distribute to handlers
            for handler in &self.handlers {
                let msg_str = msg.get_contents();

                if handler.can_handle(msg_str) {
                    // When addresser is present, ignore handlers that don't directly call the
                    // bot's name
                    if let Some(ref addresser) = self.addresser {
                        if !addresser.is_match(msg_str) {
                            continue;
                        }
                    }

                    match handler.handle(&msg) {
                        Err(e) => {
                            println!("Error in handler `{}`", handler.name());
                            println!("{:?}", e);
                            println!("The incoming message was {}", msg_str);

                            // TODO remove handler?
                        },
                        _ => ()
                    }
                }
            }
        }

        println!("chatbot shutting down");
    }
}

#[cfg(test)]
mod tests {
    use chatbot::Chatbot;
    use adapter::CliAdapter;

    #[test]
    fn test_create_chatbot() {
        let name = "testbot";
        let bot = Chatbot::new("testbot");
        assert_eq!(bot.get_name(), name);
    }

    #[test]
    fn test_chatbot_add_adapter() {
        let mut bot = Chatbot::new("testbot");
        let cli = CliAdapter::new();
        bot.add_adapter(cli);
    }

    #[test]
    fn test_chatbot_add_handler() {
        let mut bot = Chatbot::new("testbot");
        let echo = handler!("EchoHandler", r"echo .+", |_, msg| {
            Some(msg.to_owned())
        });
        bot.add_handler(echo);
    }

    #[test]
    fn test_chatbot_address_by_name() {
        let mut bot = Chatbot::new("testbot");
        bot.address_by_name();
    }

    #[test]
    fn test_chatbot_address_matches() {
        let mut bot = Chatbot::new("testbot");
        bot.address_by_name();
        let addresser = bot.get_addresser().unwrap();

        assert!(!addresser.is_match("testbotping"),
                "Shouldn't match bot name without a break (space, colon, comma)");
        assert!(!addresser.is_match("@testbotping"),
                "Shouldn't match bot name with '@' sign minus a break (space, colon, comma)");

        // Space separation
        assert!(addresser.is_match("testbot ping"), "Should match bot name with space");
        assert!(addresser.is_match("@testbot ping"),
                "Should match bot name with '@' sign plus '@' space");

        // Colon separation
        assert!(addresser.is_match("testbot:ping"), "Should match bot name with colon");
        assert!(addresser.is_match("testbot: ping"), "Should match bot name with colon and space");
        assert!(addresser.is_match("@testbot:ping"),
                "Should match bot name with '@' sign plus colon");
        assert!(addresser.is_match("@testbot: ping"),
                "Should match bot name with '@' sign plus colon and space");

        // Comma separation
        assert!(addresser.is_match("testbot,ping"), "Should match bot name with comma");
        assert!(addresser.is_match("testbot, ping"), "Should match bot name with comma and space");
        assert!(addresser.is_match("@testbot,ping"),
                "Should match bot name with '@' sign plus comma");
        assert!(addresser.is_match("@testbot, ping"),
                "Should match bot name with '@' sign plus comma and space");
    }
}
<commit_msg>Remove address_by_name method<commit_after>use regex::Regex;
use std::sync::mpsc::channel;

use adapter::ChatAdapter;
use handler::MessageHandler;

/// The Chatbot is the central data structure of the chatbot platform. It contains a `run` method
/// which listens for messages from adapters and routes them to handlers. Any program which uses
/// chatbot will need to minimally create a Chatbot, add an adapter, add a handler, and call Chatbot
/// [`run`](chatbot/struct.Chatbot.html#method.run).
pub struct Chatbot {
    name: String,
    adapters: Vec<Box<ChatAdapter>>,
    handlers: Vec<Box<MessageHandler>>,
    addresser: Regex
}

impl Chatbot {
    /// Create a new chatbot instance.
    ///
    /// The name provided here will be used for message filtering and in handlers for whatever they
    /// want. You'll want to make your binding mutable so you can call `add_adapter` and
    /// `add_handler`.
    pub fn new(name: &str) -> Chatbot {
        let addresser_str = format!(r"^\s*@?{}[:,\s]\s*", name);
        let addresser = Regex::new(addresser_str.as_ref());

        Chatbot {
            name: name.to_owned(),
            adapters: Vec::new(),
            handlers: Vec::new(),
            addresser: addresser.unwrap()
        }
    }

    /// Return the name provided in initialization
    pub fn get_name(&self) -> &str {
        self.name.as_ref()
    }

    /// Return the regular expression of what the bot will be addressed by, if present
    pub fn get_addresser(&self) -> Option<&Regex> {
        self.addresser.as_ref()
    }

    /// Add a ChatAdapter to the bot
    ///
    /// Add as many adapters as you like. The IncomingMessages sent by adapters are made available
    /// to all handlers regardless of how many adapters exist. The IncomingMessage.reply method
    /// makes sure the response is sent back to the adapter from whence the message came.
    pub fn add_adapter<T>(&mut self, adapter: T)
        where T: ChatAdapter + 'static
    {
        println!("Adding adapter {}", adapter.get_name());
        self.adapters.push(Box::new(adapter))
    }

    /// Add a MessageHandler to the bot
    ///
    /// The more handlers you have the more useful your bot becomes (for potentially loose
    /// definitions of useful :P). Check out the handler! macro for making simple handlers and also
    /// see the `MessageHandler` implementors section for a list of built in handlers.
    pub fn add_handler<T>(&mut self, handler: T)
        where T: MessageHandler + 'static
    {
        println!("Adding handler {}", handler.name());
        self.handlers.push(Box::new(handler))
    }

    /// Start processing messages
    ///
    /// Call process_events on all of the adapters and `recv` on the `IncomingMessage` channel.
    /// Distribute IncomingMessages to list of handlers.
    pub fn run(&self) {

        assert!(self.adapters.len() > 0);
        assert!(self.handlers.len() > 0);

        println!("Chatbot: {} adapters", self.adapters.len());
        println!("Chatbot: {} handlers", self.handlers.len());

        let (incoming_tx, incoming_rx) = channel();

        for adapter in &self.adapters {
            adapter.process_events(self, incoming_tx.clone());
        }

        loop {
            // Get message from adapter
            let msg = match incoming_rx.recv() {
                Ok(msg) => msg,
                Err(_) => break
            };

            // Distribute to handlers
            for handler in &self.handlers {
                let msg_str = msg.get_contents();

                if handler.can_handle(msg_str) {
                    // When addresser is present, ignore handlers that don't directly call the
                    // bot's name
                    if let Some(ref addresser) = self.addresser {
                        if !addresser.is_match(msg_str) {
                            continue;
                        }
                    }

                    match handler.handle(&msg) {
                        Err(e) => {
                            println!("Error in handler `{}`", handler.name());
                            println!("{:?}", e);
                            println!("The incoming message was {}", msg_str);

                            // TODO remove handler?
                        },
                        _ => ()
                    }
                }
            }
        }

        println!("chatbot shutting down");
    }
}

#[cfg(test)]
mod tests {
    use chatbot::Chatbot;
    use adapter::CliAdapter;

    #[test]
    fn test_create_chatbot() {
        let name = "testbot";
        let bot = Chatbot::new("testbot");
        assert_eq!(bot.get_name(), name);
    }

    #[test]
    fn test_chatbot_add_adapter() {
        let mut bot = Chatbot::new("testbot");
        let cli = CliAdapter::new();
        bot.add_adapter(cli);
    }

    #[test]
    fn test_chatbot_add_handler() {
        let mut bot = Chatbot::new("testbot");
        let echo = handler!("EchoHandler", r"echo .+", |_, msg| {
            Some(msg.to_owned())
        });
        bot.add_handler(echo);
    }

    #[test]
    fn test_chatbot_address_by_name() {
        let mut bot = Chatbot::new("testbot");
        bot.address_by_name();
    }

    #[test]
    fn test_chatbot_address_matches() {
        let mut bot = Chatbot::new("testbot");
        bot.address_by_name();
        let addresser = bot.get_addresser().unwrap();

        assert!(!addresser.is_match("testbotping"),
                "Shouldn't match bot name without a break (space, colon, comma)");
        assert!(!addresser.is_match("@testbotping"),
                "Shouldn't match bot name with '@' sign minus a break (space, colon, comma)");

        // Space separation
        assert!(addresser.is_match("testbot ping"), "Should match bot name with space");
        assert!(addresser.is_match("@testbot ping"),
                "Should match bot name with '@' sign plus '@' space");

        // Colon separation
        assert!(addresser.is_match("testbot:ping"), "Should match bot name with colon");
        assert!(addresser.is_match("testbot: ping"), "Should match bot name with colon and space");
        assert!(addresser.is_match("@testbot:ping"),
                "Should match bot name with '@' sign plus colon");
        assert!(addresser.is_match("@testbot: ping"),
                "Should match bot name with '@' sign plus colon and space");

        // Comma separation
        assert!(addresser.is_match("testbot,ping"), "Should match bot name with comma");
        assert!(addresser.is_match("testbot, ping"), "Should match bot name with comma and space");
        assert!(addresser.is_match("@testbot,ping"),
                "Should match bot name with '@' sign plus comma");
        assert!(addresser.is_match("@testbot, ping"),
                "Should match bot name with '@' sign plus comma and space");
    }
}
<|endoftext|>


<commit_before>use std::default::Default;
use std::collections::HashSet;
use jmap::method::*;
use jmap::method::ResponseMethod::*;
use jmap::util::Presence::*;

use util::RequestContext;

pub trait ContactHandler {
    fn get_contacts(&self, args: GetRequestArgs, client_id: String) -> ResponseMethod;
    fn get_contact_updates(&self, args: GetUpdatesRequestArgs, client_id: String) -> ResponseMethod;
    fn set_contacts(&self, args: SetRequestArgs, client_id: String) -> ResponseMethod;
}

impl ContactHandler for RequestContext {
    fn get_contacts(&self, args: GetRequestArgs, client_id: String) -> ResponseMethod {
        let records = self.db.get_records(self.userid, args.ids.as_option()).unwrap(); // XXX assuming success

        let not_found = match args.ids {
            Absent => None,
            Present(ids) => {
                let mut found = HashSet::new();
                for record in records.iter() {
                    found.insert(&record.id);
                }
                let not_found = ids.into_iter().filter(|id| !found.contains(id)).collect::<Vec<_>>();
                match not_found.len() {
                    0 => None,
                    _ => Some(not_found),
                }
            }
        };

        let list = match args.properties {
            Absent     => Some(records.iter().map(|ref r| r.to_partial()).collect()),
            Present(p) => Some(records.iter().map(|ref r| r.to_filtered_partial(&p)).collect()),
        };

        let response = GetResponseArgs {
            state: "abc123".to_string(),
            list: list,
            not_found: not_found,
        };

        Contacts(response, client_id)
    }

    fn get_contact_updates(&self, args: GetUpdatesRequestArgs, client_id: String) -> ResponseMethod {
        println!("get_contact_updates: {:?} {}", args, client_id);
        ContactUpdates(GetUpdatesResponseArgs::default(), client_id)
    }

    fn set_contacts(&self, args: SetRequestArgs, client_id: String) -> ResponseMethod {
        println!("set_contacts: {:?} {}", args, client_id);
        ContactsSet(SetResponseArgs::default(), client_id)
    }
}
<commit_msg>Return actual record type state in getContacts<commit_after>use std::default::Default;
use std::collections::HashSet;
use jmap::method::*;
use jmap::method::ResponseMethod::*;
use jmap::util::Presence::*;

use util::RequestContext;

pub trait ContactHandler {
    fn get_contacts(&self, args: GetRequestArgs, client_id: String) -> ResponseMethod;
    fn get_contact_updates(&self, args: GetUpdatesRequestArgs, client_id: String) -> ResponseMethod;
    fn set_contacts(&self, args: SetRequestArgs, client_id: String) -> ResponseMethod;
}

impl ContactHandler for RequestContext {
    fn get_contacts(&self, args: GetRequestArgs, client_id: String) -> ResponseMethod {
        // XXX assuming success through here
        let txn = self.db.transaction().unwrap();
        let records = self.db.get_records(self.userid, args.ids.as_option()).unwrap();
        let state = self.db.get_state(self.userid).unwrap();
        txn.commit().unwrap();

        let not_found = match args.ids {
            Absent => None,
            Present(ids) => {
                let mut found = HashSet::new();
                for record in records.iter() {
                    found.insert(&record.id);
                }
                let not_found = ids.into_iter().filter(|id| !found.contains(id)).collect::<Vec<_>>();
                match not_found.len() {
                    0 => None,
                    _ => Some(not_found),
                }
            }
        };

        let list = match args.properties {
            Absent     => Some(records.iter().map(|ref r| r.to_partial()).collect()),
            Present(p) => Some(records.iter().map(|ref r| r.to_filtered_partial(&p)).collect()),
        };

        let response = GetResponseArgs {
            state: state,
            list: list,
            not_found: not_found,
        };

        Contacts(response, client_id)
    }

    fn get_contact_updates(&self, args: GetUpdatesRequestArgs, client_id: String) -> ResponseMethod {
        println!("get_contact_updates: {:?} {}", args, client_id);
        ContactUpdates(GetUpdatesResponseArgs::default(), client_id)
    }

    fn set_contacts(&self, args: SetRequestArgs, client_id: String) -> ResponseMethod {
        println!("set_contacts: {:?} {}", args, client_id);
        ContactsSet(SetResponseArgs::default(), client_id)
    }
}
<|endoftext|>


<commit_before>use low_level as ll;
use error::Error;
use device::Device;

use std::ptr;
use std::mem::transmute;

pub struct Context {
    pub id: ll::Context,
}

impl Context {
    pub fn new(devices: &[Device]) -> Result<Context, Error> {
        let device_ids: Vec<ll::DeviceID> = devices.iter().map(|d| d.id).collect();
        let num_devices = device_ids.len() as u32;
        let callback = ptr::null(); // TODO ?
        let user_data = ptr::null(); // TODO ?
        let id = unsafe {
            let mut err: i32 = 0;
            let props: Vec<usize> = vec!(
                             0x1084,
                             transmute(try!(devices[0].platform()).id));
            let id = ll::clCreateContext(transmute(&props[0]),
                                         num_devices,
                                         &device_ids[0],
                                         callback,
                                         user_data,
                                         &mut err);
            try!(Error::check(err));
            id
        };
        Ok(Context{id:id})
    }
}

impl Drop for Context {
    fn drop(self: &mut Self) -> () {
        unsafe {
            Error::check(ll::clReleaseContext(self.id))
                .ok().expect("Error releasing context");
        }
    }
}

impl Clone for Context {
    fn clone(self: &Self) -> Self {
        unsafe {
            Error::check(ll::clRetainContext(self.id))
                .ok().expect("Error retaining context");
        }
        Context{ id: self.id }
    }
}

unsafe impl Send for Context {
}

<commit_msg>removes platform properties part of context init<commit_after>use low_level as ll;
use error::Error;
use device::Device;

use std::ptr;

pub struct Context {
    pub id: ll::Context,
}

impl Context {
    pub fn new(devices: &[Device]) -> Result<Context, Error> {
        let device_ids: Vec<ll::DeviceID> = devices.iter().map(|d| d.id).collect();
        let num_devices = device_ids.len() as u32;
        let callback = ptr::null(); // TODO ?
        let user_data = ptr::null(); // TODO ?
        let id = unsafe {
            let mut err: i32 = 0;
            let id = ll::clCreateContext(ptr::null_mut(),
                                         num_devices,
                                         &device_ids[0],
                                         callback,
                                         user_data,
                                         &mut err);
            try!(Error::check(err));
            id
        };
        Ok(Context{id:id})
    }
}

impl Drop for Context {
    fn drop(self: &mut Self) -> () {
        unsafe {
            Error::check(ll::clReleaseContext(self.id))
                .ok().expect("Error releasing context");
        }
    }
}

impl Clone for Context {
    fn clone(self: &Self) -> Self {
        unsafe {
            Error::check(ll::clRetainContext(self.id))
                .ok().expect("Error retaining context");
        }
        Context{ id: self.id }
    }
}

unsafe impl Send for Context {
}

<|endoftext|>


<commit_before>// The following definitions are correct for arm and i686,
// but may be wrong for mips

pub type c_long = i32;
pub type c_ulong = u32;
pub type mode_t = u16;
pub type off64_t = ::c_longlong;
pub type sigset_t = ::c_ulong;
pub type socklen_t = i32;
pub type time64_t = i64;

s! {
    pub struct sigaction {
        pub sa_sigaction: ::sighandler_t,
        pub sa_mask: ::sigset_t,
        pub sa_flags: ::c_ulong,
        pub sa_restorer: ::Option<extern fn()>,
    }

    pub struct rlimit64 {
        pub rlim_cur: u64,
        pub rlim_max: u64,
    }

    pub struct stat {
        pub st_dev: ::c_ulonglong,
        __pad0: [::c_uchar; 4],
        __st_ino: ::ino_t,
        pub st_mode: ::c_uint,
        pub st_nlink: ::c_uint,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulonglong,
        __pad3: [::c_uchar; 4],
        pub st_size: ::c_longlong,
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::c_ulonglong,
        pub st_atime: ::c_ulong,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::c_ulong,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::c_ulong,
        pub st_ctime_nsec: ::c_ulong,
        pub st_ino: ::c_ulonglong,
    }

    pub struct stat64 {
        pub st_dev: ::c_ulonglong,
        __pad0: [::c_uchar; 4],
        __st_ino: ::ino_t,
        pub st_mode: ::c_uint,
        pub st_nlink: ::c_uint,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulonglong,
        __pad3: [::c_uchar; 4],
        pub st_size: ::c_longlong,
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::c_ulonglong,
        pub st_atime: ::c_ulong,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::c_ulong,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::c_ulong,
        pub st_ctime_nsec: ::c_ulong,
        pub st_ino: ::c_ulonglong,
    }

    pub struct statfs64 {
        pub f_type: u32,
        pub f_bsize: u32,
        pub f_blocks: u64,
        pub f_bfree: u64,
        pub f_bavail: u64,
        pub f_files: u64,
        pub f_ffree: u64,
        f_fsid: [u32; 2],
        pub f_namelen: u32,
        pub f_frsize: u32,
        pub f_flags: u32,
        pub f_spare: [u32; 4],
    }

    pub struct statvfs64 {
        pub f_bsize: ::c_ulong,
        pub f_frsize: ::c_ulong,
        pub f_blocks: ::c_ulong,
        pub f_bfree: ::c_ulong,
        pub f_bavail: ::c_ulong,
        pub f_files: ::c_ulong,
        pub f_ffree: ::c_ulong,
        pub f_favail: ::c_ulong,
        pub f_fsid: ::c_ulong,
        pub f_flag: ::c_ulong,
        pub f_namemax: ::c_ulong,
    }

    pub struct pthread_attr_t {
        pub flags: ::uint32_t,
        pub stack_base: *mut ::c_void,
        pub stack_size: ::size_t,
        pub guard_size: ::size_t,
        pub sched_policy: ::int32_t,
        pub sched_priority: ::int32_t,
    }

    pub struct pthread_mutex_t { value: ::c_int }

    pub struct pthread_cond_t { value: ::c_int }

    pub struct pthread_rwlock_t {
        lock: pthread_mutex_t,
        cond: pthread_cond_t,
        numLocks: ::c_int,
        writerThreadId: ::c_int,
        pendingReaders: ::c_int,
        pendingWriters: ::c_int,
        attr: i32,
        __reserved: [::c_char; 12],
    }

    pub struct passwd {
        pub pw_name: *mut ::c_char,
        pub pw_passwd: *mut ::c_char,
        pub pw_uid: ::uid_t,
        pub pw_gid: ::gid_t,
        pub pw_dir: *mut ::c_char,
        pub pw_shell: *mut ::c_char,
    }

    pub struct statfs {
        pub f_type: ::uint32_t,
        pub f_bsize: ::uint32_t,
        pub f_blocks: ::uint64_t,
        pub f_bfree: ::uint64_t,
        pub f_bavail: ::uint64_t,
        pub f_files: ::uint64_t,
        pub f_ffree: ::uint64_t,
        pub f_fsid: ::__fsid_t,
        pub f_namelen: ::uint32_t,
        pub f_frsize: ::uint32_t,
        pub f_flags: ::uint32_t,
        pub f_spare: [::uint32_t; 4],
    }

    pub struct sysinfo {
        pub uptime: ::c_long,
        pub loads: [::c_ulong; 3],
        pub totalram: ::c_ulong,
        pub freeram: ::c_ulong,
        pub sharedram: ::c_ulong,
        pub bufferram: ::c_ulong,
        pub totalswap: ::c_ulong,
        pub freeswap: ::c_ulong,
        pub procs: ::c_ushort,
        pub pad: ::c_ushort,
        pub totalhigh: ::c_ulong,
        pub freehigh: ::c_ulong,
        pub mem_unit: ::c_uint,
        pub _f: [::c_char; 8],
    }
}

pub const RTLD_GLOBAL: ::c_int = 2;
pub const RTLD_NOW: ::c_int = 0;
pub const RTLD_DEFAULT: *mut ::c_void = -1isize as *mut ::c_void;

pub const PTRACE_GETFPREGS: ::c_int = 14;
pub const PTRACE_SETFPREGS: ::c_int = 15;
pub const PTRACE_GETREGS: ::c_int = 12;
pub const PTRACE_SETREGS: ::c_int = 13;

pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
    value: 0,
};
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
    value: 0,
};
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
    lock: PTHREAD_MUTEX_INITIALIZER,
    cond: PTHREAD_COND_INITIALIZER,
    numLocks: 0,
    writerThreadId: 0,
    pendingReaders: 0,
    pendingWriters: 0,
    attr: 0,
    __reserved: [0; 12],
};
pub const PTHREAD_STACK_MIN: ::size_t = 4096 * 2;
pub const CPU_SETSIZE: ::size_t = 32;
pub const __CPU_BITS: ::size_t = 32;

pub const UT_LINESIZE: usize = 8;
pub const UT_NAMESIZE: usize = 8;
pub const UT_HOSTSIZE: usize = 16;

pub const SIGSTKSZ: ::size_t = 8192;
pub const MINSIGSTKSZ: ::size_t = 2048;

extern {
    pub fn timegm64(tm: *const ::tm) -> ::time64_t;
}

cfg_if! {
    if #[cfg(target_arch = "x86")] {
        mod x86;
        pub use self::x86::*;
    } else if #[cfg(target_arch = "arm")] {
        mod arm;
        pub use self::arm::*;
    } else {
        // Unknown target_arch
    }
}
<commit_msg>[breaking change] sigaction.sa_flags changed from c_ulong to c_int on 32-bit Android<commit_after>// The following definitions are correct for arm and i686,
// but may be wrong for mips

pub type c_long = i32;
pub type c_ulong = u32;
pub type mode_t = u16;
pub type off64_t = ::c_longlong;
pub type sigset_t = ::c_ulong;
pub type socklen_t = i32;
pub type time64_t = i64;

s! {
    pub struct sigaction {
        pub sa_sigaction: ::sighandler_t,
        pub sa_mask: ::sigset_t,
        pub sa_flags: ::c_int,
        pub sa_restorer: ::Option<extern fn()>,
    }

    pub struct rlimit64 {
        pub rlim_cur: u64,
        pub rlim_max: u64,
    }

    pub struct stat {
        pub st_dev: ::c_ulonglong,
        __pad0: [::c_uchar; 4],
        __st_ino: ::ino_t,
        pub st_mode: ::c_uint,
        pub st_nlink: ::c_uint,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulonglong,
        __pad3: [::c_uchar; 4],
        pub st_size: ::c_longlong,
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::c_ulonglong,
        pub st_atime: ::c_ulong,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::c_ulong,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::c_ulong,
        pub st_ctime_nsec: ::c_ulong,
        pub st_ino: ::c_ulonglong,
    }

    pub struct stat64 {
        pub st_dev: ::c_ulonglong,
        __pad0: [::c_uchar; 4],
        __st_ino: ::ino_t,
        pub st_mode: ::c_uint,
        pub st_nlink: ::c_uint,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulonglong,
        __pad3: [::c_uchar; 4],
        pub st_size: ::c_longlong,
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::c_ulonglong,
        pub st_atime: ::c_ulong,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::c_ulong,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::c_ulong,
        pub st_ctime_nsec: ::c_ulong,
        pub st_ino: ::c_ulonglong,
    }

    pub struct statfs64 {
        pub f_type: u32,
        pub f_bsize: u32,
        pub f_blocks: u64,
        pub f_bfree: u64,
        pub f_bavail: u64,
        pub f_files: u64,
        pub f_ffree: u64,
        f_fsid: [u32; 2],
        pub f_namelen: u32,
        pub f_frsize: u32,
        pub f_flags: u32,
        pub f_spare: [u32; 4],
    }

    pub struct statvfs64 {
        pub f_bsize: ::c_ulong,
        pub f_frsize: ::c_ulong,
        pub f_blocks: ::c_ulong,
        pub f_bfree: ::c_ulong,
        pub f_bavail: ::c_ulong,
        pub f_files: ::c_ulong,
        pub f_ffree: ::c_ulong,
        pub f_favail: ::c_ulong,
        pub f_fsid: ::c_ulong,
        pub f_flag: ::c_ulong,
        pub f_namemax: ::c_ulong,
    }

    pub struct pthread_attr_t {
        pub flags: ::uint32_t,
        pub stack_base: *mut ::c_void,
        pub stack_size: ::size_t,
        pub guard_size: ::size_t,
        pub sched_policy: ::int32_t,
        pub sched_priority: ::int32_t,
    }

    pub struct pthread_mutex_t { value: ::c_int }

    pub struct pthread_cond_t { value: ::c_int }

    pub struct pthread_rwlock_t {
        lock: pthread_mutex_t,
        cond: pthread_cond_t,
        numLocks: ::c_int,
        writerThreadId: ::c_int,
        pendingReaders: ::c_int,
        pendingWriters: ::c_int,
        attr: i32,
        __reserved: [::c_char; 12],
    }

    pub struct passwd {
        pub pw_name: *mut ::c_char,
        pub pw_passwd: *mut ::c_char,
        pub pw_uid: ::uid_t,
        pub pw_gid: ::gid_t,
        pub pw_dir: *mut ::c_char,
        pub pw_shell: *mut ::c_char,
    }

    pub struct statfs {
        pub f_type: ::uint32_t,
        pub f_bsize: ::uint32_t,
        pub f_blocks: ::uint64_t,
        pub f_bfree: ::uint64_t,
        pub f_bavail: ::uint64_t,
        pub f_files: ::uint64_t,
        pub f_ffree: ::uint64_t,
        pub f_fsid: ::__fsid_t,
        pub f_namelen: ::uint32_t,
        pub f_frsize: ::uint32_t,
        pub f_flags: ::uint32_t,
        pub f_spare: [::uint32_t; 4],
    }

    pub struct sysinfo {
        pub uptime: ::c_long,
        pub loads: [::c_ulong; 3],
        pub totalram: ::c_ulong,
        pub freeram: ::c_ulong,
        pub sharedram: ::c_ulong,
        pub bufferram: ::c_ulong,
        pub totalswap: ::c_ulong,
        pub freeswap: ::c_ulong,
        pub procs: ::c_ushort,
        pub pad: ::c_ushort,
        pub totalhigh: ::c_ulong,
        pub freehigh: ::c_ulong,
        pub mem_unit: ::c_uint,
        pub _f: [::c_char; 8],
    }
}

pub const RTLD_GLOBAL: ::c_int = 2;
pub const RTLD_NOW: ::c_int = 0;
pub const RTLD_DEFAULT: *mut ::c_void = -1isize as *mut ::c_void;

pub const PTRACE_GETFPREGS: ::c_int = 14;
pub const PTRACE_SETFPREGS: ::c_int = 15;
pub const PTRACE_GETREGS: ::c_int = 12;
pub const PTRACE_SETREGS: ::c_int = 13;

pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
    value: 0,
};
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
    value: 0,
};
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
    lock: PTHREAD_MUTEX_INITIALIZER,
    cond: PTHREAD_COND_INITIALIZER,
    numLocks: 0,
    writerThreadId: 0,
    pendingReaders: 0,
    pendingWriters: 0,
    attr: 0,
    __reserved: [0; 12],
};
pub const PTHREAD_STACK_MIN: ::size_t = 4096 * 2;
pub const CPU_SETSIZE: ::size_t = 32;
pub const __CPU_BITS: ::size_t = 32;

pub const UT_LINESIZE: usize = 8;
pub const UT_NAMESIZE: usize = 8;
pub const UT_HOSTSIZE: usize = 16;

pub const SIGSTKSZ: ::size_t = 8192;
pub const MINSIGSTKSZ: ::size_t = 2048;

extern {
    pub fn timegm64(tm: *const ::tm) -> ::time64_t;
}

cfg_if! {
    if #[cfg(target_arch = "x86")] {
        mod x86;
        pub use self::x86::*;
    } else if #[cfg(target_arch = "arm")] {
        mod arm;
        pub use self::arm::*;
    } else {
        // Unknown target_arch
    }
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod get_repos_should {
    use super::*;

    #[test]
    fn return_repos_with_app_name_hello_world_library_and_language_rust_and_program_type_lib_and_user_intrepion(
    ) {
        let expected = vec![Repo {
            app_name: "hello-world-library".to_string(),
            language: ProgrammingLanguage::Rust,
        }];
    }
}

struct Repo {
    app_name: String,
}
<commit_msg>green<commit_after>#[cfg(test)]
mod get_repos_should {
    use super::*;

    #[test]
    fn return_repos_with_app_name_hello_world_library_and_language_rust_and_program_type_lib_and_user_intrepion(
    ) {
        let expected = vec![Repo {
            app_name: "hello-world-library".to_string(),
            language: ProgrammingLanguage::Rust,
        }];
    }
}

enum ProgrammingLanguage {
    Rust,
}

struct Repo {
    app_name: String,
    language: ProgrammingLanguage,
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

macro_rules! blanket_impl {
  ($trait_: ident for $($type_: ty),*) => {
    $(
      impl $trait_ for $type_ {}
    )*
  };
}

macro_rules! impl_graphql_type_for {
    ($tt: ty where name = $name: expr, description = $desc: expr) => {
        impl GraphQLType for $tt {
            fn name(&self) -> &str { $name }
            fn description(&self) -> Option<&str> { Some($desc) }
        }
    };

    ($($type_: ty),*) => {
      $(
        impl GraphQLType for $type_ {
            fn name(&self) -> &str { self.name.as_ref() }

            fn description(&self) -> Option<&str> {
                self.description.as_ref().map(|s| s.as_ref())
            }
        }
      )*
    };
}

pub trait GraphQLType {
  fn name(&self) -> &str;
  fn description(&self) -> Option<&str>;
}
impl_graphql_type_for! { GraphQLEnum }

pub trait GraphQLScalar: GraphQLType {}
blanket_impl! { GraphQLScalar for GraphQLInt, GraphQLFloat, GraphQLString, GraphQLBoolean }

pub struct GraphQLInt;
impl_graphql_type_for! {
    GraphQLInt where
    name = "Int",
    description = "The Int scalar type represents a signed 32‐bit numeric non‐fractional values."
}

pub struct GraphQLFloat;
impl_graphql_type_for! {
    GraphQLFloat where
    name = "Float",
    description = "The Float scalar type represents signed double-precision fractional values as specified by IEEE 754."
}

pub struct GraphQLString;
impl_graphql_type_for! {
    GraphQLString where
    name = "String",
    description = "The String scalar type represents textual data, represented as UTF-8 character sequences."
}

pub struct GraphQLBoolean;
impl_graphql_type_for! {
    GraphQLBoolean where
    name = "Boolean",
    description = "The Boolean scalar type represents true or false."
}

pub struct GraphQLEnum {
  name: String,
  description: Option<String>,
  values: HashMap<String, GraphQLEnumValue>,
}

impl GraphQLEnum {
  fn values(&self) -> &HashMap<String, GraphQLEnumValue> {
    &self.values
  }
}

pub struct GraphQLEnumValue {
  value: String,
  description: Option<String>,
  depreciation_reason: Option<String>,
}

impl GraphQLEnumValue {
  pub fn new(value: &str) -> GraphQLEnumValue {
    GraphQLEnumValue {
      value: value.to_owned(),
      description: None,
      depreciation_reason: None,
    }
  }

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

  pub fn description(&self) -> Option<&str> {
    self.description.as_ref().map(|s| s.as_ref())
  }

  pub fn with_description(mut self, description: &str) -> GraphQLEnumValue {
    self.description = Some(description.to_owned());
    self
  }

  pub fn mark_depreciated(mut self, depreciation_reason: &str) -> GraphQLEnumValue {
    let reason = depreciation_reason.trim().to_owned();
    if reason.len() == 0 {
      panic!("Deprecation reason for enum value {:?} cannot be empty",
             self.value);
    }
    self.depreciation_reason = Some(reason);
    self
  }
}

pub struct GraphQLEnumBuilder {
  name: String,
  description: Option<String>,
  values: HashMap<String, GraphQLEnumValue>,
}

impl GraphQLEnumBuilder {
  fn new(name: &str) -> GraphQLEnumBuilder {
    GraphQLEnumBuilder {
      name: name.to_owned(),
      description: None,
      values: HashMap::new(),
    }
  }

  fn with_description(mut self, description: &str) -> GraphQLEnumBuilder {
    self.description = Some(description.to_owned());
    self
  }

  fn value_fn<F>(mut self, name: &str, f: F) -> GraphQLEnumBuilder
    where F: FnOnce(GraphQLEnumValue) -> GraphQLEnumValue
  {
    let v = f(GraphQLEnumValue::new(name));
    self.values.insert(v.value.clone(), v);
    self
  }

  fn value(mut self, name: &str) -> GraphQLEnumBuilder {
    self.values.insert(name.to_owned(), GraphQLEnumValue::new(name));
    self
  }

  fn build(self) -> GraphQLEnum {
    if self.values.len() == 0 {
      panic!("Enum {:?} must has at least one value defined.", self.name);
    }

    GraphQLEnum {
      name: self.name,
      description: self.description,
      values: self.values,
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn test_scalar_type() {
    assert_eq!("Int", GraphQLInt.name());
    assert_eq!("Float", GraphQLFloat.name());
    assert_eq!("String", GraphQLString.name());
    assert_eq!("Boolean", GraphQLBoolean.name());
  }

  #[test]
  fn test_enum_type() {
    let rgb = GraphQLEnumBuilder::new("RGB")
                .value("RED")
                .value("GREEN")
                .value("BLUE")
                .build();
    assert_eq!(3, rgb.values().len());

    let days = GraphQLEnumBuilder::new("DAYS")
                 .with_description("Days of the week")
                 .value_fn("SAT", |v| v.with_description("Satarday"))
                 .value_fn("SUN", |v| v.with_description("Sunday"))
                 .value_fn("MON", |v| v.with_description("Monday"))
                 .value_fn("TUE", |v| v.with_description("Tuesday"))
                 .value_fn("WED", |v| v.with_description("Wedsday"))
                 .value_fn("THU", |v| v.with_description("Thusday"))
                 .value_fn("FRI", |v| v.with_description("Friday"))
                 .build();
    assert_eq!("Days of the week", days.description().unwrap_or(""));
    assert_eq!("Monday", days.values()["MON"].description().unwrap_or(""));;
  }
}
<commit_msg>add coerce_literal function to the scalar trait<commit_after>use std::collections::HashMap;
use std::str::FromStr;
use std::any::Any;

macro_rules! blanket_impl {
  ($trait_: ident for $($type_: ty),*) => {
    $(
      impl $trait_ for $type_ {}
    )*
  };
}

macro_rules! impl_graphql_type_for {
    ($tt: ty where name = $name: expr, description = $desc: expr) => {
        impl GraphQLType for $tt {
            fn name(&self) -> &str { $name }
            fn description(&self) -> Option<&str> { Some($desc) }
        }
    };

    ($($type_: ty),*) => {
      $(
        impl GraphQLType for $type_ {
            fn name(&self) -> &str { self.name.as_ref() }

            fn description(&self) -> Option<&str> {
                self.description.as_ref().map(|s| s.as_ref())
            }
        }
      )*
    };
}

pub trait GraphQLType {
  fn name(&self) -> &str;
  fn description(&self) -> Option<&str>;
}
impl_graphql_type_for! { GraphQLEnum }

pub trait GraphQLScalar: GraphQLType {
    type ValueType: Any;
  fn coerce_literal(&self, value: &str) -> Option<Self::ValueType>;
}

pub struct GraphQLInt;
impl_graphql_type_for! {
    GraphQLInt where
    name = "Int",
    description = "The Int scalar type represents a signed 32‐bit numeric non‐fractional values."
}

impl GraphQLScalar for GraphQLInt {
  type ValueType = i32;
  fn coerce_literal(&self, value: &str) -> Option<Self::ValueType> {
    i32::from_str(value).ok()
  }
}

pub struct GraphQLFloat;
impl_graphql_type_for! {
    GraphQLFloat where
    name = "Float",
    description = "The Float scalar type represents signed double-precision fractional values as specified by IEEE 754."
}

impl GraphQLScalar for GraphQLFloat {
  type ValueType = f64;
  fn coerce_literal(&self, value: &str) -> Option<Self::ValueType> {
    f64::from_str(value).ok()
  }
}

pub struct GraphQLString;
impl_graphql_type_for! {
    GraphQLString where
    name = "String",
    description = "The String scalar type represents textual data, represented as UTF-8 character sequences."
}

impl GraphQLScalar for GraphQLString {
  type ValueType = String;
  fn coerce_literal(&self, value: &str) -> Option<Self::ValueType> {
    String::from_str(value).ok()
  }
}

pub struct GraphQLBoolean;
impl_graphql_type_for! {
    GraphQLBoolean where
    name = "Boolean",
    description = "The Boolean scalar type represents true or false."
}

impl GraphQLScalar for GraphQLBoolean {
  type ValueType = bool;
  fn coerce_literal(&self, value: &str) -> Option<Self::ValueType> {
    bool::from_str(value).ok()
  }
}

pub struct GraphQLEnum {
  name: String,
  description: Option<String>,
  values: HashMap<String, GraphQLEnumValue>,
}

impl GraphQLEnum {
  fn values(&self) -> &HashMap<String, GraphQLEnumValue> {
    &self.values
  }
}

pub struct GraphQLEnumValue {
  value: String,
  description: Option<String>,
  depreciation_reason: Option<String>,
}

impl GraphQLEnumValue {
  pub fn new(value: &str) -> GraphQLEnumValue {
    GraphQLEnumValue {
      value: value.to_owned(),
      description: None,
      depreciation_reason: None,
    }
  }

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

  pub fn description(&self) -> Option<&str> {
    self.description.as_ref().map(|s| s.as_ref())
  }

  pub fn with_description(mut self, description: &str) -> GraphQLEnumValue {
    self.description = Some(description.to_owned());
    self
  }

  pub fn mark_depreciated(mut self, depreciation_reason: &str) -> GraphQLEnumValue {
    let reason = depreciation_reason.trim().to_owned();
    if reason.len() == 0 {
      panic!("Deprecation reason for enum value {:?} cannot be empty",
             self.value);
    }
    self.depreciation_reason = Some(reason);
    self
  }
}

pub struct GraphQLEnumBuilder {
  name: String,
  description: Option<String>,
  values: HashMap<String, GraphQLEnumValue>,
}

impl GraphQLEnumBuilder {
  fn new(name: &str) -> GraphQLEnumBuilder {
    GraphQLEnumBuilder {
      name: name.to_owned(),
      description: None,
      values: HashMap::new(),
    }
  }

  fn with_description(mut self, description: &str) -> GraphQLEnumBuilder {
    self.description = Some(description.to_owned());
    self
  }

  fn value_fn<F>(mut self, name: &str, f: F) -> GraphQLEnumBuilder
    where F: FnOnce(GraphQLEnumValue) -> GraphQLEnumValue
  {
    let v = f(GraphQLEnumValue::new(name));
    self.values.insert(v.value.clone(), v);
    self
  }

  fn value(mut self, name: &str) -> GraphQLEnumBuilder {
    self.values.insert(name.to_owned(), GraphQLEnumValue::new(name));
    self
  }

  fn build(self) -> GraphQLEnum {
    if self.values.len() == 0 {
      panic!("Enum {:?} must has at least one value defined.", self.name);
    }

    GraphQLEnum {
      name: self.name,
      description: self.description,
      values: self.values,
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn test_scalar_type() {
    let int_t = GraphQLInt;
    assert_eq!("Int", int_t.name());
    assert_eq!(Some(10), int_t.coerce_literal("10"));
    assert_eq!(None, int_t.coerce_literal("a"));

    let float_t = GraphQLFloat;
    assert_eq!("Float", float_t.name());
    assert_eq!(Some(2.0), float_t.coerce_literal("2.0"));
    assert_eq!(Some(2.0), float_t.coerce_literal("2"));
    assert_eq!(None, float_t.coerce_literal("2.0a"));

    let string_t = GraphQLString;
    assert_eq!("String", string_t.name());
    assert_eq!(Some(String::from("abc")), string_t.coerce_literal("abc"));
    assert_eq!(Some(String::from("2.0")), string_t.coerce_literal("2.0"));

    let boolean_t = GraphQLBoolean;
    assert_eq!("Boolean", boolean_t.name());
    assert_eq!(Some(true), boolean_t.coerce_literal("true"));
    assert_eq!(Some(false), boolean_t.coerce_literal("false"));
    assert_eq!(None, boolean_t.coerce_literal("1"));
    assert_eq!(None, boolean_t.coerce_literal("0"));
    assert_eq!(None, boolean_t.coerce_literal("True"));
    assert_eq!(None, boolean_t.coerce_literal("False"));
    assert_eq!(None, boolean_t.coerce_literal("TRUE"));
    assert_eq!(None, boolean_t.coerce_literal("FALSE"));
  }

  #[test]
  fn test_enum_type() {
    let rgb = GraphQLEnumBuilder::new("RGB")
                .value("RED")
                .value("GREEN")
                .value("BLUE")
                .build();
    assert_eq!(3, rgb.values().len());

    let days = GraphQLEnumBuilder::new("DAYS")
                 .with_description("Days of the week")
                 .value_fn("SAT", |v| v.with_description("Satarday"))
                 .value_fn("SUN", |v| v.with_description("Sunday"))
                 .value_fn("MON", |v| v.with_description("Monday"))
                 .value_fn("TUE", |v| v.with_description("Tuesday"))
                 .value_fn("WED", |v| v.with_description("Wedsday"))
                 .value_fn("THU", |v| v.with_description("Thusday"))
                 .value_fn("FRI", |v| v.with_description("Friday"))
                 .build();
    assert_eq!("Days of the week", days.description().unwrap_or(""));
    assert_eq!("Monday", days.values()["MON"].description().unwrap_or(""));;
  }
}
<|endoftext|>


<commit_before>use {Event, Loop};

/// After render arguments.
#[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct AfterRenderArgs;

/// After rendering and buffers are swapped.
pub trait AfterRenderEvent: Sized {
    /// Creates an after render event.
    fn from_after_render_args(args: &AfterRenderArgs, old_event: &Self) -> Option<Self>;
    /// Calls closure if this is an after render event.
    fn after_render<U, F>(&self, f: F) -> Option<U> where F: FnMut(&AfterRenderArgs) -> U;
    /// Returns after render arguments.
    fn after_render_args(&self) -> Option<AfterRenderArgs> {
        self.after_render(|args| args.clone())
    }
}

impl AfterRenderEvent for Event {
    fn from_after_render_args(args: &AfterRenderArgs, _old_event: &Self) -> Option<Self> {
        Some(Event::Loop(Loop::AfterRender(*args)))
    }

    fn after_render<U, F>(&self, mut f: F) -> Option<U>
        where F: FnMut(&AfterRenderArgs) -> U
    {
        match *self {
            Event::Loop(Loop::AfterRender(ref args)) => Some(f(args)),
            _ => None,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_input_after_render() {
        use AfterRenderArgs;

        let e: Event = AfterRenderArgs.into();
        let x: Option<Event> = AfterRenderEvent::from_after_render_args(&AfterRenderArgs, &e);
        let y: Option<Event> =
            x.clone()
                .unwrap()
                .after_render(|args| {
                    AfterRenderEvent::from_after_render_args(args, x.as_ref().unwrap())
                })
                .unwrap();
        assert_eq!(x, y);
    }
}
<commit_msg>Added more derive traits for `AfterRenderArgs`<commit_after>use {Event, Loop};

/// After render arguments.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Deserialize, Serialize, Hash)]
pub struct AfterRenderArgs;

/// After rendering and buffers are swapped.
pub trait AfterRenderEvent: Sized {
    /// Creates an after render event.
    fn from_after_render_args(args: &AfterRenderArgs, old_event: &Self) -> Option<Self>;
    /// Calls closure if this is an after render event.
    fn after_render<U, F>(&self, f: F) -> Option<U> where F: FnMut(&AfterRenderArgs) -> U;
    /// Returns after render arguments.
    fn after_render_args(&self) -> Option<AfterRenderArgs> {
        self.after_render(|args| args.clone())
    }
}

impl AfterRenderEvent for Event {
    fn from_after_render_args(args: &AfterRenderArgs, _old_event: &Self) -> Option<Self> {
        Some(Event::Loop(Loop::AfterRender(*args)))
    }

    fn after_render<U, F>(&self, mut f: F) -> Option<U>
        where F: FnMut(&AfterRenderArgs) -> U
    {
        match *self {
            Event::Loop(Loop::AfterRender(ref args)) => Some(f(args)),
            _ => None,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_input_after_render() {
        use AfterRenderArgs;

        let e: Event = AfterRenderArgs.into();
        let x: Option<Event> = AfterRenderEvent::from_after_render_args(&AfterRenderArgs, &e);
        let y: Option<Event> =
            x.clone()
                .unwrap()
                .after_render(|args| {
                    AfterRenderEvent::from_after_render_args(args, x.as_ref().unwrap())
                })
                .unwrap();
        assert_eq!(x, y);
    }
}
<|endoftext|>


<commit_before>use js::value::{Value, VNumber, VFunction, VObject, ResultValue, to_value, from_value};
use js::function::{NativeFunction, NativeFunc};
use collections::treemap::TreeMap;
use rand::random;
use std::f64;
use std::gc::Gc;
use std::cell::RefCell;

/// Get the absolute value of a number
pub fn abs(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.abs()
	} else {
		f64::NAN
	}))
}
/// Get the arccos of a number
pub fn acos(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.acos()
	} else {
		f64::NAN
	}))
}
/// Get the arcsine of a number
pub fn asin(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.asin()
	} else {
		f64::NAN
	}))
}
/// Get the arctangent of a number
pub fn atan(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.atan()
	} else {
		f64::NAN
	}))
}
/// Get the arctangent of a numbers
pub fn atan2(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.atan2(&args.get(1).borrow().to_num())
	} else {
		f64::NAN
	}))
}
/// Get the cubic root of a number
pub fn cbrt(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.cbrt()
	} else {
		f64::NAN
	}))
}
/// Get lowest integer above a number
pub fn ceil(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.ceil()
	} else {
		f64::NAN
	}))
}
/// Get the cosine of a number
pub fn cos(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.cos()
	} else {
		f64::NAN
	}))
}
/// Get the power to raise the natural logarithm to get the number
pub fn exp(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.exp()
	} else {
		f64::NAN
	}))
}
/// Get the highest integer below a number
pub fn floor(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.floor()
	} else {
		f64::NAN
	}))
}
/// Get the natural logarithm of a number
pub fn log(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.log(&f64::consts::E)
	} else {
		f64::NAN
	}))
}
/// Get the maximum of several numbers
pub fn max(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	let mut max = f64::NEG_INFINITY;
	for arg in args.iter() {
		let num = arg.borrow().to_num();
		max = max.max(num);
	}
	Ok(to_value(max))
}
/// Get the minimum of several numbers
pub fn min(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	let mut max = f64::INFINITY;
	for arg in args.iter() {
		let num = arg.borrow().to_num();
		max = max.min(num);
	}
	Ok(to_value(max))
}
/// Raise a number to a power
pub fn pow(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 2 {
		let num : f64 = from_value(*args.get(0)).unwrap();
		let power : f64 = from_value(*args.get(1)).unwrap();
		num.powf(&power)
	} else {
		f64::NAN
	}))
}
/// Generate a random floating-point number between 0 and 1
pub fn _random(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(random::<f64>()))
}
/// Round a number to the nearest integer
pub fn round(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.round()
	} else {
		f64::NAN
	}))
}
/// Get the sine of a number
pub fn sin(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.sin()
	} else {
		f64::NAN
	}))
}
/// Get the square root of a number
pub fn sqrt(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.sqrt()
	} else {
		f64::NAN
	}))
}
/// Get the tangent of a number
pub fn tan(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		let val : f64 = from_value(*args.get(0)).unwrap();
		val.tan()
	} else {
		f64::NAN
	}))
}
/// Create a new 'Math' object
pub fn _create() -> Value {
	let mut math = TreeMap::new();
	math.insert(~"E", to_value(f64::consts::E));
	math.insert(~"LN2", to_value(f64::consts::LN_2));
	math.insert(~"LN10", to_value(f64::consts::LN_10));
	math.insert(~"LOG2E", to_value(f64::consts::LOG2_E));
	math.insert(~"LOG10E", to_value(f64::consts::LOG10_E));
	math.insert(~"SQRT1_2", to_value(0.5f64.sqrt()));
	math.insert(~"SQRT2", to_value(f64::consts::SQRT2));
	math.insert(~"PI", to_value(f64::consts::PI));
	math.insert(~"abs", to_value(abs));
	math.insert(~"acos", to_value(acos));
	math.insert(~"asin", to_value(asin));
	math.insert(~"atan", to_value(atan));
	math.insert(~"atan2", to_value(atan2));
	math.insert(~"cbrt", to_value(cbrt));
	math.insert(~"ceil", to_value(ceil));
	math.insert(~"cos", to_value(cos));
	math.insert(~"exp", to_value(exp));
	math.insert(~"floor", to_value(floor));
	math.insert(~"log", to_value(log));
	math.insert(~"max", to_value(max));
	math.insert(~"min", to_value(min));
	math.insert(~"pow", to_value(pow));
	math.insert(~"random", to_value(_random));
	math.insert(~"round", to_value(round));
	math.insert(~"sin", to_value(sin));
	math.insert(~"sqrt", to_value(sqrt));
	math.insert(~"tan", to_value(tan));
	to_value(math)
}<commit_msg>Use shorter syntax in Math<commit_after>use js::value::{Value, VNumber, VFunction, VObject, ResultValue, to_value, from_value};
use js::function::{NativeFunction, NativeFunc};
use collections::treemap::TreeMap;
use rand::random;
use std::f64;
use std::gc::Gc;
use std::cell::RefCell;

/// Get the absolute value of a number
pub fn abs(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().abs()
	} else {
		f64::NAN
	}))
}
/// Get the arccos of a number
pub fn acos(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().acos()
	} else {
		f64::NAN
	}))
}
/// Get the arcsine of a number
pub fn asin(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().asin()
	} else {
		f64::NAN
	}))
}
/// Get the arctangent of a number
pub fn atan(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().atan()
	} else {
		f64::NAN
	}))
}
/// Get the arctangent of a numbers
pub fn atan2(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().atan2(&args.get(1).borrow().to_num())
	} else {
		f64::NAN
	}))
}
/// Get the cubic root of a number
pub fn cbrt(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().cbrt()
	} else {
		f64::NAN
	}))
}
/// Get lowest integer above a number
pub fn ceil(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().ceil()
	} else {
		f64::NAN
	}))
}
/// Get the cosine of a number
pub fn cos(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().cos()
	} else {
		f64::NAN
	}))
}
/// Get the power to raise the natural logarithm to get the number
pub fn exp(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().exp()
	} else {
		f64::NAN
	}))
}
/// Get the highest integer below a number
pub fn floor(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().floor()
	} else {
		f64::NAN
	}))
}
/// Get the natural logarithm of a number
pub fn log(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().log(&f64::consts::E)
	} else {
		f64::NAN
	}))
}
/// Get the maximum of several numbers
pub fn max(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	let mut max = f64::NEG_INFINITY;
	for arg in args.iter() {
		let num = arg.borrow().to_num();
		max = max.max(num);
	}
	Ok(to_value(max))
}
/// Get the minimum of several numbers
pub fn min(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	let mut max = f64::INFINITY;
	for arg in args.iter() {
		let num = arg.borrow().to_num();
		max = max.min(num);
	}
	Ok(to_value(max))
}
/// Raise a number to a power
pub fn pow(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 2 {
		let num : f64 = from_value(*args.get(0)).unwrap();
		let power : f64 = from_value(*args.get(1)).unwrap();
		num.powf(&power)
	} else {
		f64::NAN
	}))
}
/// Generate a random floating-point number between 0 and 1
pub fn _random(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(random::<f64>()))
}
/// Round a number to the nearest integer
pub fn round(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().round()
	} else {
		f64::NAN
	}))
}
/// Get the sine of a number
pub fn sin(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().sin()
	} else {
		f64::NAN
	}))
}
/// Get the square root of a number
pub fn sqrt(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().sqrt()
	} else {
		f64::NAN
	}))
}
/// Get the tangent of a number
pub fn tan(_:Value, _:Value, args:Vec<Value>) -> ResultValue {
	Ok(to_value(if args.len() >= 1 {
		from_value::<f64>(*args.get(0)).unwrap().tan()
	} else {
		f64::NAN
	}))
}
/// Create a new 'Math' object
pub fn _create() -> Value {
	let mut math = TreeMap::new();
	math.insert(~"E", to_value(f64::consts::E));
	math.insert(~"LN2", to_value(f64::consts::LN_2));
	math.insert(~"LN10", to_value(f64::consts::LN_10));
	math.insert(~"LOG2E", to_value(f64::consts::LOG2_E));
	math.insert(~"LOG10E", to_value(f64::consts::LOG10_E));
	math.insert(~"SQRT1_2", to_value(0.5f64.sqrt()));
	math.insert(~"SQRT2", to_value(f64::consts::SQRT2));
	math.insert(~"PI", to_value(f64::consts::PI));
	math.insert(~"abs", to_value(abs));
	math.insert(~"acos", to_value(acos));
	math.insert(~"asin", to_value(asin));
	math.insert(~"atan", to_value(atan));
	math.insert(~"atan2", to_value(atan2));
	math.insert(~"cbrt", to_value(cbrt));
	math.insert(~"ceil", to_value(ceil));
	math.insert(~"cos", to_value(cos));
	math.insert(~"exp", to_value(exp));
	math.insert(~"floor", to_value(floor));
	math.insert(~"log", to_value(log));
	math.insert(~"max", to_value(max));
	math.insert(~"min", to_value(min));
	math.insert(~"pow", to_value(pow));
	math.insert(~"random", to_value(_random));
	math.insert(~"round", to_value(round));
	math.insert(~"sin", to_value(sin));
	math.insert(~"sqrt", to_value(sqrt));
	math.insert(~"tan", to_value(tan));
	to_value(math)
}<|endoftext|>