<commit_before>#![feature(proc_macro)]

#[macro_use]
extern crate log;
extern crate hayaku_http;
#[macro_use(quick_error)]
extern crate quick_error;
extern crate regex;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

mod error;
mod trie;

use hayaku_http::{Handler, Method, Request, RequestHandler, Response, Status};

use std::collections::HashMap;

pub use error::Error;

use trie::TrieNode;

type Tree<T> = HashMap<Method, TrieNode<RequestHandler<T>>>;

#[derive(Clone)]
pub struct Router<T: Clone> {
    trees: Tree<T>,
    /// Enables automatic redirection if the current route can't be matched but
    /// a handler for the path with (without) the trailing slash exists.
    /// For example if /foo/ is requested but a route only exists for /foo, the
    /// client is redirected to /foo with http status code 301 for GET requests
    /// and 307 for all other request methods.
    pub redirect_trailing_slash: bool,
    /// If enabled, the router tries to fix the current request path, if no
    /// handle is registered for it.
    /// First superfluous path elements like ../ or // are removed.
    /// Afterwards the router does a case-insensitive lookup of the cleaned path.
    /// If a handle can be found for this route, the router makes a redirection
    /// to the corrected path with status code 301 for GET requests and 307 for
    /// all other request methods.
    /// For example /FOO and /..//Foo could be redirected to /foo.
    /// `redirect_trailing_slash` is independent of this option.
    pub redirect_fixed_path: bool,
    /// If enabled, the router checks if another method is allowed for the
    /// current route, if the current request can not be routed.
    /// If this is the case, the request is answered with `Method Not Allowed`
    /// and HTTP status code 405.
    /// If no other Method is allowed, the request is delegated to the NotFound
    /// handler.
    pub handle_method_not_allowed: bool,
    /// If enabled, the router automatically replies to OPTIONS requests.
    /// Custom OPTIONS handlers take priority over automatic replies.
    pub handle_options: bool,
    /// Configurable handler which is called when no matching route is
    /// found. If it is `None`, the default 404 handler is used.
    not_found: Option<RequestHandler<T>>,
}

impl<T: Clone> Router<T> {
    pub fn new() -> Self {
        Router {
            trees: HashMap::new(),
            redirect_trailing_slash: true,
            redirect_fixed_path: true,
            handle_method_not_allowed: true,
            handle_options: true,
            not_found: None,
        }
    }

    pub fn set_not_found_handler(&mut self, handler: RequestHandler<T>) {
        self.not_found = Some(handler);
    }

    /// `get` is a shortcut for `Self::handle(Method::Get, path, handle)`.
    pub fn get<S: Into<String>>(&mut self,
                                path: S,
                                handle: RequestHandler<T>)
                                -> Result<(), Error> {
        self.handle(Method::Get, path, handle)
    }

    /// `head` is a shortcut for `Self::handle(Method::Head, path, handle)`.
    pub fn head<S: Into<String>>(&mut self,
                                 path: S,
                                 handle: RequestHandler<T>)
                                 -> Result<(), Error> {
        self.handle(Method::Head, path, handle)
    }

    /// `options` is a shortcut for `Self::handle(Method::Options, path, handle)`.
    pub fn options<S: Into<String>>(&mut self,
                                    path: S,
                                    handle: RequestHandler<T>)
                                    -> Result<(), Error> {
        self.handle(Method::Options, path, handle)
    }

    /// `post` is a shortcut for `Self::handle(Method::Post, path, handle)`.
    pub fn post<S: Into<String>>(&mut self,
                                 path: S,
                                 handle: RequestHandler<T>)
                                 -> Result<(), Error> {
        self.handle(Method::Post, path, handle)
    }

    /// `put` is a shortcut for `Self::handle(Method::Put, path, handle)`.
    pub fn put<S: Into<String>>(&mut self,
                                path: S,
                                handle: RequestHandler<T>)
                                -> Result<(), Error> {
        self.handle(Method::Put, path, handle)
    }

    /// `patch` is a shortcut for `Self::handle(Method::Patch, path, handle)`.
    pub fn patch<S: Into<String>>(&mut self,
                                  path: S,
                                  handle: RequestHandler<T>)
                                  -> Result<(), Error> {
        self.handle(Method::Patch, path, handle)
    }

    /// `delete` is a shortcut for `Self::handle(Method::Delete, path, handle)`.
    pub fn delete<S: Into<String>>(&mut self,
                                   path: S,
                                   handle: RequestHandler<T>)
                                   -> Result<(), Error> {
        self.handle(Method::Delete, path, handle)
    }

    /// Registers a new request handle with the given path and method.
    ///
    /// For GET, POST, PUT, PATCH, and DELETE requests the respective
    /// shortcut functions can be used.
    ///
    /// This function is intended for bulk loading and to allow the usage
    /// of less frequently used, non-standardized or custom methods
    /// (e.g. for internal communication with a proxy).
    pub fn handle<S: Into<String>>(&mut self,
                                   method: Method,
                                   path: S,
                                   handle: RequestHandler<T>)
                                   -> Result<(), Error> {
        let path = path.into();
        if !path.starts_with('/') {
            return Err(Error::StartWithSlash(path.to_string()));
        }

        if self.trees.get(&method).is_none() {
            let root = TrieNode::new();
            self.trees.insert(method.clone(), root);
        }

        // TODO(nokaa): we should probably not unwrap here.
        // It may be possible for the retrieval to fail, even
        // though we check just before this.
        let mut root = self.trees.get_mut(&method).unwrap();
        root.insert(path, handle);

        Ok(())
    }
}

impl<T: Clone> Handler<T> for Router<T> {
    // Handler makes the router implement the fasthttp.ListenAndServe interface.
    fn handler(&self, req: &Request, res: &mut Response, ctx: &T) {
        let path = req.path();
        let path = {
            let data_loc = path.find('?').unwrap_or(path.len());
            &path[..data_loc]
        };
        debug!("path: {}", path);
        let method = req.method().clone();
        debug!("method: {:?}", method);

        if let Some(root) = self.trees.get(&method) {
            debug!("tree for method {:?} found", method);
            match root.get(path) {
                Some((val, map)) => {
                    let serialized = serde_json::to_vec(&map).unwrap();
                    *req.user_data.borrow_mut() = serialized;
                    val.unwrap()(req, res, ctx);
                }
                None => {
                    if self.not_found.is_none() {
                        // Default handler
                        res.status(Status::NotFound);
                        let msg = String::from("404, path \"") + path + "\" not found :(";
                        res.body(&msg.into_bytes());
                    } else {
                        // We have already checked that self.not_found is not
                        // `None`, so unwrapping should be okay.
                        let handle = self.not_found.clone().unwrap();
                        handle(req, res, ctx);
                    }
                }
            }
            // TODO(nokaa): We want to send a different error than 404
            // for this case. In this case we have an incorrect method being
            // used.
        } else if self.not_found.is_none() {
            debug!("tree for method {:?} not found", method);
            // Default handler
            res.status(Status::NotFound);
            let msg = String::from("404, path \"") + path + "\" not found :(";
            res.body(&msg.into_bytes());
        } else {
            debug!("tree for method {:?} not found", method);
            // We have already checked that self.not_found is not
            // `None`, so unwrapping should be okay.
            let handle = self.not_found.clone().unwrap();
            handle(req, res, ctx);
        }
    }
}
<commit_msg>Move get_path_params here from hayaku<commit_after>#![feature(proc_macro)]

#[macro_use]
extern crate log;
extern crate hayaku_http;
#[macro_use(quick_error)]
extern crate quick_error;
extern crate regex;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

mod error;
mod trie;

use trie::TrieNode;

use hayaku_http::{Handler, Method, Request, RequestHandler, Response, Status};

use std::collections::HashMap;

pub use error::Error;

pub fn get_path_params(req: &Request) -> HashMap<String, String> {
    serde_json::from_slice(&*req.user_data.borrow()).unwrap()
}

type Tree<T> = HashMap<Method, TrieNode<RequestHandler<T>>>;

#[derive(Clone)]
pub struct Router<T: Clone> {
    trees: Tree<T>,
    /// Enables automatic redirection if the current route can't be matched but
    /// a handler for the path with (without) the trailing slash exists.
    /// For example if /foo/ is requested but a route only exists for /foo, the
    /// client is redirected to /foo with http status code 301 for GET requests
    /// and 307 for all other request methods.
    pub redirect_trailing_slash: bool,
    /// If enabled, the router tries to fix the current request path, if no
    /// handle is registered for it.
    /// First superfluous path elements like ../ or // are removed.
    /// Afterwards the router does a case-insensitive lookup of the cleaned path.
    /// If a handle can be found for this route, the router makes a redirection
    /// to the corrected path with status code 301 for GET requests and 307 for
    /// all other request methods.
    /// For example /FOO and /..//Foo could be redirected to /foo.
    /// `redirect_trailing_slash` is independent of this option.
    pub redirect_fixed_path: bool,
    /// If enabled, the router checks if another method is allowed for the
    /// current route, if the current request can not be routed.
    /// If this is the case, the request is answered with `Method Not Allowed`
    /// and HTTP status code 405.
    /// If no other Method is allowed, the request is delegated to the NotFound
    /// handler.
    pub handle_method_not_allowed: bool,
    /// If enabled, the router automatically replies to OPTIONS requests.
    /// Custom OPTIONS handlers take priority over automatic replies.
    pub handle_options: bool,
    /// Configurable handler which is called when no matching route is
    /// found. If it is `None`, the default 404 handler is used.
    not_found: Option<RequestHandler<T>>,
}

impl<T: Clone> Router<T> {
    pub fn new() -> Self {
        Router {
            trees: HashMap::new(),
            redirect_trailing_slash: true,
            redirect_fixed_path: true,
            handle_method_not_allowed: true,
            handle_options: true,
            not_found: None,
        }
    }

    pub fn set_not_found_handler(&mut self, handler: RequestHandler<T>) {
        self.not_found = Some(handler);
    }

    /// `get` is a shortcut for `Self::handle(Method::Get, path, handle)`.
    pub fn get<S: Into<String>>(&mut self,
                                path: S,
                                handle: RequestHandler<T>)
                                -> Result<(), Error> {
        self.handle(Method::Get, path, handle)
    }

    /// `head` is a shortcut for `Self::handle(Method::Head, path, handle)`.
    pub fn head<S: Into<String>>(&mut self,
                                 path: S,
                                 handle: RequestHandler<T>)
                                 -> Result<(), Error> {
        self.handle(Method::Head, path, handle)
    }

    /// `options` is a shortcut for `Self::handle(Method::Options, path, handle)`.
    pub fn options<S: Into<String>>(&mut self,
                                    path: S,
                                    handle: RequestHandler<T>)
                                    -> Result<(), Error> {
        self.handle(Method::Options, path, handle)
    }

