<commit_before>//! Virtualize processor hardware for multiple software environments using Virtual Machine Extensions.

use crate::bits64::rflags::{self, RFlags};
use crate::vmx::{Result, VmFail};

/// Helper used to extract VMX-specific Result in accordance with
/// conventions described in Intel SDM, Volume 3C, Section 30.2.
// We inline this to provide an obstruction-free path from this function's
// call site to the moment where `rflags::read()` reads RFLAGS. Otherwise it's
// possible for RFLAGS register to be clobbered by a function prologue,
// see https://github.com/gz/rust-x86/pull/50.
#[inline(always)]
fn vmx_capture_status() -> Result<()> {
    let flags = unsafe { rflags::read() };

    if flags.contains(RFlags::FLAGS_ZF) {
        Err(VmFail::VmFailValid)
    } else if flags.contains(RFlags::FLAGS_CF) {
        Err(VmFail::VmFailInvalid)
    } else {
        Ok(())
    }
}

/// Enable VMX operation.
///
/// `addr` specifies a 4KB-aligned physical address of VMXON region initialized
/// in accordance with Intel SDM, Volume 3C, Section 24.11.5.
pub unsafe fn vmxon(addr: u64) -> Result<()> {
    asm!("vmxon $0" : /* no outputs */ : "m"(addr));
    vmx_capture_status()
}

/// Disable VMX operation.
pub unsafe fn vmxoff() -> Result<()> {
    asm!("vmxoff");
    vmx_capture_status()
}

/// Clear VMCS.
///
/// Ensures that VMCS data maintained on the processor is copied to the VMCS region
/// located at 4KB-aligned physical address `addr` and initializes some parts of it.
pub unsafe fn vmclear(addr: u64) -> Result<()> {
    asm!("vmclear $0" : /* no outputs */ : "m"(addr));
    vmx_capture_status()
}

/// Load current VMCS pointer.
///
/// Marks the current-VMCS pointer valid and loads it with the physical address `addr`.
pub unsafe fn vmptrld(addr: u64) -> Result<()> {
    asm!("vmptrld $0" : /* no outputs */ : "m"(addr));
    vmx_capture_status()
}

/// Return current VMCS pointer.
pub unsafe fn vmptrst() -> Result<u64> {
    let value: u64 = 0;
    asm!("vmptrst ($0)" : /* no outputs */ : "r"(&value) : "memory");
    vmx_capture_status().and(Ok(value))
}

/// Read a specified field from a VMCS.
pub unsafe fn vmread(field: u32) -> Result<u64> {
    let field: u64 = field.into();
    let value: u64;
    asm!("vmread $1, $0" : "=r"(value) : "r"(field));
    vmx_capture_status().and(Ok(value))
}

/// Write to a specified field in a VMCS.
pub unsafe fn vmwrite(field: u32, value: u64) -> Result<()> {
    let field: u64 = field.into();
    asm!("vmwrite $1, $0" : /* no outputs */ : "r"(field), "r"(value));
    vmx_capture_status()
}

/// Launch virtual machine.
pub unsafe fn vmlaunch() -> Result<()> {
    asm!("vmlaunch");
    vmx_capture_status()
}

/// Resume virtual machine.
pub unsafe fn vmresume() -> Result<()> {
    asm!("vmresume");
    vmx_capture_status()
}
<commit_msg>Inline vmresume() and vmlaunch()<commit_after>//! Virtualize processor hardware for multiple software environments using Virtual Machine Extensions.

use crate::bits64::rflags::{self, RFlags};
use crate::vmx::{Result, VmFail};

/// Helper used to extract VMX-specific Result in accordance with
/// conventions described in Intel SDM, Volume 3C, Section 30.2.
// We inline this to provide an obstruction-free path from this function's
// call site to the moment where `rflags::read()` reads RFLAGS. Otherwise it's
// possible for RFLAGS register to be clobbered by a function prologue,
// see https://github.com/gz/rust-x86/pull/50.
#[inline(always)]
fn vmx_capture_status() -> Result<()> {
    let flags = unsafe { rflags::read() };

    if flags.contains(RFlags::FLAGS_ZF) {
        Err(VmFail::VmFailValid)
    } else if flags.contains(RFlags::FLAGS_CF) {
        Err(VmFail::VmFailInvalid)
    } else {
        Ok(())
    }
}

/// Enable VMX operation.
///
/// `addr` specifies a 4KB-aligned physical address of VMXON region initialized
/// in accordance with Intel SDM, Volume 3C, Section 24.11.5.
pub unsafe fn vmxon(addr: u64) -> Result<()> {
    asm!("vmxon $0" : /* no outputs */ : "m"(addr));
    vmx_capture_status()
}

/// Disable VMX operation.
pub unsafe fn vmxoff() -> Result<()> {
    asm!("vmxoff");
    vmx_capture_status()
}

/// Clear VMCS.
///
/// Ensures that VMCS data maintained on the processor is copied to the VMCS region
/// located at 4KB-aligned physical address `addr` and initializes some parts of it.
pub unsafe fn vmclear(addr: u64) -> Result<()> {
    asm!("vmclear $0" : /* no outputs */ : "m"(addr));
    vmx_capture_status()
}

/// Load current VMCS pointer.
///
/// Marks the current-VMCS pointer valid and loads it with the physical address `addr`.
pub unsafe fn vmptrld(addr: u64) -> Result<()> {
    asm!("vmptrld $0" : /* no outputs */ : "m"(addr));
    vmx_capture_status()
}

/// Return current VMCS pointer.
pub unsafe fn vmptrst() -> Result<u64> {
    let value: u64 = 0;
    asm!("vmptrst ($0)" : /* no outputs */ : "r"(&value) : "memory");
    vmx_capture_status().and(Ok(value))
}

/// Read a specified field from a VMCS.
pub unsafe fn vmread(field: u32) -> Result<u64> {
    let field: u64 = field.into();
    let value: u64;
    asm!("vmread $1, $0" : "=r"(value) : "r"(field));
    vmx_capture_status().and(Ok(value))
}

/// Write to a specified field in a VMCS.
pub unsafe fn vmwrite(field: u32, value: u64) -> Result<()> {
    let field: u64 = field.into();
    asm!("vmwrite $1, $0" : /* no outputs */ : "r"(field), "r"(value));
    vmx_capture_status()
}

/// Launch virtual machine.
#[inline(always)]
pub unsafe fn vmlaunch() -> Result<()> {
    asm!("vmlaunch");
    vmx_capture_status()
}

/// Resume virtual machine.
#[inline(always)]
pub unsafe fn vmresume() -> Result<()> {
    asm!("vmresume");
    vmx_capture_status()
}
<|endoftext|>


<commit_before>pub trait Block {
    fn account_code(&self, address: Address) -> Option<&[u8]>;
    fn coinbase(&self) -> Address;
    fn balance(&self, address: Address) -> Option<U256>;
    fn timestamp(&self) -> U256;
    fn number(&self) -> U256;
    fn difficulty(&self) -> U256;
    fn gas_limit(&self) -> U256;
}

pub struct FakeBlock;

impl Block for FakeBlock {
    fn account_code(address: Address) -> Option<&[u8]> {
        None
    }

    fn coinbase(&self) -> Address {
        Address::default()
    }

    fn timestamp(&self) -> U256 {
        U256::zero()
    }

    fn number(&self) -> U256 {
        U256::zero()
    }

    fn difficulty(&self) -> U256 {
        U256::zero()
    }

    fn gas_limit(&self) -> U256 {
        U256::zero()
    }
}

impl Default for FakeBlock {
    fn default() -> FakeBlock {
        FakeBlock
    }
}

pub trait Blockchain {
    fn blockhash(n: U256) -> H256;
}

pub struct FakeBlockchain;

impl Blockchain for FakeBlockchain {
    fn blockhash(n: U256) -> H256 {
        H256::default()
    }
}

impl Default for FakeBlockchain {
    fn default() -> FakeBlockchain {
        FakeBlockchain
    }
}
<commit_msg>Problem: blockchain does not compile Solution: fix mistakes<commit_after>use utils::u256::U256;
use utils::gas::Gas;
use utils::address::Address;
use utils::hash::H256;

pub trait Block {
    fn account_code(&self, address: Address) -> Option<&[u8]>;
    fn coinbase(&self) -> Address;
    fn balance(&self, address: Address) -> Option<U256>;
    fn timestamp(&self) -> U256;
    fn number(&self) -> U256;
    fn difficulty(&self) -> U256;
    fn gas_limit(&self) -> Gas;
}

pub struct FakeBlock;

impl Block for FakeBlock {
    fn account_code(&self, address: Address) -> Option<&[u8]> {
        None
    }

    fn coinbase(&self) -> Address {
        Address::default()
    }

    fn balance(&self, address: Address) -> Option<U256> {
        None
    }

    fn timestamp(&self) -> U256 {
        U256::zero()
    }

    fn number(&self) -> U256 {
        U256::zero()
    }

    fn difficulty(&self) -> U256 {
        U256::zero()
    }

    fn gas_limit(&self) -> Gas {
        Gas::zero()
    }
}

impl Default for FakeBlock {
    fn default() -> FakeBlock {
        FakeBlock
    }
}

pub trait Blockchain {
    fn blockhash(n: U256) -> H256;
}

pub struct FakeBlockchain;

impl Blockchain for FakeBlockchain {
    fn blockhash(n: U256) -> H256 {
        H256::default()
    }
}

impl Default for FakeBlockchain {
    fn default() -> FakeBlockchain {
        FakeBlockchain
    }
}
<|endoftext|>


<commit_before>use maud::{self, PreEscaped};
use web_server::server::RequestTimer;
use iron::Request;

pub fn search_form(action: &str, placeholder: &str, value: &str, regex: bool) -> PreEscaped<String> {
    html! {
        form action=(action) {
            div class="row" {
                div class="col-md-12" style="margin-top: 20pt" {}
            }
            div class="row" {
                div class="col-md-2" ""
                div class="col-md-8" {
                    div class="input-group custom-search-form" {
                        input class="form-control" type="text" name="search" style="font-size: 18pt; height: 30pt"
                            placeholder=(placeholder) value=(value) {
                            span class="input-group-btn" {
                                button class="btn btn-default" style="height: 30pt" type="submit" {
                                    i class="fa fa-search fa-2x" {}
                                }
                            }
                        }
                    }
                }
                div class="col-md-2" {}
            }
            div class="row" {
                div class="col-md-2" ""
                div class="col-md-8" style="margin-top: 10pt" {
                    strong "Search options:"
                    label class="checkbox-inline" style="margin-left: 10pt" {
                        @if regex {
                            input type="checkbox" name="regex" checked="" {}
                        } @else {
                            input type="checkbox" name="regex" {}
                        }
                        "Regex"
                    }
                }
                div class="col-md-2" ""
            }
            div class="row" {
                div class="col-md-12" style="margin-top: 20pt" {}
            }
        }
    }
}

pub fn notification(n_type: &str, content: PreEscaped<String>) -> PreEscaped<String> {
    let alert_class = format!("alert alert-{}", n_type);
    html! {
        div class=(alert_class) {
            (content)
        }
    }
}

pub fn datatable_ajax(id: &str, url: &str, param: &str,
                      table_header: PreEscaped<String>) -> PreEscaped<String> {
    let table_id = format!("datatable-{}", id);
    html! {
        table id=(table_id) data-url=(url) data-param=(param) width="100%" class="table table-striped table-bordered table-hover" {
            thead { (table_header) }
        }
    }
}

