<commit_before>use crate::requests::*;
use crate::types::*;

#[derive(Serialize, Debug)]
pub struct AnswerInlineQuery {
    inline_query_id: InlineQueryId,
    results: Vec<InlineQueryResult>,
    // TODO: Rest of the fields
}

impl Request for AnswerInlineQuery {
    type Type = JsonRequestType<Self>;
    type Response = JsonTrueToUnitResponse;

    fn serialize(&self) -> Result<HttpRequest, Error> {
        Self::Type::serialize(RequestUrl::method("answerInlineQuery"), self)
    }
}

pub trait CanAnswerInlineQuery {
    fn answer(self, results: Vec<InlineQueryResult>) -> AnswerInlineQuery;
}

impl<T> CanAnswerInlineQuery for T
where
    T: Into<InlineQueryId>,
{
    fn answer(self, results: Vec<InlineQueryResult>) -> AnswerInlineQuery {
        AnswerInlineQuery::new(self.into(), results)
    }
}

impl AnswerInlineQuery {
    pub fn new(
        inline_query_id: InlineQueryId,
        results: Vec<InlineQueryResult>,
    ) -> AnswerInlineQuery {
        AnswerInlineQuery {
            inline_query_id,
            results,
        }
    }

    pub fn add_inline_result<T: Into<InlineQueryResult>>(&mut self, result: T) {
        self.results.push(result.into());
    }
}
<commit_msg>Add missing fields to AnswerInlineQuery<commit_after>use std::ops::Not;

use crate::requests::*;
use crate::types::*;

#[derive(Serialize, Debug)]
pub struct AnswerInlineQuery {
    inline_query_id: InlineQueryId,
    results: Vec<InlineQueryResult>,
    #[serde(skip_serializing_if = "Option::is_none")]
    cache_time: Option<Integer>,
    #[serde(skip_serializing_if = "Not::not")]
    is_personal: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    next_offset: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    switch_pm_text: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    switch_pm_parameter: Option<String>,
}

impl Request for AnswerInlineQuery {
    type Type = JsonRequestType<Self>;
    type Response = JsonTrueToUnitResponse;

    fn serialize(&self) -> Result<HttpRequest, Error> {
        Self::Type::serialize(RequestUrl::method("answerInlineQuery"), self)
    }
}

pub trait CanAnswerInlineQuery {
    fn answer(self, results: Vec<InlineQueryResult>) -> AnswerInlineQuery;
}

impl<T> CanAnswerInlineQuery for T
where
    T: Into<InlineQueryId>,
{
    fn answer(self, results: Vec<InlineQueryResult>) -> AnswerInlineQuery {
        AnswerInlineQuery::new(self.into(), results)
    }
}

impl AnswerInlineQuery {
    pub fn new(
        inline_query_id: InlineQueryId,
        results: Vec<InlineQueryResult>,
    ) -> AnswerInlineQuery {
        AnswerInlineQuery {
            inline_query_id,
            results,
            cache_time: None,
            is_personal: false,
            next_offset: None,
            switch_pm_text: None,
            switch_pm_parameter: None,
        }
    }

    pub fn add_inline_result<T: Into<InlineQueryResult>>(&mut self, result: T) {
        self.results.push(result.into());
    }

    pub fn cache_time(&mut self, cache_time: Integer) -> &mut Self {
        self.cache_time = Some(cache_time);
        self
    }

    pub fn is_personal(&mut self) -> &mut Self {
        self.is_personal = true;
        self
    }

    pub fn next_offset(&mut self, next_offset: String) -> &mut Self {
        self.next_offset = Some(next_offset);
        self
    }

    pub fn switch_pm_text(&mut self, switch_pm_text: String) -> &mut Self {
        self.switch_pm_text = Some(switch_pm_text);
        self
    }

    pub fn switch_pm_parameter(&mut self, switch_pm_parameter: String) -> &mut Self {
        self.switch_pm_parameter = Some(switch_pm_parameter);
        self
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Alexander Reece
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr(not(feature="clippy"), allow(unknown_lints))]

extern crate env_logger;

#[cfg(feature = "amqp0-codegen")]
extern crate amqp0_codegen as codegen;
#[cfg(feature = "amqp0-specs")]
extern crate amqp0_specs as specs;

fn main() {
    amqp0::build();
}

#[cfg(not(feature = "amqp0-specs"))]
mod amqp0 {
    pub fn build() {
        println!("Skipping build (neither amqp0-build-primitives nor amqp0-pregen-primitives specified)");
    }
}

#[cfg(feature = "amqp0-specs")]
mod amqp0 {
    use std::env;
    use std::fs;
    use std::path::{Path, PathBuf};

    use env_logger;

    use codegen::{self, Builder, CodeWriter};
    use codegen::primalgen::{SpecsModuleWriter, SpecModuleWriter};
    use specs::specs as amqp0_specs;

    struct PrimitivesBuilder;

    const BUILDER_CRATES: &'static [&'static str] = &["amqp0-codegen"];
    const BUILDER_REBUILD: &'static [&'static str] = &["amqp0-build-primitives"];
    const BUILDER_PREGEN: &'static [&'static str] = &["amqp0-build-primitives"];

    impl Builder for PrimitivesBuilder {
        fn name(&self) -> &str { "amqp0-primitives" }
        fn crates(&self) -> &[&str] { BUILDER_CRATES }
        fn rebuild_features(&self) -> &[&str] { BUILDER_REBUILD }
        fn pregeneration_features(&self) -> &[&str] { BUILDER_PREGEN }
    }

    pub fn build() {
        env_logger::init().unwrap();
        println!("Building primitives from amqpspec");

        let out_path = env::var_os("OUT_DIR").map(PathBuf::from).expect("Error: OUT_DIR not set");
        let specs = amqp0_specs();
        let mut paths: Vec<PathBuf> = Vec::with_capacity(1 + specs.len());

        // mod.rs
        let specs_writer = SpecsModuleWriter::from_spec_slice(&specs[..]);
        let writer = CodeWriter::new(PrimitivesBuilder, specs_writer);
        println!("Generated mod.rs");
        let mod_path = out_path.join("mod.rs");
        writer.write_to_path(&mod_path).expect("Failed to write amqp0.rs");
        paths.push(mod_path);

        // {name}{minor}_{revision}.rs
        for spec in specs {
            let spec_writer = SpecModuleWriter::from_spec(spec);
            let filename = format!("{}.rs", spec_writer.mod_name());
            let path = out_path.join(&filename);
            let writer = CodeWriter::new(PrimitivesBuilder, spec_writer);
            println!("Generating {}", filename);
            writer.write_to_path(&path).expect("Failed to write spec module");
            paths.push(path);
        }

        if cfg!(feature = "rustfmt") {
            codegen::format_files(paths.clone());
        }

        if cfg!(feature = "amqp0-pregen-primitives") {
            let pregen_dir = Path::new("pregen");
            for path in paths {
                let suffix = path.strip_prefix(&out_path).unwrap();
                let dst = pregen_dir.join(suffix);
                println!("Saving to {} to {}", path.display(), dst.display());
                fs::copy(&path, dst).unwrap();
            }
        }
    }
}<commit_msg>[primitives] Update to amqp0-codegen 0.0.5<commit_after>// Copyright 2016 Alexander Reece
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr(not(feature="clippy"), allow(unknown_lints))]
extern crate env_logger;

#[cfg(feature = "amqp0-codegen")]
extern crate amqp0_codegen as codegen;
#[cfg(feature = "amqp0-specs")]
extern crate amqp0_specs as specs;

fn main() {
    amqp0::build();
}

#[cfg(not(feature = "amqp0-specs"))]
mod amqp0 {
    pub fn build() {
        println!("Skipping build (neither amqp0-build-primitives nor amqp0-pregen-primitives specified)");
    }
}

#[cfg(feature = "amqp0-specs")]
mod amqp0 {
    use std::env;
    use std::path::{Path, PathBuf};

    use env_logger;
    use codegen;
    use codegen::primalgen::ModulesWriter;
    use specs::specs as amqp0_specs;

    const BUILDER_CRATES: &'static [&'static str] = &["amqp0-codegen"];
    const BUILDER_REBUILD: &'static [&'static str] = &["amqp0-build-primitives"];
    const BUILDER_PREGEN: &'static [&'static str] = &["amqp0-build-primitives"];

    struct PrimitivesSource {
        base_dir: PathBuf,
    }

    impl codegen::Source for PrimitivesSource {
        fn name(&self) -> &str { "amqp0-primitives" }
        fn crates(&self) -> &[&str] { BUILDER_CRATES }

        fn rebuild_features(&self) -> &[&str] { BUILDER_REBUILD }
        fn pregeneration_features(&self) -> &[&str] { BUILDER_PREGEN }

        fn base_dir(&self) -> &Path { &self.base_dir }
        fn should_format(&self) -> bool { cfg!(feature = "rustfmt") }
    }

    pub fn build() {
        let base_dir = if cfg!(feature = "amqp0-pregen-primitives") {
            PathBuf::from("pregen")
        } else {
            env::var_os("OUT_DIR")
                .map(PathBuf::from)
                .expect("Error: OUT_DIR not set")
        };

        env_logger::init().unwrap();
        println!("Building primitives from amqpspec");

        let source = PrimitivesSource { base_dir: base_dir };
        let writer = ModulesWriter::new(&source, amqp0_specs());
        writer.write_files().unwrap();
    }
}<|endoftext|>


<commit_before>use result;
use render::Renderer;

pub struct TerminalRenderer {}

impl TerminalRenderer {
    pub fn new() -> TerminalRenderer {
        TerminalRenderer {}
    }
}

impl Renderer for TerminalRenderer {
    fn render(&mut self, result: result::RequestLogAnalyzerResult) -> () {
        println!("count:\t{}", result.count);
        match result.timing {
            Some(timing) => {
                println!("time.avg:\t{}", timing.avg);
                println!("time.min:\t{}", timing.min);
                println!("time.median:\t{}", timing.median);
                println!("time.90percent:\t{}", timing.percentile90);
                println!("time.max:\t{}", timing.max);
            }
            None => warn!("No matching log lines for timing results."),
        }

        match result.error {
            Some(error) => {
                println!("error.client_error_4xx_rate:\t{}", error.client_error_4xx);
                println!("error.server_error_5xx_rate:\t{}", error.server_error_5xx);
            }
            None => warn!("No matching log lines for error rate results."),
        }
    }
}

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

    fn get_result_fixture() -> result::RequestLogAnalyzerResult {
        result::RequestLogAnalyzerResult {
            count: 3,
            timing: Some(analyzer::TimingResult {
                max: 100,
                min: 1,
                avg: 37,
                median: 10,
                percentile90: 100,
                count: 3,
            }),
            error: Some(analyzer::aggregated_error_rates::ErrorRatesResult {
                client_error_4xx: 0.1,
                server_error_5xx: 0.2,
            }),
        }
    }

    #[test]
    fn test_terminal_renderer() {
        let mut renderer = TerminalRenderer::new();

        let result = get_result_fixture();

        renderer.render(result);
    }

    #[test]
    fn test_terminal_renderer_no_lines() {
        let mut renderer = TerminalRenderer::new();

        let result = result::RequestLogAnalyzerResult {
            count: 0,
            timing: None,
            error: None,
        };

        renderer.render(result);
    }
}
<commit_msg>Actually cover with assertions<commit_after>use std::io::prelude::*;
use result;
use render::Renderer;

