<commit_before>#![allow(unused_variables)]
extern crate rand;
extern crate bytes;
extern crate byteorder;
extern crate futures;
extern crate tokio_io;
extern crate tokio_core;
extern crate env_logger;
extern crate serde;
extern crate serde_json;
#[macro_use] extern crate serde_derive;

extern crate actix;
extern crate actix_web;

use std::time::Instant;

use actix::*;
use actix_web::*;

mod codec;
mod server;
mod session;

/// This is our websocket route state, this state is shared with all route instances
/// via `HttpContext::state()`
struct WsChatSessionState {
    addr: SyncAddress<server::ChatServer>,
}

/// Entry point for our route
fn chat_route(req: HttpRequest<WsChatSessionState>) -> Result<Reply> {
    ws::start(
        req,
        WsChatSession {
            id: 0,
            hb: Instant::now(),
            room: "Main".to_owned(),
            name: None})
}

struct WsChatSession {
    /// unique session id
    id: usize,
    /// Client must send ping at least once per 10 seconds, otherwise we drop connection.
    hb: Instant,
    /// joined room
    room: String,
    /// peer name
    name: Option<String>,
}

impl Actor for WsChatSession {
    type Context = HttpContext<Self, WsChatSessionState>;
}

/// Handle messages from chat server, we simply send it to peer websocket
impl Handler<session::Message> for WsChatSession {
    fn handle(&mut self, msg: session::Message, ctx: &mut Self::Context)
              -> Response<Self, session::Message>
    {
        ws::WsWriter::text(ctx, &msg.0);
        Self::empty()
    }
}

/// WebSocket message handler
impl Handler<ws::Message> for WsChatSession {
    fn handle(&mut self, msg: ws::Message, ctx: &mut Self::Context)
              -> Response<Self, ws::Message>
    {
        println!("WEBSOCKET MESSAGE: {:?}", msg);
        match msg {
            ws::Message::Ping(msg) =>
                ws::WsWriter::pong(ctx, &msg),
            ws::Message::Pong(msg) =>
                self.hb = Instant::now(),
            ws::Message::Text(text) => {
                let m = text.trim();
                // we check for /sss type of messages
                if m.starts_with('/') {
                    let v: Vec<&str> = m.splitn(2, ' ').collect();
                    match v[0] {
                        "/list" => {
                            // Send ListRooms message to chat server and wait for response
                            println!("List rooms");
                            ctx.state().addr.call(self, server::ListRooms).then(|res, _, ctx| {
                                match res {
                                    Ok(Ok(rooms)) => {
                                        for room in rooms {
                                            ws::WsWriter::text(ctx, &room);
                                        }
                                    },
                                    _ => println!("Something is wrong"),
                                }
                                fut::ok(())
                            }).wait(ctx)
                            // .wait(ctx) pauses all events in context,
                            // so actor wont receive any new messages until it get list
                            // of rooms back
                        },
                        "/join" => {
                            if v.len() == 2 {
                                self.room = v[1].to_owned();
                                ctx.state().addr.send(
                                    server::Join{id: self.id, name: self.room.clone()});

                                ws::WsWriter::text(ctx, "joined");
                            } else {
                                ws::WsWriter::text(ctx, "!!! room name is required");
                            }
                        },
                        "/name" => {
                            if v.len() == 2 {
                                self.name = Some(v[1].to_owned());
                            } else {
                                ws::WsWriter::text(ctx, "!!! name is required");
                            }
                        },
                        _ => ws::WsWriter::text(
                            ctx, &format!("!!! unknown command: {:?}", m)),
                    }
                } else {
                    let msg = if let Some(ref name) = self.name {
                        format!("{}: {}", name, m)
                    } else {
                        m.to_owned()
                    };
                    // send message to chat server
                    ctx.state().addr.send(
                        server::Message{id: self.id,
                                        msg: msg,
                                        room: self.room.clone()})
                }
            },
            ws::Message::Binary(bin) =>
                println!("Unexpected binary"),
            ws::Message::Closed | ws::Message::Error => {
                ctx.stop();
            }
            _ => (),
        }
        Self::empty()
    }
}

impl StreamHandler<ws::Message> for WsChatSession
{
    /// Method is called when stream get polled first time.
    /// We register ws session with ChatServer
    fn started(&mut self, ctx: &mut Self::Context) {
        // register self in chat server. `AsyncContext::wait` register
        // future within context, but context waits until this future resolves
        // before processing any other events.
        // HttpContext::state() is instance of WsChatSessionState, state is shared across all
        // routes within application
        let subs = ctx.sync_subscriber();
        ctx.state().addr.call(
            self, server::Connect{addr: subs}).then(
            |res, act, ctx| {
                match res {
                    Ok(Ok(res)) => act.id = res,
                    // something is wrong with chat server
                    _ => ctx.stop(),
                }
                fut::ok(())
            }).wait(ctx);
    }

    /// Method is called when stream finishes, even if stream finishes with error.
    fn finished(&mut self, ctx: &mut Self::Context) {
        // notify chat server
        ctx.state().addr.send(server::Disconnect{id: self.id});
        ctx.stop()
    }
}

fn main() {
    let _ = env_logger::init();
    let sys = actix::System::new("websocket-example");

    // Start chat server actor in separate thread
    let server: SyncAddress<_> =
        Arbiter::start(|_| server::ChatServer::default());

    // Start tcp server in separate thread
    let srv = server.clone();
    Arbiter::new("tcp-server").send::<msgs::Execute>(
        msgs::Execute::new(move || {
            session::TcpServer::new("127.0.0.1:12345", srv);
            Ok(())
        }));

    // Websocket sessions state
    let state = WsChatSessionState { addr: server };

    // Create Http server with websocket support
    HttpServer::new(
        Application::with_state("/", state)
            // redirect to websocket.html
            .resource("/", |r| r.method(Method::GET).f(|req| {
                httpcodes::HTTPFound
                    .build()
                    .header("LOCATION", "/static/websocket.html")
                    .body(Body::Empty)
            }))
            // websocket
            .resource("/ws/", |r| r.route().f(chat_route))
            // static resources
            .resource("/static", |r| r.h(fs::StaticFiles::new("static/", true))))
        .serve::<_, ()>("127.0.0.1:8080").unwrap();

    let _ = sys.run();
}
<commit_msg>fix example<commit_after>#![allow(unused_variables)]
extern crate rand;
extern crate bytes;
extern crate byteorder;
extern crate futures;
extern crate tokio_io;
extern crate tokio_core;
extern crate env_logger;
extern crate serde;
extern crate serde_json;
#[macro_use] extern crate serde_derive;

extern crate actix;
extern crate actix_web;

use std::time::Instant;

use actix::*;
use actix_web::*;

mod codec;
mod server;
mod session;

/// This is our websocket route state, this state is shared with all route instances
/// via `HttpContext::state()`
struct WsChatSessionState {
    addr: SyncAddress<server::ChatServer>,
}

/// Entry point for our route
fn chat_route(req: HttpRequest<WsChatSessionState>) -> Result<Reply> {
    ws::start(
        req,
        WsChatSession {
            id: 0,
            hb: Instant::now(),
            room: "Main".to_owned(),
            name: None})
}

struct WsChatSession {
    /// unique session id
    id: usize,
    /// Client must send ping at least once per 10 seconds, otherwise we drop connection.
    hb: Instant,
    /// joined room
    room: String,
    /// peer name
    name: Option<String>,
}

impl Actor for WsChatSession {
    type Context = HttpContext<Self, WsChatSessionState>;
}

/// Handle messages from chat server, we simply send it to peer websocket
impl Handler<session::Message> for WsChatSession {
    fn handle(&mut self, msg: session::Message, ctx: &mut Self::Context)
              -> Response<Self, session::Message>
    {
        ws::WsWriter::text(ctx, &msg.0);
        Self::empty()
    }
}

/// WebSocket message handler
impl Handler<ws::Message> for WsChatSession {
    fn handle(&mut self, msg: ws::Message, ctx: &mut Self::Context)
              -> Response<Self, ws::Message>
    {
        println!("WEBSOCKET MESSAGE: {:?}", msg);
        match msg {
            ws::Message::Ping(msg) =>
                ws::WsWriter::pong(ctx, &msg),
            ws::Message::Pong(msg) =>
                self.hb = Instant::now(),
            ws::Message::Text(text) => {
                let m = text.trim();
                // we check for /sss type of messages
                if m.starts_with('/') {
                    let v: Vec<&str> = m.splitn(2, ' ').collect();
                    match v[0] {
                        "/list" => {
                            // Send ListRooms message to chat server and wait for response
                            println!("List rooms");
                            ctx.state().addr.call(self, server::ListRooms).then(|res, _, ctx| {
                                match res {
                                    Ok(Ok(rooms)) => {
                                        for room in rooms {
                                            ws::WsWriter::text(ctx, &room);
                                        }
                                    },
                                    _ => println!("Something is wrong"),
                                }
                                fut::ok(())
                            }).wait(ctx)
                            // .wait(ctx) pauses all events in context,
                            // so actor wont receive any new messages until it get list
                            // of rooms back
                        },
                        "/join" => {
                            if v.len() == 2 {
                                self.room = v[1].to_owned();
                                ctx.state().addr.send(
                                    server::Join{id: self.id, name: self.room.clone()});

                                ws::WsWriter::text(ctx, "joined");
                            } else {
                                ws::WsWriter::text(ctx, "!!! room name is required");
                            }
                        },
                        "/name" => {
                            if v.len() == 2 {
                                self.name = Some(v[1].to_owned());
                            } else {
                                ws::WsWriter::text(ctx, "!!! name is required");
                            }
                        },
                        _ => ws::WsWriter::text(
                            ctx, &format!("!!! unknown command: {:?}", m)),
                    }
                } else {
                    let msg = if let Some(ref name) = self.name {
                        format!("{}: {}", name, m)
                    } else {
                        m.to_owned()
                    };
                    // send message to chat server
                    ctx.state().addr.send(
                        server::Message{id: self.id,
                                        msg: msg,
                                        room: self.room.clone()})
                }
            },
            ws::Message::Binary(bin) =>
                println!("Unexpected binary"),
            ws::Message::Closed | ws::Message::Error => {
                ctx.stop();
            }
            _ => (),
        }
        Self::empty()
    }
}