    /// `post` is a shortcut for `Self::handle(Method::Post, path, handle)`.
    pub fn post<S: Into<String>>(&mut self,
                                 path: S,
                                 handle: RequestHandler<T>)
                                 -> Result<(), Error> {
        self.handle(Method::Post, path, handle)
    }

    /// `put` is a shortcut for `Self::handle(Method::Put, path, handle)`.
    pub fn put<S: Into<String>>(&mut self,
                                path: S,
                                handle: RequestHandler<T>)
                                -> Result<(), Error> {
        self.handle(Method::Put, path, handle)
    }

    /// `patch` is a shortcut for `Self::handle(Method::Patch, path, handle)`.
    pub fn patch<S: Into<String>>(&mut self,
                                  path: S,
                                  handle: RequestHandler<T>)
                                  -> Result<(), Error> {
        self.handle(Method::Patch, path, handle)
    }

    /// `delete` is a shortcut for `Self::handle(Method::Delete, path, handle)`.
    pub fn delete<S: Into<String>>(&mut self,
                                   path: S,
                                   handle: RequestHandler<T>)
                                   -> Result<(), Error> {
        self.handle(Method::Delete, path, handle)
    }

    /// Registers a new request handle with the given path and method.
    ///
    /// For GET, POST, PUT, PATCH, and DELETE requests the respective
    /// shortcut functions can be used.
    ///
    /// This function is intended for bulk loading and to allow the usage
    /// of less frequently used, non-standardized or custom methods
    /// (e.g. for internal communication with a proxy).
    pub fn handle<S: Into<String>>(&mut self,
                                   method: Method,
                                   path: S,
                                   handle: RequestHandler<T>)
                                   -> Result<(), Error> {
        let path = path.into();
        if !path.starts_with('/') {
            return Err(Error::StartWithSlash(path.to_string()));
        }

        if self.trees.get(&method).is_none() {
            let root = TrieNode::new();
            self.trees.insert(method.clone(), root);
        }

        // TODO(nokaa): we should probably not unwrap here.
        // It may be possible for the retrieval to fail, even
        // though we check just before this.
        let mut root = self.trees.get_mut(&method).unwrap();
        root.insert(path, handle);

        Ok(())
    }
}

impl<T: Clone> Handler<T> for Router<T> {
    // Handler makes the router implement the fasthttp.ListenAndServe interface.
    fn handler(&self, req: &Request, res: &mut Response, ctx: &T) {
        let path = req.path();
        let path = {
            let data_loc = path.find('?').unwrap_or(path.len());
            &path[..data_loc]
        };
        debug!("path: {}", path);
        let method = req.method().clone();
        debug!("method: {:?}", method);

        if let Some(root) = self.trees.get(&method) {
            debug!("tree for method {:?} found", method);
            match root.get(path) {
                Some((val, map)) => {
                    let serialized = serde_json::to_vec(&map).unwrap();
                    *req.user_data.borrow_mut() = serialized;
                    val.unwrap()(req, res, ctx);
                }
                None => {
                    if self.not_found.is_none() {
                        // Default handler
                        res.status(Status::NotFound);
                        let msg = String::from("404, path \"") + path + "\" not found :(";
                        res.body(&msg.into_bytes());
                    } else {
                        // We have already checked that self.not_found is not
                        // `None`, so unwrapping should be okay.
                        let handle = self.not_found.clone().unwrap();
                        handle(req, res, ctx);
                    }
                }
            }
            // TODO(nokaa): We want to send a different error than 404
            // for this case. In this case we have an incorrect method being
            // used.
        } else if self.not_found.is_none() {
            debug!("tree for method {:?} not found", method);
            // Default handler
            res.status(Status::NotFound);
            let msg = String::from("404, path \"") + path + "\" not found :(";
            res.body(&msg.into_bytes());
        } else {
            debug!("tree for method {:?} not found", method);
            // We have already checked that self.not_found is not
            // `None`, so unwrapping should be okay.
            let handle = self.not_found.clone().unwrap();
            handle(req, res, ctx);
        }
    }
}
<|endoftext|>


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

#![allow(unstable)]

use std::ascii::AsciiExt;
use std::default::Default;

use tokenizer::{PeekableTokens, Token, Tokens};
use types::GeometryCollection;
use types::LineString;
use types::Point;
use types::Polygon;
use types::MultiPoint;
use types::MultiLineString;
use types::MultiPolygon;

mod tokenizer;
mod towkt;
pub mod types;

pub use towkt::ToWkt;

pub enum Geometry {
    Point(Point),
    LineString(LineString),
    Polygon(Polygon),
    MultiPoint(MultiPoint),
    MultiLineString(MultiLineString),
    MultiPolygon(MultiPolygon),
    GeometryCollection(GeometryCollection),
}