pub struct TerminalRenderer<'a> {
    stream: &'a mut Write,
}

impl<'a> TerminalRenderer<'a> {
    pub fn new(stream: &'a mut Write) -> TerminalRenderer {
        TerminalRenderer { stream: stream }
    }
}

impl<'a> Renderer for TerminalRenderer<'a> {
    fn render(&mut self, result: result::RequestLogAnalyzerResult) -> () {
        let mut write = |text: String| {
            let _ = self.stream.write(format!("{}\n", text).as_bytes());
        };

        write(format!("count:\t{}", result.count));

        match result.timing {
            Some(timing) => {
                write(format!("time.avg:\t{}", timing.avg));
                write(format!("time.min:\t{}", timing.min));
                write(format!("time.median:\t{}", timing.median));
                write(format!("time.90percent:\t{}", timing.percentile90));
                write(format!("time.max:\t{}", timing.max));
            }
            None => warn!("No matching log lines for timing results."),
        }

        match result.error {
            Some(error) => {
                write(format!("error.client_error_4xx_rate:\t{}", error.client_error_4xx));
                write(format!("error.server_error_5xx_rate:\t{}", error.server_error_5xx));
            }
            None => warn!("No matching log lines for error rate results."),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::io;
    use std::io::prelude::*;
    use std::str;
    use analyzer;
    use super::*;

    struct MockWrite {
        write_calls: Vec<String>,
    }

    impl Write for MockWrite {
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            self.write_calls.push(str::from_utf8(buf).unwrap().to_string());
            Ok(1)
        }

        fn flush(&mut self) -> io::Result<()> {
            Ok(())
        }
    }

    fn get_result_fixture() -> result::RequestLogAnalyzerResult {
        result::RequestLogAnalyzerResult {
            count: 3,
            timing: Some(analyzer::TimingResult {
                max: 100,
                min: 1,
                avg: 37,
                median: 10,
                percentile90: 100,
                count: 3,
            }),
            error: Some(analyzer::aggregated_error_rates::ErrorRatesResult {
                client_error_4xx: 0.1,
                server_error_5xx: 0.2,
            }),
        }
    }

    #[test]
    fn test_terminal_renderer() {
        let mut mock_write = MockWrite { write_calls: vec![] };

        {
            let mut renderer = TerminalRenderer::new(&mut mock_write);
            let result = get_result_fixture();
            renderer.render(result);
        }
        println!("{:?}", mock_write.write_calls);
        assert!(mock_write.write_calls.contains(&String::from("time.max:\t100\n")));
        assert!(mock_write.write_calls.contains(&String::from("time.min:\t1\n")));
        assert!(mock_write.write_calls.contains(&String::from("time.avg:\t37\n")));
        assert!(mock_write.write_calls.contains(&String::from("time.median:\t10\n")));
        assert!(mock_write.write_calls.contains(&String::from("time.90percent:\t100\n")));
        assert!(mock_write.write_calls.contains(&String::from("count:\t3\n")));

        assert!(mock_write.write_calls
            .contains(&String::from("error.client_error_4xx_rate:\t0.1\n")));
        assert!(mock_write.write_calls
            .contains(&String::from("error.server_error_5xx_rate:\t0.2\n")));
    }

    #[test]
    fn test_terminal_renderer_no_lines() {
        let mut mock_write = MockWrite { write_calls: vec![] };

        {
            let mut renderer = TerminalRenderer::new(&mut mock_write);

            let result = result::RequestLogAnalyzerResult {
                count: 0,
                timing: None,
                error: None,
            };

            renderer.render(result);
        }

        assert!(mock_write.write_calls.contains(&String::from("count:\t0\n")));
        assert_eq!(mock_write.write_calls.len(), 1);
    }
}
<|endoftext|>


<commit_before>extern crate sdl2;
#[macro_use]
extern crate lazy_static;

use sdl2::event;
use std::sync::Mutex;

// Since only one `Sdl` context instance can be created at a time, running tests in parallel causes
// 'Cannot initialize `Sdl` more than once at a time' error. To avoid it, run tests in serial by
// locking this mutex.
lazy_static! {
    static ref CONTEXT_MUTEX: Mutex<()> = Mutex::new(());
}

#[test]
fn test_events() {
    let _lock = CONTEXT_MUTEX.lock();
    let sdl = sdl2::init().unwrap();
    let ev = sdl.event().unwrap();
    let mut ep = sdl.event_pump().unwrap();

    test1(&ev);
    test2(&ev, &mut ep);

    test3(&ev);
    test4(&ev, &mut ep);
}

fn test1(ev: &sdl2::EventSubsystem) {
    let user_event1_id = unsafe { ev.register_event().unwrap() };
    let user_event2_id = unsafe { ev.register_event().unwrap() };
    assert_ne!(user_event1_id, user_event2_id);
}

fn test2(ev: &sdl2::EventSubsystem, ep: &mut sdl2::EventPump) {
    let user_event_id = unsafe { ev.register_event().unwrap() };

    let event = event::Event::User {
        timestamp: 0,
        window_id: 0,
        type_: user_event_id,
        code: 456,
        data1: 0x12_34 as *mut libc::c_void,
        data2: 0x56_78 as *mut libc::c_void,
    };

    let (w1, t1, c1, a1, a2) = match event {
        event::Event::User {
            window_id: w1,
            type_: t1,
            code: c1,
            data1: a1,
            data2: a2,
            ..
        } => (w1, t1, c1, a1, a2),
        _ => panic!("expected user event"),
    };
    ev.push_event(event.clone()).unwrap();
    let received = ep.poll_event().unwrap();
    // Do not check for timestamp here because it is always modified by
    // SDL_PushEvent.
    match &received {
        &event::Event::User {
            window_id: w2,
            type_: t2,
            code: c2,
            data1: b1,
            data2: b2,
            ..
        } => {
            assert_eq!(w1, w2);
            assert_eq!(t1, t2);
            assert_eq!(c1, c2);
            assert_eq!(a1, b1);
            assert_eq!(a2, b2);
        }
        other => panic!("Received non User event: {:?}", other),
    }
}

#[allow(unused)]
struct SomeEventTypeTest3 {
    a: u32,
}

#[allow(unused)]
struct SomeOtherEventTypeTest3 {
    b: u32,
}

fn test3(ev: &sdl2::EventSubsystem) {
    ev.register_custom_event::<SomeEventTypeTest3>().unwrap();
    ev.register_custom_event::<SomeOtherEventTypeTest3>()
        .unwrap();

    assert!(ev.register_custom_event::<SomeEventTypeTest3>().is_err());
}

struct SomeEventTypeTest4 {
    a: u32,
}

fn test4(ev: &sdl2::EventSubsystem, ep: &mut sdl2::EventPump) {
    ev.register_custom_event::<SomeEventTypeTest4>().unwrap();
    let event = SomeEventTypeTest4 { a: 42 };
    ev.push_custom_event(event).unwrap();

    let received = ep.poll_event().unwrap();
    if received.is_user_event() {
        let e2 = received.as_user_event_type::<SomeEventTypeTest4>().unwrap();
        assert_eq!(e2.a, 42);
    }
}

#[test]
fn test_event_sender_no_subsystem() {
    let _lock = CONTEXT_MUTEX.lock();
    let sdl = sdl2::init().unwrap();
    let ev = sdl.event().unwrap();
    let tx = ev.event_sender();

    assert!(tx
        .push_event(sdl2::event::Event::Window {
            timestamp: 0,
            window_id: 0,
            win_event: sdl2::event::WindowEvent::Shown,
        })
        .is_ok());

    drop(ev);

    // Should return an error now the evet subsystem has been shut down
    assert!(tx
        .push_event(sdl2::event::Event::Window {
            timestamp: 0,
            window_id: 0,
            win_event: sdl2::event::WindowEvent::Hidden,
        })
        .is_err());
}
<commit_msg>fix events test<commit_after>extern crate sdl2;
#[macro_use]
extern crate lazy_static;

use sdl2::event;
use std::sync::Mutex;

// Since only one `Sdl` context instance can be created at a time, running tests in parallel causes
// 'Cannot initialize `Sdl` more than once at a time' error. To avoid it, run tests in serial by
// locking this mutex.
lazy_static! {
    static ref CONTEXT_MUTEX: Mutex<()> = Mutex::new(());
}

#[test]
fn test_events() {
    let _lock = CONTEXT_MUTEX.lock();
    let sdl = sdl2::init().unwrap();
    let ev = sdl.event().unwrap();
    let mut ep = sdl.event_pump().unwrap();

    test1(&ev);
    test2(&ev, &mut ep);

    drop(ev);
    drop(ep);

    // event subsystem needs to be dropped before we can add Custom User Event (only after a poll)
    let ev = sdl.event().unwrap();
    let mut ep = sdl.event_pump().unwrap();

    test3(&ev);
    test4(&ev, &mut ep);
}

fn test1(ev: &sdl2::EventSubsystem) {
    let user_event1_id = unsafe { ev.register_event().unwrap() };
    let user_event2_id = unsafe { ev.register_event().unwrap() };
    assert_ne!(user_event1_id, user_event2_id);
}

fn test2(ev: &sdl2::EventSubsystem, ep: &mut sdl2::EventPump) {
    let user_event_id = unsafe { ev.register_event().unwrap() };

    let event = event::Event::User {
        timestamp: 0,
        window_id: 0,
        type_: user_event_id,
        code: 456,
        data1: 0x12_34 as *mut libc::c_void,
        data2: 0x56_78 as *mut libc::c_void,
    };

    let (w1, t1, c1, a1, a2) = match event {
        event::Event::User {
            window_id: w1,
            type_: t1,
            code: c1,
            data1: a1,
            data2: a2,
            ..
        } => (w1, t1, c1, a1, a2),
        _ => panic!("expected user event"),
    };
    ev.push_event(event.clone()).unwrap();
    let received = ep.poll_event().unwrap();
    // Do not check for timestamp here because it is always modified by
    // SDL_PushEvent.
    match &received {
        &event::Event::User {
            window_id: w2,
            type_: t2,
            code: c2,
            data1: b1,
            data2: b2,
            ..
        } => {
            assert_eq!(w1, w2);
            assert_eq!(t1, t2);
            assert_eq!(c1, c2);
            assert_eq!(a1, b1);
            assert_eq!(a2, b2);
        }
        other => panic!("Received non User event: {:?}", other),
    }
}

#[allow(unused)]
struct SomeEventTypeTest3 {
    a: u32,
}

#[allow(unused)]
struct SomeOtherEventTypeTest3 {
    b: u32,
}

fn test3(ev: &sdl2::EventSubsystem) {
    ev.register_custom_event::<SomeEventTypeTest3>().unwrap();
    ev.register_custom_event::<SomeOtherEventTypeTest3>()
        .unwrap();

    assert!(ev.register_custom_event::<SomeEventTypeTest3>().is_err());
}

struct SomeEventTypeTest4 {
    a: u32,
}

fn test4(ev: &sdl2::EventSubsystem, ep: &mut sdl2::EventPump) {
    ev.register_custom_event::<SomeEventTypeTest4>().unwrap();
    let event = SomeEventTypeTest4 { a: 42 };
    ev.push_custom_event(event).unwrap();

    let received = ep.poll_event().unwrap();
    if received.is_user_event() {
        let e2 = received.as_user_event_type::<SomeEventTypeTest4>().unwrap();
        assert_eq!(e2.a, 42);
    }
}

#[test]
fn test_event_sender_no_subsystem() {
    let _lock = CONTEXT_MUTEX.lock();
    let sdl = sdl2::init().unwrap();
    let ev = sdl.event().unwrap();
    let tx = ev.event_sender();

    assert!(tx
        .push_event(sdl2::event::Event::Window {
            timestamp: 0,
            window_id: 0,
            win_event: sdl2::event::WindowEvent::Shown,
        })
        .is_ok());

    drop(ev);

    // Should return an error now the evet subsystem has been shut down
    assert!(tx
        .push_event(sdl2::event::Event::Window {
            timestamp: 0,
            window_id: 0,
            win_event: sdl2::event::WindowEvent::Hidden,
        })
        .is_err());
}
<|endoftext|>


<commit_before>
macro_rules! req_name {
    ($rem:ident, $str:expr, $input:ident) => {
        let len: usize = $str.len();
        if $rem.len() < len || &(&$rem[0..len]).to_ascii_lowercase()!=$str {
            return Err(ParseError::NotFound);
        }
        $rem = &$rem[len..];
    };
}
<commit_msg>rfc5322: req_crlf! macro<commit_after>
macro_rules! req_name {
    ($rem:ident, $str:expr, $input:ident) => {
        let len: usize = $str.len();
        if $rem.len() < len || &(&$rem[0..len]).to_ascii_lowercase()!=$str {
            return Err(ParseError::NotFound);
        }
        $rem = &$rem[len..];
    };
}

macro_rules! req_crlf {
    ($rem:ident, $input:ident) => {
        if &$rem[..2] != b"\r\n" {
            return Err(ParseError::NotFound);
        }
        $rem = &$rem[2..];
    }
}
<|endoftext|>


<commit_before>

pub trait StaticSymbolTable<'a>
{
	/// Return all symbols in this table with the specified name (in any namespace)
	fn lookup_name(name: &str) -> Vec<Symbol<'a>>;