impl StreamHandler<ws::Message> for WsChatSession
{
    /// Method is called when stream get polled first time.
    /// We register ws session with ChatServer
    fn started(&mut self, ctx: &mut Self::Context) {
        // register self in chat server. `AsyncContext::wait` register
        // future within context, but context waits until this future resolves
        // before processing any other events.
        // HttpContext::state() is instance of WsChatSessionState, state is shared across all
        // routes within application
        let subs = ctx.sync_subscriber();
        ctx.state().addr.call(
            self, server::Connect{addr: subs}).then(
            |res, act, ctx| {
                match res {
                    Ok(Ok(res)) => act.id = res,
                    // something is wrong with chat server
                    _ => ctx.stop(),
                }
                fut::ok(())
            }).wait(ctx);
    }

    /// Method is called when stream finishes, even if stream finishes with error.
    fn finished(&mut self, ctx: &mut Self::Context) {
        // notify chat server
        ctx.state().addr.send(server::Disconnect{id: self.id});
        ctx.stop()
    }
}

fn main() {
    let _ = env_logger::init();
    let sys = actix::System::new("websocket-example");

    // Start chat server actor in separate thread
    let server: SyncAddress<_> =
        Arbiter::start(|_| server::ChatServer::default());

    // Start tcp server in separate thread
    let srv = server.clone();
    Arbiter::new("tcp-server").send::<msgs::Execute>(
        msgs::Execute::new(move || {
            session::TcpServer::new("127.0.0.1:12345", srv);
            Ok(())
        }));

    // Create Http server with websocket support
    HttpServer::new(
        move || {
            // Websocket sessions state
            let state = WsChatSessionState { addr: server.clone() };

            Application::with_state(state)
            // redirect to websocket.html
                .resource("/", |r| r.method(Method::GET).f(|req| {
                    httpcodes::HTTPFound
                        .build()
                        .header("LOCATION", "/static/websocket.html")
                        .body(Body::Empty)
                }))
            // websocket
                .resource("/ws/", |r| r.route().f(chat_route))
            // static resources
                .resource("/static/{tail:.*}",
                          |r| r.h(fs::StaticFiles::new("tail", "static/", true)))
        })
        .serve::<_, ()>("127.0.0.1:8080").unwrap();

    let _ = sys.run();
}
<|endoftext|>


<commit_before>use params::{Params, Value};
use router::Router;
use iron::prelude::*;

use blockchain::{Blockchain, Block};
use crypto::{Hash, HexValue};
use explorer::{TxInfo, BlockInfo, BlockchainExplorer};
use api::{Api, ApiError};

const MAX_BLOCKS_PER_REQUEST: u64 = 1000;

#[derive(Clone)]
pub struct ExplorerApi {
    blockchain: Blockchain,
}

impl ExplorerApi {
    pub fn new(blockchain: Blockchain) -> ExplorerApi {
        ExplorerApi {
            blockchain: blockchain
        }
    }

    fn get_blocks(&self, count: u64, from: Option<u64>, skip_empty_blocks: bool) -> Result<Vec<Block>, ApiError> {
        if count > MAX_BLOCKS_PER_REQUEST {
             return Err(ApiError::IncorrectRequest)
        }
        let explorer = BlockchainExplorer::new(&self.blockchain);
        Ok(explorer.blocks_range(count, from, skip_empty_blocks)?)
    }

    fn get_block(&self, height: u64) -> Result<Option<BlockInfo>, ApiError> {
        let explorer = BlockchainExplorer::new(&self.blockchain);
        match explorer.block_info(height) {
            Ok(block_info) => Ok(block_info),
            Err(e) => Err(ApiError::Storage(e)),
        }
    }

    fn get_transaction(&self, hash_str: &str) -> Result<Option<TxInfo>, ApiError> {
        let explorer = BlockchainExplorer::new(&self.blockchain);
        let hash = Hash::from_hex(hash_str)?;
        match explorer.tx_info(&hash) {
            Ok(tx_info) => Ok(tx_info),
            Err(e) => Err(ApiError::Storage(e)),
        }
    }
}

impl Api for ExplorerApi {
    fn wire(&self, router: &mut Router) {

        let _self = self.clone();
        let blocks = move |req: &mut Request| -> IronResult<Response> {
            let map = req.get_ref::<Params>().unwrap();
            let count: u64;
            let from: Option<u64>;
            let skip_empty_blocks: bool;
            count = match map.find(&["count"]) {
                Some(&Value::String(ref count_str)) => {
                    count_str.parse().map_err(|_| ApiError::IncorrectRequest)?
                }
                _ => {
                    return Err(ApiError::IncorrectRequest)?;
                }
            };
            from = match map.find(&["from"]) {
                Some(&Value::String(ref from_str)) => {
                    Some(from_str.parse().map_err(|_| ApiError::IncorrectRequest)?)
                }
                _ => None,
            };
            skip_empty_blocks = match map.find(&["skip_empty_blocks"]) {
                Some(&Value::String(ref skip_str)) => {
                    skip_str.parse().map_err(|_| ApiError::IncorrectRequest)?
                }
                _ => false,
            };
            let info = _self
                .get_blocks(count, from, skip_empty_blocks)?;
            _self.ok_response(&::serde_json::to_value(info).unwrap())
        };

        let _self = self.clone();
        let block = move |req: &mut Request| -> IronResult<Response> {
            let params = req.extensions.get::<Router>().unwrap();
            match params.find("height") {
                Some(height_str) => {
                    let height: u64 = height_str.parse().map_err(|_| ApiError::IncorrectRequest)?;
                    let info = _self.get_block(height)?;
                    _self.ok_response(&::serde_json::to_value(info).unwrap())
                }
                None => Err(ApiError::IncorrectRequest)?,
            }
        };

        let _self = self.clone();
        let transaction = move |req: &mut Request| -> IronResult<Response> {
            let params = req.extensions.get::<Router>().unwrap();
            match params.find("hash") {
                Some(hash_str) => {
                    let info = _self.get_transaction(hash_str)?;
                    _self.ok_response(&::serde_json::to_value(info).unwrap())
                }
                None => Err(ApiError::IncorrectRequest)?,
            }
        };

        router.get("/v1/blocks", blocks, "blocks");
        router.get("/v1/blocks/:height", block, "height");
        router.get("/v1/transactions/:hash", transaction, "hash");
    }
}
<commit_msg>Minor edit<commit_after>use params::{Params, Value};
use router::Router;
use iron::prelude::*;

use blockchain::{Blockchain, Block};
use crypto::{Hash, HexValue};
use explorer::{TxInfo, BlockInfo, BlockchainExplorer};
use api::{Api, ApiError};

const MAX_BLOCKS_PER_REQUEST: u64 = 1000;

#[derive(Clone)]
pub struct ExplorerApi {
    blockchain: Blockchain,
}

impl ExplorerApi {
    pub fn new(blockchain: Blockchain) -> ExplorerApi {
        ExplorerApi {
            blockchain: blockchain
        }
    }

    fn get_blocks(&self, count: u64, from: Option<u64>, skip_empty_blocks: bool) -> Result<Vec<Block>, ApiError> {
        if count > MAX_BLOCKS_PER_REQUEST {
             return Err(ApiError::IncorrectRequest)
        }
        let explorer = BlockchainExplorer::new(&self.blockchain);
        Ok(explorer.blocks_range(count, from, skip_empty_blocks)?)
    }

    fn get_block(&self, height: u64) -> Result<Option<BlockInfo>, ApiError> {
        let explorer = BlockchainExplorer::new(&self.blockchain);
        match explorer.block_info(height) {
            Ok(block_info) => Ok(block_info),
            Err(e) => Err(ApiError::Storage(e)),
        }
    }

    fn get_transaction(&self, hash_str: &str) -> Result<Option<TxInfo>, ApiError> {
        let explorer = BlockchainExplorer::new(&self.blockchain);
        let hash = Hash::from_hex(hash_str)?;
        match explorer.tx_info(&hash) {
            Ok(tx_info) => Ok(tx_info),
            Err(e) => Err(ApiError::Storage(e)),
        }
    }
}

impl Api for ExplorerApi {
    fn wire(&self, router: &mut Router) {

        let _self = self.clone();
        let blocks = move |req: &mut Request| -> IronResult<Response> {
            let map = req.get_ref::<Params>().unwrap();
            let count: u64 = match map.find(&["count"]) {
                Some(&Value::String(ref count_str)) => {
                    count_str.parse().map_err(|_| ApiError::IncorrectRequest)?
                }
                _ => {
                    return Err(ApiError::IncorrectRequest)?;
                }
            };
            let from: Option<u64> = match map.find(&["from"]) {
                Some(&Value::String(ref from_str)) => {
                    Some(from_str.parse().map_err(|_| ApiError::IncorrectRequest)?)
                }
                _ => None,
            };
            let skip_empty_blocks: bool = match map.find(&["skip_empty_blocks"]) {
                Some(&Value::String(ref skip_str)) => {
                    skip_str.parse().map_err(|_| ApiError::IncorrectRequest)?
                }
                _ => false,
            };
            let info = _self
                .get_blocks(count, from, skip_empty_blocks)?;
            _self.ok_response(&::serde_json::to_value(info).unwrap())
        };

        let _self = self.clone();
        let block = move |req: &mut Request| -> IronResult<Response> {
            let params = req.extensions.get::<Router>().unwrap();
            match params.find("height") {
                Some(height_str) => {
                    let height: u64 = height_str.parse().map_err(|_| ApiError::IncorrectRequest)?;
                    let info = _self.get_block(height)?;
                    _self.ok_response(&::serde_json::to_value(info).unwrap())
                }
                None => Err(ApiError::IncorrectRequest)?,
            }
        };

        let _self = self.clone();
        let transaction = move |req: &mut Request| -> IronResult<Response> {
            let params = req.extensions.get::<Router>().unwrap();
            match params.find("hash") {
                Some(hash_str) => {
                    let info = _self.get_transaction(hash_str)?;
                    _self.ok_response(&::serde_json::to_value(info).unwrap())
                }
                None => Err(ApiError::IncorrectRequest)?,
            }
        };

        router.get("/v1/blocks", blocks, "blocks");
        router.get("/v1/blocks/:height", block, "height");
        router.get("/v1/transactions/:hash", transaction, "hash");
    }
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<commit_msg>chore: Remove repl/src/lib.rs<commit_after><|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::fmt;
use std::rc::Rc;
use std::hash::Hash;
use util::integerisable::Integerisable1;
use integeriser::{HashIntegeriser, Integeriser};

/// upside-down tree with a designated position (the *stack pointer*) and *nodes* of type `a`.
#[derive(Clone)]
pub struct TreeStack<A> {
    parent: Option<(usize, Rc<TreeStack<A>>)>,
    value: A,
    children: Vec<Option<Rc<TreeStack<A>>>>,
}

impl<A> TreeStack<A> {
    /// Creates a new `TreeStack<A>` with root label `a`.
    pub fn new(a: A) -> Self {
        TreeStack { value: a, children: Vec::new(), parent: None }
    }