fn html_head(title: &str) -> PreEscaped<String> {
    html! {
        head profile="http://www.w3.org/2005/10/profile" {
            link rel="icon" type="image/png" href="/public/images/webkafka_favicon.png" {}
            meta charset="utf-8" {}
            meta http-equiv="X-UA-Compatible" content="IE=edge" {}
            meta name="viewport" content="width=device-width, initial-scale=1" {}
            title (title)
            link href="/public/sb-admin-2/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet" {}
            link href="/public/sb-admin-2/vendor/metisMenu/metisMenu.min.css" rel="stylesheet" {}
            link href="/public/sb-admin-2/vendor/datatables-plugins/dataTables.bootstrap.css" rel="stylesheet" {}
            // link href="/public/sb-admin-2/vendor/datatables/css/jquery.dataTables.min.css" rel="stylesheet" {}
            // link href="/public/sb-admin-2/vendor/datatables/css/dataTables.jqueryui.min.css" rel="stylesheet" {}
            link href="/public/sb-admin-2/dist/css/sb-admin-2.css" rel="stylesheet" {}
            link href="/public/sb-admin-2/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css" {}
            link href="/public/my_css.css" rel="stylesheet" type="text/css" {}
            script async="" defer="" src="https://buttons.github.io/buttons.js" {}
        }
    }
}

fn navbar_header() -> PreEscaped<String> {
    html! {
        div class="navbar-header" {
            button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse" {
                span class="sr-only" Toggle navigation {}
                span class="icon-bar" {}
                span class="icon-bar" {}
                span class="icon-bar" {}
            }
            a class="navbar-brand" href="/" {
                    img src="/public/images/kafka_logo.png"
                        style="float:left;max-width:160%;max-height:160%; margin-top: -0.06in; margin-right: 0.07in"
                        align="bottom"
                "Kafka-view"
            }
        }
    }
}

fn navbar_top() -> PreEscaped<String> {
    html! {
        ul class="nav navbar-top-links navbar-right" {
            li class="dropdown" {
                a class="dropdown-toggle" data-toggle="dropdown" href="#" {
                    i class="fa fa-question-circle-o fa-fw" {}
                    i class="fa fa-caret-down" {}
                }
                ul class="dropdown-menu dropdown-user" {
                    li { a href="https://github.com/fede1024/kafka-view" {
                        i class="fa fa-github fa-fw" {} "GitHub" }
                    }
                    // li class="divider" {}
                    // li { a href="#" {i class="fa fa-sign-out fa-fw" {} "Logout" } }
                }
            }
        }
    }
}

fn navbar_side() -> PreEscaped<String> {
    html! {
        div class="navbar-default sidebar" role="navigation" {
            div class="sidebar-nav navbar-collapse" {
                ul class="nav" id="side-menu" {
                    li class="sidebar-search" {
                        div class="input-group custom-search-form" {
                            input type="text" class="form-control" placeholder="Omnisearch..."
                            span class="input-group-btn" {
                                button class="btn btn-default" type="button" {
                                    i class="fa fa-search" {}
                                }
                            }
                        }
                    }
                    // li a href="/" { i class="fa fa-dashboard fa-fw" {}  " Home" }
                    //li a href="/" style="font-size: 12pt" { i class="fa fa-info-circle fa-fw" {}  " Home" }
                    li a href="/clusters/" style="font-size: 12pt" { i class="fa fa-server fa-fw" {}  " Clusters" }
                    li a href="/topics/" style="font-size: 12pt" { i class="fa fa-exchange fa-fw" {}  " Topics" }
                    li a href="/consumers/" style="font-size: 12pt" { i class="fa fa-cubes fa-fw" {}  " Consumers" }
                    //li {
                    //    a href="#" {
                    //        i class="fa fa-server fa-fw" {} " Clusters"
                    //        span class="fa arrow" {}
                    //    }
                    //    ul class="nav nav-second-level" {
                    //        @for cluster_id in clusters.iter() {
                    //            li a href=(format_cluster_path(cluster_id)) (cluster_id)
                    //        }
                    //        // li {
                    //        //     a href="#" { "Third Level" span class="fa arrow" {} }
                    //        //     ul class="nav nav-third-level" {
                    //        //         li a href="#" "Third Level Item"
                    //        //         li a href="#" "Third Level Item"
                    //        //         li a href="#" "Third Level Item"
                    //        //         li a href="#" "Third Level Item"
                    //        //     }
                    //        // }
                    //    }
                    //}
                }
            }
        }
    }
}

fn body(page_title: &str, content: PreEscaped<String>) -> PreEscaped<String> {
    html! {
        div id="wrapper" {
            // Navigation
            nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0" {
                (navbar_header())
                (navbar_top())
                (navbar_side())
            }

            div id="page-wrapper" class="flex-container" {
                div class="row" {
                    div class="col-md-12" {
                        h1 class="page-header" (page_title)
                    }
                }
                div class="row flex-body" {
                    div class="col-md-12" {
                        (content)
                    }
                }
                div class="row" {
                    div class="col-md-12" {}
                }
                div class="row flex-footer" style="border-top: 1px solid #eee; margin-top: 0.2in; padding-top: 0.05in"  {
                    div class="col-md-4" style="text-align: center;" {
                        "kafka-view " (option_env!("CARGO_PKG_VERSION").unwrap_or("")) }
                    div class="col-md-4" style="text-align: center;" {
                        "Rust nightly"
                    }
                    div class="col-md-4" style="text-align: center;" {
                        a class="github-button" href="https://github.com/fede1024/kafka-view"
                            data-icon="octicon-star" data-count-href="/fede1024/kafka-view/stargazers"
                            data-count-api="/repos/fede1024/kafka-view#stargazers_count"
                            data-count-aria-label="# stargazers on GitHub" // data-style="mega"
                            aria-label="Star fede1024/kafka-view on GitHub" { "Star" }
                    }
                }
            }
        }

        script src="/public/sb-admin-2/vendor/jquery/jquery.min.js" {}
        script src="/public/sb-admin-2/vendor/bootstrap/js/bootstrap.min.js" {}
        script src="/public/sb-admin-2/vendor/metisMenu/metisMenu.min.js" {}
        script src="/public/sb-admin-2/vendor/datatables/js/jquery.dataTables.min.js" {}
        script src="/public/sb-admin-2/vendor/datatables-plugins/dataTables.bootstrap.min.js" {}
        script src="/public/sb-admin-2/vendor/datatables-responsive/dataTables.responsive.js" {}
        script src="/public/sb-admin-2/dist/js/sb-admin-2.js" {}
        // (PreEscaped("<script async defer src=\"https://buttons.github.io/buttons.js\">"))
        script src="/public/my_js.js" {}
    }
}

pub fn page(req: &Request, page_title: &str, page_content: PreEscaped<String>) -> PreEscaped<String> {
    let request_timer = req.extensions.get::<RequestTimer>();
    let request_id = request_timer.map(|t| t.request_id).unwrap_or(-1);
    html! {
        (maud::DOCTYPE)
        html {
            (html_head(page_title))
            body (body(page_title, page_content))
            span id="request_id" style="display: none" (request_id)
        }
    }
}
<commit_msg>Improve footer<commit_after>use maud::{self, PreEscaped};
use web_server::server::RequestTimer;
use iron::Request;

pub fn search_form(action: &str, placeholder: &str, value: &str, regex: bool) -> PreEscaped<String> {
    html! {
        form action=(action) {
            div class="row" {
                div class="col-md-12" style="margin-top: 20pt" {}
            }
            div class="row" {
                div class="col-md-2" ""
                div class="col-md-8" {
                    div class="input-group custom-search-form" {
                        input class="form-control" type="text" name="search" style="font-size: 18pt; height: 30pt"
                            placeholder=(placeholder) value=(value) {
                            span class="input-group-btn" {
                                button class="btn btn-default" style="height: 30pt" type="submit" {
                                    i class="fa fa-search fa-2x" {}
                                }
                            }
                        }
                    }
                }
                div class="col-md-2" {}
            }
            div class="row" {
                div class="col-md-2" ""
                div class="col-md-8" style="margin-top: 10pt" {
                    strong "Search options:"
                    label class="checkbox-inline" style="margin-left: 10pt" {
                        @if regex {
                            input type="checkbox" name="regex" checked="" {}
                        } @else {
                            input type="checkbox" name="regex" {}
                        }
                        "Regex"
                    }
                }
                div class="col-md-2" ""
            }
            div class="row" {
                div class="col-md-12" style="margin-top: 20pt" {}
            }
        }
    }
}

pub fn notification(n_type: &str, content: PreEscaped<String>) -> PreEscaped<String> {
    let alert_class = format!("alert alert-{}", n_type);
    html! {
        div class=(alert_class) {
            (content)
        }
    }
}

pub fn datatable_ajax(id: &str, url: &str, param: &str,
                      table_header: PreEscaped<String>) -> PreEscaped<String> {
    let table_id = format!("datatable-{}", id);
    html! {
        table id=(table_id) data-url=(url) data-param=(param) width="100%" class="table table-striped table-bordered table-hover" {
            thead { (table_header) }
        }
    }
}

fn html_head(title: &str) -> PreEscaped<String> {
    html! {
        head profile="http://www.w3.org/2005/10/profile" {
            link rel="icon" type="image/png" href="/public/images/webkafka_favicon.png" {}
            meta charset="utf-8" {}
            meta http-equiv="X-UA-Compatible" content="IE=edge" {}
            meta name="viewport" content="width=device-width, initial-scale=1" {}
            title (title)
            link href="/public/sb-admin-2/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet" {}
            link href="/public/sb-admin-2/vendor/metisMenu/metisMenu.min.css" rel="stylesheet" {}
            link href="/public/sb-admin-2/vendor/datatables-plugins/dataTables.bootstrap.css" rel="stylesheet" {}
            // link href="/public/sb-admin-2/vendor/datatables/css/jquery.dataTables.min.css" rel="stylesheet" {}
            // link href="/public/sb-admin-2/vendor/datatables/css/dataTables.jqueryui.min.css" rel="stylesheet" {}
            link href="/public/sb-admin-2/dist/css/sb-admin-2.css" rel="stylesheet" {}
            link href="/public/sb-admin-2/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css" {}
            link href="/public/my_css.css" rel="stylesheet" type="text/css" {}
            script async="" defer="" src="https://buttons.github.io/buttons.js" {}
        }
    }
}

fn navbar_header() -> PreEscaped<String> {
    html! {
        div class="navbar-header" {
            button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse" {
                span class="sr-only" Toggle navigation {}
                span class="icon-bar" {}
                span class="icon-bar" {}
                span class="icon-bar" {}
            }
            a class="navbar-brand" href="/" {
                    img src="/public/images/kafka_logo.png"
                        style="float:left;max-width:160%;max-height:160%; margin-top: -0.06in; margin-right: 0.07in"
                        align="bottom"
                "Kafka-view"
            }
        }
    }
}

fn navbar_top() -> PreEscaped<String> {
    html! {
        ul class="nav navbar-top-links navbar-right" {
            li class="dropdown" {
                a class="dropdown-toggle" data-toggle="dropdown" href="#" {
                    i class="fa fa-question-circle-o fa-fw" {}
                    i class="fa fa-caret-down" {}
                }
                ul class="dropdown-menu dropdown-user" {
                    li { a href="https://github.com/fede1024/kafka-view" {
                        i class="fa fa-github fa-fw" {} "GitHub" }
                    }
                    // li class="divider" {}
                    // li { a href="#" {i class="fa fa-sign-out fa-fw" {} "Logout" } }
                }
            }
        }
    }
}