impl Geometry {
    fn from_word_and_tokens(word: &str, tokens: &mut PeekableTokens)-> Result<Self, &'static str> {
        match word {
            "POINT" => {
                let x = <Point as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "LINESTRING" => {
                let x = <LineString as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "POLYGON" => {
                let x = <Polygon as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "MULTIPOINT" => {
                let x = <MultiPoint as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "MULTILINESTRING" => {
                let x = <MultiLineString as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "MULTIPOLYGON" => {
                let x = <MultiPolygon as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "GEOMETRYCOLLECTION" => {
                let x = <GeometryCollection as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            _ => Err("Invalid type encountered"),
        }
    }
}
pub struct Wkt {
    pub items: Vec<Geometry>
}

impl Wkt {
    fn new() -> Self {
        Wkt {items: vec![]}
    }

    fn add_item(&mut self, item: Geometry) {
        self.items.push(item);
    }

    fn from_str(wkt_str: &str) -> Result<Self, &'static str> {
        let tokens = Tokens::from_str(wkt_str);
        Wkt::from_tokens(tokens)
    }

    fn from_tokens(tokens: Tokens) -> Result<Self, &'static str> {
        let mut wkt = Wkt::new();
        let mut tokens = tokens.peekable();
        let word = match tokens.next() {
            Some(Token::Word(word)) => {
                if !word.is_ascii() {
                    return Err("Encountered non-ascii word");
                }
                word.to_ascii_uppercase()
            },
            None => return Ok(wkt),
            _ => return Err("Invalid WKT format"),
        };
        match Geometry::from_word_and_tokens(&word, &mut tokens) {
            Ok(item) => wkt.add_item(item),
            Err(s) => return Err(s),
        }
        Ok(wkt)
    }
}

trait FromTokens: Sized+Default {
    fn from_tokens(tokens: &mut PeekableTokens) -> Result<Self, &'static str>;

    fn from_tokens_with_parens(tokens: &mut PeekableTokens) -> Result<Self, &'static str> {
        match tokens.next() {
            Some(Token::ParenOpen) => (),
            Some(Token::Word(ref s)) if s.to_ascii_uppercase() == "EMPTY" =>
                return Ok(Default::default()),
            _ => return Err("Missing open parenthesis for type"),
        };
        let result = FromTokens::from_tokens(tokens);
        match tokens.next() {
            Some(Token::ParenClose) => (),
            _ => return Err("Missing closing parenthesis for type"),
        };
        result
    }

    fn comma_many<F>(f: F, tokens: &mut PeekableTokens) -> Result<Vec<Self>, &'static str>
            where F: Fn(&mut PeekableTokens) -> Result<Self, &'static str> {
        let mut items = Vec::new();

        let item = try!(f(tokens));
        items.push(item);

        while let Some(&Token::Comma) = tokens.peek() {
            tokens.next();  // throw away comma

            let item = try!(f(tokens));
            items.push(item);
        }

        Ok(items)
    }
}

#[cfg(test)]
mod tests {
    use {Wkt, Geometry};
    use types::{MultiPolygon, Point};

    #[test]
    fn empty_string() {
        let wkt = Wkt::from_str("").ok().unwrap();
        assert_eq!(0, wkt.items.len());
    }

    #[test]
    fn empty_items() {
        let mut wkt = Wkt::from_str("POINT EMPTY").ok().unwrap();
        assert_eq!(1, wkt.items.len());
        match wkt.items.pop().unwrap() {
            Geometry::Point(Point(None)) => (),
            _ => unreachable!(),
        };

        let mut wkt = Wkt::from_str("MULTIPOLYGON EMPTY").ok().unwrap();
        assert_eq!(1, wkt.items.len());
        match wkt.items.pop().unwrap() {
            Geometry::MultiPolygon(MultiPolygon(polygons)) =>
                assert_eq!(polygons.len(), 0),
            _ => unreachable!(),
        };
    }
}
<commit_msg>Clean up some warnings<commit_after>// Copyright 2014-2015 The GeoRust Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(collections,core,std_misc)]

use std::ascii::AsciiExt;
use std::default::Default;

use tokenizer::{PeekableTokens, Token, Tokens};
use types::GeometryCollection;
use types::LineString;
use types::Point;
use types::Polygon;
use types::MultiPoint;
use types::MultiLineString;
use types::MultiPolygon;

mod tokenizer;
mod towkt;
pub mod types;

pub use towkt::ToWkt;

pub enum Geometry {
    Point(Point),
    LineString(LineString),
    Polygon(Polygon),
    MultiPoint(MultiPoint),
    MultiLineString(MultiLineString),
    MultiPolygon(MultiPolygon),
    GeometryCollection(GeometryCollection),
}

impl Geometry {
    fn from_word_and_tokens(word: &str, tokens: &mut PeekableTokens)-> Result<Self, &'static str> {
        match word {
            "POINT" => {
                let x = <Point as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "LINESTRING" => {
                let x = <LineString as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "POLYGON" => {
                let x = <Polygon as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "MULTIPOINT" => {
                let x = <MultiPoint as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "MULTILINESTRING" => {
                let x = <MultiLineString as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "MULTIPOLYGON" => {
                let x = <MultiPolygon as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            "GEOMETRYCOLLECTION" => {
                let x = <GeometryCollection as FromTokens>::from_tokens_with_parens(tokens);
                x.map(|y| y.as_item())
            },
            _ => Err("Invalid type encountered"),
        }
    }
}
pub struct Wkt {
    pub items: Vec<Geometry>
}

impl Wkt {
    fn new() -> Self {
        Wkt {items: vec![]}
    }

    fn add_item(&mut self, item: Geometry) {
        self.items.push(item);
    }

    fn from_str(wkt_str: &str) -> Result<Self, &'static str> {
        let tokens = Tokens::from_str(wkt_str);
        Wkt::from_tokens(tokens)
    }

    fn from_tokens(tokens: Tokens) -> Result<Self, &'static str> {
        let mut wkt = Wkt::new();
        let mut tokens = tokens.peekable();
        let word = match tokens.next() {
            Some(Token::Word(word)) => {
                if !word.is_ascii() {
                    return Err("Encountered non-ascii word");
                }
                word.to_ascii_uppercase()
            },
            None => return Ok(wkt),
            _ => return Err("Invalid WKT format"),
        };
        match Geometry::from_word_and_tokens(&word, &mut tokens) {
            Ok(item) => wkt.add_item(item),
            Err(s) => return Err(s),
        }
        Ok(wkt)
    }
}

trait FromTokens: Sized+Default {
    fn from_tokens(tokens: &mut PeekableTokens) -> Result<Self, &'static str>;

    fn from_tokens_with_parens(tokens: &mut PeekableTokens) -> Result<Self, &'static str> {
        match tokens.next() {
            Some(Token::ParenOpen) => (),
            Some(Token::Word(ref s)) if s.to_ascii_uppercase() == "EMPTY" =>
                return Ok(Default::default()),
            _ => return Err("Missing open parenthesis for type"),
        };
        let result = FromTokens::from_tokens(tokens);
        match tokens.next() {
            Some(Token::ParenClose) => (),
            _ => return Err("Missing closing parenthesis for type"),
        };
        result
    }

    fn comma_many<F>(f: F, tokens: &mut PeekableTokens) -> Result<Vec<Self>, &'static str>
            where F: Fn(&mut PeekableTokens) -> Result<Self, &'static str> {
        let mut items = Vec::new();

        let item = try!(f(tokens));
        items.push(item);

        while let Some(&Token::Comma) = tokens.peek() {
            tokens.next();  // throw away comma

            let item = try!(f(tokens));
            items.push(item);
        }

        Ok(items)
    }
}

#[cfg(test)]
mod tests {
    use {Wkt, Geometry};
    use types::{MultiPolygon, Point};

    #[test]
    fn empty_string() {
        let wkt = Wkt::from_str("").ok().unwrap();
        assert_eq!(0, wkt.items.len());
    }

    #[test]
    fn empty_items() {
        let mut wkt = Wkt::from_str("POINT EMPTY").ok().unwrap();
        assert_eq!(1, wkt.items.len());
        match wkt.items.pop().unwrap() {
            Geometry::Point(Point(None)) => (),
            _ => unreachable!(),
        };

        let mut wkt = Wkt::from_str("MULTIPOLYGON EMPTY").ok().unwrap();
        assert_eq!(1, wkt.items.len());
        match wkt.items.pop().unwrap() {
            Geometry::MultiPolygon(MultiPolygon(polygons)) =>
                assert_eq!(polygons.len(), 0),
            _ => unreachable!(),
        };
    }
}
<|endoftext|>


<commit_before>//! Jamal provides a bi-directional interface for transformations between json and yaml documents.
extern crate serde_json;
extern crate serde_yaml;

use serde_json::Value as JsonValue;
use serde_yaml::Value as YamlValue;
use std::error::Error as StdError;
use std::num::ParseFloatError;
use std::collections::BTreeMap;

/// represents potential errors that can happen during the transformation process
#[derive(Debug)]
pub enum Error {
    /// Occurs when an attempt to parse a `serde_yaml::Real` as an `f64` fails
    ParseFloat(ParseFloatError),
    /// Occurs when a transformation is requested for an invalid value
    InvalidValue,
    /// Occurs when an unsupported transformation is requested
    UnsupportedValue(YamlValue)
}

impl StdError for Error {
    fn description(&self) -> &str {
        match *self {
            Error::ParseFloat(ref e) => e.description(),
            Error::InvalidValue => "invalid value",
            Error::UnsupportedValue(_) => "supported value",
        }
    }

    fn cause(&self) -> Option<&StdError> {
        match *self {
            Error::ParseFloat(ref e) => Some(e),
            _ => None,
        }
    }
}

impl ::std::fmt::Display for Error {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

/// A result type with a fixed type for `jamal::Errors`
pub type Result<T> = std::result::Result<T, Error>;

impl From<ParseFloatError> for Error {
    fn from(error: ParseFloatError) -> Error {
        Error::ParseFloat(error)
    }
}

/// converts a `serde_json::Value` into a `serde_yaml::Value`
pub fn to_yaml(json: &JsonValue) -> Result<YamlValue> {
    match json {
        &JsonValue::Null => Ok(YamlValue::Null),
        &JsonValue::Bool(ref value) => Ok(YamlValue::Boolean(value.clone())),
        &JsonValue::I64(ref value) => Ok(YamlValue::Integer(value.clone())),
        &JsonValue::U64(ref value) => Ok(YamlValue::Integer(value.clone() as i64)),
        &JsonValue::F64(ref value) => Ok(YamlValue::Real(value.to_string())),
        &JsonValue::String(ref value) => Ok(YamlValue::String(value.clone())),
        &JsonValue::Array(ref values) => {
            let mut yaml_values = vec![];
            for value in values {
                yaml_values.push(try!(to_yaml(&value)));
            }
            Ok(YamlValue::Array(yaml_values))
        }
        &JsonValue::Object(ref value) => {
            let mut yaml_value = BTreeMap::new();
            for (k, v) in value {
                let yaml = try!(to_yaml(&v));
                yaml_value.insert(YamlValue::String(k.clone()), yaml);
            }
            Ok(YamlValue::Hash(yaml_value))
        }
    }
}

/// converts a `serde_yaml::Value` into a `serde_json::Value`
pub fn to_json(yaml: &YamlValue) -> Result<JsonValue> {
    match yaml {
        &YamlValue::Real(ref value) => Ok(JsonValue::F64(try!(value.parse::<f64>()))),
        &YamlValue::Integer(ref value) => Ok(JsonValue::I64(value.clone())),
        &YamlValue::String(ref value) => Ok(JsonValue::String(value.clone())),
        &YamlValue::Boolean(ref value) => Ok(JsonValue::Bool(value.clone())),
        &YamlValue::Array(ref values) => {
            let mut json_values = vec![];
            for value in values {
                let json = try!(to_json(&value));
                json_values.push(json);
            }
            Ok(JsonValue::Array(json_values))
        }
        &YamlValue::Hash(ref value) => {
            let mut json_value = BTreeMap::new();
            for (k, v) in value {
                match k {
                    &YamlValue::String(ref key) => {
                        let json = try!(to_json(&v));
                        json_value.insert(key.clone(), json);
                    }
                    unsupported => return Err(Error::UnsupportedValue(unsupported.clone())),
                }
            }
            Ok(JsonValue::Object(json_value))
        }
        alias @ &YamlValue::Alias(_) => Err(Error::UnsupportedValue(alias.clone())),
        &YamlValue::Null => Ok(JsonValue::Null),
        &YamlValue::BadValue => Err(Error::InvalidValue),
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeMap;
    use super::serde_json;
    use super::serde_yaml;
    use super::{to_json, to_yaml};

    #[test]
    fn json_str_vec_to_yaml() {
        let input = serde_json::to_value(&vec!["foo"]);
        let output = serde_yaml::Value::Array(vec![serde_yaml::Value::String("foo".to_owned())]);
        assert_eq!(to_yaml(&input).unwrap(), output);
    }

    #[test]
    fn yaml_str_vec_to_json() {
        let input = serde_yaml::to_value(&vec!["foo"]);
        let output = serde_json::Value::Array(vec![serde_json::Value::String("foo".to_owned())]);
        assert_eq!(to_json(&input).unwrap(), output);
    }

    #[test]
    fn json_obj_to_yaml() {
        let mut json_obj = BTreeMap::new();
        json_obj.insert("foo", 1);
        let input = serde_json::to_value(&json_obj);

        let mut yaml_obj = BTreeMap::new();
        yaml_obj.insert(serde_yaml::Value::String("foo".to_owned()), serde_yaml::Value::Integer(1));
        let output = serde_yaml::Value::Hash(yaml_obj);
        assert_eq!(to_yaml(&input).unwrap(), output);
    }

    #[test]
    fn yaml_obj_to_json() {
        let mut yaml_obj = BTreeMap::new();
        yaml_obj.insert("foo", 1);
        let input = serde_yaml::to_value(&yaml_obj);

        let mut json_obj = BTreeMap::new();
        json_obj.insert("foo".to_owned(), serde_json::Value::I64(1));
        let output = serde_json::Value::Object(json_obj);
        assert_eq!(to_json(&input).unwrap(), output);
    }

}
<commit_msg>increase cov<commit_after>//! Jamal provides a bi-directional interface for transformations between json and yaml documents.
extern crate serde_json;
extern crate serde_yaml;

use serde_json::Value as JsonValue;
use serde_yaml::Value as YamlValue;
use std::error::Error as StdError;
use std::num::ParseFloatError;
use std::collections::BTreeMap;

/// represents potential errors that can happen during the transformation process
#[derive(Debug)]
pub enum Error {
    /// Occurs when an attempt to parse a `serde_yaml::Real` as an `f64` fails
    ParseFloat(ParseFloatError),
    /// Occurs when a transformation is requested for an invalid value
    InvalidValue,
    /// Occurs when an unsupported transformation is requested
    UnsupportedValue(YamlValue)
}

impl StdError for Error {
    fn description(&self) -> &str {
        match *self {
            Error::ParseFloat(ref e) => e.description(),
            Error::InvalidValue => "invalid value",
            Error::UnsupportedValue(_) => "supported value",
        }
    }

    fn cause(&self) -> Option<&StdError> {
        match *self {
            Error::ParseFloat(ref e) => Some(e),
            _ => None,
        }
    }
}

impl ::std::fmt::Display for Error {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

/// A result type with a fixed type for `jamal::Errors`
pub type Result<T> = std::result::Result<T, Error>;

impl From<ParseFloatError> for Error {
    fn from(error: ParseFloatError) -> Error {
        Error::ParseFloat(error)
    }
}

/// converts a `serde_json::Value` into a `serde_yaml::Value`
pub fn to_yaml(json: &JsonValue) -> Result<YamlValue> {
    match json {
        &JsonValue::Null => Ok(YamlValue::Null),
        &JsonValue::Bool(ref value) => Ok(YamlValue::Boolean(value.clone())),
        &JsonValue::I64(ref value) => Ok(YamlValue::Integer(value.clone())),
        &JsonValue::U64(ref value) => Ok(YamlValue::Integer(value.clone() as i64)),
        &JsonValue::F64(ref value) => Ok(YamlValue::Real(value.to_string())),
        &JsonValue::String(ref value) => Ok(YamlValue::String(value.clone())),
        &JsonValue::Array(ref values) => {
            let mut yaml_values = vec![];
            for value in values {
                yaml_values.push(try!(to_yaml(&value)));
            }
            Ok(YamlValue::Array(yaml_values))
        }
        &JsonValue::Object(ref value) => {
            let mut yaml_value = BTreeMap::new();
            for (k, v) in value {
                let yaml = try!(to_yaml(&v));
                yaml_value.insert(YamlValue::String(k.clone()), yaml);
            }
            Ok(YamlValue::Hash(yaml_value))
        }
    }
}

/// converts a `serde_yaml::Value` into a `serde_json::Value`
pub fn to_json(yaml: &YamlValue) -> Result<JsonValue> {
    match yaml {
        &YamlValue::Real(ref value) => Ok(JsonValue::F64(try!(value.parse::<f64>()))),
        &YamlValue::Integer(ref value) => Ok(JsonValue::I64(value.clone())),
        &YamlValue::String(ref value) => Ok(JsonValue::String(value.clone())),
        &YamlValue::Boolean(ref value) => Ok(JsonValue::Bool(value.clone())),
        &YamlValue::Array(ref values) => {
            let mut json_values = vec![];
            for value in values {
                let json = try!(to_json(&value));
                json_values.push(json);
            }
            Ok(JsonValue::Array(json_values))
        }
        &YamlValue::Hash(ref value) => {
            let mut json_value = BTreeMap::new();
            for (k, v) in value {
                match k {
                    &YamlValue::String(ref key) => {
                        let json = try!(to_json(&v));
                        json_value.insert(key.clone(), json);
                    }
                    unsupported => return Err(Error::UnsupportedValue(unsupported.clone())),
                }
            }
            Ok(JsonValue::Object(json_value))
        }
        alias @ &YamlValue::Alias(_) => Err(Error::UnsupportedValue(alias.clone())),
        &YamlValue::Null => Ok(JsonValue::Null),
        &YamlValue::BadValue => Err(Error::InvalidValue),
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeMap;
    use super::serde_json;
    use super::serde_yaml;
    use super::{to_json, to_yaml};

    #[test]
    fn json_str_vec_to_yaml() {
        let input = serde_json::to_value(&vec!["foo"]);
        let output = serde_yaml::Value::Array(vec![serde_yaml::Value::String("foo".to_owned())]);
        assert_eq!(to_yaml(&input).unwrap(), output);
    }

    #[test]
    fn yaml_str_vec_to_json() {
        let input = serde_yaml::to_value(&vec!["foo"]);
        let output = serde_json::Value::Array(vec![serde_json::Value::String("foo".to_owned())]);
        assert_eq!(to_json(&input).unwrap(), output);
    }

    #[test]
    fn json_obj_to_yaml() {
        let mut json_obj = BTreeMap::new();
        json_obj.insert("foo", 1);
        let input = serde_json::to_value(&json_obj);

        let mut yaml_obj = BTreeMap::new();
        yaml_obj.insert(serde_yaml::Value::String("foo".to_owned()), serde_yaml::Value::Integer(1));
        let output = serde_yaml::Value::Hash(yaml_obj);
        assert_eq!(to_yaml(&input).unwrap(), output);
    }

    #[test]
    fn yaml_obj_to_json() {
        let mut yaml_obj = BTreeMap::new();
        yaml_obj.insert("foo", 1);
        let input = serde_yaml::to_value(&yaml_obj);

        let mut json_obj = BTreeMap::new();
        json_obj.insert("foo".to_owned(), serde_json::Value::I64(1));
        let output = serde_json::Value::Object(json_obj);
        assert_eq!(to_json(&input).unwrap(), output);
    }

    #[test]
    fn json_bool_to_yaml() {
        let input = serde_json::to_value(&true);
        let output = serde_yaml::Value::Boolean(true);
        assert_eq!(to_yaml(&input).unwrap(), output);
    }

    #[test]
    fn yaml_bool_to_json() {
        let input = serde_yaml::to_value(&true);
        let output = serde_json::Value::Bool(true);
        assert_eq!(to_json(&input).unwrap(), output);
    }
}
<|endoftext|>


<commit_before>//! A library for abstracting the most common interfaces and filtering for making an AI for the
//! RoboCup's SSL robot soccer game.
//!
//! The main purpose is to provide an _stdio_ based interface for building an AI.  The usage of
//! this library is useful for building or customizing a user interface around that concept.
//!
//! # Examples
//!
//! The following will make a CLI program that will run an executable called `demo-ai` for it to
//! play on a running __grSim__ (or any simulator protocol compatible).
//!
//! Note that there is no referee state in this example.
//!
//! ```no_run
//! use std::sync::mpsc::channel;
//! use std::process::Command;
//! use roboime_next::prelude::*;
//! use roboime_next::{game, ai, grsim};
//!
//! let state = game::State::new();
//!
//! let mut grsim = grsim::Interface::new()
//!     .vision_addr("224.5.23.2:11002").unwrap()
//!     .grsim_addr("127.0.0.1:20011").unwrap()
//!     .spawn().unwrap();
//!
//! let mut ai = ai::Interface::new(Command::new("./demo-ai"))
//!     .is_yellow(true)
//!     .spawn().unwrap();
//!
//! grsim.wait_for_geom(&mut state).unwrap();
//! ai.push_init(&state).unwrap();
//!
//! loop {
//!     grsim.recv_to_state(&mut state).unwrap();
//!     ai.push_state(&state).unwrap();
//!     let cmd = ai.read_command(&state).unwrap();
//!     grsim.send_command(cmd).unwrap();
//! }
//!
//! ```
//!
//! To see that in action you will need a __demo-ai__ (there's one in this project which needs
//! Python 3 to run), and a running __grSim__ with matching settings (which could very well be
//! running on another machine, just change the `grsim_addr`).

extern crate roboime_next_protocol as protocol;
extern crate net2;
#[macro_use] extern crate log;

pub use error::{Result, Error, ErrorKind};
pub use interface::InterfaceHandle;

mod error;
mod interface;
pub mod game;
pub mod ai;
pub mod grsim;
pub mod sim;
pub mod prelude {
    pub use ::InterfaceHandle;
    pub use ::game::{Position, Pose};
    pub use ::ai::CommandAiExt;
}
<commit_msg>Fix mutability error triggered on rust 1.10<commit_after>//! A library for abstracting the most common interfaces and filtering for making an AI for the
//! RoboCup's SSL robot soccer game.
//!
//! The main purpose is to provide an _stdio_ based interface for building an AI.  The usage of
//! this library is useful for building or customizing a user interface around that concept.
//!
//! # Examples
//!
//! The following will make a CLI program that will run an executable called `demo-ai` for it to
//! play on a running __grSim__ (or any simulator protocol compatible).
//!
//! Note that there is no referee state in this example.
//!
//! ```no_run
//! use std::sync::mpsc::channel;
//! use std::process::Command;
//! use roboime_next::prelude::*;
//! use roboime_next::{game, ai, grsim};
//!
//! let mut state = game::State::new();
//!
//! let mut grsim = grsim::Interface::new()
//!     .vision_addr("224.5.23.2:11002").unwrap()
//!     .grsim_addr("127.0.0.1:20011").unwrap()
//!     .spawn().unwrap();
//!
//! let mut ai = ai::Interface::new(Command::new("./demo-ai"))
//!     .is_yellow(true)
//!     .spawn().unwrap();
//!
//! grsim.wait_for_geom(&mut state).unwrap();
//! ai.push_init(&state).unwrap();
//!
//! loop {
//!     grsim.recv_to_state(&mut state).unwrap();
//!     ai.push_state(&state).unwrap();
//!     let cmd = ai.read_command(&state).unwrap();
//!     grsim.send_command(cmd).unwrap();
//! }
//!
//! ```
//!
//! To see that in action you will need a __demo-ai__ (there's one in this project which needs
//! Python 3 to run), and a running __grSim__ with matching settings (which could very well be
//! running on another machine, just change the `grsim_addr`).

extern crate roboime_next_protocol as protocol;
extern crate net2;
#[macro_use] extern crate log;

pub use error::{Result, Error, ErrorKind};
pub use interface::InterfaceHandle;

mod error;
mod interface;
pub mod game;
pub mod ai;
pub mod grsim;
pub mod sim;
pub mod prelude {
    pub use ::InterfaceHandle;
    pub use ::game::{Position, Pose};
    pub use ::ai::CommandAiExt;
}
<|endoftext|>


<commit_before>//! A scoped linear allocator.
//! This is useful for reusing a block of memory for temporary allocations within
//! a tight inner loop. Multiple nested scopes can be used if desired.
//!
//! # Examples
//! ```rust
//! use scoped_allocator::{Allocator, ScopedAllocator};
//! struct Bomb(u8);
//! impl Drop for Bomb {
//!     fn drop(&mut self) {
//!         println!("Boom! {}", self.0);
//!     }
//! }
//! // new allocator with a kilobyte of memory.
//! let alloc = ScopedAllocator::new(1024);
//!
//! alloc.scope(|inner| {
//!     let mut bombs = Vec::new();
//!     for i in 0..100 { bombs.push(inner.allocate(Bomb(i)).ok().unwrap())}
//!     // watch the bombs go off!
//! });
//!
//! let my_int = alloc.allocate(23).ok().unwrap();
//! println!("My int: {}", *my_int);
//! ```

#![feature(
    alloc,
    coerce_unsized,
    core_intrinsics,
    heap_api,
    ptr_as_ref,
    raw,
    unsize
)]

use std::any::Any;
use std::borrow::{Borrow, BorrowMut};
use std::cell::Cell;
use std::intrinsics::drop_in_place;
use std::marker::Unsize;
use std::mem;
use std::ops::{CoerceUnsized, Deref, DerefMut};
use std::raw::TraitObject;
use std::ptr;

use alloc::heap;

extern crate alloc;

/// A custom memory allocator.
pub trait Allocator {
    /// Attempts to allocate space for the T supplied to it.
    fn allocate<'a, T>(&'a self, val: T) -> Result<Allocated<'a, T, Self>, T> where Self: Sized {
        let (size, align) = (mem::size_of::<T>(), mem::align_of::<T>());
        match unsafe { self.allocate_raw(size, align) } {
            Ok(ptr) => {
                let item = ptr as *mut T;
                unsafe { ptr::write(item, val) };

                Ok(Allocated {
                    item: unsafe { item.as_mut().expect("allocate returned null ptr") },
                    allocator: self,
                    size: size,
                    align: align
                })
            }
            Err(_) => Err(val)
        }
    }

    /// Attempt to allocate a block of memory.
    ///
    /// # Safety
    /// Never use the pointer outside of the lifetime of the allocator.
    /// It must be deallocated with the same allocator as it was allocated with.
    /// It is undefined behavior to provide a non power-of-two align.
    unsafe fn allocate_raw(&self, size: usize, align: usize) -> Result<*mut u8, ()>;

    /// Deallocate the memory referred to by this pointer.
    ///
    /// # Safety
    /// This pointer must have been allocated by this allocator.
    /// The size and align must be the same as when they were allocated.
    /// Do not deallocate the same pointer twice. Behavior is implementation-defined,
    /// but usually not expected.
    unsafe fn deallocate_raw(&self, ptr: *mut u8, size: usize, align: usize);
}

/// An item allocated by a custom allocator.
pub struct Allocated<'a, T: 'a + ?Sized, A: 'a + Allocator> {
    item: *mut T,
    allocator: &'a A,
    size: usize,
    align: usize,
}

impl<'a, T: ?Sized, A: Allocator> Deref for Allocated<'a, T, A> {
    type Target = T;

    fn deref<'b>(&'b self) -> &'b T {
        unsafe { mem::transmute(self.item) }
    }
}