    /// Applies a function `Fn(&A) -> B`to every node in a `TreeStack<A>`.
    pub fn map<F, B>(&self, f: &mut F) -> TreeStack<B>
        where F: FnMut(&A) -> B,
    {
        let new_value = f(&self.value);
        let new_parent = match self.parent {
            Some((i, ref p)) => Some((i, Rc::new(p.map(f)))),
            None => None,
        };
        let new_children = self.children.iter().map(|o| o.clone().map(|v| Rc::new(v.map(f)))).collect();
        TreeStack { parent: new_parent, value: new_value, children: new_children }
    }

    /// Returns `True` if the stack pointer points to the bottom node.
    pub fn is_at_bottom(&self) -> bool {
        self.parent.is_none()
    }

    /// Returns a reference to label of the current node.
    pub fn current_symbol(&self) -> &A {
        &self.value
    }

    /// Replaces the current value by the given value.
    pub fn set(mut self, a: A) -> Self {
        self.value = a;
        self
    }

    /// Writes a value to the specified child position (if the child position is vacant) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn push(mut self, n: usize, a: A) -> Result<Self, Self> {
        if n >= self.children.len() {
            let len = n - self.children.len() + 1;
            let filler = &mut vec![None; len];
            self.children.append(filler);
        }

        if self.children[n].is_none() {
            Ok(TreeStack { value: a,
                           children: Vec::new(),
                           parent: Some((n, Rc::new(self))) })
        } else {
            Err(self)
        }
    }
}

impl<A: Clone + fmt::Display + fmt::Debug> fmt::Debug for TreeStack<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let (tree, pointer) = self.to_tree();

        for (path, value) in tree.iter() {
            let mut line1 = String::from(" ");
            let mut line2 = String::from(if path.eq(&pointer) {
                "*"
            } else {
                " "
            });

            match path.last() {
                Some(child_num) => {
                    for _ in 0..path.len() - 1 {
                        line1.push_str("| ");
                        line2.push_str("| ");
                    }

                    line1.push_str("|");
                    line2.push_str(&format!("+-{}: {}", child_num, value));
                },
                None => line2.push_str(&value.to_string()),
            }

            write!(f, "{}\n{}\n", line1, line2)?
        }

        Ok(())
    }
}

impl<A: Clone> TreeStack<A> {
    /// Goes up to a specific child position (if this position is occupied) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn up(mut self, n: usize) -> Result<Self, Self> {
        match {
            if self.children.len() > n {
                self.children.push(None);
                self.children.swap_remove(n)
            } else {
                None
            }
        } {
            Some(ref tn) => Ok(TreeStack { value: tn.value.clone(),
                                           children: tn.children.clone(),
                                           parent: Some((n, Rc::new(self))) }),
            _ => Err(self),
        }
    }

    /// Goes down to the parent position (if there is one) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn down(mut self) -> Result<Self, Self> {
        match self.parent.take() {
            Some((n, pn)) => {
                let mut new_pch = pn.children.clone();
                new_pch[n] = Some(Rc::new(self));
                Ok(TreeStack { value: pn.value.clone(),
                               children: new_pch,
                               parent: pn.parent.clone() })
            },
            None => Err(self),
        }
    }

    fn to_tree(&self) -> (BTreeMap<Vec<usize>, A>, Vec<usize>) {
        let mut tree_map = BTreeMap::new();
        let mut curr_path = Vec::new();

        if let Some((num, ref parent)) = self.parent {
            let (parent_map, parent_path) = parent.to_tree();
            curr_path = parent_path;
            curr_path.push(num);

            for (path, value) in parent_map.iter() {
                tree_map.insert(path.clone(), value.clone());
            }
        }

        tree_map.insert(curr_path.clone(), self.value.clone());

        for (num, maybe_child) in self.children.iter().enumerate() {
            if let &Some(ref child) = maybe_child {
                let (mut child_map, _) = child.to_tree();

                for (path, value) in child_map {
                    let mut new_path = curr_path.clone();
                    new_path.append(&mut path.clone());
                    new_path.push(num);
                    tree_map.insert(new_path, value.clone());
                }
            }
        }

        (tree_map, curr_path)
    }
}

impl<A: Clone + Eq + Hash> Integerisable1 for TreeStack<A> {
    type AInt = TreeStack<usize>;
    type I = HashIntegeriser<A>;

    fn integerise(&self, integeriser: &mut Self::I) -> Self::AInt {
        self.map(&mut move |v| integeriser.integerise(v.clone()))
    }

    fn un_integerise(aint: &Self::AInt, integeriser: &Self::I) -> Self {
        aint.map(&mut |&v| integeriser.find_value(v).unwrap().clone())
    }
}

impl<A: PartialEq> PartialEq for TreeStack<A> {
    fn eq(&self, other: &Self) -> bool {
        let comp = |p1, p2| Rc::ptr_eq(p1, p2) || p1 == p2;
        self.value == other.value
            && match (&self.parent, &other.parent) {
                (&Some((i1, ref p1)), &Some((i2, ref p2))) => i1 == i2 && comp(p1, p2),
                (&None, &None)                             => true,
                _                                          => false,
            }
            && self.children == other.children
    }
}

impl<A: Eq> Eq for TreeStack<A> {}

impl<A: PartialOrd> PartialOrd for TreeStack<A> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match self.value.partial_cmp(&other.value) {
            None | Some(Ordering::Equal) =>
                match self.parent.partial_cmp(&other.parent) {
                    None | Some(Ordering::Equal) => self.children.partial_cmp(&other.children),
                    x => x,
                }
            x => x,
        }
    }
}

impl<A: Ord> Ord for TreeStack<A> {
    fn cmp(&self, other: &Self) -> Ordering {
        match self.value.cmp(&other.value) {
            Ordering::Equal =>
                match self.parent.cmp(&other.parent) {
                    Ordering::Equal => self.children.cmp(&other.children),
                    x => x,
                }
            x => x,
        }
    }
}

#[test]
fn test_tree_stack() {
    let mut ts: TreeStack<u8> = TreeStack::new(0);
    assert_eq!(&0, ts.current_symbol());

    ts = ts.push(1, 1).unwrap().clone();
    assert_eq!(&1, ts.current_symbol());

    ts = ts.down().unwrap().clone();
    assert_eq!(&0, ts.current_symbol());

    ts = ts.push(2, 2).unwrap().clone();
    assert_eq!(&2, ts.current_symbol());

    ts = ts.down().unwrap().clone();
    ts = ts.up(1).unwrap().clone();
    assert_eq!(&1, ts.current_symbol());

    let ts1 = ts.clone().push(1, 11);
    let ts2 = ts.push(1, 11);
    assert_eq!(ts1, ts2);
}
<commit_msg>src/tree_stack_automaton/tree_stack.rs: Moved Debug impl to Display<commit_after>use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::fmt;
use std::rc::Rc;
use std::hash::Hash;
use util::integerisable::Integerisable1;
use integeriser::{HashIntegeriser, Integeriser};

/// upside-down tree with a designated position (the *stack pointer*) and *nodes* of type `a`.
#[derive(Clone, Debug)]
pub struct TreeStack<A> {
    parent: Option<(usize, Rc<TreeStack<A>>)>,
    value: A,
    children: Vec<Option<Rc<TreeStack<A>>>>,
}

impl<A> TreeStack<A> {
    /// Creates a new `TreeStack<A>` with root label `a`.
    pub fn new(a: A) -> Self {
        TreeStack { value: a, children: Vec::new(), parent: None }
    }

    /// Applies a function `Fn(&A) -> B`to every node in a `TreeStack<A>`.
    pub fn map<F, B>(&self, f: &mut F) -> TreeStack<B>
        where F: FnMut(&A) -> B,
    {
        let new_value = f(&self.value);
        let new_parent = match self.parent {
            Some((i, ref p)) => Some((i, Rc::new(p.map(f)))),
            None => None,
        };
        let new_children = self.children.iter().map(|o| o.clone().map(|v| Rc::new(v.map(f)))).collect();
        TreeStack { parent: new_parent, value: new_value, children: new_children }
    }

    /// Returns `True` if the stack pointer points to the bottom node.
    pub fn is_at_bottom(&self) -> bool {
        self.parent.is_none()
    }

    /// Returns a reference to label of the current node.
    pub fn current_symbol(&self) -> &A {
        &self.value
    }

    /// Replaces the current value by the given value.
    pub fn set(mut self, a: A) -> Self {
        self.value = a;
        self
    }

    /// Writes a value to the specified child position (if the child position is vacant) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn push(mut self, n: usize, a: A) -> Result<Self, Self> {
        if n >= self.children.len() {
            let len = n - self.children.len() + 1;
            let filler = &mut vec![None; len];
            self.children.append(filler);
        }

        if self.children[n].is_none() {
            Ok(TreeStack { value: a,
                           children: Vec::new(),
                           parent: Some((n, Rc::new(self))) })
        } else {
            Err(self)
        }
    }
}

impl<A: Clone + fmt::Display> fmt::Display for TreeStack<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let (tree, pointer) = self.to_tree();

        for (path, value) in tree.iter() {
            let mut line1 = String::from(" ");
            let mut line2 = String::from(if path.eq(&pointer) {
                "*"
            } else {
                " "
            });

            match path.last() {
                Some(child_num) => {
                    for _ in 0..path.len() - 1 {
                        line1.push_str("| ");
                        line2.push_str("| ");
                    }

                    line1.push_str("|");
                    line2.push_str(&format!("+-{}: {}", child_num, value));
                },
                None => line2.push_str(&value.to_string()),
            }

            write!(f, "{}\n{}\n", line1, line2)?
        }

        Ok(())
    }
}