fn navbar_side() -> PreEscaped<String> {
    html! {
        div class="navbar-default sidebar" role="navigation" {
            div class="sidebar-nav navbar-collapse" {
                ul class="nav" id="side-menu" {
                    li class="sidebar-search" {
                        div class="input-group custom-search-form" {
                            input type="text" class="form-control" placeholder="Omnisearch..."
                            span class="input-group-btn" {
                                button class="btn btn-default" type="button" {
                                    i class="fa fa-search" {}
                                }
                            }
                        }
                    }
                    // li a href="/" { i class="fa fa-dashboard fa-fw" {}  " Home" }
                    //li a href="/" style="font-size: 12pt" { i class="fa fa-info-circle fa-fw" {}  " Home" }
                    li a href="/clusters/" style="font-size: 12pt" { i class="fa fa-server fa-fw" {}  " Clusters" }
                    li a href="/topics/" style="font-size: 12pt" { i class="fa fa-exchange fa-fw" {}  " Topics" }
                    li a href="/consumers/" style="font-size: 12pt" { i class="fa fa-cubes fa-fw" {}  " Consumers" }
                    //li {
                    //    a href="#" {
                    //        i class="fa fa-server fa-fw" {} " Clusters"
                    //        span class="fa arrow" {}
                    //    }
                    //    ul class="nav nav-second-level" {
                    //        @for cluster_id in clusters.iter() {
                    //            li a href=(format_cluster_path(cluster_id)) (cluster_id)
                    //        }
                    //        // li {
                    //        //     a href="#" { "Third Level" span class="fa arrow" {} }
                    //        //     ul class="nav nav-third-level" {
                    //        //         li a href="#" "Third Level Item"
                    //        //         li a href="#" "Third Level Item"
                    //        //         li a href="#" "Third Level Item"
                    //        //         li a href="#" "Third Level Item"
                    //        //     }
                    //        // }
                    //    }
                    //}
                }
            }
        }
    }
}

fn body(page_title: &str, content: PreEscaped<String>) -> PreEscaped<String> {
    html! {
        div id="wrapper" {
            // Navigation
            nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0" {
                (navbar_header())
                (navbar_top())
                (navbar_side())
            }

            div id="page-wrapper" class="flex-container" {
                div class="row" {
                    div class="col-md-12" {
                        h1 class="page-header" (page_title)
                    }
                }
                div class="row flex-body" {
                    div class="col-md-12" {
                        (content)
                    }
                }
                div class="row" {
                    div class="col-md-12" {}
                }
                div class="row flex-footer" style="border-top: 1px solid #eee; margin-top: 0.2in; padding-top: 0.05in"  {
                    div class="col-md-4" style="text-align: center;" {
                        a href="https://github.com/fede1024/kafka-view" {
                            "kafka-view " (option_env!("CARGO_PKG_VERSION").unwrap_or("")) }
                        }
                    div class="col-md-4" style="text-align: center;" {
                        a href="https://www.rust-lang.org" "Rust 1.17.0-nightly"
                    }
                    div class="col-md-4" style="text-align: center;" {
                        a class="github-button" href="https://github.com/fede1024/kafka-view"
                            data-icon="octicon-star" data-count-href="/fede1024/kafka-view/stargazers"
                            data-count-api="/repos/fede1024/kafka-view#stargazers_count"
                            data-count-aria-label="# stargazers on GitHub" // data-style="mega"
                            aria-label="Star fede1024/kafka-view on GitHub" { "Star" }
                    }
                }
            }
        }

        script src="/public/sb-admin-2/vendor/jquery/jquery.min.js" {}
        script src="/public/sb-admin-2/vendor/bootstrap/js/bootstrap.min.js" {}
        script src="/public/sb-admin-2/vendor/metisMenu/metisMenu.min.js" {}
        script src="/public/sb-admin-2/vendor/datatables/js/jquery.dataTables.min.js" {}
        script src="/public/sb-admin-2/vendor/datatables-plugins/dataTables.bootstrap.min.js" {}
        script src="/public/sb-admin-2/vendor/datatables-responsive/dataTables.responsive.js" {}
        script src="/public/sb-admin-2/dist/js/sb-admin-2.js" {}
        // (PreEscaped("<script async defer src=\"https://buttons.github.io/buttons.js\">"))
        script src="/public/my_js.js" {}
    }
}