impl<'a, T: ?Sized, A: Allocator> DerefMut for Allocated<'a, T, A> {
    fn deref_mut<'b>(&'b mut self) -> &'b mut T {
        unsafe { mem::transmute(self.item) }
    }
}

// Allocated can store trait objects!
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Allocated<'a, U, A>> for Allocated<'a, T, A> {}

impl<'a, A: Allocator> Allocated<'a, Any, A> {
    /// Attempts to downcast this `Allocated` to a concrete type.
    pub fn downcast<T: Any>(self) -> Result<Allocated<'a, T, A>, Allocated<'a, Any, A>> {
        if self.is::<T>() {
            let obj: TraitObject = unsafe { mem::transmute(self.item as *mut Any) };
            let new_allocated = Allocated {
                item: unsafe { mem::transmute(obj.data) },
                allocator: self.allocator,
                size: self.size,
                align: self.align
            };
            mem::forget(self);
            Ok(new_allocated)
        } else {
            Err(self)
        }
    }
}

impl<'a, T: ?Sized, A: Allocator> Borrow<T> for Allocated<'a, T, A> {
    fn borrow(&self) -> &T { &**self }
}

impl<'a, T: ?Sized, A: Allocator> BorrowMut<T> for Allocated<'a, T, A> {
    fn borrow_mut(&mut self) -> &mut T { &mut **self }
}