impl<A: Clone> TreeStack<A> {
    /// Goes up to a specific child position (if this position is occupied) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn up(mut self, n: usize) -> Result<Self, Self> {
        match {
            if self.children.len() > n {
                self.children.push(None);
                self.children.swap_remove(n)
            } else {
                None
            }
        } {
            Some(ref tn) => Ok(TreeStack { value: tn.value.clone(),
                                           children: tn.children.clone(),
                                           parent: Some((n, Rc::new(self))) }),
            _ => Err(self),
        }
    }

    /// Goes down to the parent position (if there is one) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn down(mut self) -> Result<Self, Self> {
        match self.parent.take() {
            Some((n, pn)) => {
                let mut new_pch = pn.children.clone();
                new_pch[n] = Some(Rc::new(self));
                Ok(TreeStack { value: pn.value.clone(),
                               children: new_pch,
                               parent: pn.parent.clone() })
            },
            None => Err(self),
        }
    }

    pub fn to_tree(&self) -> (BTreeMap<Vec<usize>, A>, Vec<usize>) {
        let mut tree_map = BTreeMap::new();
        let mut curr_path = Vec::new();

        if let Some((num, ref parent)) = self.parent {
            let (parent_map, parent_path) = parent.to_tree();
            curr_path = parent_path;
            curr_path.push(num);

            for (path, value) in parent_map.iter() {
                tree_map.insert(path.clone(), value.clone());
            }
        }

        tree_map.insert(curr_path.clone(), self.value.clone());

        for (num, maybe_child) in self.children.iter().enumerate() {
            if let &Some(ref child) = maybe_child {
                let (mut child_map, _) = child.to_tree();

                for (path, value) in child_map {
                    let mut new_path = curr_path.clone();
                    new_path.append(&mut path.clone());
                    new_path.push(num);
                    tree_map.insert(new_path, value.clone());
                }
            }
        }

        (tree_map, curr_path)
    }
}

impl<A: Clone + Eq + Hash> Integerisable1 for TreeStack<A> {
    type AInt = TreeStack<usize>;
    type I = HashIntegeriser<A>;

    fn integerise(&self, integeriser: &mut Self::I) -> Self::AInt {
        self.map(&mut move |v| integeriser.integerise(v.clone()))
    }

    fn un_integerise(aint: &Self::AInt, integeriser: &Self::I) -> Self {
        aint.map(&mut |&v| integeriser.find_value(v).unwrap().clone())
    }
}

impl<A: PartialEq> PartialEq for TreeStack<A> {
    fn eq(&self, other: &Self) -> bool {
        let comp = |p1, p2| Rc::ptr_eq(p1, p2) || p1 == p2;
        self.value == other.value
            && match (&self.parent, &other.parent) {
                (&Some((i1, ref p1)), &Some((i2, ref p2))) => i1 == i2 && comp(p1, p2),
                (&None, &None)                             => true,
                _                                          => false,
            }
            && self.children == other.children
    }
}

impl<A: Eq> Eq for TreeStack<A> {}

impl<A: PartialOrd> PartialOrd for TreeStack<A> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match self.value.partial_cmp(&other.value) {
            None | Some(Ordering::Equal) =>
                match self.parent.partial_cmp(&other.parent) {
                    None | Some(Ordering::Equal) => self.children.partial_cmp(&other.children),
                    x => x,
                }
            x => x,
        }
    }
}

impl<A: Ord> Ord for TreeStack<A> {
    fn cmp(&self, other: &Self) -> Ordering {
        match self.value.cmp(&other.value) {
            Ordering::Equal =>
                match self.parent.cmp(&other.parent) {
                    Ordering::Equal => self.children.cmp(&other.children),
                    x => x,
                }
            x => x,
        }
    }
}

#[test]
fn test_tree_stack() {
    let mut ts: TreeStack<u8> = TreeStack::new(0);
    assert_eq!(&0, ts.current_symbol());

    ts = ts.push(1, 1).unwrap();
    assert_eq!(&1, ts.current_symbol());

    ts = ts.down().unwrap();
    assert_eq!(&0, ts.current_symbol());

    ts = ts.push(2, 2).unwrap();
    assert_eq!(&2, ts.current_symbol());

    ts = ts.down().unwrap();
    ts = ts.up(1).unwrap();
    assert_eq!(&1, ts.current_symbol());

    ts = ts.push(1, 11).unwrap();
    assert_eq!(&11, ts.current_symbol());

    ts = ts.down().unwrap();
    ts = ts.down().unwrap();
    ts = ts.up(2).unwrap();
    ts = ts.push(1, 21).unwrap();
    assert_eq!(&21, ts.current_symbol());

    ts = ts.down().unwrap();
    ts = ts.down().unwrap();

    println!("Display: {}", &ts);
    println!("Debug: {:?}", &ts);
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::rc::Rc;
use std::hash::Hash;
use util::integerisable::Integerisable1;
use integeriser::{HashIntegeriser, Integeriser};

/// upside-down tree with a designated position (the *stack pointer*) and *nodes* of type `a`.
#[derive(Debug, Clone)]
pub struct TreeStack<A> {
    parent: Option<(usize, Rc<TreeStack<A>>)>,
    value: A,
    children: Vec<Option<Rc<TreeStack<A>>>>,
}

impl<A> TreeStack<A> {
    /// Creates a new `TreeStack<A>` with root label `a`.
    pub fn new(a: A) -> Self {
        TreeStack { value: a, children: Vec::new(), parent: None }
    }

    /// Applies a function `Fn(&A) -> B`to every node in a `TreeStack<A>`.
    pub fn map<B>(&self, f: &Fn(&A) -> B) -> TreeStack<B> {
        let new_parent = match self.parent {
            Some((i, ref p)) => Some((i, Rc::new(p.map(f)))),
            None => None,
        };
        let new_children = self.children.iter().map(|o| o.clone().map(|v| Rc::new(v.map(f)))).collect();
        TreeStack { parent: new_parent, value: f(&self.value), children: new_children }
    }

    /// Applies a function `FnMut(&A) -> B`to every node in a `TreeStack<A>`.
    pub fn map_mut<B: Clone>(&self, f: &mut FnMut(&A) -> B) -> TreeStack<B> {
        let new_parent = match self.parent {
            Some((i, ref p)) => Some((i, Rc::new(p.map_mut(f)))),
            None => None,
        };
        let new_children = self.children.iter().map(|o| o.clone().map(|v| Rc::new(v.map_mut(f)))).collect();
        TreeStack { parent: new_parent, value: f(&self.value), children: new_children }
    }

    /// Returns `True` if the stack pointer points to the bottom node.
    pub fn is_at_bottom(&self) -> bool {
        self.parent.is_none()
    }

    /// Returns a reference to label of the current node.
    pub fn current_symbol(&self) -> &A {
        &self.value
    }

    /// Replaces the current value by the given value.
    pub fn set(mut self, a: A) -> Self {
        self.value = a;
        self
    }

    /// Writes a value to the specified child position (if the child position is vacant) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn push(mut self, n: usize, a: A) -> Result<Self, Self> {
        if n >= self.children.len() {
            let len = n - self.children.len() + 1;
            let filler = &mut vec![None; len];
            self.children.append(filler);
        }

        if self.children[n].is_none() {
            Ok(TreeStack { value: a,
                           children: Vec::new(),
                           parent: Some((n, Rc::new(self))) })
        } else {
            Err(self)
        }
    }
}

impl<A: Clone> TreeStack<A> {
    /// Goes up to a specific child position (if this position is occupied) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn up(mut self, n: usize) -> Result<Self, Self> {
        match {
            if self.children.len() > n {
                self.children.push(None);
                self.children.swap_remove(n)
            } else {
                None
            }
        } {
            Some(ref tn) => Ok(TreeStack { value: tn.value.clone(),
                                           children: tn.children.clone(),
                                           parent: Some((n, Rc::new(self))) }),
            _ => Err(self),
        }
    }

    /// Goes down to the parent position (if there is one) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn down(mut self) -> Result<Self, Self> {
        match self.parent.take() {
            Some((n, pn)) => {
                let mut new_pch = pn.children.clone();
                new_pch[n] = Some(Rc::new(self));
                Ok(TreeStack { value: pn.value.clone(),
                               children: new_pch,
                               parent: pn.parent.clone() })
            },
            None => Err(self),
        }
    }
}

impl<A: Clone + Eq + Hash> Integerisable1 for TreeStack<A> {
    type AInt = TreeStack<usize>;
    type I = HashIntegeriser<A>;

    fn integerise(&self, integeriser: &mut Self::I) -> Self::AInt {
        self.map_mut(&mut move |v| integeriser.integerise(v.clone()))
    }

    fn un_integerise(aint: &Self::AInt, integeriser: &Self::I) -> Self {
        aint.map(&|&v| integeriser.find_value(v).unwrap().clone())
    }
}

impl<A: PartialEq> PartialEq for TreeStack<A> {
    fn eq(&self, other: &Self) -> bool {
        let comp = |p1, p2| Rc::ptr_eq(p1, p2) || p1 == p2;
        self.value == other.value
            && match (&self.parent, &other.parent) {
                (&Some((i1, ref p1)), &Some((i2, ref p2))) => i1 == i2 && comp(p1, p2),
                (&None, &None)                             => true,
                _                                          => false,
            }
            && self.children == other.children
    }
}

impl<A: Eq> Eq for TreeStack<A> {}

impl<A: PartialOrd> PartialOrd for TreeStack<A> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match self.value.partial_cmp(&other.value) {
            None | Some(Ordering::Equal) =>
                self.children.partial_cmp(&other.children),
            x => x,
        }
    }
}

impl<A: Ord> Ord for TreeStack<A> {
    fn cmp(&self, other: &Self) -> Ordering {
        match self.value.cmp(&other.value) {
            Ordering::Equal =>
                self.children.cmp(&other.children),
            x => x,
        }
    }
}

#[test]
fn test_tree_stack() {
    let mut ts: TreeStack<u8> = TreeStack::new(0);
    assert_eq!(&0, ts.current_symbol());

    ts = ts.push(1, 1).unwrap().clone();
    assert_eq!(&1, ts.current_symbol());

    ts = ts.down().unwrap().clone();
    assert_eq!(&0, ts.current_symbol());

    ts = ts.push(2, 2).unwrap().clone();
    assert_eq!(&2, ts.current_symbol());

    ts = ts.down().unwrap().clone();
    ts = ts.up(1).unwrap().clone();
    assert_eq!(&1, ts.current_symbol());

    let ts1 = ts.clone().push(1, 11);
    let ts2 = ts.push(1, 11);
    assert_eq!(ts1, ts2);
}
<commit_msg>src/tree_stack_automaton/tree_stack.rs: Ord and PartialOrd now take the parent node into consideration<commit_after>use std::cmp::Ordering;
use std::rc::Rc;
use std::hash::Hash;
use util::integerisable::Integerisable1;
use integeriser::{HashIntegeriser, Integeriser};