pub fn page(req: &Request, page_title: &str, page_content: PreEscaped<String>) -> PreEscaped<String> {
    let request_timer = req.extensions.get::<RequestTimer>();
    let request_id = request_timer.map(|t| t.request_id).unwrap_or(-1);
    html! {
        (maud::DOCTYPE)
        html {
            (html_head(page_title))
            body (body(page_title, page_content))
            span id="request_id" style="display: none" (request_id)
        }
    }
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate common;

use common::*;
use common::Projection::*;

use rand::{StdRng, SeedableRng, Rng};

#[cfg(debug_assertions)]
#[no_mangle]
pub fn new_state() -> State {
    println!("debug on");

    let seed: &[_] = &[42];
    let rng: StdRng = SeedableRng::from_seed(seed);

    make_state(rng)
}
#[cfg(not(debug_assertions))]
#[no_mangle]
pub fn new_state() -> State {
    let timestamp = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .map(|dur| dur.as_secs())
        .unwrap_or(42);

    println!("{}", timestamp);
    let seed: &[_] = &[timestamp as usize];
    let rng: StdRng = SeedableRng::from_seed(seed);

    make_state(rng)
}

fn make_state(rng: StdRng) -> State {
    let mut state = State {
        rng,
        polys: Vec::new(),
        cam_x: 0.0,
        cam_y: 0.0,
        zoom: 1.0,
    };

    add_random_poly(&mut state);

    state
}

#[no_mangle]
//returns true if quit requested
pub fn update_and_render(p: &Platform, state: &mut State, events: &mut Vec<Event>) -> bool {
    for event in events {
        println!("{:?}", *event);

        match *event {
            Event::Quit |
            Event::KeyDown(Keycode::Escape) |
            Event::KeyDown(Keycode::F10) => {
                return true;
            }
            Event::KeyDown(Keycode::Space) => {
                add_random_poly(state);
            }
            Event::KeyDown(Keycode::R) => {
                state.polys.clear();
                add_random_poly(state);
            }
            Event::KeyDown(Keycode::V) => {
                (p.set_verts)(get_vert_vecs());
            }
            Event::KeyDown(Keycode::Up) => {
                state.cam_y += 0.0625;
            }
            Event::KeyDown(Keycode::Down) => {
                state.cam_y -= 0.0625;
            }
            Event::KeyDown(Keycode::Right) => {
                state.cam_x += 0.0625;
            }
            Event::KeyDown(Keycode::Left) => {
                state.cam_x -= 0.0625;
            }
            Event::KeyDown(Keycode::Num0) => {
                state.cam_x = 0.0;
                state.cam_y = 0.0;
                state.zoom = 1.0;
            }
            Event::KeyDown(Keycode::W) => {
                state.zoom *= 1.25;
            }
            Event::KeyDown(Keycode::S) => {
                state.zoom /= 1.25;
            }
            _ => {}
        }
    }

    let aspect_ratio = 800.0 / 600.0;
    let near = 0.5;
    let far = 1024.0;

    let scale = state.zoom * near;
    let top = scale;
    let bottom = -top;
    let right = aspect_ratio * scale;
    let left = -right;

    let projection = get_projection(&ProjectionSpec {
        top,
        bottom,
        left,
        right,
        near,
        far,
        projection: Perspective,
        // projection: Orthographic,
    });

    let camera = [
        1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        1.0,
        0.0,
        state.cam_x,
        state.cam_y,
        0.0,
        1.0,
    ];

    let view = mat4x4_mul(&camera, &projection);

    for poly in state.polys.iter() {
        let world_matrix = [
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0,
            0.0,
            poly.x,
            poly.y,
            0.0,
            1.0,
        ];

        let matrix = mat4x4_mul(&world_matrix, &view);

        // (p.draw_poly_with_matrix)(matrix, poly.index);
        (p.draw_textured_poly_with_matrix)(matrix, poly.index, 0);
    }

    false
}

fn add_random_poly(state: &mut State) {
    let poly = Polygon {
        x: state.rng.gen_range(-9.0, 10.0) / 10.0,
        y: state.rng.gen_range(-9.0, 10.0) / 10.0,
        index: state.rng.gen_range(0, 6),
        scale: state.rng.gen_range(0.0, 2.0),
    };

    state.polys.push(poly);
}

//These are the verticies of the polygons which can be drawn.
//The index refers to the index of the inner vector within the outer vecton.
#[cfg_attr(rustfmt, rustfmt_skip)]
#[no_mangle]
pub fn get_vert_vecs() -> Vec<Vec<f32>> {
    vec![
        // star heptagon
        vec![
            -0.012640, 0.255336,
            0.152259, 0.386185,
            0.223982, 0.275978,
            0.191749, 0.169082,
            0.396864, 0.121742,
            0.355419, -0.003047,
            0.251747, -0.044495,
            0.342622, -0.234376,
            0.219218, -0.279777,
            0.122174, -0.224565,
            0.030379, -0.414003,
            -0.082058, -0.345830,
            -0.099398, -0.235534,
            -0.304740, -0.281878,
            -0.321543, -0.151465,
            -0.246122, -0.069141,
            -0.410383, 0.062507,
            -0.318899, 0.156955,
            -0.207511, 0.149317,
            -0.207000, 0.359823,
            -0.076118, 0.347186,
            -0.012640, 0.255336,
        ],
        // heptagon
        vec![
            0.555765, -0.002168,
            0.344819, -0.435866,
            -0.125783, -0.541348,
            -0.501668, -0.239184,
            -0.499786, 0.243091,
            -0.121556, 0.542313,
            0.348209, 0.433163,
            0.555765, -0.002168,
        ],
        // star hexagon
        vec![
            -0.736842105, 1.0,
            -0.736842105, -1.0,
            0.736842105, -1.0,
            0.736842105, 1.0,
        ],
        //hexagon
        vec![
        0.002000, -0.439500,
        -0.379618, -0.221482,
        -0.381618, 0.218018,
        -0.002000, 0.439500,
        0.379618, 0.221482,
        0.381618, -0.218018,
        0.002000, -0.439500,
        ],
        //invert 7 point star
        vec![
        -1.037129, 0.000000,
        -0.487625, 0.071884,
        -0.036111, 0.158214,
        0.934421, 0.449993,
        0.470524, 0.146807,
        0.101182, -0.126878,
        -0.646639, -0.810860,
        -0.360230, -0.336421,
        -0.146212, 0.070412,
        0.230783, 1.011126,
        0.178589, 0.459403,
        0.162283, 0.000000,
        0.230783, -1.011126,
        0.038425, -0.491395,
        -0.146212, -0.070412,
        -0.646639, 0.810860,
        -0.247828, 0.426059,
        0.101182, 0.126878,
        0.934421, -0.449993,
        0.408145, -0.276338,
        -0.036111, -0.158214,
        -1.037129, -0.000000,
        ],
        //invers 6 point star
        vec![
        -1.037129, 0.000000,
        -0.583093, -0.055358,
        -0.204743, -0.117901,
        0.517890, -0.299004,
        0.243039, -0.029458,
        -0.000266, 0.236263,
        -0.518564, 0.898180,
        -0.339488, 0.477294,
        -0.204477, 0.118362,
        0.000000, -0.598008,
        0.096008, -0.225207,
        0.204477, 0.118362,
        0.518564, 0.898180,
        0.243605, 0.532652,
        0.000266, 0.236263,
        -0.517890, -0.299004,
        -0.147031, -0.195748,
        0.204743, -0.117901,
        1.037129, 0.000000,
        0.583093, 0.055358,
        0.204743, 0.117901,
        -0.517890, 0.299004,
        -0.243039, 0.029458,
        0.000266, -0.236263,
        0.518564, -0.898180,
        0.339488, -0.477294,
        0.204477, -0.118362,
        -0.000000, 0.598008,
        -0.096008, 0.225207,
        -0.204477, -0.118362,
        -0.518564, -0.898180,
        -0.243605, -0.532652,
        -0.000266, -0.236263,
        0.517890, 0.299004,
        0.147031, 0.195748,
        -0.204743, 0.117901,
        -1.037129, -0.000000,
        -0.583093, -0.055358,
        -0.204743, -0.117901,
        0.517890, -0.299004,
        0.147031, -0.195748,
        -0.204743, -0.117901,
        -1.037129, 0.000000
        ]
    ]
}
<commit_msg>rotation works<commit_after>extern crate rand;
extern crate common;

use common::*;
use common::Projection::*;

use rand::{StdRng, SeedableRng, Rng};

use std::f32::consts;

#[cfg(debug_assertions)]
#[no_mangle]
pub fn new_state() -> State {
    println!("debug on");

    let seed: &[_] = &[42];
    let rng: StdRng = SeedableRng::from_seed(seed);

    make_state(rng)
}
#[cfg(not(debug_assertions))]
#[no_mangle]
pub fn new_state() -> State {
    let timestamp = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .map(|dur| dur.as_secs())
        .unwrap_or(42);

    println!("{}", timestamp);
    let seed: &[_] = &[timestamp as usize];
    let rng: StdRng = SeedableRng::from_seed(seed);

    make_state(rng)
}

fn make_state(rng: StdRng) -> State {
    let mut state = State {
        rng,
        polys: Vec::new(),
        cam_x: 0.0,
        cam_y: 0.0,
        zoom: 1.0,
    };

    add_random_poly(&mut state);

    state
}

#[no_mangle]
//returns true if quit requested
pub fn update_and_render(p: &Platform, state: &mut State, events: &mut Vec<Event>) -> bool {
    for event in events {
        println!("{:?}", *event);

        match *event {
            Event::Quit |
            Event::KeyDown(Keycode::Escape) |
            Event::KeyDown(Keycode::F10) => {
                return true;
            }
            Event::KeyDown(Keycode::Space) => {
                add_random_poly(state);
            }
            Event::KeyDown(Keycode::R) => {
                state.polys.clear();
                add_random_poly(state);
            }
            Event::KeyDown(Keycode::V) => {
                (p.set_verts)(get_vert_vecs());
            }
            Event::KeyDown(Keycode::Up) => {
                state.cam_y += 0.0625;
            }
            Event::KeyDown(Keycode::Down) => {
                state.cam_y -= 0.0625;
            }
            Event::KeyDown(Keycode::Right) => {
                state.cam_x += 0.0625;
            }
            Event::KeyDown(Keycode::Left) => {
                state.cam_x -= 0.0625;
            }
            Event::KeyDown(Keycode::Num0) => {
                state.cam_x = 0.0;
                state.cam_y = 0.0;
                state.zoom = 1.0;
            }
            Event::KeyDown(Keycode::W) => {
                state.zoom *= 1.25;
            }
            Event::KeyDown(Keycode::S) => {
                state.zoom /= 1.25;
            }
            _ => {}
        }
    }

    let aspect_ratio = 800.0 / 600.0;
    let near = 0.5;
    let far = 1024.0;

    let scale = state.zoom * near;
    let top = scale;
    let bottom = -top;
    let right = aspect_ratio * scale;
    let left = -right;

    let projection = get_projection(&ProjectionSpec {
        top,
        bottom,
        left,
        right,
        near,
        far,
        projection: Perspective,
        // projection: Orthographic,
    });

    let camera = [
        1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        1.0,
        0.0,
        state.cam_x,
        state.cam_y,
        0.0,
        1.0,
    ];

    let view = mat4x4_mul(&camera, &projection);

    for poly in state.polys.iter() {
        let world_matrix = [
            f32::cos(std::f32::consts::FRAC_PI_2),
            f32::sin(std::f32::consts::FRAC_PI_2),
            0.0,
            0.0,
            f32::sin(std::f32::consts::FRAC_PI_2),
            f32::cos(std::f32::consts::FRAC_PI_2),
            0.0,
            0.0,
            0.0,
            0.0,
            1.0,
            0.0,
            poly.x,
            poly.y,
            0.0,
            1.0,
        ];

        let matrix = mat4x4_mul(&world_matrix, &view);

        // (p.draw_poly_with_matrix)(matrix, poly.index);
        (p.draw_textured_poly_with_matrix)(matrix, poly.index, 0);
    }

    false
}

fn add_random_poly(state: &mut State) {
    let poly = Polygon {
        x: state.rng.gen_range(-9.0, 10.0) / 10.0,
        y: state.rng.gen_range(-9.0, 10.0) / 10.0,
        index: state.rng.gen_range(0, 6),
        scale: state.rng.gen_range(0.0, 2.0),
    };

    state.polys.push(poly);
}

//These are the verticies of the polygons which can be drawn.
//The index refers to the index of the inner vector within the outer vecton.
#[cfg_attr(rustfmt, rustfmt_skip)]
#[no_mangle]
pub fn get_vert_vecs() -> Vec<Vec<f32>> {
    vec![
        // star heptagon
        vec![
            -0.012640, 0.255336,
            0.152259, 0.386185,
            0.223982, 0.275978,
            0.191749, 0.169082,
            0.396864, 0.121742,
            0.355419, -0.003047,
            0.251747, -0.044495,
            0.342622, -0.234376,
            0.219218, -0.279777,
            0.122174, -0.224565,
            0.030379, -0.414003,
            -0.082058, -0.345830,
            -0.099398, -0.235534,
            -0.304740, -0.281878,
            -0.321543, -0.151465,
            -0.246122, -0.069141,
            -0.410383, 0.062507,
            -0.318899, 0.156955,
            -0.207511, 0.149317,
            -0.207000, 0.359823,
            -0.076118, 0.347186,
            -0.012640, 0.255336,
        ],
        // heptagon
        vec![
            0.555765, -0.002168,
            0.344819, -0.435866,
            -0.125783, -0.541348,
            -0.501668, -0.239184,
            -0.499786, 0.243091,
            -0.121556, 0.542313,
            0.348209, 0.433163,
            0.555765, -0.002168,
        ],
        // star hexagon
        vec![
            -0.736842105, 1.0,
            -0.736842105, -1.0,
            0.736842105, -1.0,
            0.736842105, 1.0,
        ],
        //hexagon
        vec![
        0.002000, -0.439500,
        -0.379618, -0.221482,
        -0.381618, 0.218018,
        -0.002000, 0.439500,
        0.379618, 0.221482,
        0.381618, -0.218018,
        0.002000, -0.439500,
        ],
        //invert 7 point star
        vec![
        -1.037129, 0.000000,
        -0.487625, 0.071884,
        -0.036111, 0.158214,
        0.934421, 0.449993,
        0.470524, 0.146807,
        0.101182, -0.126878,
        -0.646639, -0.810860,
        -0.360230, -0.336421,
        -0.146212, 0.070412,
        0.230783, 1.011126,
        0.178589, 0.459403,
        0.162283, 0.000000,
        0.230783, -1.011126,
        0.038425, -0.491395,
        -0.146212, -0.070412,
        -0.646639, 0.810860,
        -0.247828, 0.426059,
        0.101182, 0.126878,
        0.934421, -0.449993,
        0.408145, -0.276338,
        -0.036111, -0.158214,
        -1.037129, -0.000000,
        ],
        //invers 6 point star
        vec![
        -1.037129, 0.000000,
        -0.583093, -0.055358,
        -0.204743, -0.117901,
        0.517890, -0.299004,
        0.243039, -0.029458,
        -0.000266, 0.236263,
        -0.518564, 0.898180,
        -0.339488, 0.477294,
        -0.204477, 0.118362,
        0.000000, -0.598008,
        0.096008, -0.225207,
        0.204477, 0.118362,
        0.518564, 0.898180,
        0.243605, 0.532652,
        0.000266, 0.236263,
        -0.517890, -0.299004,
        -0.147031, -0.195748,
        0.204743, -0.117901,
        1.037129, 0.000000,
        0.583093, 0.055358,
        0.204743, 0.117901,
        -0.517890, 0.299004,
        -0.243039, 0.029458,
        0.000266, -0.236263,
        0.518564, -0.898180,
        0.339488, -0.477294,
        0.204477, -0.118362,
        -0.000000, 0.598008,
        -0.096008, 0.225207,
        -0.204477, -0.118362,
        -0.518564, -0.898180,
        -0.243605, -0.532652,
        -0.000266, -0.236263,
        0.517890, 0.299004,
        0.147031, 0.195748,
        -0.204743, 0.117901,
        -1.037129, -0.000000,
        -0.583093, -0.055358,
        -0.204743, -0.117901,
        0.517890, -0.299004,
        0.147031, -0.195748,
        -0.204743, -0.117901,
        -1.037129, 0.000000
        ]
    ]
}
<|endoftext|>


<commit_before>mod document_spec;

use futures::future::{Future, ok, err, result};
use futures::Stream;
use hyper;
use hyper::{Get, Post, Head, StatusCode};
use hyper::header::ContentType;
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::server::{Request, Response};
use serde_json;
use slog;
use tokio_service::{NewService, Service};
use tokio_core::reactor::Remote;

use error::{Error, ErrorKind};
pub use self::document_spec::DocumentSpec;
use workspace::Workspace;

pub struct Papers {
    remote: Remote,
    logger: slog::Logger,
}

impl Papers {
    pub fn new(remote: Remote, logger: slog::Logger) -> Papers {
        Papers {
            remote: remote,
            logger: logger,
        }
    }

    fn submit(&self, req: Request) -> Box<Future<Item=Response, Error=Error>> {
        info!(
            self.logger,
            "Received a submit request ({}) from {:?}",
            req.method(),
            req.remote_addr().unwrap(),
        );
        debug!(self.logger, "Full request: {:#?}", req);

        let content_type = req.headers().get::<ContentType>().cloned();

        // Return an error if the content type is not application/json
        match content_type {
            Some(ContentType(Mime(TopLevel::Application, SubLevel::Json, _))) => (),
            _ => return Box::new(err(ErrorKind::UnprocessableEntity.into())),
        };

        let remote = self.remote.clone();
        let handle = self.remote.handle().unwrap().clone();
        let logger = self.logger.clone();

        let response = req.body()
            // Ignore hyper errors (i.e. io error, invalid utf-8, etc.) for now
            .map_err(|_| ErrorKind::UnprocessableEntity.into())
            .fold(Vec::new(), |mut acc, chunk| {
            // Receive all the body chunks into a vector
            acc.extend_from_slice(&chunk);
            ok::<_, Error>(acc)
        })

        // Parse the body into a DocumentSpec
        .and_then(|body| {
            result(
                serde_json::from_slice::<DocumentSpec>(body.as_slice())
                    .map_err(|err| Error::with_chain(err, ErrorKind::UnprocessableEntity))
            )
        })

        // Handle the parsed request
        .map_err(|_| ErrorKind::InternalServerError.into())
        .and_then(|document_spec| {
            result(Workspace::new(remote, document_spec, logger))
        }).and_then(move |workspace| {
            handle.spawn(workspace.execute().map(|_| ()).map_err(|err| panic!("{}", err)));
            ok(Response::new().with_status(StatusCode::Ok))
        }).map_err(|_| ErrorKind::InternalServerError.into());

        Box::new(response)
    }

    fn preview(&self, req: Request) -> Box<Future<Item=Response, Error=Error>> {
        info!(
            self.logger,
            "Received a preview request ({}) from: {:?}",
            req.method(),
            req.remote_addr().unwrap(),
        );
        debug!(self.logger, "Full request: {:#?}", req);
        let content_type = {
            req.headers().get::<ContentType>().cloned()
        };

        // Return an error if the content type is not application/json
        match content_type {
            Some(ContentType(Mime(TopLevel::Application, SubLevel::Json, _))) => (),
            _ => return Box::new(err(ErrorKind::UnprocessableEntity.into())),
        };

        let remote = self.remote.clone();
        let logger = self.logger.clone();

        let response = req.body()
            // Ignore hyper errors (i.e. io error, invalid utf-8, etc.) for now
            .map_err(|err| Error::with_chain(err, ErrorKind::UnprocessableEntity))
            .fold(Vec::new(), |mut acc, chunk| {
            // Receive all the body chunks into a vector
            acc.extend_from_slice(&chunk);
            ok::<_, Error>(acc)
        })

        // Parse the body into a DocumentSpec
        .and_then(|body| {
            result(
                serde_json::from_slice::<DocumentSpec>(body.as_slice())
                    .map_err(|_| ErrorKind::UnprocessableEntity.into())
            )
        })

        // Handle the parsed request
        .and_then(|document_spec| {
            result(Workspace::new(remote, document_spec, logger))
                .map_err(|err| Error::with_chain(err, ErrorKind::InternalServerError))
        })
        .and_then(|workspace| {
            workspace.preview()
        }).and_then(|populated_template| {
            ok(Response::new()
                .with_status(StatusCode::Ok)
                .with_body(populated_template))
        });

        Box::new(response)

    }

    fn health_check(&self, req: Request) -> Box<Future<Item=Response, Error=Error>> {
        info!(
            self.logger,
            "Received a health check request ({}) from {:?}",
            req.method(),
            req.remote_addr().unwrap(),
        );
        ok(Response::new().with_status(StatusCode::Ok)).boxed()
    }
}

impl Service for Papers {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = Box<Future<Item=Response, Error=hyper::Error>>;

    fn call(&self, req: Self::Request) -> Self::Future {
        // debug!("called with uri {:?}, and method {:?}", req.path(), req.method());
        let response = match (req.method(), req.path()) {
            (&Get, "/healthz") | (&Head, "/healthz") => self.health_check(req),
            (&Post, "/preview") => self.preview(req),
            (&Post, "/submit") => self.submit(req),
            _ => {
                info!(
                    self.logger,
                    "Received a request to a non-existing endpoint \"{}\" from {:?}",
                    req.path(),
                    req.remote_addr().unwrap(),
                );
                ok(Response::new().with_status(StatusCode::NotFound)).boxed()
            }
        }.then(|handler_result| {
            match handler_result {
                Ok(response) => ok(response),
                Err(err) => ok(err.into_response()),
            }
        });

        Box::new(response)
    }
}

impl NewService for Papers {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Instance = Papers;

    fn new_service(&self) -> Result<Self::Instance, ::std::io::Error> {
        Ok(Papers {
            remote: self.remote.clone(),
            logger: self.logger.clone(),
        })
    }
}
<commit_msg>:sparkles: Add method to 404 request log<commit_after>mod document_spec;

use futures::future::{Future, ok, err, result};
use futures::Stream;
use hyper;
use hyper::{Get, Post, Head, StatusCode};
use hyper::header::ContentType;
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::server::{Request, Response};
use serde_json;
use slog;
use tokio_service::{NewService, Service};
use tokio_core::reactor::Remote;

use error::{Error, ErrorKind};
pub use self::document_spec::DocumentSpec;
use workspace::Workspace;

pub struct Papers {
    remote: Remote,
    logger: slog::Logger,
}

impl Papers {
    pub fn new(remote: Remote, logger: slog::Logger) -> Papers {
        Papers {
            remote: remote,
            logger: logger,
        }
    }

    fn submit(&self, req: Request) -> Box<Future<Item=Response, Error=Error>> {
        info!(
            self.logger,
            "Received a submit request ({}) from {:?}",
            req.method(),
            req.remote_addr().unwrap(),
        );
        debug!(self.logger, "Full request: {:#?}", req);

        let content_type = req.headers().get::<ContentType>().cloned();

        // Return an error if the content type is not application/json
        match content_type {
            Some(ContentType(Mime(TopLevel::Application, SubLevel::Json, _))) => (),
            _ => return Box::new(err(ErrorKind::UnprocessableEntity.into())),
        };

        let remote = self.remote.clone();
        let handle = self.remote.handle().unwrap().clone();
        let logger = self.logger.clone();

        let response = req.body()
            // Ignore hyper errors (i.e. io error, invalid utf-8, etc.) for now
            .map_err(|_| ErrorKind::UnprocessableEntity.into())
            .fold(Vec::new(), |mut acc, chunk| {
            // Receive all the body chunks into a vector
            acc.extend_from_slice(&chunk);
            ok::<_, Error>(acc)
        })

        // Parse the body into a DocumentSpec
        .and_then(|body| {
            result(
                serde_json::from_slice::<DocumentSpec>(body.as_slice())
                    .map_err(|err| Error::with_chain(err, ErrorKind::UnprocessableEntity))
            )
        })

        // Handle the parsed request
        .map_err(|_| ErrorKind::InternalServerError.into())
        .and_then(|document_spec| {
            result(Workspace::new(remote, document_spec, logger))
        }).and_then(move |workspace| {
            handle.spawn(workspace.execute().map(|_| ()).map_err(|err| panic!("{}", err)));
            ok(Response::new().with_status(StatusCode::Ok))
        }).map_err(|_| ErrorKind::InternalServerError.into());

        Box::new(response)
    }

    fn preview(&self, req: Request) -> Box<Future<Item=Response, Error=Error>> {
        info!(
            self.logger,
            "Received a preview request ({}) from: {:?}",
            req.method(),
            req.remote_addr().unwrap(),
        );
        debug!(self.logger, "Full request: {:#?}", req);
        let content_type = {
            req.headers().get::<ContentType>().cloned()
        };

        // Return an error if the content type is not application/json
        match content_type {
            Some(ContentType(Mime(TopLevel::Application, SubLevel::Json, _))) => (),
            _ => return Box::new(err(ErrorKind::UnprocessableEntity.into())),
        };

        let remote = self.remote.clone();
        let logger = self.logger.clone();

        let response = req.body()
            // Ignore hyper errors (i.e. io error, invalid utf-8, etc.) for now
            .map_err(|err| Error::with_chain(err, ErrorKind::UnprocessableEntity))
            .fold(Vec::new(), |mut acc, chunk| {
            // Receive all the body chunks into a vector
            acc.extend_from_slice(&chunk);
            ok::<_, Error>(acc)
        })

        // Parse the body into a DocumentSpec
        .and_then(|body| {
            result(
                serde_json::from_slice::<DocumentSpec>(body.as_slice())
                    .map_err(|_| ErrorKind::UnprocessableEntity.into())
            )
        })

        // Handle the parsed request
        .and_then(|document_spec| {
            result(Workspace::new(remote, document_spec, logger))
                .map_err(|err| Error::with_chain(err, ErrorKind::InternalServerError))
        })
        .and_then(|workspace| {
            workspace.preview()
        }).and_then(|populated_template| {
            ok(Response::new()
                .with_status(StatusCode::Ok)
                .with_body(populated_template))
        });

        Box::new(response)

    }

    fn health_check(&self, req: Request) -> Box<Future<Item=Response, Error=Error>> {
        info!(
            self.logger,
            "Received a health check request ({}) from {:?}",
            req.method(),
            req.remote_addr().unwrap(),
        );
        ok(Response::new().with_status(StatusCode::Ok)).boxed()
    }
}

impl Service for Papers {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = Box<Future<Item=Response, Error=hyper::Error>>;

    fn call(&self, req: Self::Request) -> Self::Future {
        let response = match (req.method(), req.path()) {
            (&Get, "/healthz") | (&Head, "/healthz") => self.health_check(req),
            (&Post, "/preview") => self.preview(req),
            (&Post, "/submit") => self.submit(req),
            _ => {
                info!(
                    self.logger,
                    "Received a {} request to a non-existing endpoint \"{}\" from {:?}",
                    req.method(),
                    req.path(),
                    req.remote_addr().unwrap(),
                );
                ok(Response::new().with_status(StatusCode::NotFound)).boxed()
            }
        }.then(|handler_result| {
            match handler_result {
                Ok(response) => ok(response),
                Err(err) => ok(err.into_response()),
            }
        });

        Box::new(response)
    }
}

impl NewService for Papers {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Instance = Papers;

    fn new_service(&self) -> Result<Self::Instance, ::std::io::Error> {
        Ok(Papers {
            remote: self.remote.clone(),
            logger: self.logger.clone(),
        })
    }
}
<|endoftext|>


<commit_before>use std::fmt::{self, Display};
use std::io::{self, Write};
use std::path::Path;

use crate::rustfmt_diff::{DiffLine, Mismatch};

/// The checkstyle header - should be emitted before the output of Rustfmt.
///
/// Note that emitting checkstyle output is not stable and may removed in a
/// future version of Rustfmt.
pub(crate) fn header() -> String {
    let mut xml_heading = String::new();
    xml_heading.push_str(r#"<?xml version="1.0" encoding="utf-8"?>"#);
    xml_heading.push_str("\n");
    xml_heading.push_str(r#"<checkstyle version="4.3">"#);
    xml_heading
}

/// The checkstyle footer - should be emitted after the output of Rustfmt.
///
/// Note that emitting checkstyle output is not stable and may removed in a
/// future version of Rustfmt.
pub(crate) fn footer() -> String {
    "</checkstyle>\n".to_owned()
}

pub(crate) fn output_checkstyle_file<T>(
    mut writer: T,
    filename: &Path,
    diff: Vec<Mismatch>,
) -> Result<(), io::Error>
where
    T: Write,
{
    write!(writer, r#"<file name="{}">"#, filename.display())?;
    for mismatch in diff {
        for line in mismatch.lines {
            // Do nothing with `DiffLine::Context` and `DiffLine::Resulting`.
            if let DiffLine::Expected(message) = line {
                write!(
                    writer,
                    r#"<error line="{}" severity="warning" message="Should be `{}`" />"#,
                    mismatch.line_number,
                    XmlEscaped(&message)
                )?;
            }
        }
    }
    write!(writer, "</file>")?;
    Ok(())
}

/// Convert special characters into XML entities.
/// This is needed for checkstyle output.
struct XmlEscaped<'a>(&'a str);

impl<'a> Display for XmlEscaped<'a> {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        for char in self.0.chars() {
            match char {
                '<' => write!(formatter, "<"),
                '>' => write!(formatter, ">"),
                '"' => write!(formatter, """),
                '\'' => write!(formatter, "'"),
                '&' => write!(formatter, "&"),
                _ => write!(formatter, "{}", char),
            }?;
        }

        Ok(())
    }
}

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

    #[test]
    fn special_characters_are_escaped() {
        assert_eq!(
            "<>"'&",
            format!("{}", XmlEscaped(r#"<>"'&"#)),
        );
    }

    #[test]
    fn special_characters_are_escaped_in_string_with_other_characters() {
        assert_eq!(
            "The quick brown "🦊" jumps <over> the lazy 🐶",
            format!(
                "{}",
                XmlEscaped(r#"The quick brown "🦊" jumps <over> the lazy 🐶"#)
            ),
        );
    }

    #[test]
    fn other_characters_are_not_escaped() {
        let string = "The quick brown 🦊 jumps over the lazy 🐶";
        assert_eq!(string, format!("{}", XmlEscaped(string)),);
    }
}
<commit_msg>Remove unnecessary comma<commit_after>use std::fmt::{self, Display};
use std::io::{self, Write};
use std::path::Path;

use crate::rustfmt_diff::{DiffLine, Mismatch};

/// The checkstyle header - should be emitted before the output of Rustfmt.
///
/// Note that emitting checkstyle output is not stable and may removed in a
/// future version of Rustfmt.
pub(crate) fn header() -> String {
    let mut xml_heading = String::new();
    xml_heading.push_str(r#"<?xml version="1.0" encoding="utf-8"?>"#);
    xml_heading.push_str("\n");
    xml_heading.push_str(r#"<checkstyle version="4.3">"#);
    xml_heading
}

/// The checkstyle footer - should be emitted after the output of Rustfmt.
///
/// Note that emitting checkstyle output is not stable and may removed in a
/// future version of Rustfmt.
pub(crate) fn footer() -> String {
    "</checkstyle>\n".to_owned()
}

pub(crate) fn output_checkstyle_file<T>(
    mut writer: T,
    filename: &Path,
    diff: Vec<Mismatch>,
) -> Result<(), io::Error>
where
    T: Write,
{
    write!(writer, r#"<file name="{}">"#, filename.display())?;
    for mismatch in diff {
        for line in mismatch.lines {
            // Do nothing with `DiffLine::Context` and `DiffLine::Resulting`.
            if let DiffLine::Expected(message) = line {
                write!(
                    writer,
                    r#"<error line="{}" severity="warning" message="Should be `{}`" />"#,
                    mismatch.line_number,
                    XmlEscaped(&message)
                )?;
            }
        }
    }
    write!(writer, "</file>")?;
    Ok(())
}

/// Convert special characters into XML entities.
/// This is needed for checkstyle output.
struct XmlEscaped<'a>(&'a str);

impl<'a> Display for XmlEscaped<'a> {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        for char in self.0.chars() {
            match char {
                '<' => write!(formatter, "<"),
                '>' => write!(formatter, ">"),
                '"' => write!(formatter, """),
                '\'' => write!(formatter, "'"),
                '&' => write!(formatter, "&"),
                _ => write!(formatter, "{}", char),
            }?;
        }

        Ok(())
    }
}

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

    #[test]
    fn special_characters_are_escaped() {
        assert_eq!(
            "<>"'&",
            format!("{}", XmlEscaped(r#"<>"'&"#)),
        );
    }

    #[test]
    fn special_characters_are_escaped_in_string_with_other_characters() {
        assert_eq!(
            "The quick brown "🦊" jumps <over> the lazy 🐶",
            format!(
                "{}",
                XmlEscaped(r#"The quick brown "🦊" jumps <over> the lazy 🐶"#)
            ),
        );
    }

    #[test]
    fn other_characters_are_not_escaped() {
        let string = "The quick brown 🦊 jumps over the lazy 🐶";
        assert_eq!(string, format!("{}", XmlEscaped(string)));
    }
}
<|endoftext|>


<commit_before>use byte_conversion::*;

pub struct PaddedBytes {
	ciphertext: Vec<u8>
}

impl PaddedBytes {
	pub fn from_text(text: &str, block_size: usize) -> Result<PaddedBytes, String> {
		PaddedBytes::from_bytes(&readable_text_to_bytes(&text)[..], block_size)
	}

	pub fn from_bytes(bytes: &[u8], block_size: usize) -> Result<PaddedBytes, String> {
		let length = bytes.len();
		if length == 0 {
			return Err("Attempted to pad 0 bytes.".to_string());
		}

		let mut padded = bytes.to_vec();
		let mut bytes_left = 0;

		// Normalise the bytes length for the padding value
		while bytes_left < length as u8 {
			bytes_left += block_size as u8;
		}
		while bytes_left > length as u8 {
			bytes_left -= length as u8;
		}

		// Pad the bytes
		while padded.len() % block_size > 0 {
			padded.push(bytes_left);
		}

		Ok(
			PaddedBytes {
				ciphertext: padded
			}
		)
	}

	pub fn bytes(&self) -> &[u8] {
		&self.ciphertext[..]
	}

	pub fn vec(&self) -> &Vec<u8> {
		&self.ciphertext
	}
}

//-----------------------------------------------------------------------------

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

	#[test]
	fn PaddedText_empty() {
		let text = PaddedBytes::from_text("", 16);

		assert!(text.is_err());
	}

	#[test]
	fn PaddedText_yellow_submarine_20() {
		let text = match PaddedBytes::from_text("YELLOW SUBMARINE", 20) {
			Ok(x) => x,
			Err(x) => panic!(x),
		};

		let expected = ::byte_conversion::readable_text_to_bytes(&"YELLOW SUBMARINE\x04\x04\x04\x04");

		assert_eq!(expected, text.bytes());
	}

	#[test]
	fn PaddedText_yellow_submarine_16() {
		let text = match PaddedBytes::from_text("YELLOW SUBMARINE", 16) {
			Ok(x) => x,
			Err(x) => panic!(x),
		};

		let expected = ::byte_conversion::readable_text_to_bytes(&"YELLOW SUBMARINE");

		assert_eq!(expected, text.bytes());
	}

	#[test]
	fn PaddedText_yellow_submarine_32() {
		let text = match PaddedBytes::from_text("YELLOW SUBMARINE", 32) {
			Ok(x) => x,
			Err(x) => panic!(x),
		};

		let expected = ::byte_conversion::readable_text_to_bytes(&"YELLOW SUBMARINE\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10");

		assert_eq!(expected, text.bytes());
	}

	#[test]
	fn PaddedText_yellow_submarine_10() {
		let text = match PaddedBytes::from_text("YELLOW SUBMARINE", 10) {
			Ok(x) => x,
			Err(x) => panic!(x),
		};

		let expected = ::byte_conversion::readable_text_to_bytes(&"YELLOW SUBMARINE\x04\x04\x04\x04");

		assert_eq!(expected, text.bytes());
	}

	#[test]
	fn PaddedText_yellow_submarine_3() {
		let text = match PaddedBytes::from_text("YELLOW SUBMARINE", 3) {
			Ok(x) => x,
			Err(x) => panic!(x),
		};

		let expected = ::byte_conversion::readable_text_to_bytes(&"YELLOW SUBMARINE\x02\x02");

		assert_eq!(expected, text.bytes());
	}
}<commit_msg>Ciphertext padding fix<commit_after>use byte_conversion::*;

pub struct PaddedBytes {
	ciphertext: Vec<u8>
}

impl PaddedBytes {
	pub fn from_text(text: &str, block_size: usize) -> Result<PaddedBytes, String> {
		PaddedBytes::from_bytes(&readable_text_to_bytes(&text)[..], block_size)
	}

	pub fn from_bytes(bytes: &[u8], block_size: usize) -> Result<PaddedBytes, String> {
		let length = bytes.len();
		if length == 0 {
			return Err("Attempted to pad 0 bytes.".to_string());
		}

		let mut padded = bytes.to_vec();
		let mut bytes_left = 0;

		// Normalise the bytes length for the padding value
		while bytes_left < length as u8 {
			bytes_left += block_size as u8;
		}
		while bytes_left >= block_size as u8 {
			bytes_left -= length as u8;
		}

		// Pad the bytes
		while padded.len() % block_size > 0 {
			padded.push(bytes_left);
		}

		Ok(
			PaddedBytes {
				ciphertext: padded
			}
		)
	}

	pub fn bytes(&self) -> &[u8] {
		&self.ciphertext[..]
	}

	pub fn vec(&self) -> &Vec<u8> {
		&self.ciphertext
	}
}

//-----------------------------------------------------------------------------

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

	#[test]
	fn PaddedText_empty() {
		let text = PaddedBytes::from_text("", 16);

		assert!(text.is_err());
	}

	#[test]
	fn PaddedText_yellow_submarine_20() {
		let text = match PaddedBytes::from_text("YELLOW SUBMARINE", 20) {
			Ok(x) => x,
			Err(x) => panic!(x),
		};

		let expected = ::byte_conversion::readable_text_to_bytes(&"YELLOW SUBMARINE\x04\x04\x04\x04");

		assert_eq!(expected, text.bytes());
	}

	#[test]
	fn PaddedText_12345_16() {
		let text = match PaddedBytes::from_text("12345", 16) {
			Ok(x) => x,
			Err(x) => panic!(x),
		};

		let expected = ::byte_conversion::readable_text_to_bytes(&"12345\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B");

		assert_eq!(expected, text.bytes());
	}

	#[test]
	fn PaddedText_yellow_submarine_16() {
		let text = match PaddedBytes::from_text("YELLOW SUBMARINE", 16) {
			Ok(x) => x,
			Err(x) => panic!(x),
		};

		let expected = ::byte_conversion::readable_text_to_bytes(&"YELLOW SUBMARINE");

		assert_eq!(expected, text.bytes());
	}

	#[test]
	fn PaddedText_yellow_submarine_32() {
		let text = match PaddedBytes::from_text("YELLOW SUBMARINE", 32) {
			Ok(x) => x,
			Err(x) => panic!(x),
		};

		let expected = ::byte_conversion::readable_text_to_bytes(&"YELLOW SUBMARINE\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10");

		assert_eq!(expected, text.bytes());
	}

	#[test]
	fn PaddedText_yellow_submarine_10() {
		let text = match PaddedBytes::from_text("YELLOW SUBMARINE", 10) {
			Ok(x) => x,
			Err(x) => panic!(x),
		};

		let expected = ::byte_conversion::readable_text_to_bytes(&"YELLOW SUBMARINE\x04\x04\x04\x04");

		assert_eq!(expected, text.bytes());
	}

	#[test]
	fn PaddedText_yellow_submarine_3() {
		let text = match PaddedBytes::from_text("YELLOW SUBMARINE", 3) {
			Ok(x) => x,
			Err(x) => panic!(x),
		};

		let expected = ::byte_conversion::readable_text_to_bytes(&"YELLOW SUBMARINE\x02\x02");

		assert_eq!(expected, text.bytes());
	}
}<|endoftext|>


<commit_before>use std::sync::{Mutex, Arc};
use std::net::{SocketAddr, ToSocketAddrs};
use std::f64::consts::PI;
use std::collections::VecDeque;
use opengl_graphics::GlGraphics;
use piston::input::{Button, MouseButton, RenderArgs, UpdateArgs};

use std::{thread, time};
use std::net::TcpStream;
use network::{Command, Message};

use bincode::{serialize_into, deserialize_from, Infinite};

use state::WorldState;
use shapes::Unit;

pub struct NetworkClient {
    pub world_state: Arc<Mutex<WorldState>>,
    server_addr: SocketAddr,
    stream: Option<TcpStream>,
    commands: Arc<Mutex<VecDeque<Command>>>,
}

impl NetworkClient {
    pub fn new<T: ToSocketAddrs>(server_addrs: T, world_state:
                                 Arc<Mutex<WorldState>>,
                                 commands: Arc<Mutex<VecDeque<Command>>>) -> NetworkClient {
        let server_addr = server_addrs.to_socket_addrs().unwrap().next().unwrap();
        NetworkClient {
            world_state: world_state,
            server_addr: server_addr,
            stream: None,
            commands: commands,
        }
    }

    // todo: Maybe return client_id here? Would allow the application to reconnect...
    pub fn connect(&mut self) {
        let mut stream = TcpStream::connect(self.server_addr).unwrap();
        serialize_into(&mut stream, &Message::ClientHello, Infinite).unwrap();
        let server_hello = deserialize_from(&mut stream, Infinite);

        self.stream = Some(stream);
        if let Ok(Message::ServerHello(_, world_state)) = server_hello {
            let mut world_state_lock = self.world_state.lock().unwrap();
            *world_state_lock = world_state;
        } else {
            panic!("Could not connect to server");
        }
    }

    pub fn update(self) {
        let stream = self.stream.expect("Stream not here :(");
        let mut command_stream = stream.try_clone().unwrap();
        let commands = self.commands.clone();

        // Command sender loop
        thread::spawn(move || {
            loop {
                let command = {
                    let mut commands = commands.lock().unwrap();
                    commands.pop_front()
                };
                command.map(|cmd| {
                    println!("Got command: {:?}", cmd);
                    //let cmd = Message::Command(Command::Move(0.into(), [100f64, 100f64]));
                    serialize_into(&mut command_stream, &Message::Command(cmd), Infinite)
                        .unwrap_or_else(|e|println!("Sending command failed: {}", e));
                });
                thread::sleep(time::Duration::from_millis(10));
            }
        });

        let mut game_state_stream = stream.try_clone().unwrap();
        let world_state = self.world_state.clone();
        thread::spawn(move || {
            loop {
                let game_state = deserialize_from(&mut game_state_stream,
                                                  Infinite);
                match game_state {
                    Ok(game) => {
                        //println!("{:?}", game);
                        let mut world_state_lock = world_state.lock().unwrap();
                        world_state_lock.game = game;

                    }
                    Err(e) => {
                        println!("{:?}", e);
                        thread::sleep(time::Duration::from_millis(200));
                    }
                }
            }
        });
    }
}

pub struct App {
    pub gl: GlGraphics, // OpenGL drawing backend.
    pub world_state: Arc<Mutex<WorldState>>,
    pub units: Vec<Unit>,
    pub commands: Arc<Mutex<VecDeque<Command>>>,
    pub cursor: [f64; 2],
}

impl App {
    pub fn new(gl: GlGraphics) -> App {
        App {
            gl: gl,
            world_state: Arc::new(Mutex::new(WorldState::new(0, 0))),
            units: vec![],
            commands: Arc::new(Mutex::new(VecDeque::new())),
            cursor: [0.0, 0.0],
        }
    }

    pub fn select(&mut self, position: [f64;2]) {
        for u in &mut self.units {
            u.selected = u.is_hit(position);
        };
    }

    pub fn render(&mut self, args: &RenderArgs) {
        use graphics::{polygon, clear};
        use graphics::Transformed;
        use graphics::types::Polygon;

        const BLACK:  [f32; 4] = [0.0, 0.0,  0.0,  1.0];
        const YELLOW: [f32; 4] = [1.0, 1.0,  0.22, 1.0];
        const ORANGE: [f32; 4] = [1.0, 0.61, 0.22, 1.0];

        const FRONT_THICKNESS: f64 = 5.0;

        let units = &self.units;

        self.gl.draw(args.viewport(), |c, gl| {

            // Clear the screen.
            clear(BLACK, gl);

            for s in units.iter() {

                // Create a triangle polygon. The initial orientation is facing east.
                let triangle: Polygon = &s.get_shape();

                // Create a border on the front of the polygon. This is a trapezoid.
                // Because the angle of the trapezoid side is 22.5°, we know that `dx` is always `2 * dy`.
                let front: Polygon = &[
                    [s.size, s.size],                                           // Top right
                    [s.size, 0.0],                                                 // Bottom right
                    [s.size - FRONT_THICKNESS, FRONT_THICKNESS / 2.0],             // Bottom left
                    [s.size - FRONT_THICKNESS, s.size - FRONT_THICKNESS / 2.0], // Top left
                ];

                // Rotate the front to match the unit
                let transform_front = c.transform.trans(s.position[0], s.position[1])
                    .rot_rad(s.rotation)
                    .trans(-25.0, -25.0);

                // We don't need to apply any transformation to the units
                let transform_triangle = c.transform;

                // Draw the unit ORANGE if selected
                if s.selected {
                    polygon(ORANGE, triangle, transform_triangle, gl);
                    polygon(YELLOW, front, transform_front, gl);
                } else {
                    polygon(YELLOW, triangle, transform_triangle, gl);
                    polygon(ORANGE, front, transform_front, gl);
                }

            }
        });
    }

    pub fn update(&mut self, _: &UpdateArgs) {
        let player = {
            let world_lock = self.world_state.lock().unwrap();
            world_lock.game.players.get(0).map(|v| v.clone())
        };
        if let Some(player) = player {
            for unit in player.units.iter() {
                self.units.get_mut(unit.id.0 as usize)
                    .map(|app_unit| app_unit.position = unit.position)
                    .or_else(|| {
                        self.units.push(Unit::new(unit.position.clone(), 0.0f64));
                        None
                    }
                    );
            }
        }
    }

    pub fn on_button_press(&mut self, button: &Button) {
        match button {
            &Button::Keyboard(_) => {}
            &Button::Mouse(button) => {
                self.on_mouse_click(&button);
            }
            &Button::Controller(_) => {}
        }
    }

    pub fn on_mouse_click(&mut self, button: &MouseButton) {
        let cursor = self.cursor;
        match *button {
            MouseButton::Left  => self.select(cursor),
            MouseButton::Right => self.move_selected(cursor),
            _ => println!("Pressed mouse button '{:?}'", button),
        }
    }

    pub fn on_mouse_move(&mut self, cursor: [f64; 2]) {
        self.cursor = cursor;
    }

    pub fn move_selected(&mut self, position: [f64;2]) {
        for i in 0..self.units.len() {
            let s = &mut self.units[i];
            if s.selected {
                s.target = position;
                let dx = position[0] - s.position[0];
                let dy = position[1] - s.position[1];
                if dx.is_sign_negative() {
                    s.rotation = (dy / dx).atan() + PI;
                } else {
                    s.rotation = (dy / dx).atan();
                }
                let id = i as u32;
                let mut commands = self.commands.lock().unwrap();
                commands.push_back(Command::Move(id.into(), position));
                println!("dx: {}, dy: {}, new rotation: {}", dx, dy, s.rotation);
            }
        }
    }
}
<commit_msg>client: Get angle from server<commit_after>use std::sync::{Mutex, Arc};
use std::net::{SocketAddr, ToSocketAddrs};
use std::f64::consts::PI;
use std::collections::VecDeque;
use opengl_graphics::GlGraphics;
use piston::input::{Button, MouseButton, RenderArgs, UpdateArgs};

use std::{thread, time};
use std::net::TcpStream;
use network::{Command, Message};

use bincode::{serialize_into, deserialize_from, Infinite};

use state::WorldState;
use shapes::Unit;

pub struct NetworkClient {
    pub world_state: Arc<Mutex<WorldState>>,
    server_addr: SocketAddr,
    stream: Option<TcpStream>,
    commands: Arc<Mutex<VecDeque<Command>>>,
}

impl NetworkClient {
    pub fn new<T: ToSocketAddrs>(server_addrs: T, world_state:
                                 Arc<Mutex<WorldState>>,
                                 commands: Arc<Mutex<VecDeque<Command>>>) -> NetworkClient {
        let server_addr = server_addrs.to_socket_addrs().unwrap().next().unwrap();
        NetworkClient {
            world_state: world_state,
            server_addr: server_addr,
            stream: None,
            commands: commands,
        }
    }

    // todo: Maybe return client_id here? Would allow the application to reconnect...
    pub fn connect(&mut self) {
        let mut stream = TcpStream::connect(self.server_addr).unwrap();
        serialize_into(&mut stream, &Message::ClientHello, Infinite).unwrap();
        let server_hello = deserialize_from(&mut stream, Infinite);

        self.stream = Some(stream);
        if let Ok(Message::ServerHello(_, world_state)) = server_hello {
            let mut world_state_lock = self.world_state.lock().unwrap();
            *world_state_lock = world_state;
        } else {
            panic!("Could not connect to server");
        }
    }

    pub fn update(self) {
        let stream = self.stream.expect("Stream not here :(");
        let mut command_stream = stream.try_clone().unwrap();
        let commands = self.commands.clone();

        // Command sender loop
        thread::spawn(move || {
            loop {
                let command = {
                    let mut commands = commands.lock().unwrap();
                    commands.pop_front()
                };
                command.map(|cmd| {
                    println!("Got command: {:?}", cmd);
                    //let cmd = Message::Command(Command::Move(0.into(), [100f64, 100f64]));
                    serialize_into(&mut command_stream, &Message::Command(cmd), Infinite)
                        .unwrap_or_else(|e|println!("Sending command failed: {}", e));
                });
                thread::sleep(time::Duration::from_millis(10));
            }
        });

        let mut game_state_stream = stream.try_clone().unwrap();
        let world_state = self.world_state.clone();
        thread::spawn(move || {
            loop {
                let game_state = deserialize_from(&mut game_state_stream,
                                                  Infinite);
                match game_state {
                    Ok(game) => {
                        //println!("{:?}", game);
                        let mut world_state_lock = world_state.lock().unwrap();
                        world_state_lock.game = game;

                    }
                    Err(e) => {
                        println!("{:?}", e);
                        thread::sleep(time::Duration::from_millis(200));
                    }
                }
            }
        });
    }
}

pub struct App {
    pub gl: GlGraphics, // OpenGL drawing backend.
    pub world_state: Arc<Mutex<WorldState>>,
    pub units: Vec<Unit>,
    pub commands: Arc<Mutex<VecDeque<Command>>>,
    pub cursor: [f64; 2],
}

impl App {
    pub fn new(gl: GlGraphics) -> App {
        App {
            gl: gl,
            world_state: Arc::new(Mutex::new(WorldState::new(0, 0))),
            units: vec![],
            commands: Arc::new(Mutex::new(VecDeque::new())),
            cursor: [0.0, 0.0],
        }
    }

    pub fn select(&mut self, position: [f64;2]) {
        for u in &mut self.units {
            u.selected = u.is_hit(position);
        };
    }

    pub fn render(&mut self, args: &RenderArgs) {
        use graphics::{polygon, clear};
        use graphics::Transformed;
        use graphics::types::Polygon;

        const BLACK:  [f32; 4] = [0.0, 0.0,  0.0,  1.0];
        const YELLOW: [f32; 4] = [1.0, 1.0,  0.22, 1.0];
        const ORANGE: [f32; 4] = [1.0, 0.61, 0.22, 1.0];

        const FRONT_THICKNESS: f64 = 5.0;

        let units = &self.units;

        self.gl.draw(args.viewport(), |c, gl| {

            // Clear the screen.
            clear(BLACK, gl);

            for s in units.iter() {

                // Create a triangle polygon. The initial orientation is facing east.
                let triangle: Polygon = &s.get_shape();

                // Create a border on the front of the polygon. This is a trapezoid.
                // Because the angle of the trapezoid side is 22.5°, we know that `dx` is always `2 * dy`.
                let front: Polygon = &[
                    [s.size, s.size],                                           // Top right
                    [s.size, 0.0],                                                 // Bottom right
                    [s.size - FRONT_THICKNESS, FRONT_THICKNESS / 2.0],             // Bottom left
                    [s.size - FRONT_THICKNESS, s.size - FRONT_THICKNESS / 2.0], // Top left
                ];

                // Rotate the front to match the unit
                let transform_front = c.transform.trans(s.position[0], s.position[1])
                    .rot_rad(s.rotation)
                    .trans(-25.0, -25.0);

                // We don't need to apply any transformation to the units
                let transform_triangle = c.transform;

                // Draw the unit ORANGE if selected
                if s.selected {
                    polygon(ORANGE, triangle, transform_triangle, gl);
                    polygon(YELLOW, front, transform_front, gl);
                } else {
                    polygon(YELLOW, triangle, transform_triangle, gl);
                    polygon(ORANGE, front, transform_front, gl);
                }

            }
        });
    }

    pub fn update(&mut self, _: &UpdateArgs) {
        let player = {
            let world_lock = self.world_state.lock().unwrap();
            world_lock.game.players.get(0).map(|v| v.clone())
        };
        if let Some(player) = player {
            for unit in player.units.iter() {
                self.units.get_mut(unit.id.0 as usize)
                    .map(|app_unit| {
                        app_unit.position = unit.position;
                        app_unit.rotation = unit.angle;
                    })
                    .or_else(|| {
                        self.units.push(Unit::new(unit.position.clone(), unit.angle));
                        None
                    });
            }
        }
    }

    pub fn on_button_press(&mut self, button: &Button) {
        match button {
            &Button::Keyboard(_) => {}
            &Button::Mouse(button) => {
                self.on_mouse_click(&button);
            }
            &Button::Controller(_) => {}
        }
    }

    pub fn on_mouse_click(&mut self, button: &MouseButton) {
        let cursor = self.cursor;
        match *button {
            MouseButton::Left  => self.select(cursor),
            MouseButton::Right => self.move_selected(cursor),
            _ => println!("Pressed mouse button '{:?}'", button),
        }
    }

    pub fn on_mouse_move(&mut self, cursor: [f64; 2]) {
        self.cursor = cursor;
    }

    pub fn move_selected(&mut self, position: [f64;2]) {
        for i in 0..self.units.len() {
            let s = &mut self.units[i];
            if s.selected {
                s.target = position;
                let dx = position[0] - s.position[0];
                let dy = position[1] - s.position[1];
                if dx.is_sign_negative() {
                    s.rotation = (dy / dx).atan() + PI;
                } else {
                    s.rotation = (dy / dx).atan();
                }
                let id = i as u32;
                let mut commands = self.commands.lock().unwrap();
                commands.push_back(Command::Move(id.into(), position));
                println!("dx: {}, dy: {}, new rotation: {}", dx, dy, s.rotation);
            }
        }
    }
}
<|endoftext|>


<commit_before>use super::mode;
use super::util;
use std::collections::Deque;
use std::collections::RingBuf;

#[deriving(Clone)]
#[deriving(Show)]
enum DOC {
    Nil,
    Append(Box<Doc>, Box<Doc>),
    Group(Box<Doc>),
    Nest(uint, Box<Doc>),
    Newline,
    Text(String),
}

pub type Doc = DOC;
type Cmd<'a> = (uint,mode::Mode,&'a Doc);

fn fitting(mut cmds:RingBuf<Cmd>, mut rem:int) -> bool {
    let mut fits = true;

    loop {
        if rem < 0 {
            fits = false;
            break;
        }
        match cmds.pop_front() {
            None => {
                break;
            },
            Some((ind, mode, doc)) => match doc {
                &Nil => {
                },
                &Append(box ref ldoc, box ref rdoc) => {
                    cmds.push_front((ind, mode, rdoc));
                    cmds.push_front((ind, mode, ldoc));
                },
                &Group(box ref doc) => {
                    cmds.push_front((ind, mode, doc));
                },
                &Nest(off, box ref doc) => {
                    cmds.push_front((ind + off, mode, doc));
                },
                &Newline => {
                    fits = true;
                },
                &Text(ref str) => {
                    rem -= str.len() as int;
                },
            }
        }
    }

    fits
}

impl Doc {

    fn best(&self, width:uint) -> Vec<String> {
        let mut pos: uint = 0;
        let mut cmds: RingBuf<Cmd> = RingBuf::new();
        let mut result:Vec<String> = Vec::new();

        cmds.push((0, mode::Break, self));

        loop {
            match cmds.pop_front() {
                None => {
                    break;
                },
                Some((ind, mode, doc)) => match doc {
                    &Nil => {
                    },
                    &Append(box ref ldoc, box ref rdoc) => {
                        cmds.push_front((ind, mode, rdoc));
                        cmds.push_front((ind, mode, ldoc));
                    },
                    &Group(box ref doc) => match mode {
                        mode::Flat => {
                            cmds.push_front((ind, mode::Flat, doc));
                        },
                        mode::Break => {
                            // FIXME: fitting() modifies cmds so we must either
                            // take a clone and pass it or rewrite fitting()
                            // to modify a separate cmd stack and only observe
                            // this one.
                            let mut cmds_dup = cmds.clone();
                            let next = (ind, mode::Flat, doc);
                            cmds_dup.push_front(next);
                            if fitting(cmds_dup, width as int - pos as int) {
                                cmds.push_front(next);
                            } else {
                                cmds.push_front((ind, mode::Break, doc));
                            }
                        }
                    },
                    &Nest(off, box ref doc) => {
                        cmds.push_front((ind + off, mode, doc));
                    },
                    &Newline => {
                        result.push(util::string::nl_spaces(ind));
                        pos = ind;
                    },
                    &Text(ref str) => {
                        // FIXME: we have to clone here otherwise result would
                        // have to contain String and &String. We cannot make
                        // Newline case return &String because the region is
                        // limited to the scope of its arm; it does not live
                        // long enough (the strings in Text will outlast).
                        result.push(str.clone());
                        pos += str.len();
                    },
                }
            }
        }

        result
    }

    #[inline]
    pub fn nil() -> Doc {
        Nil
    }

    #[inline]
    pub fn append(self, that:Doc) -> Doc {
        match self {
            Nil => {
                that
            },
            ldoc => match that {
                Nil => {
                    ldoc
                },
                rdoc => {
                    Append(box ldoc, box rdoc)
                },
            }
        }
    }

    #[inline]
    pub fn as_string<T:ToString>(t:T) -> Doc {
        Doc::text(t.to_string())
    }

    #[inline]
    pub fn concat(ds:&[Doc]) -> Doc {
        ds.iter().fold(Nil, |a, b| a.append(b.clone()))
    }

    #[inline]
    pub fn group(self) -> Doc {
        Group(box self)
    }

    #[inline]
    pub fn nest(self, off:uint) -> Doc {
        Nest(off, box self)
    }

    #[inline]
    pub fn newline() -> Doc {
        Newline
    }

    // FIXME: could possibly parallelize this part since string append should
    // be associative. Might be a good example for rust-monoid…
    #[inline]
    pub fn render(&self, width:uint) -> String {
        let mut result = String::new();
        for str in self.best(width).iter() {
            result.push_str(str.as_slice());
        }
        result
    }

    #[inline]
    pub fn text<T:Str>(str:T) -> Doc {
        Text(String::from_str(str.as_slice()))
    }

}
<commit_msg>Remove unnecessary annotations<commit_after>use super::mode;
use super::util;
use std::collections::Deque;
use std::collections::RingBuf;

#[deriving(Clone)]
#[deriving(Show)]
enum DOC {
    Nil,
    Append(Box<Doc>, Box<Doc>),
    Group(Box<Doc>),
    Nest(uint, Box<Doc>),
    Newline,
    Text(String),
}

pub type Doc = DOC;
type Cmd<'a> = (uint,mode::Mode,&'a Doc);