impl<'a, T: ?Sized, A: Allocator> Drop for Allocated<'a, T, A> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            drop_in_place(self.item);
            self.allocator.deallocate_raw(self.item as *mut u8, self.size, self.align);
        }

    }
}

/// A scoped linear allocator
pub struct ScopedAllocator {
    current: Cell<*mut u8>,
    end: *mut u8,
    start: *mut u8,
}

impl ScopedAllocator {
    /// Creates a new `ScopedAllocator` backed by `size` bytes.
    pub fn new(size: usize) -> Self {
        // Create a memory buffer with the desired size and maximal align.
        let start = if size != 0 {
            unsafe { heap::allocate(size, mem::align_of::<usize>()) }
        } else {
            heap::EMPTY as *mut u8
        };

        if start.is_null() {
            // do result-based error management instead?
            panic!("Out of memory!");
        }

        ScopedAllocator {
            current: Cell::new(start),
            end: unsafe { start.offset(size as isize) },
            start: start,
        }
    }

    /// Calls the supplied function with a new scope of the allocator.
    ///
    /// # Safety
    ///
    /// Any of the member functions of ScopedAllocator will panic if called
    /// on the outer allocator inside the scope.
    pub fn scope<F, U>(&self, f: F) -> U where F: FnMut(&ScopedAllocator) -> U {
        self.ensure_not_scoped();
        let mut f = f;
        let old = self.current.get();
        let alloc = ScopedAllocator {
            current: self.current.clone(),
            end: self.end,
            start: self.start,
        };

        // set the current pointer to null as a flag to indicate
        // that this allocator is being scoped.
        self.current.set(ptr::null_mut());
        let u = f(&alloc);
        self.current.set(old);

        mem::forget(alloc);
        u
    }

    fn ensure_not_scoped(&self) {
        debug_assert!(
            !self.current.get().is_null(),
            "Called method on currently scoped allocator"
        );
    }
}

impl Allocator for ScopedAllocator {

    /// Attempts to allocate some bytes directly.
    /// Returns either a pointer to the start of the allocated block or nothing.
    ///
    /// # Panics
    ///
    /// Panics if this is called on a currently scoped allocator.
    unsafe fn allocate_raw(&self, size: usize, align: usize) -> Result<*mut u8, ()> {
        self.ensure_not_scoped();
        let current_ptr = self.current.get();
        let aligned_ptr = ((current_ptr as usize + align - 1) & !(align - 1)) as *mut u8;
        let end_ptr = aligned_ptr.offset(size as isize);

        if end_ptr > self.end {
            Err(())
        } else {
            self.current.set(end_ptr);
            Ok(aligned_ptr)
        }
    }

    #[allow(unused_variables)]
    unsafe fn deallocate_raw(&self, ptr: *mut u8, size: usize, align: usize) {
        self.ensure_not_scoped();
        // no op for this. The memory gets reused when the scope is cleared.
    }
}

impl Drop for ScopedAllocator {
    /// Drops the `ScopedAllocator`
    fn drop(&mut self) {
        let size = self.end as usize - self.start as usize;
        // if the allocator is scoped, the memory will be freed by the child.
        if !self.current.get().is_null() && size > 0 {
            unsafe { heap::deallocate(self.start, size, mem::align_of::<usize>()) }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::any::Any;

    use super::*;

    #[test]
    #[should_panic]
    fn use_outer() {
        let alloc = ScopedAllocator::new(4);
        alloc.scope(|_inner| {
            // using outer allocator is dangerous and should fail.
            let _val = alloc.allocate(1i32).ok().unwrap();
        })
    }

    #[test]
    fn test_unsizing() {
        struct Bomb;
        impl Drop for Bomb {
            fn drop(&mut self) { println!("Boom") }
        }

        let alloc = ScopedAllocator::new(4);
        let my_foo: Allocated<Any, _> = alloc.allocate(Bomb).ok().unwrap();
        let _: Allocated<Bomb, _> = my_foo.downcast().ok().unwrap();
    }
}<commit_msg>Implemented Allocator trait for Heap and Scoped.<commit_after>//! A scoped linear allocator.
//! This is useful for reusing a block of memory for temporary allocations within
//! a tight inner loop. Multiple nested scopes can be used if desired.
//!
//! # Examples
//! ```rust
//! use scoped_allocator::{Allocator, ScopedAllocator};
//! struct Bomb(u8);
//! impl Drop for Bomb {
//!     fn drop(&mut self) {
//!         println!("Boom! {}", self.0);
//!     }
//! }
//! // new allocator with a kilobyte of memory.
//! let alloc = ScopedAllocator::new(1024);
//!
//! alloc.scope(|inner| {
//!     let mut bombs = Vec::new();
//!     for i in 0..100 { bombs.push(inner.allocate(Bomb(i)).ok().unwrap())}
//!     // watch the bombs go off!
//! });
//!
//! let my_int = alloc.allocate(23).ok().unwrap();
//! println!("My int: {}", *my_int);
//! ```

#![feature(
    alloc,
    coerce_unsized,
    core_intrinsics,
    heap_api,
    raw,
    unsize
)]

use std::any::Any;
use std::borrow::{Borrow, BorrowMut};
use std::cell::Cell;
use std::intrinsics::drop_in_place;
use std::marker::Unsize;
use std::mem;
use std::ops::{CoerceUnsized, Deref, DerefMut};
use std::raw::TraitObject;
use std::ptr;

use alloc::heap;

extern crate alloc;

/// A custom memory allocator.
pub trait Allocator {
    /// Attempts to allocate space for the T supplied to it.
    fn allocate<'a, T>(&'a self, val: T) -> Result<Allocated<'a, T, Self>, T> where Self: Sized {
        let (size, align) = (mem::size_of::<T>(), mem::align_of::<T>());
        match unsafe { self.allocate_raw(size, align) } {
            Ok(ptr) => {
                let item = ptr as *mut T;
                unsafe { ptr::write(item, val) };
                Ok(Allocated {
                    item: item,
                    allocator: self,
                    size: size,
                    align: align
                })
            }
            Err(_) => Err(val)
        }
    }

    /// Attempt to allocate a block of memory.
    ///
    /// # Safety
    /// Never use the pointer outside of the lifetime of the allocator.
    /// It must be deallocated with the same allocator as it was allocated with.
    /// It is undefined behavior to provide a non power-of-two align.
    unsafe fn allocate_raw(&self, size: usize, align: usize) -> Result<*mut u8, ()>;

    /// Deallocate the memory referred to by this pointer.
    ///
    /// # Safety
    /// This pointer must have been allocated by this allocator.
    /// The size and align must be the same as when they were allocated.
    /// Do not deallocate the same pointer twice. Behavior is implementation-defined,
    /// but usually it will not behave as expected.
    unsafe fn deallocate_raw(&self, ptr: *mut u8, size: usize, align: usize);
}

/// Allocator stub that just forwards to heap allocation.
pub struct HeapAllocator;

// A constant so allocators can use the heap as a root.
const HEAP: &'static HeapAllocator = &HeapAllocator;

impl Allocator for HeapAllocator {
    unsafe fn allocate_raw(&self, size: usize, align: usize) -> Result<*mut u8, ()> {
        let ptr = if size != 0 {
            heap::allocate(size, align)
        } else {
            heap::EMPTY as *mut u8
        };

        if ptr.is_null() {
            Err(())
        } else {
            Ok(ptr)
        }
    }

    unsafe fn deallocate_raw(&self, ptr: *mut u8, size: usize, align: usize) {
        heap::deallocate(ptr, size, align)
    }
}

/// An item allocated by a custom allocator.
pub struct Allocated<'a, T: 'a + ?Sized, A: 'a + Allocator> {
    item: *mut T,
    allocator: &'a A,
    size: usize,
    align: usize,
}

impl<'a, T: ?Sized, A: Allocator> Deref for Allocated<'a, T, A> {
    type Target = T;

    fn deref<'b>(&'b self) -> &'b T {
        unsafe { mem::transmute(self.item) }
    }
}

impl<'a, T: ?Sized, A: Allocator> DerefMut for Allocated<'a, T, A> {
    fn deref_mut<'b>(&'b mut self) -> &'b mut T {
        unsafe { mem::transmute(self.item) }
    }
}

// Allocated can store trait objects!
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Allocated<'a, U, A>> for Allocated<'a, T, A> {}

impl<'a, A: Allocator> Allocated<'a, Any, A> {
    /// Attempts to downcast this `Allocated` to a concrete type.
    pub fn downcast<T: Any>(self) -> Result<Allocated<'a, T, A>, Allocated<'a, Any, A>> {
        if self.is::<T>() {
            let obj: TraitObject = unsafe { mem::transmute(self.item as *mut Any) };
            let new_allocated = Allocated {
                item: unsafe { mem::transmute(obj.data) },
                allocator: self.allocator,
                size: self.size,
                align: self.align
            };
            mem::forget(self);
            Ok(new_allocated)
        } else {
            Err(self)
        }
    }
}

impl<'a, T: ?Sized, A: Allocator> Borrow<T> for Allocated<'a, T, A> {
    fn borrow(&self) -> &T { &**self }
}

impl<'a, T: ?Sized, A: Allocator> BorrowMut<T> for Allocated<'a, T, A> {
    fn borrow_mut(&mut self) -> &mut T { &mut **self }
}

impl<'a, T: ?Sized, A: Allocator> Drop for Allocated<'a, T, A> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            drop_in_place(self.item);
            self.allocator.deallocate_raw(self.item as *mut u8, self.size, self.align);
        }

    }
}

/// A scoped linear allocator
pub struct ScopedAllocator<'parent, A: 'parent + Allocator> {
    allocator: &'parent A,
    current: Cell<*mut u8>,
    end: *mut u8,
    root: bool,
    start: *mut u8,
}