/// upside-down tree with a designated position (the *stack pointer*) and *nodes* of type `a`.
#[derive(Debug, Clone)]
pub struct TreeStack<A> {
    parent: Option<(usize, Rc<TreeStack<A>>)>,
    value: A,
    children: Vec<Option<Rc<TreeStack<A>>>>,
}

impl<A> TreeStack<A> {
    /// Creates a new `TreeStack<A>` with root label `a`.
    pub fn new(a: A) -> Self {
        TreeStack { value: a, children: Vec::new(), parent: None }
    }

    /// Applies a function `Fn(&A) -> B`to every node in a `TreeStack<A>`.
    pub fn map<B>(&self, f: &Fn(&A) -> B) -> TreeStack<B> {
        let new_parent = match self.parent {
            Some((i, ref p)) => Some((i, Rc::new(p.map(f)))),
            None => None,
        };
        let new_children = self.children.iter().map(|o| o.clone().map(|v| Rc::new(v.map(f)))).collect();
        TreeStack { parent: new_parent, value: f(&self.value), children: new_children }
    }

    /// Applies a function `FnMut(&A) -> B`to every node in a `TreeStack<A>`.
    pub fn map_mut<B: Clone>(&self, f: &mut FnMut(&A) -> B) -> TreeStack<B> {
        let new_parent = match self.parent {
            Some((i, ref p)) => Some((i, Rc::new(p.map_mut(f)))),
            None => None,
        };
        let new_children = self.children.iter().map(|o| o.clone().map(|v| Rc::new(v.map_mut(f)))).collect();
        TreeStack { parent: new_parent, value: f(&self.value), children: new_children }
    }

    /// Returns `True` if the stack pointer points to the bottom node.
    pub fn is_at_bottom(&self) -> bool {
        self.parent.is_none()
    }

    /// Returns a reference to label of the current node.
    pub fn current_symbol(&self) -> &A {
        &self.value
    }

    /// Replaces the current value by the given value.
    pub fn set(mut self, a: A) -> Self {
        self.value = a;
        self
    }

    /// Writes a value to the specified child position (if the child position is vacant) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn push(mut self, n: usize, a: A) -> Result<Self, Self> {
        if n >= self.children.len() {
            let len = n - self.children.len() + 1;
            let filler = &mut vec![None; len];
            self.children.append(filler);
        }

        if self.children[n].is_none() {
            Ok(TreeStack { value: a,
                           children: Vec::new(),
                           parent: Some((n, Rc::new(self))) })
        } else {
            Err(self)
        }
    }
}

impl<A: Clone> TreeStack<A> {
    /// Goes up to a specific child position (if this position is occupied) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn up(mut self, n: usize) -> Result<Self, Self> {
        match {
            if self.children.len() > n {
                self.children.push(None);
                self.children.swap_remove(n)
            } else {
                None
            }
        } {
            Some(ref tn) => Ok(TreeStack { value: tn.value.clone(),
                                           children: tn.children.clone(),
                                           parent: Some((n, Rc::new(self))) }),
            _ => Err(self),
        }
    }

    /// Goes down to the parent position (if there is one) and returns the resulting `TreeStack` in an `Ok`.
    /// Returns the unmodified `TreeStack` in an `Err` otherwise.
    pub fn down(mut self) -> Result<Self, Self> {
        match self.parent.take() {
            Some((n, pn)) => {
                let mut new_pch = pn.children.clone();
                new_pch[n] = Some(Rc::new(self));
                Ok(TreeStack { value: pn.value.clone(),
                               children: new_pch,
                               parent: pn.parent.clone() })
            },
            None => Err(self),
        }
    }
}

impl<A: Clone + Eq + Hash> Integerisable1 for TreeStack<A> {
    type AInt = TreeStack<usize>;
    type I = HashIntegeriser<A>;

    fn integerise(&self, integeriser: &mut Self::I) -> Self::AInt {
        self.map_mut(&mut move |v| integeriser.integerise(v.clone()))
    }

    fn un_integerise(aint: &Self::AInt, integeriser: &Self::I) -> Self {
        aint.map(&|&v| integeriser.find_value(v).unwrap().clone())
    }
}

impl<A: PartialEq> PartialEq for TreeStack<A> {
    fn eq(&self, other: &Self) -> bool {
        let comp = |p1, p2| Rc::ptr_eq(p1, p2) || p1 == p2;
        self.value == other.value
            && match (&self.parent, &other.parent) {
                (&Some((i1, ref p1)), &Some((i2, ref p2))) => i1 == i2 && comp(p1, p2),
                (&None, &None)                             => true,
                _                                          => false,
            }
            && self.children == other.children
    }
}

impl<A: Eq> Eq for TreeStack<A> {}

impl<A: PartialOrd> PartialOrd for TreeStack<A> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match self.value.partial_cmp(&other.value) {
            None | Some(Ordering::Equal) =>
                match self.parent.partial_cmp(&other.parent) {
                    None | Some(Ordering::Equal) => self.children.partial_cmp(&other.children),
                    x => x,
                }
            x => x,
        }
    }
}

impl<A: Ord> Ord for TreeStack<A> {
    fn cmp(&self, other: &Self) -> Ordering {
        match self.value.cmp(&other.value) {
            Ordering::Equal =>
                match self.parent.cmp(&other.parent) {
                    Ordering::Equal => self.children.cmp(&other.children),
                    x => x,
                }
            x => x,
        }
    }
}

#[test]
fn test_tree_stack() {
    let mut ts: TreeStack<u8> = TreeStack::new(0);
    assert_eq!(&0, ts.current_symbol());

    ts = ts.push(1, 1).unwrap().clone();
    assert_eq!(&1, ts.current_symbol());

    ts = ts.down().unwrap().clone();
    assert_eq!(&0, ts.current_symbol());

    ts = ts.push(2, 2).unwrap().clone();
    assert_eq!(&2, ts.current_symbol());

    ts = ts.down().unwrap().clone();
    ts = ts.up(1).unwrap().clone();
    assert_eq!(&1, ts.current_symbol());

    let ts1 = ts.clone().push(1, 11);
    let ts2 = ts.push(1, 11);
    assert_eq!(ts1, ts2);
}
<|endoftext|>


<commit_before>use std::io::{stderr, Write};

extern crate clap;
use clap::{App, Arg};

fn main() {
    let matches = App::new("qotd")
        .author("Justinas Stankevicius")
        .arg_required_else_help(true)
        .arg(
            Arg::with_name("quote_file").index(1).required(true)
            .help("The file with the quotes to use, one per line.")
        )
        .arg(Arg::with_name("port").short("p").takes_value(true))
        .get_matches();

    // unwrap() should be fine
    // as the existence of the argument is enforced by arg_required_else_help()
    let filename = matches.value_of("quote_file").unwrap();
    let port = matches.value_of("port").unwrap_or("17")
        .parse::<u16>().ok().unwrap_or_else(|| {
            write!(stderr(), "{}", "An invalid port number supplied, defaulting to 17.\n");
            17
        });

    println!("{}", filename);
    println!("{}", port);
}
<commit_msg>[qotd] Parse the quote file<commit_after>use std::fs::File;
use std::io::{BufRead, BufReader, stderr, Write};

extern crate clap;
use clap::{App, Arg};

fn main() {
    let matches = App::new("qotd")
        .author("Justinas Stankevicius")
        .arg_required_else_help(true)
        .arg(
            Arg::with_name("quote_file").index(1).required(true)
            .help("The file with the quotes to use, one per line.")
        )
        .arg(Arg::with_name("port").short("p").takes_value(true))
        .get_matches();

    // unwrap() should be fine
    // as the existence of the argument is enforced by arg_required_else_help()
    let filename = matches.value_of("quote_file").unwrap();
    let port = matches.value_of("port").unwrap_or("17")
        .parse::<u16>().ok().unwrap_or_else(|| {
            write!(stderr(), "{}", "An invalid port number supplied, defaulting to 17.\n");
            17
        });

    let reader = BufReader::new(File::open(filename).ok().expect("Failed to open the quote file."));
    let quotes: Vec<String> = reader.lines().map(|x| x.unwrap()).filter(|x| x.len() != 0).collect();

    println!("{}", filename);
    println!("{}", port);
    println!("{:?}", quotes);
}
<|endoftext|>


<commit_before>use stack::Stack;

mod stack;

fn main() {
    let mut my_stack = Stack::new();
    println!("Current Stack: {}", my_stack.to_string());
    println!("Has Next? {}", my_stack.has_next());

    my_stack = my_stack.push(1);
    println!("Current Stack: {}", my_stack);

    my_stack = my_stack.push(2);
    my_stack = my_stack.push(3);
    println!("Current Stack: {}", my_stack);

    println!("Has Next? {}", my_stack.has_next());

    while my_stack.has_next() {

        let (tail, val) = my_stack.pop();
        println!("Popped: {}", val);

        my_stack = tail;
        println!("Current Stack: {}", my_stack);
    }

    println!("Done!");
}
<commit_msg>Add REPL loop<commit_after>use std::io;

use stack::Stack;

mod stack;

fn main() {
    let mut my_stack = Stack::new();
    loop {
        print!("> ");
        let input = io::stdin().read_line().ok().expect("Failed to read line");
        let trimmed_input = input.trim_right_chars('\n');

        let mut split = trimmed_input.split_str(" ");

        match split.next().unwrap() {
            "q" => break,
            "push" => {
                match split.next() {
                    None => println!("! Provide a value to push !"),
                    Some(i) => {
                        let num = from_str(i);
                        match num {
                            None => println!("! Value must be numeric !"),
                            Some(i) => my_stack = my_stack.push(i)
                        }
                    }
                };
            },
            "pop" => {
                if my_stack.has_next() {
                    let (tail, val) = my_stack.pop();
                    println!("Popped: {}", val);
                    my_stack = tail;
                } else {
                    println!("! Can't pop any more !");
                }
            },
            _ => println!("! What?? (q/pop/push) !")
        };

        println!("Current Stack: {}", my_stack);
    }

    println!("Done!");
}
<|endoftext|>


<commit_before>use ::*;

#[derive(Debug, Serialize)]
struct Ballstats {
    name: String,
    games: i32,
    goals: i32,
    img: String,
}

#[get("/balls")]
fn balls<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("select ball_id, sum(home_score+away_score) as goals, count(ball_id) as balls, (select name from balls where ball_id = balls.id), (select img from balls where ball_id = balls.id) FROM games WHERE dato > date('now','start of month') GROUP BY ball_id order by balls desc , goals desc")
            .unwrap();

    let ballstats: Vec<_> = stmt.query_map(&[], |row| {
        Ballstats {
            name: row.get(3),
            img: row.get(4),
            games: row.get(2),
            goals: row.get(1),
        }
    })
    .unwrap()
    .map(Result::unwrap)
    .collect();
    let mut context = create_context("balls");
    context.add("ballstats", &ballstats);

    respond_page("balls", context)
}