fn fitting(mut cmds:RingBuf<Cmd>, mut rem:int) -> bool {
    let mut fits = true;

    loop {
        if rem < 0 {
            fits = false;
            break;
        }
        match cmds.pop_front() {
            None => {
                break;
            },
            Some((ind, mode, doc)) => match doc {
                &Nil => {
                },
                &Append(box ref ldoc, box ref rdoc) => {
                    cmds.push_front((ind, mode, rdoc));
                    cmds.push_front((ind, mode, ldoc));
                },
                &Group(box ref doc) => {
                    cmds.push_front((ind, mode, doc));
                },
                &Nest(off, box ref doc) => {
                    cmds.push_front((ind + off, mode, doc));
                },
                &Newline => {
                    fits = true;
                },
                &Text(ref str) => {
                    rem -= str.len() as int;
                },
            }
        }
    }

    fits
}

impl Doc {

    fn best(&self, width:uint) -> Vec<String> {
        let mut pos = 0u;
        let mut cmds = RingBuf::new();
        let mut result = Vec::new();

        cmds.push((0, mode::Break, self));

        loop {
            match cmds.pop_front() {
                None => {
                    break;
                },
                Some((ind, mode, doc)) => match doc {
                    &Nil => {
                    },
                    &Append(box ref ldoc, box ref rdoc) => {
                        cmds.push_front((ind, mode, rdoc));
                        cmds.push_front((ind, mode, ldoc));
                    },
                    &Group(box ref doc) => match mode {
                        mode::Flat => {
                            cmds.push_front((ind, mode::Flat, doc));
                        },
                        mode::Break => {
                            // FIXME: fitting() modifies cmds so we must either
                            // take a clone and pass it or rewrite fitting()
                            // to modify a separate cmd stack and only observe
                            // this one.
                            let mut cmds_dup = cmds.clone();
                            let next = (ind, mode::Flat, doc);
                            cmds_dup.push_front(next);
                            if fitting(cmds_dup, width as int - pos as int) {
                                cmds.push_front(next);
                            } else {
                                cmds.push_front((ind, mode::Break, doc));
                            }
                        }
                    },
                    &Nest(off, box ref doc) => {
                        cmds.push_front((ind + off, mode, doc));
                    },
                    &Newline => {
                        result.push(util::string::nl_spaces(ind));
                        pos = ind;
                    },
                    &Text(ref str) => {
                        // FIXME: we have to clone here otherwise result would
                        // have to contain String and &String. We cannot make
                        // Newline case return &String because the region is
                        // limited to the scope of its arm; it does not live
                        // long enough (the strings in Text will outlast).
                        result.push(str.clone());
                        pos += str.len();
                    },
                }
            }
        }

        result
    }