impl ScopedAllocator<'static, HeapAllocator> {
    /// Creates a new `ScopedAllocator` backed by `size` bytes from the heap.
    pub fn new(size: usize) -> Self {
        ScopedAllocator::new_from(HEAP, size)
    }
}
impl<'parent, A: Allocator> ScopedAllocator<'parent, A> {
    /// Creates a new `ScopedAllocator` backed by `size` bytes from the allocator supplied.
    pub fn new_from(alloc: &'parent A, size: usize) -> Self {
        // Create a memory buffer with the desired size and maximal align from the parent.
        let start = if size != 0 {
            unsafe {
                alloc.allocate_raw(size, mem::align_of::<usize>())
                .unwrap_or(ptr::null_mut())
            }
        } else {
            heap::EMPTY as *mut u8
        };

        if start.is_null() {
            // do result-based error management instead?
            panic!("Out of memory!");
        }

        ScopedAllocator {
            allocator: alloc,
            current: Cell::new(start),
            end: unsafe { start.offset(size as isize) },
            root: true,
            start: start,
        }
    }

    /// Calls the supplied function with a new scope of the allocator.
    ///
    /// # Safety
    ///
    /// Any of the member functions of ScopedAllocator will panic if called
    /// on the outer allocator inside the scope.
    pub fn scope<F, U>(&self, f: F) -> U where F: FnMut(&Self) -> U {
        self.ensure_not_scoped();
        let mut f = f;
        let old = self.current.get();
        let alloc = ScopedAllocator {
            allocator: self.allocator,
            current: self.current.clone(),
            end: self.end,
            root: false,
            start: self.start,
        };

        // set the current pointer to null as a flag to indicate
        // that this allocator is being scoped.
        self.current.set(ptr::null_mut());
        let u = f(&alloc);
        self.current.set(old);

        mem::forget(alloc);
        u
    }

    // Whether this allocator is currently scoped.
    pub fn is_scoped(&self) -> bool {
        self.current.get().is_null()
    }

    fn ensure_not_scoped(&self) {
        debug_assert!(
            !self.is_scoped(),
            "Called method on currently scoped allocator"
        );
    }
}

impl<'a, A: Allocator> Allocator for ScopedAllocator<'a, A> {

    /// Attempts to allocate some bytes directly.
    /// Returns either a pointer to the start of the allocated block or nothing.
    ///
    /// # Panics
    ///
    /// Panics if this is called on a currently scoped allocator.
    unsafe fn allocate_raw(&self, size: usize, align: usize) -> Result<*mut u8, ()> {
        debug_assert!(
            !self.is_scoped(),
            "Called method on currently scoped allocator"
        );
        let current_ptr = self.current.get();
        let aligned_ptr = ((current_ptr as usize + align - 1) & !(align - 1)) as *mut u8;
        let end_ptr = aligned_ptr.offset(size as isize);

        if end_ptr > self.end {
            Err(())
        } else {
            self.current.set(end_ptr);
            Ok(aligned_ptr)
        }
    }

    #[allow(unused_variables)]
    unsafe fn deallocate_raw(&self, ptr: *mut u8, size: usize, align: usize) {
        // no op for this. The memory gets reused when the scope is cleared.
    }
}

impl<'a, A: Allocator> Drop for ScopedAllocator<'a, A> {
    /// Drops the `ScopedAllocator`
    fn drop(&mut self) {
        let size = self.end as usize - self.start as usize;
        // only free if this allocator is the root to make sure
        // that memory is freed after destructors for allocated objects
        // are called in case of unwind
        if self.root && size > 0 {
            unsafe { self.allocator.deallocate_raw(self.start, size, mem::align_of::<usize>()) }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::any::Any;

    use super::*;

    #[test]
    #[should_panic]
    fn use_outer() {
        let alloc = ScopedAllocator::new(4);
        let mut outer_val = alloc.allocate(0i32).ok().unwrap();
        alloc.scope(|_inner| {
            // using outer allocator is dangerous and should fail.
            outer_val = alloc.allocate(1i32).ok().unwrap();
        })
    }

    #[test]
    fn unsizing() {
        struct Bomb;
        impl Drop for Bomb {
            fn drop(&mut self) { println!("Boom") }
        }

        let alloc = ScopedAllocator::new(4);
        let my_foo: Allocated<Any, _> = alloc.allocate(Bomb).ok().unwrap();
        let _: Allocated<Bomb, _> = my_foo.downcast().ok().unwrap();
    }

    #[test]
    fn scope_scope() {
        let alloc = ScopedAllocator::new(64);
        let _ = alloc.allocate(0).ok().unwrap();
        alloc.scope(|inner| {
            let _ = inner.allocate(32);
            inner.scope(|bottom| {
                let _ = bottom.allocate(23);
            })
        });
    }
}<|endoftext|>


<commit_before>//! Documentation for the `suffix` crate.

#![crate_name = "suffix"]
#![doc(html_root_url = "http://burntsushi.net/rustdoc/suffix")]
#![experimental]

#![allow(dead_code, unused_imports, unused_variables)]
#![allow(unstable)]

#[macro_use] extern crate log;
#[cfg(test)] extern crate quickcheck;
extern crate stopwatch;
extern crate stats;

use std::collections::btree_map::{self, BTreeMap};
use std::collections::RingBuf;
use std::fmt;
use std::iter::{self, AdditiveIterator};
use std::mem;
use std::ptr;

pub use array::naive as array_naive;
pub use array::{naive_table, sais_table};
pub use array2::sais_table as sais_table2;
pub use array2::sais as sais2;
pub use array3::sais_table as sais_table3;
pub use array4::sais_table as sais_table4;

#[derive(Eq, PartialEq)]
pub struct SuffixArray<'s> {
    text: &'s str,
    table: Vec<u32>,
    inverse: Vec<u32>,
    lcp_lens: Vec<u32>,
}

impl<'s> SuffixArray<'s> {
    pub fn len(&self) -> u32 {
        self.text.len() as u32
    }

    pub fn to_suffix_tree(&'s self) -> SuffixTree<'s> {
        to_suffix_tree::to_suffix_tree(self)
    }

    pub fn suffix(&self, i: u32) -> &str {
        &self.text[self.table[i as usize] as usize..]
    }

    pub fn lcp(&self, i: u32) -> &str {
        let i = i as usize;
        let sufi = self.table[i] as usize;
        &self.text[sufi..sufi + (self.lcp_lens[i] as usize)]
    }
}

impl<'s> fmt::Debug for SuffixArray<'s> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(writeln!(f, "\n-----------------------------------------"));
        try!(writeln!(f, "SUFFIX ARRAY"));
        try!(writeln!(f, "text: {}", self.text));
        for (rank, &sufstart) in self.table.iter().enumerate() {
            try!(writeln!(f, "suffix[{}] {}, {}",
                          rank, sufstart, self.suffix(rank as u32)));
        }
        for (sufstart, &rank) in self.inverse.iter().enumerate() {
            try!(writeln!(f, "inverse[{}] {}, {}",
                          sufstart, rank, self.suffix(rank as u32)));
        }
        for (i, &len) in self.lcp_lens.iter().enumerate() {
            try!(writeln!(f, "lcp_length[{}] {}", i, len));
        }
        writeln!(f, "-----------------------------------------")
    }
}

pub struct SuffixTree<'s> {
    text: &'s str,
    root: Box<Node>,
}

struct Node {
    parent: Rawlink<Node>,
    children: BTreeMap<char, Box<Node>>,
    suffixes: Vec<u32>,
    start: u32,
    end: u32,
    path_len: u32,
}

struct Rawlink<T> {
    p: *mut T,
}

impl<T> Copy for Rawlink<T> {}

impl<'s> SuffixTree<'s> {
    fn init(s: &'s str) -> SuffixTree<'s> {
        SuffixTree {
            text: s,
            root: Node::leaf(0, 0, 0),
        }
    }

    fn root(&self) -> &Node {
        &*self.root
    }

    fn label(&self, node: &Node) -> &'s str {
        &self.text[node.start as usize .. node.end as usize]
    }

    fn suffix(&self, node: &Node) -> &'s str {
        assert!(node.suffixes.len() > 0);
        &self.text[node.suffixes[0] as usize..]
    }

    fn key(&self, node: &Node) -> char {
        self.label(node).char_at(0)
    }
}

impl Node {
    fn leaf(sufstart: u32, start: u32, end: u32) -> Box<Node> {
        Box::new(Node {
            parent: Rawlink::none(),
            children: BTreeMap::new(),
            suffixes: vec![sufstart],
            start: start,
            end: end,
            path_len: 0,
        })
    }

    fn internal(start: u32, end: u32) -> Box<Node> {
        Box::new(Node {
            parent: Rawlink::none(),
            children: BTreeMap::new(),
            suffixes: vec![],
            start: start,
            end: end,
            path_len: 0,
        })
    }

    fn len(&self) -> u32 {
        self.end - self.start
    }

    fn parent(&self) -> Option<&Node> {
        self.parent.resolve()
    }

    fn parent_mut(&mut self) -> Option<&mut Node> {
        self.parent.resolve_mut()
    }

    fn children<'t>(&'t self) -> Children<'t> {
        Children { it: self.children.values() }
    }

    fn ancestors<'t>(&'t self) -> Ancestors<'t> {
        Ancestors { cur: Some(self) }
    }

    fn preorder<'t>(&'t self) -> Preorder<'t> {
        Preorder::new(self)
    }

    fn leaves<'t>(&'t self) -> Leaves<'t> {
        Leaves { it: self.preorder() }
    }

    fn suffix_indices<'t>(&'t self) -> SuffixIndices<'t> {
        SuffixIndices { it: self.leaves(), node: None, cur_suffix: 0 }
    }

    fn has_terminals(&self) -> bool {
        self.suffixes.len() > 0
    }

    fn is_root(&self) -> bool {
        self.parent.resolve().is_none()
    }

    fn add_parent(&mut self, node: &mut Node) {
        self.parent = Rawlink::some(node);
        self.path_len = node.path_len + self.len();
    }

    fn depth(&self) -> usize {
        self.ancestors().count() - 1
    }
}

/// Rawlink is a type like Option<T> but for holding a raw mutable pointer.
impl<T> Rawlink<T> {
    /// Like `Option::None` for Rawlink.
    fn none() -> Rawlink<T> {
        Rawlink{p: ptr::null_mut()}
    }

    /// Like `Option::Some` for Rawlink
    fn some(n: &mut T) -> Rawlink<T> {
        Rawlink{p: n}
    }

    /// Convert the `Rawlink` into an immutable Option value.
    fn resolve<'a>(&self) -> Option<&'a T> {
        unsafe { self.p.as_ref() }
    }

    /// Convert the `Rawlink` into a mutable Option value.
    fn resolve_mut<'a>(&mut self) -> Option<&'a mut T> {
        unsafe { self.p.as_mut() }
    }