#[get("/ball/<ball>")]
fn ball<'a>(ball:String) -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("SELECT \
            (SELECT name FROM players p WHERE p.id = g.home_id) AS home, \
            (SELECT name FROM players p WHERE p.id = g.away_id) AS away, home_score, away_score, ball_id,  \
            (SELECT img FROM balls b WHERE ball_id = b.id), \
            (SELECT name FROM balls b WHERE ball_id = b.id) AS ballname, \
            dato \
            FROM games g  \
            WHERE ballname = ?1 \
            ORDER BY ID DESC")
            .unwrap();
    let games: Vec<_> = stmt.query_map(&[&ball], |row| {
            PlayedGame {
                home: row.get(0),
                away: row.get(1),
                home_score: row.get(2),
                away_score: row.get(3),
                ball: row.get(5),
                ball_name: row.get(6),
                dato: row.get(7),
            }
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    let mut context = create_context("balls");
         // TODO handle players that don't exist
    if games.len() != 0 {
        println!("Ukendt bold: {}",ball);
    }

    context.add("games", &games);
    context.add("ball", &ball);
    respond_page("ball", context)
}

#[get("/newball")]
fn newball<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt = conn.prepare("SELECT id, name, img from balls ORDER BY name ASC").unwrap();

    let mut balls = Vec::new();

    for ball in stmt.query_map(&[], |row| (row.get::<_, i32>(0), row.get::<_, String>(1), row.get::<_, String>(2))).unwrap() {
        let (id, name, img) = ball.unwrap();
        balls.push(Ball{id: id, name: name, img: img});
    }

    let mut context = create_context("balls");
    context.add("balls", &balls);

    respond_page("newball", context)
}

#[derive(FromForm)]
struct NewBallQuery {
    name: String,
    img: String,
    secret: String,
    #[allow(dead_code)]
    submit: IgnoreField
}

#[post("/newball/submit", data = "<f>")]
fn submit_newball<'r>(f: Form<NewBallQuery>) -> Resp<'r> {
    let NewBallQuery{name, img, secret, ..} = f.into_inner();

    let mut context = create_context("balls");
    if secret != CONFIG.secret {
        context.add("fejl", &"Det indtastede kodeord er forkert 💩");
    } else if name.is_empty() {
        context.add("fejl", &"Den indtastede bold er ikke lovlig 😜");
    } else {
        let n = lock_database().execute("INSERT INTO balls (name, img) VALUES (?, ?)", &[&img, &name]).unwrap();

        if n == 0 {
            context.add("fejl", &"Den indtastede bold eksisterer allerede 💩");
        } else {
            reset_ratings();
            return Resp::red(Redirect::to("/"));
        }
    }
    Resp::cont(respond_page("newball_fejl", context))
}

#[get("/analysis/balls")]
fn ballstats<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("select ball_id, sum(home_score+away_score) as goals, count(ball_id) as balls, (select name from balls where ball_id = balls.id), (select img from balls where ball_id = balls.id) FROM games WHERE dato > date('now','start of month') GROUP BY ball_id order by balls desc , goals desc")
            .unwrap();
    let ballstats: Vec<_> = stmt.query_map(&[], |row| {
        Ballstats {
            name: row.get(3),
            img: row.get(4),
            games: row.get(2),
            goals: row.get(1),
        }
    })
    .unwrap()
    .map(Result::unwrap)
    .collect();

    let mut context = create_context("analysis");

    context.add("ballstats", &ballstats);
    respond_page("ballstats", context)
}
<commit_msg>Added date restraint on games by ball<commit_after>use ::*;

#[derive(Debug, Serialize)]
struct Ballstats {
    name: String,
    games: i32,
    goals: i32,
    img: String,
}

#[get("/balls")]
fn balls<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("select ball_id, sum(home_score+away_score) as goals, count(ball_id) as balls, (select name from balls where ball_id = balls.id), (select img from balls where ball_id = balls.id) FROM games WHERE dato > date('now','start of month') GROUP BY ball_id order by balls desc , goals desc")
            .unwrap();

    let ballstats: Vec<_> = stmt.query_map(&[], |row| {
        Ballstats {
            name: row.get(3),
            img: row.get(4),
            games: row.get(2),
            goals: row.get(1),
        }
    })
    .unwrap()
    .map(Result::unwrap)
    .collect();
    let mut context = create_context("balls");
    context.add("ballstats", &ballstats);

    respond_page("balls", context)
}

#[get("/ball/<ball>")]
fn ball<'a>(ball:String) -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("SELECT \
            (SELECT name FROM players p WHERE p.id = g.home_id) AS home, \
            (SELECT name FROM players p WHERE p.id = g.away_id) AS away, home_score, away_score, ball_id,  \
            (SELECT img FROM balls b WHERE ball_id = b.id), \
            (SELECT name FROM balls b WHERE ball_id = b.id) AS ballname, \
            dato \
            FROM games g  \
            WHERE ballname = ?1 AND dato > date('now','start of month') \
            ORDER BY ID DESC")
            .unwrap();
    let games: Vec<_> = stmt.query_map(&[&ball], |row| {
            PlayedGame {
                home: row.get(0),
                away: row.get(1),
                home_score: row.get(2),
                away_score: row.get(3),
                ball: row.get(5),
                ball_name: row.get(6),
                dato: row.get(7),
            }
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    let mut context = create_context("balls");
    if games.len() != 0 {
        println!("Ukendt bold: {}",ball);
    }

    context.add("games", &games);
    context.add("ball", &ball);
    respond_page("ball", context)
}

#[get("/newball")]
fn newball<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt = conn.prepare("SELECT id, name, img from balls ORDER BY name ASC").unwrap();

    let mut balls = Vec::new();

    for ball in stmt.query_map(&[], |row| (row.get::<_, i32>(0), row.get::<_, String>(1), row.get::<_, String>(2))).unwrap() {
        let (id, name, img) = ball.unwrap();
        balls.push(Ball{id: id, name: name, img: img});
    }

    let mut context = create_context("balls");
    context.add("balls", &balls);

    respond_page("newball", context)
}

#[derive(FromForm)]
struct NewBallQuery {
    name: String,
    img: String,
    secret: String,
    #[allow(dead_code)]
    submit: IgnoreField
}

#[post("/newball/submit", data = "<f>")]
fn submit_newball<'r>(f: Form<NewBallQuery>) -> Resp<'r> {
    let NewBallQuery{name, img, secret, ..} = f.into_inner();

    let mut context = create_context("balls");
    if secret != CONFIG.secret {
        context.add("fejl", &"Det indtastede kodeord er forkert 💩");
    } else if name.is_empty() {
        context.add("fejl", &"Den indtastede bold er ikke lovlig 😜");
    } else {
        let n = lock_database().execute("INSERT INTO balls (name, img) VALUES (?, ?)", &[&img, &name]).unwrap();

        if n == 0 {
            context.add("fejl", &"Den indtastede bold eksisterer allerede 💩");
        } else {
            reset_ratings();
            return Resp::red(Redirect::to("/"));
        }
    }
    Resp::cont(respond_page("newball_fejl", context))
}

#[get("/analysis/balls")]
fn ballstats<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("select ball_id, sum(home_score+away_score) as goals, count(ball_id) as balls, (select name from balls where ball_id = balls.id), (select img from balls where ball_id = balls.id) FROM games WHERE dato > date('now','start of month') GROUP BY ball_id order by balls desc , goals desc")
            .unwrap();
    let ballstats: Vec<_> = stmt.query_map(&[], |row| {
        Ballstats {
            name: row.get(3),
            img: row.get(4),
            games: row.get(2),
            goals: row.get(1),
        }
    })
    .unwrap()
    .map(Result::unwrap)
    .collect();

    let mut context = create_context("analysis");

    context.add("ballstats", &ballstats);
    respond_page("ballstats", context)
}
<|endoftext|>


<commit_before>// - Walk from octagonal to triangular since the higher order values will
//   split the search space more rapidly.
//
// - The search space is fairly small, so a brute-force-ish approach seems
//   like the right way to go.
//
// - We can pre-generate all the numbers and place them in an array of 100
//   entries, ordered by the first two-digits that they occur in. This makes
//   traversal for the next values relatively quick.

/// Return a vector of 6 elements filled with 4-digit values satisfying the
/// required constraint. The first two-digits of these values are found in
/// the index of the cache, with the remaining two the lookup values.
fn cache_new() -> Vec<Vec<Vec<usize>>> {
    let mut v = vec![vec![vec![]; 100]; 3];

    // Compute all 4-digit numbers for each type, largest (octagonal) first
    //fill4(&mut v[0], |n| n*(3*n-2));    // octagonal
    //fill4(&mut v[1], |n| n*(5*n-3)/2);  // heptagonal
    //fill4(&mut v[2], |n| n*(2*n-1));    // hexagonal
    fill4(&mut v[0], |n| n*(3*n-1)/2);  // pentagonal
    fill4(&mut v[1], |n| n*n);          // square
    fill4(&mut v[2], |n| n*(n+1)/2);    // triangle

    v
}

/// Fills the input vector with elements of length 4-digits for the specified
/// function. The function is expected to monotonically increasing.
fn fill4<F: Fn(usize) -> usize>(v: &mut Vec<Vec<usize>>, f: F) {
    for value in (1..).map(|x| f(x)).skip_while(|&x| x < 1000).take_while(|&x| x < 10000) {
        v[value / 100].push(value % 100);
    }
}

/// Walk a filled cache-set and return the first result found
fn cache_walk(v: &Vec<Vec<Vec<usize>>>) -> Vec<usize> {
    let mut rs = Vec::with_capacity(v.len());

    // remember we can walk to any value next time, so must traverse through all
    // traverse forward and back at the same time

    for value in v[0] {
        if v[0].is_empty() {
            continue;
        }
    }

    rs
}

fn main() {
    // We effectively have a tree with which we need to walk through to the
    // first leaf node.
    let v = cache_new();
    //let rs = cache_walk(&v);
}
<commit_msg>Add problem 61 solution<commit_after>extern crate permutohedron;

use permutohedron::LexicalPermutation;

/// Represents a sub-graph of partitioned 4-element fields.
type Group = Vec<Vec<usize>>;