    #[inline]
    pub fn nil() -> Doc {
        Nil
    }

    #[inline]
    pub fn append(self, that:Doc) -> Doc {
        match self {
            Nil => {
                that
            },
            ldoc => match that {
                Nil => {
                    ldoc
                },
                rdoc => {
                    Append(box ldoc, box rdoc)
                },
            }
        }
    }

    #[inline]
    pub fn as_string<T:ToString>(t:T) -> Doc {
        Doc::text(t.to_string())
    }

    #[inline]
    pub fn concat(ds:&[Doc]) -> Doc {
        ds.iter().fold(Nil, |a, b| a.append(b.clone()))
    }

    #[inline]
    pub fn group(self) -> Doc {
        Group(box self)
    }

    #[inline]
    pub fn nest(self, off:uint) -> Doc {
        Nest(off, box self)
    }

    #[inline]
    pub fn newline() -> Doc {
        Newline
    }

    // FIXME: could possibly parallelize this part since string append should
    // be associative. Might be a good example for rust-monoid…
    #[inline]
    pub fn render(&self, width:uint) -> String {
        let mut result = String::new();
        for str in self.best(width).iter() {
            result.push_str(str.as_slice());
        }
        result
    }

    #[inline]
    pub fn text<T:Str>(str:T) -> Doc {
        Text(String::from_str(str.as_slice()))
    }

}
<|endoftext|>