    /// Return the `Rawlink` and replace with `Rawlink::none()`.
    fn take(&mut self) -> Rawlink<T> {
        mem::replace(self, Rawlink::none())
    }
}

impl<'s> fmt::Debug for SuffixTree<'s> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fn fmt<'s>(f: &mut fmt::Formatter, st: &SuffixTree<'s>,
                   node: &Node, depth: usize) -> fmt::Result {
            let indent: String = iter::repeat(' ').take(depth * 2).collect();
            if node.is_root() {
                try!(writeln!(f, "ROOT"));
            } else {
                try!(writeln!(f, "{}{}", indent, st.label(node)));
            }
            for child in node.children() {
                try!(fmt(f, st, child, depth + 1));
            }
            Ok(())
        }
        try!(writeln!(f, "\n-----------------------------------------"));
        try!(writeln!(f, "SUFFIX TREE"));
        try!(writeln!(f, "text: {}", self.text));
        try!(fmt(f, self, self.root(), 0));
        writeln!(f, "-----------------------------------------")
    }
}

impl fmt::Debug for Node {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Node {{ start: {}, end: {}, len(children): {}, \
                           terminals: {}, parent? {} }}",
               self.start, self.end, self.children.len(), self.suffixes.len(),
               self.parent().map(|_| "yes").unwrap_or("no"))
    }
}

struct Ancestors<'t> {
    cur: Option<&'t Node>,
}

impl<'t> Iterator for Ancestors<'t> {
    type Item = &'t Node;

    fn next(&mut self) -> Option<&'t Node> {
        if let Some(node) = self.cur {
            self.cur = node.parent();
            Some(node)
        } else {
            None
        }
    }
}

struct Children<'t> {
    it: btree_map::Values<'t, char, Box<Node>>,
}

impl<'t> Iterator for Children<'t> {
    type Item = &'t Node;

    fn next(&mut self) -> Option<&'t Node> {
        self.it.next().map(|n| &**n)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.it.size_hint()
    }
}

impl<'t> DoubleEndedIterator for Children<'t> {
    fn next_back(&mut self) -> Option<&'t Node> {
        self.it.next_back().map(|n| &**n)
    }
}

impl<'t> ExactSizeIterator for Children<'t> {}

struct Preorder<'t> {
    stack: Vec<&'t Node>,
}

impl<'t> Preorder<'t> {
    fn new(start: &'t Node) -> Preorder<'t> {
        Preorder { stack: vec![start] }
    }
}

impl<'t> Iterator for Preorder<'t> {
    type Item = &'t Node;

    fn next(&mut self) -> Option<&'t Node> {
        match self.stack.pop() {
            None => None,
            Some(node) => {
                self.stack.extend(node.children().rev());
                Some(node)
            }
        }
    }
}

struct Leaves<'t> {
    it: Preorder<'t>,
}

impl<'t> Iterator for Leaves<'t> {
    type Item = &'t Node;

    fn next(&mut self) -> Option<&'t Node> {
        for n in self.it {
            if n.has_terminals() {
                return Some(n);
            }
        }
        None
    }
}

struct SuffixIndices<'t> {
    it: Leaves<'t>,
    node: Option<&'t Node>,
    cur_suffix: u32,
}

impl<'t> Iterator for SuffixIndices<'t> {
    type Item = u32;

    fn next(&mut self) -> Option<u32> {
        if let Some(node) = self.node {
            if (self.cur_suffix as usize) < node.suffixes.len() {
                self.cur_suffix += 1;
                return Some(node.suffixes[self.cur_suffix as usize - 1]);
            }
            self.node = None;
            self.cur_suffix = 0;
        }
        match self.it.next() {
            None => None,
            Some(leaf) => { self.node = Some(leaf); self.next() }
        }
    }
}

mod array;
mod array2;
mod array3;
mod array4;
mod to_suffix_tree;
<commit_msg>Remove experiments.<commit_after>//! Documentation for the `suffix` crate.

#![crate_name = "suffix"]
#![doc(html_root_url = "http://burntsushi.net/rustdoc/suffix")]
#![experimental]

#![allow(dead_code, unused_imports, unused_variables)]
#![allow(unstable)]

#[macro_use] extern crate log;
#[cfg(test)] extern crate quickcheck;
extern crate stopwatch;
extern crate stats;

use std::collections::btree_map::{self, BTreeMap};
use std::collections::RingBuf;
use std::fmt;
use std::iter::{self, AdditiveIterator};
use std::mem;
use std::ptr;

pub use array::naive as array_naive;
pub use array::{naive_table, sais_table};
pub use array2::sais_table as sais_table2;
pub use array2::sais as sais2;

#[derive(Eq, PartialEq)]
pub struct SuffixArray<'s> {
    text: &'s str,
    table: Vec<u32>,
    inverse: Vec<u32>,
    lcp_lens: Vec<u32>,
}

impl<'s> SuffixArray<'s> {
    pub fn len(&self) -> u32 {
        self.text.len() as u32
    }

    pub fn to_suffix_tree(&'s self) -> SuffixTree<'s> {
        to_suffix_tree::to_suffix_tree(self)
    }

    pub fn suffix(&self, i: u32) -> &str {
        &self.text[self.table[i as usize] as usize..]
    }

    pub fn lcp(&self, i: u32) -> &str {
        let i = i as usize;
        let sufi = self.table[i] as usize;
        &self.text[sufi..sufi + (self.lcp_lens[i] as usize)]
    }
}

impl<'s> fmt::Debug for SuffixArray<'s> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(writeln!(f, "\n-----------------------------------------"));
        try!(writeln!(f, "SUFFIX ARRAY"));
        try!(writeln!(f, "text: {}", self.text));
        for (rank, &sufstart) in self.table.iter().enumerate() {
            try!(writeln!(f, "suffix[{}] {}, {}",
                          rank, sufstart, self.suffix(rank as u32)));
        }
        for (sufstart, &rank) in self.inverse.iter().enumerate() {
            try!(writeln!(f, "inverse[{}] {}, {}",
                          sufstart, rank, self.suffix(rank as u32)));
        }
        for (i, &len) in self.lcp_lens.iter().enumerate() {
            try!(writeln!(f, "lcp_length[{}] {}", i, len));
        }
        writeln!(f, "-----------------------------------------")
    }
}

pub struct SuffixTree<'s> {
    text: &'s str,
    root: Box<Node>,
}

struct Node {
    parent: Rawlink<Node>,
    children: BTreeMap<char, Box<Node>>,
    suffixes: Vec<u32>,
    start: u32,
    end: u32,
    path_len: u32,
}

struct Rawlink<T> {
    p: *mut T,
}

impl<T> Copy for Rawlink<T> {}

impl<'s> SuffixTree<'s> {
    fn init(s: &'s str) -> SuffixTree<'s> {
        SuffixTree {
            text: s,
            root: Node::leaf(0, 0, 0),
        }
    }

    fn root(&self) -> &Node {
        &*self.root
    }

    fn label(&self, node: &Node) -> &'s str {
        &self.text[node.start as usize .. node.end as usize]
    }

    fn suffix(&self, node: &Node) -> &'s str {
        assert!(node.suffixes.len() > 0);
        &self.text[node.suffixes[0] as usize..]
    }

    fn key(&self, node: &Node) -> char {
        self.label(node).char_at(0)
    }
}

impl Node {
    fn leaf(sufstart: u32, start: u32, end: u32) -> Box<Node> {
        Box::new(Node {
            parent: Rawlink::none(),
            children: BTreeMap::new(),
            suffixes: vec![sufstart],
            start: start,
            end: end,
            path_len: 0,
        })
    }

    fn internal(start: u32, end: u32) -> Box<Node> {
        Box::new(Node {
            parent: Rawlink::none(),
            children: BTreeMap::new(),
            suffixes: vec![],
            start: start,
            end: end,
            path_len: 0,
        })
    }

    fn len(&self) -> u32 {
        self.end - self.start
    }

    fn parent(&self) -> Option<&Node> {
        self.parent.resolve()
    }

    fn parent_mut(&mut self) -> Option<&mut Node> {
        self.parent.resolve_mut()
    }

    fn children<'t>(&'t self) -> Children<'t> {
        Children { it: self.children.values() }
    }

    fn ancestors<'t>(&'t self) -> Ancestors<'t> {
        Ancestors { cur: Some(self) }
    }

    fn preorder<'t>(&'t self) -> Preorder<'t> {
        Preorder::new(self)
    }

    fn leaves<'t>(&'t self) -> Leaves<'t> {
        Leaves { it: self.preorder() }
    }

    fn suffix_indices<'t>(&'t self) -> SuffixIndices<'t> {
        SuffixIndices { it: self.leaves(), node: None, cur_suffix: 0 }
    }

    fn has_terminals(&self) -> bool {
        self.suffixes.len() > 0
    }

    fn is_root(&self) -> bool {
        self.parent.resolve().is_none()
    }

    fn add_parent(&mut self, node: &mut Node) {
        self.parent = Rawlink::some(node);
        self.path_len = node.path_len + self.len();
    }

    fn depth(&self) -> usize {
        self.ancestors().count() - 1
    }
}

/// Rawlink is a type like Option<T> but for holding a raw mutable pointer.
impl<T> Rawlink<T> {
    /// Like `Option::None` for Rawlink.
    fn none() -> Rawlink<T> {
        Rawlink{p: ptr::null_mut()}
    }

    /// Like `Option::Some` for Rawlink
    fn some(n: &mut T) -> Rawlink<T> {
        Rawlink{p: n}
    }

    /// Convert the `Rawlink` into an immutable Option value.
    fn resolve<'a>(&self) -> Option<&'a T> {
        unsafe { self.p.as_ref() }
    }

    /// Convert the `Rawlink` into a mutable Option value.
    fn resolve_mut<'a>(&mut self) -> Option<&'a mut T> {
        unsafe { self.p.as_mut() }
    }

    /// Return the `Rawlink` and replace with `Rawlink::none()`.
    fn take(&mut self) -> Rawlink<T> {
        mem::replace(self, Rawlink::none())
    }
}

impl<'s> fmt::Debug for SuffixTree<'s> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fn fmt<'s>(f: &mut fmt::Formatter, st: &SuffixTree<'s>,
                   node: &Node, depth: usize) -> fmt::Result {
            let indent: String = iter::repeat(' ').take(depth * 2).collect();
            if node.is_root() {
                try!(writeln!(f, "ROOT"));
            } else {
                try!(writeln!(f, "{}{}", indent, st.label(node)));
            }
            for child in node.children() {
                try!(fmt(f, st, child, depth + 1));
            }
            Ok(())
        }
        try!(writeln!(f, "\n-----------------------------------------"));
        try!(writeln!(f, "SUFFIX TREE"));
        try!(writeln!(f, "text: {}", self.text));
        try!(fmt(f, self, self.root(), 0));
        writeln!(f, "-----------------------------------------")
    }
}