/// `f` is expected to be a monotonically increasing function.
fn make_group<F>(func: F) -> Group
    where F: Fn(usize) -> usize
{
    let mut map = vec![vec![]; 100];
    let result = (1..).map(func)
                     .skip_while(|&x| x < 1000)
                     .take_while(|&x| x < 10000);

    for value in result {
        let (hd, tl) = (value / 100, value % 100);
        map[hd].push(tl)
    }

    map
}

pub struct Walker<'a> {
    /// The order in which we will traverse the groups.
    indices: &'a [usize],

    /// The set of groups for each function.
    groups: &'a [Group],

    /// The initial prefix of the chain
    start: usize
}

impl<'a> Walker<'a> {
    /// Construct a new walker over a set of groups.
    pub fn new(indices: &'a [usize], groups: &'a [Group]) -> Walker<'a> {
        Walker { start: 0, indices, groups }
    }

    /// Walk the set of groups for a single-chain.
    ///
    /// Returns the chain if one was found.
    pub fn walk(&mut self) -> Option<Vec<(usize, usize)>> {
        let length = self.groups[self.indices[0]].len();

        for i in 0..length {
            for ref suffix in &self.groups[self.indices[0]][i] {
                self.start = i;
                match self.walk_chain(**suffix, 1) {
                    Some(mut v) => {
                        v.push((self.start, **suffix));
                        return Some(v)
                    }

                    None => ()
                }
            }
        }

        None
    }

    /// Walk a single direction for the specified prefix.
    fn walk_chain(&self, prefix: usize, depth: usize)
        -> Option<Vec<(usize, usize)>>
    {
        // wraparound and check the complete chain
        if depth >= self.indices.len() {
            if prefix == self.start {
                Some(vec![])
            } else {
                None
            }
        } else {
            for ref suffix in &self.groups[self.indices[depth]][prefix] {
                match self.walk_chain(**suffix, depth + 1) {
                    Some(mut v) => {
                        v.push((prefix, **suffix));
                        return Some(v);
                    }

                    None => ()
                }
            }

            None
        }
    }
}

fn result() -> Vec<(usize, usize)> {
    let groups = [
        make_group(|n| n*(n+1)/2),
        make_group(|n| n*n),
        make_group(|n| n*(3*n-1)/2),
        make_group(|n| n*(2*n-1)),
        make_group(|n| n*(5*n-3)/2),
        make_group(|n| n*(3*n-2))
    ];

    let mut indices: Vec<_> = (0..groups.len()).collect();
    loop {
        {
            let mut walker = Walker::new(&indices, &groups);
            match walker.walk() {
                Some(v) => {
                    return v;
                }

                _ => ()
            }
        }

        if !indices.next_permutation() {
            break;
        }
    }

    unreachable!()
}

fn main() {
    let r = result();
    println!("{}", r.iter().fold(0, |acc, &(hd, tl)| acc + (100 * hd + tl)));
}
<|endoftext|>


<commit_before>extern crate cairo;
extern crate cairo_sys;
extern crate cssparser;
extern crate glib;
extern crate glib_sys;
extern crate libc;

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate downcast_rs;

pub use aspect_ratio::{
    rsvg_aspect_ratio_parse,
    rsvg_aspect_ratio_compute
};

pub use bbox::{
    RsvgBbox,
    rsvg_bbox_init,
    rsvg_bbox_insert,
    rsvg_bbox_clip
};

pub use cnode::{
    rsvg_rust_cnode_new,
    rsvg_rust_cnode_get_impl
};

pub use color::{
    AllowCurrentColor,
    AllowInherit,
    ColorKind,
    ColorSpec,
    rsvg_css_parse_color
};

pub use gradient::{
    rsvg_node_linear_gradient_new,
    rsvg_node_radial_gradient_new,
    gradient_resolve_fallbacks_and_set_pattern
};

pub use length::{
    LengthUnit,
    LengthDir,
    RsvgLength,
    rsvg_length_parse,
    rsvg_length_normalize,
    rsvg_length_hand_normalize,
};

pub use marker::{
    rsvg_node_marker_new,
};

pub use node::{
    rsvg_node_get_type,
    rsvg_node_get_parent,
    rsvg_node_ref,
    rsvg_node_unref,
    rsvg_node_is_same,
    rsvg_node_get_state,
    rsvg_node_add_child,
    rsvg_node_set_atts,
    rsvg_node_draw,
    rsvg_node_set_attribute_parse_error,
    rsvg_node_foreach_child,
    rsvg_node_draw_children,
};

pub use opacity::{
    OpacityKind,
    OpacitySpec,
    rsvg_css_parse_opacity
};

pub use parsers::{
    rsvg_css_parse_number_list,
    rsvg_css_parse_number_optional_number
};

pub use path_builder::{
    rsvg_path_builder_add_to_cairo_context
};

pub use pattern::{
    rsvg_node_pattern_new,
    pattern_resolve_fallbacks_and_set_pattern,
};

pub use shapes::{
    rsvg_node_circle_new,
    rsvg_node_ellipse_new,
    rsvg_node_line_new,
    rsvg_node_path_new,
    rsvg_node_polygon_new,
    rsvg_node_polyline_new,
    rsvg_node_rect_new,
};

pub use stop::{
    rsvg_node_stop_new
};

pub use structure::{
    rsvg_node_group_new,
    rsvg_node_defs_new,
    rsvg_node_switch_new,
    rsvg_node_symbol_new,
    rsvg_node_svg_new,
    rsvg_node_svg_get_size,
    rsvg_node_svg_get_view_box,
    rsvg_node_svg_apply_atts,
    rsvg_node_use_new,
};

pub use transform::{
    rsvg_parse_transform,
};

pub use viewbox::{
    RsvgViewBox
};

mod aspect_ratio;
mod bbox;
mod cnode;
mod color;
mod drawing_ctx;
mod error;
mod handle;
mod gradient;
mod length;
mod marker;
mod node;
mod opacity;
mod paint_server;
mod parsers;
mod parse_transform;
mod path_builder;
mod path_parser;
mod pattern;
mod property_bag;
mod state;
mod stop;
mod shapes;
mod structure;
mod transform;
mod util;
mod viewbox;
<commit_msg>lib.rs: sort the list of modules<commit_after>extern crate cairo;
extern crate cairo_sys;
extern crate cssparser;
extern crate glib;
extern crate glib_sys;
extern crate libc;

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate downcast_rs;

pub use aspect_ratio::{
    rsvg_aspect_ratio_parse,
    rsvg_aspect_ratio_compute
};

pub use bbox::{
    RsvgBbox,
    rsvg_bbox_init,
    rsvg_bbox_insert,
    rsvg_bbox_clip
};

pub use cnode::{
    rsvg_rust_cnode_new,
    rsvg_rust_cnode_get_impl
};

pub use color::{
    AllowCurrentColor,
    AllowInherit,
    ColorKind,
    ColorSpec,
    rsvg_css_parse_color
};

pub use gradient::{
    rsvg_node_linear_gradient_new,
    rsvg_node_radial_gradient_new,
    gradient_resolve_fallbacks_and_set_pattern
};

pub use length::{
    LengthUnit,
    LengthDir,
    RsvgLength,
    rsvg_length_parse,
    rsvg_length_normalize,
    rsvg_length_hand_normalize,
};

pub use marker::{
    rsvg_node_marker_new,
};

pub use node::{
    rsvg_node_get_type,
    rsvg_node_get_parent,
    rsvg_node_ref,
    rsvg_node_unref,
    rsvg_node_is_same,
    rsvg_node_get_state,
    rsvg_node_add_child,
    rsvg_node_set_atts,
    rsvg_node_draw,
    rsvg_node_set_attribute_parse_error,
    rsvg_node_foreach_child,
    rsvg_node_draw_children,
};

pub use opacity::{
    OpacityKind,
    OpacitySpec,
    rsvg_css_parse_opacity
};

pub use parsers::{
    rsvg_css_parse_number_list,
    rsvg_css_parse_number_optional_number
};

pub use path_builder::{
    rsvg_path_builder_add_to_cairo_context
};

pub use pattern::{
    rsvg_node_pattern_new,
    pattern_resolve_fallbacks_and_set_pattern,
};

pub use shapes::{
    rsvg_node_circle_new,
    rsvg_node_ellipse_new,
    rsvg_node_line_new,
    rsvg_node_path_new,
    rsvg_node_polygon_new,
    rsvg_node_polyline_new,
    rsvg_node_rect_new,
};

pub use stop::{
    rsvg_node_stop_new
};

pub use structure::{
    rsvg_node_group_new,
    rsvg_node_defs_new,
    rsvg_node_switch_new,
    rsvg_node_symbol_new,
    rsvg_node_svg_new,
    rsvg_node_svg_get_size,
    rsvg_node_svg_get_view_box,
    rsvg_node_svg_apply_atts,
    rsvg_node_use_new,
};

pub use transform::{
    rsvg_parse_transform,
};

pub use viewbox::{
    RsvgViewBox
};

mod aspect_ratio;
mod bbox;
mod cnode;
mod color;
mod drawing_ctx;
mod error;
mod gradient;
mod handle;
mod length;
mod marker;
mod node;
mod opacity;
mod paint_server;
mod parse_transform;
mod parsers;
mod path_builder;
mod path_parser;
mod pattern;
mod property_bag;
mod shapes;
mod state;
mod stop;
mod structure;
mod transform;
mod util;
mod viewbox;
<|endoftext|>


<commit_before>/* The derby clock state machine. */

use std::time::{Instant, Duration};

#[derive(Clone, Copy, PartialEq)]
pub enum Clocktype {
    Jam,
    Lineup,
    TeamTimeout,
    OtherTimeout,
    Intermission,
}

impl Clocktype {
    pub fn next_state(self) -> Clocktype {
        match self {
            Clocktype::Jam => Clocktype::Lineup,
            Clocktype::Lineup => Clocktype::Jam,
            Clocktype::TeamTimeout => Clocktype::Lineup,
            _ => self,
        }
    }
    pub fn counts_down(self) -> bool {
        match self {
            Clocktype::Jam | Clocktype::Lineup | Clocktype::TeamTimeout
                | Clocktype::Intermission
                => true,
            _ => false,
        }
    }
    pub fn game_clock_runs(self) -> bool {
        match self {
            Clocktype::Jam|Clocktype::Lineup => true,
            _ => false,
        }
    }
}

pub struct Clock {
    gameclock: Duration,
    period: u8,
    clocktype: Clocktype,
    activeclock: Duration,
    lastupdate: Instant,
}