	/// Return all symbols in this table with the specified namespace
	fn lookup_namespace(namespace: &str) -> Vec<Symbol<'a>>;

	/// Lookup a symbol by its name and namespace. Duplicate symbols are not allowed, so the result will be unique
	fn lookup_variable(namespace: &str, name: &str) -> Symbol<'a>;

	/// Lookup a symbol by its name and namespace. Duplicate symbols are not allowed, so the result will be unique
	fn lookup_function(namespace: &str, name: &str, argument_types: &Vec<&str>) -> Symbol<'a>;

	/// Adds a symbol to this table and allocates it's location
	/// Returns true if the symbol could be added; false otherwise
	/// Duplicate symbols are not allowed
	/// TODO: support overloaded methods
	fn add(class: SymbolClass<'a>, namespace: &'a str, name: &'a str) -> bool;
}

pub enum SymbolLocation<'a>
{
	/// Indicates that a register has been reserved for a specific use (e.g. by a variable)
	Register { name: &'a str },

	/// Indicates a location in memory
	Memory { address: MemoryAddress<'a> },

	/// Indicates that the symbol should not be accessed, as it represents a structured entity
	Structured
}

pub enum SymbolClass<'a>
{
	Variable { variable_type: &'a str },

	/// Function signature //TODO: support exceptions
	Function { return_type: &'a str, argument_types: &'a Vec<&'a str> },

	/// Includes class, enum, and interface
	Structure { subtype: &'a str },
}

pub struct Symbol<'a>
{
	/// Namespace of this symbol, without the final "." or the name of this symbol
	pub namespace: &'a str,

	/// Identifier for the symbol (e.g. name of variable, function, class, etc. without it's namespace)
	pub name: &'a str,

	/// What this symbol represents (class, enum, variable, function, etc)
	pub symbol_class: SymbolClass<'a>,

	/// Memory location of this symbol. Methods will always map to a SymbolLocation::Memory label with a 0 offset
	pub location: SymbolLocation<'a>,
}

pub struct MemoryAddress<'a>
{
	/// Label marking the base address where the symbol is stored
	pub label_name: &'a str,

	/// Offset from the base address to access the symbol. Methods will always have an offset of 0
	pub offset: u16,
}
<commit_msg>Update SymbolTable<commit_after>

pub trait StaticSymbolTable<'a>
{
	/// Return all symbols in this table with the specified name (in any namespace)
	fn lookup_name(name: &str) -> Vec<Symbol<'a>>;

	/// Return all symbols in this table with the specified namespace
	fn lookup_namespace(namespace: &str) -> Vec<Symbol<'a>>;

	/// Lookup a symbol by its name and namespace. Duplicate symbols are not allowed, so the result will be unique
	/// @return the specified symbol or None if the specified symbol is not in this namespace
	fn lookup_variable(namespace: &str, name: &str) -> Option<Symbol<'a>>;

	/// Lookup a symbol by its name and namespace. Duplicate symbols are not allowed, so the result will be unique
	/// @return the specified symbol or None if the specified symbol is not in this namespace
	fn lookup_function(namespace: &str, name: &str, argument_types: &Vec<&str>) -> Option<Symbol<'a>>;

	/// Adds a symbol to this table and allocates it's location
	/// Returns true if the symbol could be added; false otherwise
	/// Duplicate symbols are not allowed
	/// TODO: support overloaded methods
	fn add(class: SymbolClass<'a>, namespace: &'a str, name: &'a str) -> bool;
}

pub enum SymbolLocation<'a>
{
	/// Indicates that a register has been reserved for a specific use (e.g. by a variable)
	Register { name: &'a str },

	/// Indicates a location in memory
	Memory { address: MemoryAddress<'a> },

	/// Indicates that the symbol should not be accessed, as it represents a structured entity
	Structured
}

pub enum SymbolClass<'a>
{
	Variable { variable_type: &'a str },

	/// Function signature //TODO: support exceptions
	Function { return_type: &'a str, argument_types: &'a Vec<&'a str> },

	/// Includes class, enum, and interface
	Structure { subtype: &'a str },
}

pub struct Symbol<'a>
{
	/// Namespace of this symbol, without the final "." or the name of this symbol
	pub namespace: &'a str,

	/// Identifier for the symbol (e.g. name of variable, function, class, etc. without it's namespace)
	pub name: &'a str,

	/// What this symbol represents (class, enum, variable, function, etc)
	pub symbol_class: SymbolClass<'a>,

	/// Memory location of this symbol. Methods will always map to a SymbolLocation::Memory label with a 0 offset
	pub location: SymbolLocation<'a>,
}

pub struct MemoryAddress<'a>
{
	/// Label marking the base address where the symbol is stored
	pub label_name: &'a str,

	/// Offset from the base address to access the symbol. Methods will always have an offset of 0
	pub offset: u16,
}
<|endoftext|>


<commit_before>use set1::challenge2::fixed_xor;
use set1::utils::hex_to_bytes;

pub fn chi_squared(text: &str) -> f32 {
    let mut chars_count = vec![0.0; 26];
    let mut ignored = 0;
    for byte in text.bytes() {
        if (byte >= 65 && byte <= 90) || (byte >= 97 && byte <= 122) {
            chars_count[if byte >= 97 {
                (byte - 97) as usize
            } else {
                (byte - 65) as usize
            }] += 1.0;
        }
        // space
        else if byte != 32 {
            ignored += 1;
        }
    }
    // ascii only hence len usage
    let length = (text.len() - ignored) as f32;
    vec![0.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015, 0.06094, 0.06966, 0.00153,
         0.00772, 0.04025, 0.02406, 0.06749, 0.07507, 0.01929, 0.00095, 0.05987, 0.06327, 0.09056,
         0.02758, 0.00978, 0.02360, 0.00150, 0.01974, 0.00074]
        .iter()
        .zip(chars_count.iter())
        .map(|(x, y)| (y - x * (text.len() as f32 + ignored as f32)).powf(2.0) / (x * length))
        .sum()
}

pub fn find_original(text: &str) -> Option<(f32, String)>{
    (0..255).filter_map(|x| {
            let cipher = vec![x; text.len()];
            let xor = fixed_xor(&hex_to_bytes(text), &cipher);
            String::from_utf8(xor).ok()
        })
        .map(|x| (chi_squared(&x), x))
        .filter(|&(x, _)| x.is_finite())
        .min_by(|a, b| a.0.partial_cmp(&b.0).unwrap())
}

#[test]
fn test_chi_squared_upper_a() {
    assert_eq!(chi_squared("A"), 11.244388)
}

#[test]
fn test_chi_squared_a() {
    assert_eq!(chi_squared("a"), 11.244388)
}

#[test]
fn test_find_original() {
    assert_eq!(find_original("1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736").unwrap().1,
               String::from("Cooking MC\'s like a pound of bacon"))
}
<commit_msg>set1: Remove filter from find_original<commit_after>use set1::challenge2::fixed_xor;
use set1::utils::hex_to_bytes;

pub fn chi_squared(text: &str) -> f32 {
    let mut chars_count = vec![0.0; 26];
    let mut ignored = 0;
    for byte in text.bytes() {
        if (byte >= 65 && byte <= 90) || (byte >= 97 && byte <= 122) {
            chars_count[if byte >= 97 {
                (byte - 97) as usize
            } else {
                (byte - 65) as usize
            }] += 1.0;
        }
        // space
        else if byte != 32 {
            ignored += 1;
        }
    }
    // ascii only hence len usage
    let length = (text.len() - ignored) as f32;
    vec![0.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015, 0.06094, 0.06966, 0.00153,
         0.00772, 0.04025, 0.02406, 0.06749, 0.07507, 0.01929, 0.00095, 0.05987, 0.06327, 0.09056,
         0.02758, 0.00978, 0.02360, 0.00150, 0.01974, 0.00074]
        .iter()
        .zip(chars_count.iter())
        .map(|(x, y)| (y - x * (text.len() as f32 + ignored as f32)).powf(2.0) / (x * length))
        .sum()
}

pub fn find_original(text: &str) -> Option<(f32, String)>{
    (0..255).filter_map(|x| {
            let cipher = vec![x; text.len()];
            let xor = fixed_xor(&hex_to_bytes(text), &cipher);
            String::from_utf8(xor).ok()
        })
        .map(|x| (chi_squared(&x), x))
        .min_by(|a, b| a.0.partial_cmp(&b.0).unwrap())
}

#[test]
fn test_chi_squared_upper_a() {
    assert_eq!(chi_squared("A"), 11.244388)
}

#[test]
fn test_chi_squared_a() {
    assert_eq!(chi_squared("a"), 11.244388)
}

#[test]
fn test_find_original() {
    assert_eq!(find_original("1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736").unwrap().1,
               String::from("Cooking MC\'s like a pound of bacon"))
}
<|endoftext|>


<commit_before>use super::directory_stack::DirectoryStack;
use super::variables::Variables;
use liner::{Completer, FilenameCompleter};

/// Performs escaping to an inner `FilenameCompleter` to enable a handful of special cases
/// needed by the shell, such as expanding '~' to a home directory, or adding a backslash
/// when a special character is contained within an expanded filename.
pub(crate) struct IonFileCompleter {
    /// The completer that this completer is  handling.
    inner: FilenameCompleter,
    /// A pointer to the directory stack in the shell.
    dir_stack: *const DirectoryStack,
    /// A pointer to the variables map in the shell.
    vars: *const Variables,
}

impl IonFileCompleter {
    pub(crate) fn new(
        path: Option<&str>,
        dir_stack: *const DirectoryStack,
        vars: *const Variables,
    ) -> IonFileCompleter {
        IonFileCompleter {
            inner:     FilenameCompleter::new(path),
            dir_stack: dir_stack,
            vars:      vars,
        }
    }
}

impl Completer for IonFileCompleter {
    /// When the tab key is pressed, **Liner** will use this method to perform completions of
    /// filenames. As our `IonFileCompleter` is a wrapper around **Liner**'s
    /// `FilenameCompleter`,
    /// the purpose of our custom `Completer` is to expand possible `~` characters in the
    /// `start`
    /// value that we receive from the prompt, grab completions from the inner
    /// `FilenameCompleter`,
    /// and then escape the resulting filenames, as well as remove the expanded form of the `~`
    /// character and re-add the `~` character in it's place.
    fn completions(&self, start: &str) -> Vec<String> {
        // Only if the first character is a tilde character will we perform expansions
        if start.starts_with('~') {
            // Dereferencing the raw pointers here should be entirely safe, theoretically,
            // because no changes will occur to either of the underlying references in the
            // duration between creation of the completers and execution of their completions.
            if let Some(expanded) = unsafe { (*self.vars).tilde_expansion(start, &*self.dir_stack) }
            {
                // Now we obtain completions for the `expanded` form of the `start` value.
                let completions = self.inner.completions(&expanded);
                let mut iterator = completions.iter();

                // And then we will need to take those completions and remove the expanded form
                // of the tilde pattern and replace it with that pattern yet again.
                let mut completions = Vec::new();

                // We can do that by obtaining the index position where the tilde character ends.
                // We don't search with `~` because we also want to handle other tilde variants.
                let t_index = start.find('/').unwrap_or(1);
                // `tilde` is the tilde pattern, and `search` is the pattern that follows.
                let (tilde, search) = start.split_at(t_index as usize);

                if search.len() < 2 {
                    // If the length of the search pattern is less than 2, the search pattern is
                    // empty, and thus the completions actually contain files and directories in
                    // the home directory.

                    // The tilde pattern will actually be our `start` command in itself,
                    // and the completed form will be all of the characters beyond the length of
                    // the expanded form of the tilde pattern.
                    for completion in iterator {
                        completions.push([start, &completion[expanded.len()..]].concat());
                    }
                } else {
                    // To save processing time, we should get obtain the index position where our
                    // search pattern begins, and re-use that index to slice the completions so
                    // that we may re-add the tilde character with the completion that follows.
                    if let Some(completion) = iterator.next() {
                        if let Some(e_index) = completion.find(search) {
                            completions.push(escape(&[tilde, &completion[e_index..]].concat()));
                            for completion in iterator {
                                let expanded = &completion[e_index..];
                                completions.push(escape(&[tilde, expanded].concat()));
                            }
                        }
                    }
                }

                return completions;
            }
        }

        self.inner.completions(&unescape(start)).iter().map(|x| escape(x.as_str())).collect()
    }
}

/// Escapes filenames from the completer so that special characters will be properly escaped.
///
/// NOTE: Perhaps we should submit a PR to Liner to add a &'static [u8] field to
/// `FilenameCompleter` so that we don't have to perform the escaping ourselves?
fn escape(input: &str) -> String {
    let mut output = Vec::with_capacity(input.len());
    for character in input.bytes() {
        match character {
            b'('
            | b')'
            | b'['
            | b']'
            | b'&'
            | b'$'
            | b'@'
            | b'{'
            | b'}'
            | b'<'
            | b'>'
            | b';'
            | b'"'
            | b'\'' => output.push(b'\\'),
            _ => (),
        }
        output.push(character);
    }
    unsafe { String::from_utf8_unchecked(output) }
}

/// Unescapes filenames to be passed into the completer
fn unescape(input: &str) -> String {
    let mut output = Vec::with_capacity(input.len());
    let mut bytes = input.bytes();
    while let Some(b) = bytes.next() {
        match b {
            b'\\' => if let Some(next) = bytes.next() {
                output.push(next);
            } else {
                output.push(b'\\')
            },
            _ => output.push(b),
        }
    }
    unsafe { String::from_utf8_unchecked(output) }
}

/// A completer that combines suggestions from multiple completers.
#[derive(Clone, Eq, PartialEq)]
pub(crate) struct MultiCompleter<A, B>
    where A: Completer,
          B: Completer
{
    a: Vec<A>,
    b: B,
}

impl<A, B> MultiCompleter<A, B>
    where A: Completer,
          B: Completer
{
    pub(crate) fn new(a: Vec<A>, b: B) -> MultiCompleter<A, B> { MultiCompleter { a: a, b: b } }
}

impl<A, B> Completer for MultiCompleter<A, B>
    where A: Completer,
          B: Completer
{
    fn completions(&self, start: &str) -> Vec<String> {
        let mut completions = self.b.completions(start);
        for x in &self.a {
            completions.extend_from_slice(&x.completions(start));
        }
        completions
    }
}
<commit_msg>Fix #554 Closes #554<commit_after>use super::directory_stack::DirectoryStack;
use super::variables::Variables;
use liner::{Completer, FilenameCompleter};

/// Performs escaping to an inner `FilenameCompleter` to enable a handful of special cases
/// needed by the shell, such as expanding '~' to a home directory, or adding a backslash
/// when a special character is contained within an expanded filename.
pub(crate) struct IonFileCompleter {
    /// The completer that this completer is  handling.
    inner: FilenameCompleter,
    /// A pointer to the directory stack in the shell.
    dir_stack: *const DirectoryStack,
    /// A pointer to the variables map in the shell.
    vars: *const Variables,
}

impl IonFileCompleter {
    pub(crate) fn new(
        path: Option<&str>,
        dir_stack: *const DirectoryStack,
        vars: *const Variables,
    ) -> IonFileCompleter {
        IonFileCompleter {
            inner:     FilenameCompleter::new(path),
            dir_stack: dir_stack,
            vars:      vars,
        }
    }
}

impl Completer for IonFileCompleter {
    /// When the tab key is pressed, **Liner** will use this method to perform completions of
    /// filenames. As our `IonFileCompleter` is a wrapper around **Liner**'s
    /// `FilenameCompleter`,
    /// the purpose of our custom `Completer` is to expand possible `~` characters in the
    /// `start`
    /// value that we receive from the prompt, grab completions from the inner
    /// `FilenameCompleter`,
    /// and then escape the resulting filenames, as well as remove the expanded form of the `~`
    /// character and re-add the `~` character in it's place.
    fn completions(&self, start: &str) -> Vec<String> {
        // Only if the first character is a tilde character will we perform expansions
        if start.starts_with('~') {
            // Dereferencing the raw pointers here should be entirely safe, theoretically,
            // because no changes will occur to either of the underlying references in the
            // duration between creation of the completers and execution of their completions.
            if let Some(expanded) = unsafe { (*self.vars).tilde_expansion(start, &*self.dir_stack) }
            {
                // Now we obtain completions for the `expanded` form of the `start` value.
                let completions = self.inner.completions(&expanded);
                let mut iterator = completions.iter();

                // And then we will need to take those completions and remove the expanded form
                // of the tilde pattern and replace it with that pattern yet again.
                let mut completions = Vec::new();

                // We can do that by obtaining the index position where the tilde character ends.
                // We don't search with `~` because we also want to handle other tilde variants.
                let t_index = start.find('/').unwrap_or(1);
                // `tilde` is the tilde pattern, and `search` is the pattern that follows.
                let (tilde, search) = start.split_at(t_index as usize);

                if search.len() < 2 {
                    // If the length of the search pattern is less than 2, the search pattern is
                    // empty, and thus the completions actually contain files and directories in
                    // the home directory.

                    // The tilde pattern will actually be our `start` command in itself,
                    // and the completed form will be all of the characters beyond the length of
                    // the expanded form of the tilde pattern.
                    for completion in iterator {
                        completions.push([start, &completion[expanded.len()..]].concat());
                    }
                } else {
                    // To save processing time, we should get obtain the index position where our
                    // search pattern begins, and re-use that index to slice the completions so
                    // that we may re-add the tilde character with the completion that follows.
                    if let Some(completion) = iterator.next() {
                        if let Some(e_index) = completion.find(search) {
                            completions.push(escape(&[tilde, &completion[e_index..]].concat()));
                            for completion in iterator {
                                let expanded = &completion[e_index..];
                                completions.push(escape(&[tilde, expanded].concat()));
                            }
                        }
                    }
                }

                return completions;
            }
        }

        self.inner.completions(&unescape(start)).iter().map(|x| escape(x.as_str())).collect()
    }
}

/// Escapes filenames from the completer so that special characters will be properly escaped.
///
/// NOTE: Perhaps we should submit a PR to Liner to add a &'static [u8] field to
/// `FilenameCompleter` so that we don't have to perform the escaping ourselves?
fn escape(input: &str) -> String {
    let mut output = Vec::with_capacity(input.len());
    for character in input.bytes() {
        match character {
            b'('
            | b')'
            | b'['
            | b']'
            | b'&'
            | b'$'
            | b'@'
            | b'{'
            | b'}'
            | b'<'
            | b'>'
            | b';'
            | b'"'
            | b'\''
            | b'#'
            | b'^'
            | b'*' => output.push(b'\\'),
            _ => (),
        }
        output.push(character);
    }
    unsafe { String::from_utf8_unchecked(output) }
}

/// Unescapes filenames to be passed into the completer
fn unescape(input: &str) -> String {
    let mut output = Vec::with_capacity(input.len());
    let mut bytes = input.bytes();
    while let Some(b) = bytes.next() {
        match b {
            b'\\' => if let Some(next) = bytes.next() {
                output.push(next);
            } else {
                output.push(b'\\')
            },
            _ => output.push(b),
        }
    }
    unsafe { String::from_utf8_unchecked(output) }
}

/// A completer that combines suggestions from multiple completers.
#[derive(Clone, Eq, PartialEq)]
pub(crate) struct MultiCompleter<A, B>
    where A: Completer,
          B: Completer
{
    a: Vec<A>,
    b: B,
}

impl<A, B> MultiCompleter<A, B>
    where A: Completer,
          B: Completer
{
    pub(crate) fn new(a: Vec<A>, b: B) -> MultiCompleter<A, B> { MultiCompleter { a: a, b: b } }
}

impl<A, B> Completer for MultiCompleter<A, B>
    where A: Completer,
          B: Completer
{
    fn completions(&self, start: &str) -> Vec<String> {
        let mut completions = self.b.completions(start);
        for x in &self.a {
            completions.extend_from_slice(&x.completions(start));
        }
        completions
    }
}
<|endoftext|>


<commit_before>use super::scheduler_future::*;

use futures::prelude::*;
use futures::task;
use futures::task::{Poll};
use futures::channel::oneshot;

use std::mem;
use std::pin::*;

///
/// The state of a SyncFuture operation
///
enum SyncFutureState<TFn, TFuture>
where TFuture: Future {
    /// Waiting for the queue to start running the future
    WaitingForQueue(oneshot::Receiver<()>, TFn),

    /// Evaluating an active future for its result
    WaitingForFuture(TFuture),

    /// The sync future has completed and now we're waiting for the scheduler to complete
    WaitingForScheduler(Box<TFuture::Output>),

    /// Finished evaluating
    Completed
}

///
/// Represents a future that runs synchronously with a queue
///
/// The future is only run in an exclusive time slot within the queue - this property is used to guarantee the
/// safety of `Desync::future_sync`, which provides exclusive access to the data store while the future is running.
/// The queue is allowed to continue once the returned future has completed.
///
pub struct SyncFuture<TFn, TFuture>
where   TFn:                Send+FnOnce() -> TFuture,
        TFuture:            Send+Future,
        TFuture::Output:    Send {
    /// The state of this future
    state: SyncFutureState<TFn, TFuture>,

    /// Tracks this future on the scheduler (this allows polling this future to invoke desync's thread-stealing semantics instead of leaving the queue scheduling to a separate thread)
    scheduler_future: SchedulerFuture<()>,

    /// Signals when the future has finished running (None if this future is completed)
    task_finished: Option<oneshot::Sender<()>>
}

impl<TFn, TFuture> SyncFuture<TFn, TFuture>
where   TFn:                Send+FnOnce() -> TFuture,
        TFuture:            Send+Future,
        TFuture::Output:    Send {
    ///
    /// Creates a new SyncFuture
    ///
    pub fn new(create_future: TFn, scheduler_future: SchedulerFuture<()>, queue_ready: oneshot::Receiver<()>, task_finished: oneshot::Sender<()>) -> SyncFuture<TFn, TFuture> {
        SyncFuture {
            state:              SyncFutureState::WaitingForQueue(queue_ready, create_future),
            scheduler_future:   scheduler_future,
            task_finished:      Some(task_finished)
        }
    }
}

impl<TFn, TFuture> Future for SyncFuture<TFn, TFuture>
where   TFn:                Unpin+Send+FnOnce() -> TFuture,
        TFuture:            Unpin+Send+Future,
        TFuture::Output:    Send {
    type Output = Result<TFuture::Output, oneshot::Canceled>;

    fn poll(mut self: Pin<&mut Self>, context: &mut task::Context) -> Poll<Self::Output> {
        use self::SyncFutureState::*;

        // Rust doesn't seem to have a way to let us update the state in-place, so we need to swap out the old state and swap in the new state
        let mut result;
        let mut state = Completed;
        mem::swap(&mut state, &mut self.state);

        // Update the state now we own it
        loop {
            // Set to true if a 'pending' result should trigger another state update (eg, if we start a new future, we should poll it)
            let mut retry = false;

            state = match state {
                WaitingForQueue(mut recv, create_future) => {
                    // Check the scheduler future (give it a chance to steal the thread)
                    if let Poll::Ready(Err(_)) = self.scheduler_future.poll_unpin(context) {
                        // The queue will never get to the point of polling this future
                        result = Poll::Ready(Err(oneshot::Canceled));
                        self.task_finished.take().map(|finished| finished.send(()));
                        Completed
                    } else {
                        // Poll the receiver
                        match recv.poll_unpin(context) {
                            Poll::Ready(Ok(())) => {
                                // Start the future
                                let mut future = create_future();

                                // Poll it immediately to determine its status
                                if let Poll::Ready(future_result) = future.poll_unpin(context) {
                                    // Future has completed
                                    result = Poll::Pending;
                                    self.task_finished.take().map(|finished| finished.send(()));

                                    retry = true;
                                    WaitingForScheduler(Box::new(future_result))
                                } else {
                                    // Future is still running
                                    result = Poll::Pending;
                                    WaitingForFuture(future)
                                }
                            }

                            Poll::Ready(Err(_)) => {
                                // Future never became ready
                                result = Poll::Ready(Err(oneshot::Canceled));
                                Completed
                            }

                            Poll::Pending => {
                                // Waiting for the queue to start this future
                                result = Poll::Pending;
                                WaitingForQueue(recv, create_future)
                            }
                        }
                    }
                }

                WaitingForFuture(mut future) => {
                    if let Poll::Ready(future_result) = future.poll_unpin(context) {
                        // Future has completed
                        result = Poll::Pending;
                        self.task_finished.take().map(|finished| finished.send(()));

                        retry = true;
                        WaitingForScheduler(Box::new(future_result))
                    } else {
                        // Future is still running
                        result = Poll::Pending;
                        WaitingForFuture(future)
                    }
                }

                WaitingForScheduler(future_result) => {
                    // Poll until the scheduler has finished running the task entirely (can deadlock while draining if we don't)
                    if let Poll::Ready(_) = self.scheduler_future.poll_unpin(context) {
                        result = Poll::Ready(Ok(*future_result));
                        Completed
                    } else {
                        result = Poll::Pending;
                        WaitingForScheduler(future_result)
                    }
                }

                Completed => {
                    // Polling after the result has been returned
                    result = Poll::Ready(Err(oneshot::Canceled));
                    Completed
                }
            };

            // Finish once retry is left at false
            if !retry {
                break;
            }
        }

        // Swap the state back into the structure
        self.state = state;

        result
    }
}
<commit_msg>Can simplify the step where we need to poll the future immediately using the retry flag<commit_after>use super::scheduler_future::*;

use futures::prelude::*;
use futures::task;
use futures::task::{Poll};
use futures::channel::oneshot;

use std::mem;
use std::pin::*;

///
/// The state of a SyncFuture operation
///
enum SyncFutureState<TFn, TFuture>
where TFuture: Future {
    /// Waiting for the queue to start running the future
    WaitingForQueue(oneshot::Receiver<()>, TFn),

    /// Evaluating an active future for its result
    WaitingForFuture(TFuture),

    /// The sync future has completed and now we're waiting for the scheduler to complete
    WaitingForScheduler(Box<TFuture::Output>),

    /// Finished evaluating
    Completed
}

///
/// Represents a future that runs synchronously with a queue
///
/// The future is only run in an exclusive time slot within the queue - this property is used to guarantee the
/// safety of `Desync::future_sync`, which provides exclusive access to the data store while the future is running.
/// The queue is allowed to continue once the returned future has completed.
///
pub struct SyncFuture<TFn, TFuture>
where   TFn:                Send+FnOnce() -> TFuture,
        TFuture:            Send+Future,
        TFuture::Output:    Send {
    /// The state of this future
    state: SyncFutureState<TFn, TFuture>,

    /// Tracks this future on the scheduler (this allows polling this future to invoke desync's thread-stealing semantics instead of leaving the queue scheduling to a separate thread)
    scheduler_future: SchedulerFuture<()>,

    /// Signals when the future has finished running (None if this future is completed)
    task_finished: Option<oneshot::Sender<()>>
}

impl<TFn, TFuture> SyncFuture<TFn, TFuture>
where   TFn:                Send+FnOnce() -> TFuture,
        TFuture:            Send+Future,
        TFuture::Output:    Send {
    ///
    /// Creates a new SyncFuture
    ///
    pub fn new(create_future: TFn, scheduler_future: SchedulerFuture<()>, queue_ready: oneshot::Receiver<()>, task_finished: oneshot::Sender<()>) -> SyncFuture<TFn, TFuture> {
        SyncFuture {
            state:              SyncFutureState::WaitingForQueue(queue_ready, create_future),
            scheduler_future:   scheduler_future,
            task_finished:      Some(task_finished)
        }
    }
}

impl<TFn, TFuture> Future for SyncFuture<TFn, TFuture>
where   TFn:                Unpin+Send+FnOnce() -> TFuture,
        TFuture:            Unpin+Send+Future,
        TFuture::Output:    Send {
    type Output = Result<TFuture::Output, oneshot::Canceled>;

    fn poll(mut self: Pin<&mut Self>, context: &mut task::Context) -> Poll<Self::Output> {
        use self::SyncFutureState::*;

        // Rust doesn't seem to have a way to let us update the state in-place, so we need to swap out the old state and swap in the new state
        let mut result;
        let mut state = Completed;
        mem::swap(&mut state, &mut self.state);

        // Update the state now we own it
        loop {
            // Set to true if a 'pending' result should trigger another state update (eg, if we start a new future, we should poll it)
            let mut retry = false;

            state = match state {
                WaitingForQueue(mut recv, create_future) => {
                    // Check the scheduler future (give it a chance to steal the thread)
                    if let Poll::Ready(Err(_)) = self.scheduler_future.poll_unpin(context) {
                        // The queue will never get to the point of polling this future
                        result = Poll::Ready(Err(oneshot::Canceled));
                        self.task_finished.take().map(|finished| finished.send(()));
                        Completed
                    } else {
                        // Poll the receiver
                        match recv.poll_unpin(context) {
                            Poll::Ready(Ok(())) => {
                                // Start the future
                                let future = create_future();

                                // Poll it immediately to determine its status
                                result = Poll::Pending;

                                retry = true;
                                WaitingForFuture(future)
                            }

                            Poll::Ready(Err(_)) => {
                                // Future never became ready
                                result = Poll::Ready(Err(oneshot::Canceled));
                                Completed
                            }

                            Poll::Pending => {
                                // Waiting for the queue to start this future
                                result = Poll::Pending;
                                WaitingForQueue(recv, create_future)
                            }
                        }
                    }
                }

                WaitingForFuture(mut future) => {
                    if let Poll::Ready(future_result) = future.poll_unpin(context) {
                        // Future has completed
                        result = Poll::Pending;
                        self.task_finished.take().map(|finished| finished.send(()));

                        retry = true;
                        WaitingForScheduler(Box::new(future_result))
                    } else {
                        // Future is still running
                        result = Poll::Pending;
                        WaitingForFuture(future)
                    }
                }

                WaitingForScheduler(future_result) => {
                    // Poll until the scheduler has finished running the task entirely (can deadlock while draining if we don't)
                    if let Poll::Ready(_) = self.scheduler_future.poll_unpin(context) {
                        result = Poll::Ready(Ok(*future_result));
                        Completed
                    } else {
                        result = Poll::Pending;
                        WaitingForScheduler(future_result)
                    }
                }

                Completed => {
                    // Polling after the result has been returned
                    result = Poll::Ready(Err(oneshot::Canceled));
                    Completed
                }
            };

            // Finish once retry is left at false
            if !retry {
                break;
            }
        }

        // Swap the state back into the structure
        self.state = state;

        result
    }
}
<|endoftext|>


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

use sync::Arc;
#[cfg(target_os="linux")]
use libc::c_void;

use glfw::{WindowEvent, Glfw, Context, FullScreen};
use glfw::{Windowed, RenderContext};
use glfw;
use nice_glfw;
use gl;

use collections::TrieMap;

use ovr;

use input;

pub type WindowId = uint;

struct WindowHandle {
    window: glfw::Window,
    receiver: Receiver<(f64, WindowEvent)>,
}

pub struct IOManager {
    glfw: Glfw,
    ovr: Option<ovr::Ovr>,
    windows: TrieMap<WindowHandle>,
    window_id: uint
}

impl IOManager {
    pub fn new(glfw: glfw::Glfw) -> IOManager {
        IOManager {
            glfw: glfw,
            ovr: None,
            windows: TrieMap::new(),
            window_id: 0
        }
    }

    fn add_window(&mut self, window: glfw::Window, recv: Receiver<(f64, WindowEvent)>) -> InputHandle {
        let id = self.window_id;
        self.window_id += 1;

        self.windows.insert(id, {
            WindowHandle {
                window: window,
                receiver: recv
            }
        });

        InputHandle{ handle: id }
    }

    fn create_window_context(&self, width: u32, height: u32, name: &str, mode: glfw::WindowMode)
            -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {

        nice_glfw::WindowBuilder::new(&self.glfw)
            .try_modern_context_hints()
            .size(width, height)
            .title(name)
            .mode(mode)
            .create()
    }

    pub fn window(&mut self, size: (u32, u32)) -> Option<Window> {
        let (width, height) = size;
        let win_opt = self.create_window_context(width, height, "Snowmew", Windowed);
        let (mut window, events) = match win_opt {
            Some((window, events)) => (window, events),
            None => return None
        };

        window.make_current();
        gl::load_with(|name| self.glfw.get_proc_address_raw(name));
        self.glfw.set_swap_interval(0);
        glfw::make_context_current(None);

        window.set_all_polling(true);
        window.show();
        let version = window.get_context_version();
        let rc = window.render_context();
        let handle = self.add_window(window, events);

        Some(Window {
            handle: handle,
            render: rc,
            version: (version.major, version.minor),
            hmd: None,
            os_spec: WindowOSSpec::new(&self.glfw)
        })
    }

    pub fn primary(&mut self, size: (u32, u32)) -> Option<Window> {
        let screen = {
            self.glfw.with_primary_monitor(|display| {
                let display = display.unwrap();
                let (width, height) = size;
                self.create_window_context(width, height, "Snowmew Fullscreen", FullScreen(display))
            })
        };

        match screen {
            None => None,
            Some((mut window, events)) => {
                window.make_current();
                gl::load_with(|name| self.glfw.get_proc_address_raw(name));
                self.glfw.set_swap_interval(0);
                glfw::make_context_current(None);

                window.set_all_polling(true);
                window.show();
                let version = window.get_context_version();
                let rc = window.render_context();
                let handle = self.add_window(window, events);

                Some(Window {
                    handle: handle,
                    render: rc,
                    version: (version.major, version.minor),
                    hmd: None,
                    os_spec: WindowOSSpec::new(&self.glfw)
                })
            }
        }

    }

    pub fn get_primary_resolution(&self) -> (u32, u32) {
        self.glfw.with_primary_monitor(|display| {
            let display = display.expect("Could not get primnay display");
            let vm = display.get_video_mode().expect("Could not get video mode");
            (vm.width, vm.height)
        })
    }

    pub fn get_primary_position(&self) -> (i32, i32) {
        self.glfw.with_primary_monitor(|display| {
            let display = display.expect("Could not get primnay display");
            display.get_pos()
        })
    }

    #[cfg(target_os="linux")]
    fn create_hmd_window(&self, hmd: &ovr::HmdDescription) -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {
        self.glfw.with_connected_monitors(|monitors| {
            for m in monitors.iter() {
                let (x, y) = m.get_pos();
                if x == hmd.window_position.x &&
                   y == hmd.window_position.y {
                    let (width, height) = (hmd.resolution.x, hmd.resolution.y);
                    let win_opt = self.create_window_context(width as u32, height as u32, "Snowmew Fullscreen", FullScreen(m));
                    let (window, events) = match win_opt {
                        Some((window, events)) => (window, events),
                        None => return None
                    };

                    return Some((window, events));
                }
            }

            // fallback if we could not guess at the screen
            let (width, height) = (hmd.resolution.x, hmd.resolution.y);
            let win_opt = self.glfw.create_window(width as u32, height as u32, "Snowmew", Windowed);
            let (window, events) = match win_opt {
                Some((window, events)) => (window, events),
                None => return None
            };

            // move viewport
            let (dx, dy) = (hmd.window_position.x, hmd.window_position.y);
            window.set_pos(dx as i32, dy as i32);

            Some((window, events))

        })
    }

    #[cfg(target_os="macos")]
    fn create_hmd_window(&self, hmd: &ovr::HmdDescription) -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {
        self.glfw.with_connected_monitors(|monitors| {
            for m in monitors.iter() {
                if !m.get_name().as_slice().contains("Rift") {
                    continue;
                }

                let (width, height) = (hmd.resolution.x, hmd.resolution.y);
                let win_opt = self.create_window_context(width as u32, height as u32, "Snowmew Fullscreen", FullScreen(m));
                let (window, events) = match win_opt {
                    Some((window, events)) => (window, events),
                    None => return None
                };

                return Some((window, events));
            }
            None
        })
    }

    pub fn hmd(&mut self) -> Option<Window> {
        if !self.setup_ovr() {
            return None;
        }

        let (window, events, rc, hmd) = {
            let hmd = match self.ovr.as_ref().unwrap().first_hmd() {
                Some(hmd) => hmd,
                None => return None
            };
            let hmdinfo = hmd.get_description();

            let (mut window, events) = match self.create_hmd_window(&hmdinfo) {
                Some((window, events)) => (window, events),
                None => return None
            };

            window.make_current();
            gl::load_with(|name| self.glfw.get_proc_address_raw(name));
            self.glfw.set_swap_interval(1);
            glfw::make_context_current(None);

            window.set_all_polling(true);
            window.show();

            let rc = window.render_context();
            (window, events, rc, hmd)
        };

        let version = window.get_context_version();
        let handle = self.add_window(window, events);

        Some(Window {
            handle: handle,
            render: rc,
            version: (version.major, version.minor),
            hmd: Some(Arc::new(hmd)),
            os_spec: WindowOSSpec::new(&self.glfw)
        })
    }

    pub fn wait(&mut self) {
        self.glfw.wait_events();
    }

    pub fn poll(&mut self) {
        self.glfw.poll_events();
    }

    pub fn next_event(&mut self, handle: &InputHandle) -> input::EventGroup {
        let evt = self.windows.find_mut(&handle.handle)
        .map(|rx| {
            for (_, evt) in glfw::flush_messages(&rx.receiver) {
                let evt = input::Event::from_glfw(evt);
                if evt != input::NopEvent {
                    return evt;
                }
            }
            input::NopEvent
        });

        match evt {
            Some(e) => e,
            _ => input::NopEvent
        }
    }

    pub fn should_close(&mut self, handle: &InputHandle) -> bool {
        let should_close = self.windows.find_mut(&handle.handle)
        .map(|win| win.window.should_close());

        if let Some(x) = should_close {
            x
        } else {
            true
        }
    }

    fn setup_ovr(&mut self) -> bool {
        if self.ovr.is_some() &&
           self.ovr.as_ref().unwrap().detect() > 0 {
            return true;
        }

        if self.ovr.is_none() {
            self.ovr = ovr::Ovr::init();
        }

        self.ovr.is_some() && self.ovr.as_ref().unwrap().detect() > 0
    }

    pub fn set_window_position(&mut self, window: &Window, pos: (i32, i32)) {
        let (w, h) = pos;
        match self.windows.find_mut(&window.handle.handle) {
            Some(win) => win.window.set_pos(w, h),
            None => ()
        }
    }

    pub fn get_framebuffer_size(&mut self, window: &Window) -> (i32, i32) {
        match self.windows.find_mut(&window.handle.handle) {
            Some(win) => win.window.get_framebuffer_size(),
            None => (0, 0)
        }
    }

    pub fn get_proc_address(&self, name: &str) -> *const ::libc::c_void {
        self.glfw.get_proc_address_raw(name)
    }
}

#[deriving(Clone)]
pub struct InputHandle {
    handle: uint,
}

#[cfg(target_os="macos")]
struct WindowOSSpec;

#[cfg(target_os="macos")]
impl WindowOSSpec {
    fn new(_: &Glfw) -> WindowOSSpec {WindowOSSpec}
}

#[cfg(target_os="linux")]
struct WindowOSSpec {
    display: *mut c_void
}

#[cfg(target_os="linux")]
impl WindowOSSpec {
    fn new(glfw: &Glfw) -> WindowOSSpec {
        WindowOSSpec {
            display: glfw.get_x11_display()
        }
    }
}

pub struct Window {
    handle: InputHandle,
    render: RenderContext,
    version: (uint, uint),
    hmd: Option<Arc<ovr::Hmd>>,
    os_spec: WindowOSSpec
}

impl Window {
    pub fn swap_buffers(&self) {
        self.render.swap_buffers()
    }

    pub fn make_context_current(&self) {
        self.render.make_current()
    }

    pub fn get_context_version(&self) -> (uint, uint) {
        self.version
    }

    pub fn handle(&self) -> InputHandle {
        self.handle.clone()
    }

    pub fn is_hmd(&self) -> bool {
        self.hmd.is_some()
    }

    pub fn get_hmd<'a>(&'a self) -> Arc<ovr::Hmd> {
        self.hmd.as_ref().expect("no hmd device found!").clone()
    }

    /// Wrapper for `glfwGetGLXContext`
    #[cfg(target_os="linux")]
    pub fn get_x11_display(&self) -> *mut c_void {
        self.os_spec.display
    }
}

#[deriving(Clone, Encodable, Decodable)]
pub struct IoState {
    pub render_size: (uint, uint),
    pub size: (uint, uint),
    pub position: (int, int),
    pub show_mouse: bool,
    pub mouse_over: bool
}

impl IoState {
    pub fn new() -> IoState {
        IoState {
            render_size: (0, 0),
            size: (0, 0),
            position: (0, 0),
            show_mouse: true,
            mouse_over: false
        }
    }

    pub fn window_action(&mut self, win: input::WindowEvent) {
        match win {
            input::Size(x, y) => {
                self.size = (x as uint, y as uint);
            }
            input::Position(x, y) => {
                self.position = (x, y);
            }
            input::MouseOver(mouse) => {
                self.mouse_over = mouse;
            }
        }
    }
}<commit_msg>fixed input buffer size on osx<commit_after>//   Copyright 2014 Colin Sherratt
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

use sync::Arc;
#[cfg(target_os="linux")]
use libc::c_void;

use glfw::{WindowEvent, Glfw, Context, FullScreen};
use glfw::{Windowed, RenderContext};
use glfw;
use nice_glfw;
use gl;

use collections::TrieMap;

use ovr;

use input;

pub type WindowId = uint;

struct WindowHandle {
    window: glfw::Window,
    forced_event: Option<WindowEvent>,
    receiver: Receiver<(f64, WindowEvent)>,
}

pub struct IOManager {
    glfw: Glfw,
    ovr: Option<ovr::Ovr>,
    windows: TrieMap<WindowHandle>,
    window_id: uint
}

impl IOManager {
    pub fn new(glfw: glfw::Glfw) -> IOManager {
        IOManager {
            glfw: glfw,
            ovr: None,
            windows: TrieMap::new(),
            window_id: 0
        }
    }

    fn add_window(&mut self, window: glfw::Window, recv: Receiver<(f64, WindowEvent)>) -> InputHandle {
        let id = self.window_id;
        self.window_id += 1;

        let (w, h) = window.get_framebuffer_size();

        self.windows.insert(id, {
            WindowHandle {
                window: window,
                forced_event: Some(glfw::FramebufferSizeEvent(w, h)),
                receiver: recv
            }
        });

        InputHandle{ handle: id }
    }

    fn create_window_context(&self, width: u32, height: u32, name: &str, mode: glfw::WindowMode)
            -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {

        nice_glfw::WindowBuilder::new(&self.glfw)
            .try_modern_context_hints()
            .size(width, height)
            .title(name)
            .mode(mode)
            .create()
    }

    pub fn window(&mut self, size: (u32, u32)) -> Option<Window> {
        let (width, height) = size;
        let win_opt = self.create_window_context(width, height, "Snowmew", Windowed);
        let (mut window, events) = match win_opt {
            Some((window, events)) => (window, events),
            None => return None
        };

        window.make_current();
        gl::load_with(|name| self.glfw.get_proc_address_raw(name));
        self.glfw.set_swap_interval(0);
        glfw::make_context_current(None);

        window.set_all_polling(true);
        window.show();
        let version = window.get_context_version();
        let rc = window.render_context();
        let handle = self.add_window(window, events);

        Some(Window {
            handle: handle,
            render: rc,
            version: (version.major, version.minor),
            hmd: None,
            os_spec: WindowOSSpec::new(&self.glfw)
        })
    }

    pub fn primary(&mut self, size: (u32, u32)) -> Option<Window> {
        let screen = {
            self.glfw.with_primary_monitor(|display| {
                let display = display.unwrap();
                let (width, height) = size;
                self.create_window_context(width, height, "Snowmew Fullscreen", FullScreen(display))
            })
        };

        match screen {
            None => None,
            Some((mut window, events)) => {
                window.make_current();
                gl::load_with(|name| self.glfw.get_proc_address_raw(name));
                self.glfw.set_swap_interval(0);
                glfw::make_context_current(None);

                window.set_all_polling(true);
                window.show();
                let version = window.get_context_version();
                let rc = window.render_context();
                let handle = self.add_window(window, events);

                Some(Window {
                    handle: handle,
                    render: rc,
                    version: (version.major, version.minor),
                    hmd: None,
                    os_spec: WindowOSSpec::new(&self.glfw)
                })
            }
        }

    }

    pub fn get_primary_resolution(&self) -> (u32, u32) {
        self.glfw.with_primary_monitor(|display| {
            let display = display.expect("Could not get primnay display");
            let vm = display.get_video_mode().expect("Could not get video mode");
            (vm.width, vm.height)
        })
    }

    pub fn get_primary_position(&self) -> (i32, i32) {
        self.glfw.with_primary_monitor(|display| {
            let display = display.expect("Could not get primnay display");
            display.get_pos()
        })
    }

    #[cfg(target_os="linux")]
    fn create_hmd_window(&self, hmd: &ovr::HmdDescription) -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {
        self.glfw.with_connected_monitors(|monitors| {
            for m in monitors.iter() {
                let (x, y) = m.get_pos();
                if x == hmd.window_position.x &&
                   y == hmd.window_position.y {
                    let (width, height) = (hmd.resolution.x, hmd.resolution.y);
                    let win_opt = self.create_window_context(width as u32, height as u32, "Snowmew Fullscreen", FullScreen(m));
                    let (window, events) = match win_opt {
                        Some((window, events)) => (window, events),
                        None => return None
                    };

                    return Some((window, events));
                }
            }

            // fallback if we could not guess at the screen
            let (width, height) = (hmd.resolution.x, hmd.resolution.y);
            let win_opt = self.glfw.create_window(width as u32, height as u32, "Snowmew", Windowed);
            let (window, events) = match win_opt {
                Some((window, events)) => (window, events),
                None => return None
            };

            // move viewport
            let (dx, dy) = (hmd.window_position.x, hmd.window_position.y);
            window.set_pos(dx as i32, dy as i32);

            Some((window, events))

        })
    }

    #[cfg(target_os="macos")]
    fn create_hmd_window(&self, hmd: &ovr::HmdDescription) -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {
        self.glfw.with_connected_monitors(|monitors| {
            for m in monitors.iter() {
                if !m.get_name().as_slice().contains("Rift") {
                    continue;
                }

                let (width, height) = (hmd.resolution.x, hmd.resolution.y);
                let win_opt = self.create_window_context(width as u32, height as u32, "Snowmew Fullscreen", FullScreen(m));
                let (window, events) = match win_opt {
                    Some((window, events)) => (window, events),
                    None => return None
                };

                return Some((window, events));
            }
            None
        })
    }

    pub fn hmd(&mut self) -> Option<Window> {
        if !self.setup_ovr() {
            return None;
        }

        let (window, events, rc, hmd) = {
            let hmd = match self.ovr.as_ref().unwrap().first_hmd() {
                Some(hmd) => hmd,
                None => return None
            };
            let hmdinfo = hmd.get_description();

            let (mut window, events) = match self.create_hmd_window(&hmdinfo) {
                Some((window, events)) => (window, events),
                None => return None
            };

            window.make_current();
            gl::load_with(|name| self.glfw.get_proc_address_raw(name));
            self.glfw.set_swap_interval(1);
            glfw::make_context_current(None);

            window.set_all_polling(true);
            window.show();

            let rc = window.render_context();
            (window, events, rc, hmd)
        };

        let version = window.get_context_version();
        let handle = self.add_window(window, events);

        Some(Window {
            handle: handle,
            render: rc,
            version: (version.major, version.minor),
            hmd: Some(Arc::new(hmd)),
            os_spec: WindowOSSpec::new(&self.glfw)
        })
    }

    pub fn wait(&mut self) {
        self.glfw.wait_events();
    }

    pub fn poll(&mut self) {
        self.glfw.poll_events();
    }

    pub fn next_event(&mut self, handle: &InputHandle) -> input::EventGroup {
        let evt = self.windows.find_mut(&handle.handle)
        .map(|rx| {
            // this is a hack to inject the correct size into the event buffer
            match rx.forced_event.take() {
                Some(evt) => return input::Event::from_glfw(evt),
                None => ()
            };
            for (_, evt) in glfw::flush_messages(&rx.receiver) {
                let evt = input::Event::from_glfw(evt);
                if evt != input::NopEvent {
                    return evt;
                }
            }
            input::NopEvent
        });

        match evt {
            Some(e) => e,
            _ => input::NopEvent
        }
    }

    pub fn should_close(&mut self, handle: &InputHandle) -> bool {
        let should_close = self.windows.find_mut(&handle.handle)
        .map(|win| win.window.should_close());

        if let Some(x) = should_close {
            x
        } else {
            true
        }
    }

    fn setup_ovr(&mut self) -> bool {
        if self.ovr.is_some() &&
           self.ovr.as_ref().unwrap().detect() > 0 {
            return true;
        }

        if self.ovr.is_none() {
            self.ovr = ovr::Ovr::init();
        }

        self.ovr.is_some() && self.ovr.as_ref().unwrap().detect() > 0
    }

    pub fn set_window_position(&mut self, window: &Window, pos: (i32, i32)) {
        let (w, h) = pos;
        match self.windows.find_mut(&window.handle.handle) {
            Some(win) => win.window.set_pos(w, h),
            None => ()
        }
    }

    pub fn get_framebuffer_size(&mut self, window: &Window) -> (i32, i32) {
        match self.windows.find_mut(&window.handle.handle) {
            Some(win) => win.window.get_framebuffer_size(),
            None => (0, 0)
        }
    }

    pub fn get_proc_address(&self, name: &str) -> *const ::libc::c_void {
        self.glfw.get_proc_address_raw(name)
    }
}

#[deriving(Clone)]
pub struct InputHandle {
    handle: uint,
}

#[cfg(target_os="macos")]
struct WindowOSSpec;

#[cfg(target_os="macos")]
impl WindowOSSpec {
    fn new(_: &Glfw) -> WindowOSSpec {WindowOSSpec}
}

#[cfg(target_os="linux")]
struct WindowOSSpec {
    display: *mut c_void
}

#[cfg(target_os="linux")]
impl WindowOSSpec {
    fn new(glfw: &Glfw) -> WindowOSSpec {
        WindowOSSpec {
            display: glfw.get_x11_display()
        }
    }
}

pub struct Window {
    handle: InputHandle,
    render: RenderContext,
    version: (uint, uint),
    hmd: Option<Arc<ovr::Hmd>>,
    os_spec: WindowOSSpec
}

impl Window {
    pub fn swap_buffers(&self) {
        self.render.swap_buffers()
    }

    pub fn make_context_current(&self) {
        self.render.make_current()
    }

    pub fn get_context_version(&self) -> (uint, uint) {
        self.version
    }

    pub fn handle(&self) -> InputHandle {
        self.handle.clone()
    }

    pub fn is_hmd(&self) -> bool {
        self.hmd.is_some()
    }

    pub fn get_hmd<'a>(&'a self) -> Arc<ovr::Hmd> {
        self.hmd.as_ref().expect("no hmd device found!").clone()
    }

    /// Wrapper for `glfwGetGLXContext`
    #[cfg(target_os="linux")]
    pub fn get_x11_display(&self) -> *mut c_void {
        self.os_spec.display
    }
}

#[deriving(Clone, Encodable, Decodable)]
pub struct IoState {
    pub render_size: (uint, uint),
    pub size: (uint, uint),
    pub position: (int, int),
    pub show_mouse: bool,
    pub mouse_over: bool
}

impl IoState {
    pub fn new() -> IoState {
        IoState {
            render_size: (1, 1),
            size: (1, 1),
            position: (0, 0),
            show_mouse: true,
            mouse_over: false
        }
    }

    pub fn window_action(&mut self, win: input::WindowEvent) {
        match win {
            input::Size(x, y) => {
                self.size = (x as uint, y as uint);
            }
            input::Position(x, y) => {
                self.position = (x, y);
            }
            input::MouseOver(mouse) => {
                self.mouse_over = mouse;
            }
        }
    }
}<|endoftext|>


<commit_before>use anyhow::*;
use rocket;
use rocket::config::{Environment, LoggingLevel};
use rocket_contrib::serve::StaticFiles;
use std::path::PathBuf;
use std::sync::Arc;

use super::api;
use crate::db::DB;
use crate::index::CommandSender;

pub fn get_server(
	port: u16,
	auth_secret: &[u8],
	api_url: &str,
	web_url: &str,
	web_dir_path: &PathBuf,
	swagger_url: &str,
	swagger_dir_path: &PathBuf,
	db: DB,
	command_sender: Arc<CommandSender>,
) -> Result<rocket::Rocket> {
	let mut config = rocket::Config::build(Environment::Production)
		.log_level(LoggingLevel::Normal)
		.port(port)
		.keep_alive(0)
		.finalize()?;

	let encoded = base64::encode(auth_secret);
	config.set_secret_key(encoded)?;

	let swagger_routes_rank = 0;
	let web_routes_rank = swagger_routes_rank + 1;

	Ok(rocket::custom(config)
		.manage(db)
		.manage(command_sender)
		.mount(&api_url, api::get_routes())
		.mount(
			&swagger_url,
			StaticFiles::from(swagger_dir_path).rank(swagger_routes_rank),
		)
		.mount(
			&web_url,
			StaticFiles::from(web_dir_path).rank(web_routes_rank),
		))
}

pub fn run(
	port: u16,
	auth_secret: &[u8],
	api_url: String,
	web_url: String,
	web_dir_path: PathBuf,
	swagger_url: String,
	swagger_dir_path: PathBuf,
	db: DB,
	command_sender: Arc<CommandSender>,
) -> Result<()> {
	let server = get_server(
		port,
		auth_secret,
		&api_url,
		&web_url,
		&web_dir_path,
		&swagger_url,
		&swagger_dir_path,
		db,
		command_sender,
	)?;
	// TODO do this in main
	std::thread::spawn(move || {
		server.launch();
	});
	Ok(())
}
<commit_msg>Removed outdated TODO<commit_after>use anyhow::*;
use rocket;
use rocket::config::{Environment, LoggingLevel};
use rocket_contrib::serve::StaticFiles;
use std::path::PathBuf;
use std::sync::Arc;

use super::api;
use crate::db::DB;
use crate::index::CommandSender;

pub fn get_server(
	port: u16,
	auth_secret: &[u8],
	api_url: &str,
	web_url: &str,
	web_dir_path: &PathBuf,
	swagger_url: &str,
	swagger_dir_path: &PathBuf,
	db: DB,
	command_sender: Arc<CommandSender>,
) -> Result<rocket::Rocket> {
	let mut config = rocket::Config::build(Environment::Production)
		.log_level(LoggingLevel::Normal)
		.port(port)
		.keep_alive(0)
		.finalize()?;

	let encoded = base64::encode(auth_secret);
	config.set_secret_key(encoded)?;

	let swagger_routes_rank = 0;
	let web_routes_rank = swagger_routes_rank + 1;

	Ok(rocket::custom(config)
		.manage(db)
		.manage(command_sender)
		.mount(&api_url, api::get_routes())
		.mount(
			&swagger_url,
			StaticFiles::from(swagger_dir_path).rank(swagger_routes_rank),
		)
		.mount(
			&web_url,
			StaticFiles::from(web_dir_path).rank(web_routes_rank),
		))
}

pub fn run(
	port: u16,
	auth_secret: &[u8],
	api_url: String,
	web_url: String,
	web_dir_path: PathBuf,
	swagger_url: String,
	swagger_dir_path: PathBuf,
	db: DB,
	command_sender: Arc<CommandSender>,
) -> Result<()> {
	let server = get_server(
		port,
		auth_secret,
		&api_url,
		&web_url,
		&web_dir_path,
		&swagger_url,
		&swagger_dir_path,
		db,
		command_sender,
	)?;
	server.launch();
	Ok(())
}
<|endoftext|>


<commit_before>use std::sync::mpsc::{channel, Sender};
use std::thread::Thread;

use search;
use timer;

use super::types::{Cmd, Response};
use super::state::{State, Mode};

mod go_param;

pub fn process(state: &mut State, cmd: Cmd, output: &Sender<Response>) {
    match cmd {
        Cmd::Debug(val) => {
            state.search_state.as_mut().map(|x| { x.is_debug = val; } );
            state.search_tx.as_mut().map(|tx| { let _ = tx.send(search::Cmd::Stop); } );
        },
        Cmd::IsReady => {
            // TODO implement IsReady
            unimplemented!();
        },
        Cmd::Register(ref param) => {
            // TODO register
            unimplemented!();
        },
        cmd => {
            match state.mode {
                Mode::Init => {
                    if cmd == Cmd::Uci {
                        // TODO print id/option/uciok
                        state.mode = Mode::Wait;
                        unimplemented!();
                    }
                },
                Mode::Wait => {
                    match cmd {
                        Cmd::SetOption(ref name, ref val_opt) => {
                            // TODO maybe initialize
                            // TODO set options
                            unimplemented!();
                        },
                        Cmd::UciNewGame => {
                            // TODO note that ucinewgame supported
                            // TODO reset game status
                            state.mode = Mode::NewGame;
                            unimplemented!();
                        },
                        cmd @Cmd::SetupPosition(..) => {
                            if state.ucinewgame_support {
                                // TODO set up position for same game
                                state.mode = Mode::Ready;
                                unimplemented!();
                            } else {
                                process(state, Cmd::UciNewGame, output);
                                state.ucinewgame_support = false;
                                process(state, cmd, output);
                            }
                        },
                        _ => {},
                    }
                },
                Mode::NewGame => {
                    if let Cmd::SetupPosition(ref pos, ref from_to_vec) = cmd {
                        // TODO setup position for new game
                        state.mode = Mode::Ready;
                        unimplemented!();
                    }
                },
                Mode::Ready => {
                    if let Cmd::Go(param) = cmd {
                        go_param::setup(state, param);
                        let (search_tx, search_rx) = channel::<search::Cmd>();
                        let search_state = state.search_state.as_ref().unwrap().clone();
                        let output = output.clone();
                        let temp = Thread::scoped(move ||
                                                  search::start(search_state, search_rx, output));

                        state.search_tx = Some(search_tx.clone());
                        state.search_guard = Some(temp);

                        let time_data = state.time_data.clone().unwrap();
                        let c = state.search_state.as_ref().unwrap().pos.side_to_move();

                        Thread::spawn(move || timer::start(time_data, c, search_tx));

                        state.mode = Mode::Search;
                    }
                },
                Mode::Search => {
                    match cmd {
                        Cmd::PonderHit => {
                            // TODO ponder hit
                            unimplemented!();
                        },
                        Cmd::Stop => {
                            // TODO stop search
                            // Also if time is out
                            unimplemented!();
                        },
                        _ => {},
                    }
                },
            }
        },
    }
}
<commit_msg>Implement processing PonderHit and partially implement for Stop.<commit_after>use time::precise_time_ns;

use std::sync::mpsc::{channel, Sender};
use std::thread::Thread;

use search;
use timer;

use super::types::{Cmd, Response};
use super::state::{State, Mode};

mod go_param;

pub fn process(state: &mut State, cmd: Cmd, output: &Sender<Response>) {
    match cmd {
        Cmd::Debug(val) => {
            state.search_state.as_mut().map(|x| { x.is_debug = val; } );
            state.search_tx.as_mut().map(|tx| { let _ = tx.send(search::Cmd::Stop); } );
        },
        Cmd::IsReady => {
            // TODO implement IsReady
            unimplemented!();
        },
        Cmd::Register(ref param) => {
            // TODO register
            unimplemented!();
        },
        cmd => {
            match state.mode {
                Mode::Init => {
                    if cmd == Cmd::Uci {
                        // TODO print id/option/uciok
                        state.mode = Mode::Wait;
                        unimplemented!();
                    }
                },
                Mode::Wait => {
                    match cmd {
                        Cmd::SetOption(ref name, ref val_opt) => {
                            // TODO maybe initialize
                            // TODO set options
                            unimplemented!();
                        },
                        Cmd::UciNewGame => {
                            // TODO note that ucinewgame supported
                            // TODO reset game status
                            state.mode = Mode::NewGame;
                            unimplemented!();
                        },
                        cmd @Cmd::SetupPosition(..) => {
                            if state.ucinewgame_support {
                                // TODO set up position for same game
                                state.mode = Mode::Ready;
                                unimplemented!();
                            } else {
                                process(state, Cmd::UciNewGame, output);
                                state.ucinewgame_support = false;
                                process(state, cmd, output);
                            }
                        },
                        _ => {},
                    }
                },
                Mode::NewGame => {
                    if let Cmd::SetupPosition(ref pos, ref from_to_vec) = cmd {
                        // TODO setup position for new game
                        state.mode = Mode::Ready;
                        unimplemented!();
                    }
                },
                Mode::Ready => {
                    assert!(state.search_state.is_some());
                    if let Cmd::Go(param) = cmd {
                        go_param::setup(state, param);
                        let (search_tx, search_rx) = channel::<search::Cmd>();
                        let search_state = state.search_state.as_ref().unwrap().clone();
                        let output = output.clone();
                        let temp = Thread::scoped(move ||
                                                  search::start(search_state, search_rx, output));

                        state.search_tx = Some(search_tx.clone());
                        state.search_guard = Some(temp);

                        let time_data = state.time_data.clone().unwrap();
                        let c = state.search_state.as_ref().unwrap().pos.side_to_move();

                        Thread::spawn(move || timer::start(time_data, c, search_tx));

                        state.mode = Mode::Search;
                    }
                },
                Mode::Search => {
                    assert!(state.search_state.is_some());
                    assert!(state.search_guard.is_some());
                    assert!(state.search_tx.is_some());
                    match cmd {
                        Cmd::PonderHit => {
                            state.search_tx.as_ref().map(|ref tx| tx.send(search::Cmd::PonderHit));
                            state.search_state.as_mut().map(|ref mut x| x.param.ponder = false);
                            state.start_move_time = Some(precise_time_ns());
                        },
                        Cmd::Stop => {
                            state.search_tx.as_mut().map(|ref tx| tx.send(search::Cmd::Stop));
                            state.search_guard.take().map(|x| x.join());
                            state.search_tx = None;
                            state.mode = Mode::Wait;
                            state.start_search_time = None;
                            state.start_move_time = None;
                            state.time_data = None;
                            // TODO what to do about search_state
                            // TODO what to do about the timer thread
                            // TODO what if time is out
                            unimplemented!();
                        },
                        _ => {},
                    }
                },
            }
        },
    }
}
<|endoftext|>