impl fmt::Debug for Node {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Node {{ start: {}, end: {}, len(children): {}, \
                           terminals: {}, parent? {} }}",
               self.start, self.end, self.children.len(), self.suffixes.len(),
               self.parent().map(|_| "yes").unwrap_or("no"))
    }
}

struct Ancestors<'t> {
    cur: Option<&'t Node>,
}

impl<'t> Iterator for Ancestors<'t> {
    type Item = &'t Node;

    fn next(&mut self) -> Option<&'t Node> {
        if let Some(node) = self.cur {
            self.cur = node.parent();
            Some(node)
        } else {
            None
        }
    }
}

struct Children<'t> {
    it: btree_map::Values<'t, char, Box<Node>>,
}

impl<'t> Iterator for Children<'t> {
    type Item = &'t Node;

    fn next(&mut self) -> Option<&'t Node> {
        self.it.next().map(|n| &**n)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.it.size_hint()
    }
}

impl<'t> DoubleEndedIterator for Children<'t> {
    fn next_back(&mut self) -> Option<&'t Node> {
        self.it.next_back().map(|n| &**n)
    }
}

impl<'t> ExactSizeIterator for Children<'t> {}

struct Preorder<'t> {
    stack: Vec<&'t Node>,
}

impl<'t> Preorder<'t> {
    fn new(start: &'t Node) -> Preorder<'t> {
        Preorder { stack: vec![start] }
    }
}

impl<'t> Iterator for Preorder<'t> {
    type Item = &'t Node;

    fn next(&mut self) -> Option<&'t Node> {
        match self.stack.pop() {
            None => None,
            Some(node) => {
                self.stack.extend(node.children().rev());
                Some(node)
            }
        }
    }
}

struct Leaves<'t> {
    it: Preorder<'t>,
}

impl<'t> Iterator for Leaves<'t> {
    type Item = &'t Node;

    fn next(&mut self) -> Option<&'t Node> {
        for n in self.it {
            if n.has_terminals() {
                return Some(n);
            }
        }
        None
    }
}

struct SuffixIndices<'t> {
    it: Leaves<'t>,
    node: Option<&'t Node>,
    cur_suffix: u32,
}

impl<'t> Iterator for SuffixIndices<'t> {
    type Item = u32;

    fn next(&mut self) -> Option<u32> {
        if let Some(node) = self.node {
            if (self.cur_suffix as usize) < node.suffixes.len() {
                self.cur_suffix += 1;
                return Some(node.suffixes[self.cur_suffix as usize - 1]);
            }
            self.node = None;
            self.cur_suffix = 0;
        }
        match self.it.next() {
            None => None,
            Some(leaf) => { self.node = Some(leaf); self.next() }
        }
    }
}

mod array;
mod array2;
mod to_suffix_tree;
<|endoftext|>


<commit_before>//! Ethereum devp2p protocol implementation

#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
#![allow(
    unreachable_code,
    clippy::cast_possible_truncation,
    clippy::default_trait_access,
    clippy::filter_map,
    clippy::if_not_else,
    clippy::missing_errors_doc,
    clippy::module_name_repetitions,
    clippy::too_many_arguments,
    clippy::too_many_lines,
    clippy::used_underscore_binding,
    clippy::wildcard_imports
)]

pub mod ecies;
mod errors;
mod eth;
mod mac;
mod mux;
mod node_filter;
mod peer;
mod rlpx;
mod types;
mod util;

pub use eth::{proto as eth_proto, Server as EthServer};
pub use mux::MuxServer;
pub use peer::PeerStream;
pub use rlpx::Server as RLPxNode;
pub use types::{CapabilityInfo, CapabilityName, Discovery, NodeRecord};
<commit_msg>Expand documentation<commit_after>//! Ethereum devp2p protocol implementation
//!
//! It is layered in the following way:
//! * `RLPxNode` which represents the whole pool of connected peers. It handles message routing and peer management.
//! * `MuxServer` which provides a request-response API to otherwise stateless P2P protocol.
//! * `EthIngressServer` which `MuxServer` calls into when new requests and gossip messages arrive.
//! * `MuxServer` itself implements `EthProtocol` which is a simple gateway to abstract Ethereum network.

#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
#![allow(
    unreachable_code,
    clippy::cast_possible_truncation,
    clippy::default_trait_access,
    clippy::filter_map,
    clippy::if_not_else,
    clippy::missing_errors_doc,
    clippy::module_name_repetitions,
    clippy::too_many_arguments,
    clippy::too_many_lines,
    clippy::used_underscore_binding,
    clippy::wildcard_imports
)]

pub mod ecies;
mod errors;
mod eth;
mod mac;
mod mux;
mod node_filter;
mod peer;
mod rlpx;
mod types;
mod util;

pub use eth::{proto as eth_proto, Server as EthServer};
pub use mux::MuxServer;
pub use peer::PeerStream;
pub use rlpx::Server as RLPxNode;
pub use types::{CapabilityInfo, CapabilityName, Discovery, NodeRecord};
<|endoftext|>


<commit_before>//! Demoscene framework.
//!
//! # Foreword
//!
//! This framework is intented to be used to build up [demos](https://en.wikipedia.org/wiki/Demoscene)
//! as a primary purpose. Everything was designed to quickly write demoscene effects and edit them
//! into an audiovisual executable. However, because a lot was added – especially for debugging
//! purposes, it *should* be possible to use this framework for other purposes as well – among
//! *simulations*, *animations* and *video games*.
//!
//! # Design
//!
//! This framework was designed to be *simple* and *flexible*. Following that path, it’s not
//! impossible that some of its features get moved out of the framework to become a set of
//! dependencies – so that people who don’t want those features can just preclude them from the
//! compilation chain.
//!
//! Up to now, the framework provides you with several modules:
//!
//! - **audio**: this module gives you the ability to play a soundtrack (no streaming implemented
//!   yet though; the whole soundtrack is loaded into memory) and interact with basic yet useful
//!   information about playback (play, pause, toggle, track length, track cursor, etc.)
//! - **bootstrapping**: this module abstracts over the underlying technologies and provides several
//!   simple types that can be used to interact with the demo, such as initialization, default
//!   event handling, and so on
//! - **camera**: provides some camera features for both release and debugging purposes
//! - **color**: color types
//! - **edit**: everything you need to edit your demo – it provides types and functions to reason
//!   about timelines, tracks, cuts and clips, hence easing the overall making of a demo
//! - **gui**: this module provides some GUI code that you can use to build nice debugging
//!   interfaces – up to now, it’s not designed for release code, but it might be at some time
//! - **linear**: linear algebra
//! - **model**: this module provides all the code required to abstract other meshes and add them
//!   the concept of *materials*
//! - **object**: linked to **models**, this module adds the concept of *space properties* to
//!   *models* – so that you can actually have them in your scenes
//! - **overlay**: this module provides 2D primitives and rendering functions
//! - **projection**: projection trait and functions
//! - **shader**: provides
//! - **extra**: some extra (but not mandatory) other modules

#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(conservative_impl_trait)]
#![feature(const_fn)]
#![feature(macro_reexport)]
#![feature(slice_patterns)]

extern crate alto;
extern crate any_cache;
extern crate cgmath;
extern crate chrono;
#[macro_reexport(crate_authors, crate_name, crate_version)]
extern crate clap;
extern crate image;
#[macro_reexport(gtup, uniform_interface)]
pub extern crate luminance;
extern crate luminance_glfw;
extern crate glsl;
#[macro_use]
extern crate nom;
extern crate num_traits;
//extern crate rusttype; // FIXME: uncomment when we support text render back
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate vorbis;
extern crate wavefront_obj;
extern crate warmy;

#[macro_use]
pub mod report;
#[macro_use]
pub mod sys;

pub mod audio;
//pub mod gui;
pub mod linear;
//pub mod overlay;
//pub mod text;

pub mod anim;
pub mod render;
pub mod scene;
<commit_msg>Re-export luminance’s stuff.<commit_after>//! Demoscene framework.
//!
//! # Foreword
//!
//! This framework is intented to be used to build up [demos](https://en.wikipedia.org/wiki/Demoscene)
//! as a primary purpose. Everything was designed to quickly write demoscene effects and edit them
//! into an audiovisual executable. However, because a lot was added – especially for debugging
//! purposes, it *should* be possible to use this framework for other purposes as well – among
//! *simulations*, *animations* and *video games*.
//!
//! # Design
//!
//! This framework was designed to be *simple* and *flexible*. Following that path, it’s not
//! impossible that some of its features get moved out of the framework to become a set of
//! dependencies – so that people who don’t want those features can just preclude them from the
//! compilation chain.
//!
//! Up to now, the framework provides you with several modules:
//!
//! - **audio**: this module gives you the ability to play a soundtrack (no streaming implemented
//!   yet though; the whole soundtrack is loaded into memory) and interact with basic yet useful
//!   information about playback (play, pause, toggle, track length, track cursor, etc.)
//! - **bootstrapping**: this module abstracts over the underlying technologies and provides several
//!   simple types that can be used to interact with the demo, such as initialization, default
//!   event handling, and so on
//! - **camera**: provides some camera features for both release and debugging purposes
//! - **color**: color types
//! - **edit**: everything you need to edit your demo – it provides types and functions to reason
//!   about timelines, tracks, cuts and clips, hence easing the overall making of a demo
//! - **gui**: this module provides some GUI code that you can use to build nice debugging
//!   interfaces – up to now, it’s not designed for release code, but it might be at some time
//! - **linear**: linear algebra
//! - **model**: this module provides all the code required to abstract other meshes and add them
//!   the concept of *materials*
//! - **object**: linked to **models**, this module adds the concept of *space properties* to
//!   *models* – so that you can actually have them in your scenes
//! - **overlay**: this module provides 2D primitives and rendering functions
//! - **projection**: projection trait and functions
//! - **shader**: provides
//! - **extra**: some extra (but not mandatory) other modules

#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(conservative_impl_trait)]
#![feature(const_fn)]
#![feature(macro_reexport)]
#![feature(slice_patterns)]

extern crate alto;
extern crate any_cache;
extern crate cgmath;
extern crate chrono;
#[macro_reexport(crate_authors, crate_name, crate_version)]
extern crate clap;
extern crate image;
#[macro_reexport(gtup, uniform_interface, uniform_interface_build_struct, uniform_interface,
                 uniform_interface_impl_trait, uniform_interface_impl_trait_map)]
pub extern crate luminance;
extern crate luminance_glfw;
extern crate glsl;
#[macro_use]
extern crate nom;
extern crate num_traits;
//extern crate rusttype; // FIXME: uncomment when we support text render back
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate vorbis;
extern crate wavefront_obj;
extern crate warmy;

#[macro_use]
pub mod report;
#[macro_use]
pub mod sys;

pub mod audio;
//pub mod gui;
pub mod linear;
//pub mod overlay;
//pub mod text;

pub mod anim;
pub mod render;
pub mod scene;
<|endoftext|>