/* tick is called on every tick. Also,
 * every command has an implicit tick. */
impl Clock {
    pub fn new() -> Clock {
        Clock {
            gameclock: Duration::new(30*60, 0),
            period: 0,
            clocktype: Clocktype::Intermission,
            activeclock: Duration::new(0, 0),
            lastupdate: Instant::now(),
        }
    }
    fn clock_start_amt(&self, ty: Clocktype) -> Duration {
        // TODO: use clock policy
        match ty {
            Clocktype::Jam => Duration::new(120, 0),
            Clocktype::Lineup => Duration::new(30, 0),
            Clocktype::TeamTimeout => Duration::new(60, 0),
            Clocktype::Intermission => Duration::new(10 * 60, 0),
            _ => Duration::new(0, 0),
        }
    }

    fn start_clock(&mut self, ty: Clocktype, decrement: Option<Duration>)
                   -> () {
        let mut amt = self.clock_start_amt(ty);
        if let Some(d) = decrement {
            amt -= d;
        }
        self.clocktype = ty;
        self.activeclock = amt;
    }

    // Jam -> Lineup, Lineup -> Jam, TeamTimeout -> Lineup
    pub fn tick(&mut self) -> bool {
        let now = Instant::now();
        let decrement = now - self.lastupdate;
        let oldclocktype = self.clocktype;

        if self.clocktype.counts_down() {
            if self.activeclock > decrement {
                self.activeclock -= decrement;
            } else {
                let rem = decrement - self.activeclock;
                let nextstate = Clocktype::next_state(self.clocktype);
                self.start_clock(nextstate, Some(rem))
            };
        } else {
            self.activeclock += decrement;
        }

        /* Update game clock */
        if self.clocktype.game_clock_runs() {
            if decrement < self.gameclock {
                self.gameclock = self.gameclock - decrement;
            } else {
                self.gameclock = Duration::new(0, 0);
                if let Clocktype::Lineup = self.clocktype {
                    self.start_clock(Clocktype::Intermission, None);
                }
            }
        }

        self.lastupdate = now;
        return self.clocktype != oldclocktype;
    }

    // Valid when clock is any but Jam.
    //  * -> Jam
    pub fn start_jam(&mut self) -> () {
        self.tick();
        if let Clocktype::Intermission = self.clocktype {
            self.period += 1;
            self.gameclock = Duration::new(30 * 60, 0);
        }

        if let Clocktype::Jam = self.clocktype {
            // don't do anything, it's already running.
        } else {
            self.start_clock(Clocktype::Jam, None);
        };
    }

    // {Jam, Lineup, OtherTimeout} -> TeamTimeout
    pub fn team_timeout(&mut self) -> () {
        match self.clocktype {
            Clocktype::Jam | Clocktype::Lineup | Clocktype::OtherTimeout => {
                self.start_clock(Clocktype::TeamTimeout, None);
            },
            // can't start a team timeout
            Clocktype::Intermission | Clocktype::TeamTimeout => (),
        }
    }

    // {Jam, Lineup} -> OtherTimeout
    pub fn other_timeout(&mut self) -> () {
        match self.clocktype {
            Clocktype::Jam | Clocktype::Lineup => {
                self.start_clock(Clocktype::OtherTimeout, None);
            },
            Clocktype::TeamTimeout => { /* convert to an other timeout */ },
            Clocktype::Intermission | Clocktype::OtherTimeout =>  {
                // can't start Other Timeout
            }
        }
    }

    // pub fn end_timeout(&mut self) -> ActiveClock {}
    // Jam -> Lineup
    pub fn stop_jam(&mut self) -> () {
        match self.clocktype {
            Clocktype::Jam => {
                self.start_clock(Clocktype::Lineup, None);
            },
            _ => (), // Jam not running, can't stop.

        }
    }

    pub fn get_time(&self) -> (u8, Duration) {
        (self.period, self.gameclock)
    }
    pub fn set_time(&mut self, time: Duration) {
        self.gameclock = time;
    }

    pub fn get_active_clock(&self) -> (Clocktype, Duration) {
        (self.clocktype, self.activeclock)
    }
}
<commit_msg>Change team timeouts to behave correctly<commit_after>/* The derby clock state machine. */

use std::time::{Instant, Duration};

#[derive(Clone, Copy, PartialEq)]
pub enum Clocktype {
    Jam,
    Lineup,
    TeamTimeout,
    OtherTimeout,
    Intermission,
}

impl Clocktype {
    pub fn next_state(self) -> Clocktype {
        match self {
            Clocktype::Jam => Clocktype::Lineup,
            Clocktype::Lineup => Clocktype::Jam,
            Clocktype::TeamTimeout => Clocktype::OtherTimeout,
            _ => self,
        }
    }
    pub fn counts_down(self) -> bool {
        match self {
            Clocktype::Jam | Clocktype::Lineup | Clocktype::Intermission
                => true,
            _ => false,
        }
    }
    pub fn game_clock_runs(self) -> bool {
        match self {
            Clocktype::Jam|Clocktype::Lineup => true,
            _ => false,
        }
    }
}

pub struct Clock {
    gameclock: Duration,
    period: u8,
    clocktype: Clocktype,
    activeclock: Duration,
    lastupdate: Instant,
}

/* tick is called on every tick. Also,
 * every command has an implicit tick. */
impl Clock {
    pub fn new() -> Clock {
        Clock {
            gameclock: Duration::new(30*60, 0),
            period: 0,
            clocktype: Clocktype::Intermission,
            activeclock: Duration::new(0, 0),
            lastupdate: Instant::now(),
        }
    }
    fn clock_start_amt(&self, ty: Clocktype) -> Duration {
        // TODO: use clock policy
        match ty {
            Clocktype::Jam => Duration::new(120, 0),
            Clocktype::Lineup => Duration::new(30, 0),
            Clocktype::TeamTimeout => Duration::new(60, 0),
            Clocktype::Intermission => Duration::new(10 * 60, 0),
            _ => Duration::new(0, 0),
        }
    }

    fn start_clock(&mut self, ty: Clocktype, decrement: Option<Duration>)
                   -> () {
        let mut amt = self.clock_start_amt(ty);
        if let Some(d) = decrement {
            amt -= d;
        }
        self.clocktype = ty;
        self.activeclock = amt;
    }

    // Jam -> Lineup, Lineup -> Jam, TeamTimeout -> Lineup
    pub fn tick(&mut self) -> bool {
        let now = Instant::now();
        let decrement = now - self.lastupdate;
        let oldclocktype = self.clocktype;

        if self.clocktype.counts_down() {
            if self.activeclock > decrement {
                self.activeclock -= decrement;
            } else {
                let rem = decrement - self.activeclock;
                let nextstate = Clocktype::next_state(self.clocktype);
                self.start_clock(nextstate, Some(rem))
            };
        } else {
            self.activeclock += decrement;
            // TODO: clock policy for timeout length
            if let Clocktype::TeamTimeout = self.clocktype {
                if self.activeclock >= Duration::new(90, 0) {
                    self.start_clock(Clocktype::OtherTimeout, None);
                }
            }
        }

        /* Update game clock */
        if self.clocktype.game_clock_runs() {
            if decrement < self.gameclock {
                self.gameclock = self.gameclock - decrement;
            } else {
                self.gameclock = Duration::new(0, 0);
                if let Clocktype::Lineup = self.clocktype {
                    self.start_clock(Clocktype::Intermission, None);
                }
            }
        }

        self.lastupdate = now;
        return self.clocktype != oldclocktype;
    }

    // Valid when clock is any but Jam.
    //  * -> Jam
    pub fn start_jam(&mut self) -> () {
        self.tick();
        if let Clocktype::Intermission = self.clocktype {
            self.period += 1;
            self.gameclock = Duration::new(30 * 60, 0);
        }

        if let Clocktype::Jam = self.clocktype {
            // don't do anything, it's already running.
        } else {
            self.start_clock(Clocktype::Jam, None);
        };
    }

    // {Jam, Lineup, OtherTimeout} -> TeamTimeout
    pub fn team_timeout(&mut self) -> () {
        match self.clocktype {
            Clocktype::Jam | Clocktype::Lineup | Clocktype::OtherTimeout => {
                self.start_clock(Clocktype::TeamTimeout, None);
            },
            // can't start a team timeout
            Clocktype::Intermission | Clocktype::TeamTimeout => (),
        }
    }

    // {Jam, Lineup} -> OtherTimeout
    pub fn other_timeout(&mut self) -> () {
        match self.clocktype {
            Clocktype::Jam | Clocktype::Lineup => {
                self.start_clock(Clocktype::OtherTimeout, None);
            },
            Clocktype::TeamTimeout => { /* convert to an other timeout */ },
            Clocktype::Intermission | Clocktype::OtherTimeout =>  {
                // can't start Other Timeout
            }
        }
    }

    // pub fn end_timeout(&mut self) -> ActiveClock {}
    // Jam -> Lineup
    pub fn stop_jam(&mut self) -> () {
        match self.clocktype {
            Clocktype::Jam => {
                self.start_clock(Clocktype::Lineup, None);
            },
            _ => (), // Jam not running, can't stop.

        }
    }

    pub fn get_time(&self) -> (u8, Duration) {
        (self.period, self.gameclock)
    }
    pub fn set_time(&mut self, time: Duration) {
        self.gameclock = time;
    }

    pub fn get_active_clock(&self) -> (Clocktype, Duration) {
        (self.clocktype, self.activeclock)
    }
}

#[cfg(test)]
#[test]
fn test_jam_start() {
    let mut clock = Clock::new();
    clock.start_jam();
    // check that jam started
    // sleep 1s
    // check that things are running
    // start jam again, check that nothing happened
}

#[cfg(test)]
#[test]
fn test_jam_end() {
    use std::thread;
    let mut clock = Clock::new();
    clock.start_jam();
    assert!(clock.clocktype == Clocktype::Jam);
    clock.activeclock = Duration::new(0, 500_000_000);
    thread::sleep(Duration::new(1,0));
    clock.tick();
    assert!(clock.clocktype == Clocktype::Lineup);

}

#[cfg(test)]
#[test]
fn test_timeout_expires() {
    use std::thread;
    let mut clock = Clock::new();
    clock.start_jam();
    clock.team_timeout();
    clock.activeclock = Duration::new(89, 500_000_000);
    thread::sleep(Duration::new(1,0));
    clock.tick();
    assert!(clock.clocktype == Clocktype::OtherTimeout);

}
<|endoftext|>