<commit_before>//! Client-side Proc-Macro crate
//!
//! We separate proc-macro expanding logic to an extern program to allow
//! different implementations (e.g. wasm or dylib loading). And this crate
//! is used to provide basic infrastructure for communication between two
//! processes: Client (RA itself), Server (the external program)

mod rpc;
mod process;
pub mod msg;

use std::{
    ffi::OsStr,
    io,
    path::{Path, PathBuf},
    sync::Arc,
};

use tt::{SmolStr, Subtree};

use crate::process::{ProcMacroProcessSrv, ProcMacroProcessThread};

pub use rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask, ProcMacroKind};

#[derive(Debug, Clone)]
pub struct ProcMacroProcessExpander {
    process: Arc<ProcMacroProcessSrv>,
    dylib_path: PathBuf,
    name: SmolStr,
}

impl Eq for ProcMacroProcessExpander {}
impl PartialEq for ProcMacroProcessExpander {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name
            && self.dylib_path == other.dylib_path
            && Arc::ptr_eq(&self.process, &other.process)
    }
}

impl tt::TokenExpander for ProcMacroProcessExpander {
    fn expand(
        &self,
        subtree: &Subtree,
        _attr: Option<&Subtree>,
    ) -> Result<Subtree, tt::ExpansionError> {
        self.process.custom_derive(&self.dylib_path, subtree, &self.name)
    }
}

#[derive(Debug)]
enum ProcMacroClientKind {
    Process { process: Arc<ProcMacroProcessSrv>, thread: ProcMacroProcessThread },
    Dummy,
}

#[derive(Debug)]
pub struct ProcMacroClient {
    kind: ProcMacroClientKind,
}

impl ProcMacroClient {
    pub fn extern_process(
        process_path: PathBuf,
        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
    ) -> io::Result<ProcMacroClient> {
        let (thread, process) = ProcMacroProcessSrv::run(process_path, args)?;
        Ok(ProcMacroClient {
            kind: ProcMacroClientKind::Process { process: Arc::new(process), thread },
        })
    }

    pub fn dummy() -> ProcMacroClient {
        ProcMacroClient { kind: ProcMacroClientKind::Dummy }
    }

    pub fn by_dylib_path(&self, dylib_path: &Path) -> Vec<(SmolStr, Arc<dyn tt::TokenExpander>)> {
        match &self.kind {
            ProcMacroClientKind::Dummy => vec![],
            ProcMacroClientKind::Process { process, .. } => {
                let macros = match process.find_proc_macros(dylib_path) {
                    Err(err) => {
                        eprintln!("Failed to find proc macros. Error: {:#?}", err);
                        return vec![];
                    }
                    Ok(macros) => macros,
                };

                macros
                    .into_iter()
                    .filter_map(|(name, kind)| {
                        // FIXME: Support custom derive only for now.
                        match kind {
                            ProcMacroKind::CustomDerive => {
                                let name = SmolStr::new(&name);
                                let expander: Arc<dyn tt::TokenExpander> =
                                    Arc::new(ProcMacroProcessExpander {
                                        process: process.clone(),
                                        name: name.clone(),
                                        dylib_path: dylib_path.into(),
                                    });
                                Some((name, expander))
                            }
                            _ => None,
                        }
                    })
                    .collect()
            }
        }
    }
}
<commit_msg>Hacky support for fn-like proc macros<commit_after>//! Client-side Proc-Macro crate
//!
//! We separate proc-macro expanding logic to an extern program to allow
//! different implementations (e.g. wasm or dylib loading). And this crate
//! is used to provide basic infrastructure for communication between two
//! processes: Client (RA itself), Server (the external program)

mod rpc;
mod process;
pub mod msg;

use std::{
    ffi::OsStr,
    io,
    path::{Path, PathBuf},
    sync::Arc,
};

use tt::{SmolStr, Subtree};

use crate::process::{ProcMacroProcessSrv, ProcMacroProcessThread};

pub use rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask, ProcMacroKind};

#[derive(Debug, Clone)]
pub struct ProcMacroProcessExpander {
    process: Arc<ProcMacroProcessSrv>,
    dylib_path: PathBuf,
    name: SmolStr,
}

impl Eq for ProcMacroProcessExpander {}
impl PartialEq for ProcMacroProcessExpander {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name
            && self.dylib_path == other.dylib_path
            && Arc::ptr_eq(&self.process, &other.process)
    }
}

impl tt::TokenExpander for ProcMacroProcessExpander {
    fn expand(
        &self,
        subtree: &Subtree,
        _attr: Option<&Subtree>,
    ) -> Result<Subtree, tt::ExpansionError> {
        self.process.custom_derive(&self.dylib_path, subtree, &self.name)
    }
}

#[derive(Debug)]
enum ProcMacroClientKind {
    Process { process: Arc<ProcMacroProcessSrv>, thread: ProcMacroProcessThread },
    Dummy,
}

#[derive(Debug)]
pub struct ProcMacroClient {
    kind: ProcMacroClientKind,
}

impl ProcMacroClient {
    pub fn extern_process(
        process_path: PathBuf,
        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
    ) -> io::Result<ProcMacroClient> {
        let (thread, process) = ProcMacroProcessSrv::run(process_path, args)?;
        Ok(ProcMacroClient {
            kind: ProcMacroClientKind::Process { process: Arc::new(process), thread },
        })
    }

    pub fn dummy() -> ProcMacroClient {
        ProcMacroClient { kind: ProcMacroClientKind::Dummy }
    }

    pub fn by_dylib_path(&self, dylib_path: &Path) -> Vec<(SmolStr, Arc<dyn tt::TokenExpander>)> {
        match &self.kind {
            ProcMacroClientKind::Dummy => vec![],
            ProcMacroClientKind::Process { process, .. } => {
                let macros = match process.find_proc_macros(dylib_path) {
                    Err(err) => {
                        eprintln!("Failed to find proc macros. Error: {:#?}", err);
                        return vec![];
                    }
                    Ok(macros) => macros,
                };

                macros
                    .into_iter()
                    .filter_map(|(name, kind)| {
                        match kind {
                            ProcMacroKind::CustomDerive | ProcMacroKind::FuncLike => {
                                let name = SmolStr::new(&name);
                                let expander: Arc<dyn tt::TokenExpander> =
                                    Arc::new(ProcMacroProcessExpander {
                                        process: process.clone(),
                                        name: name.clone(),
                                        dylib_path: dylib_path.into(),
                                    });
                                Some((name, expander))
                            }
                            // FIXME: Attribute macro are currently unsupported.
                            ProcMacroKind::Attr => None,
                        }
                    })
                    .collect()
            }
        }
    }
}
<|endoftext|>


<commit_before>extern mod std;

use std::bitv;
use io::{ReaderUtil, WriterUtil};

// Computes a single solution to a given 9x9 sudoku
//
// Call with "-" to read input sudoku from stdin
//
// The expected line-based format is:
//
// 9,9
// <row>,<column>,<color>
// ...
//
// Row and column are 0-based (i.e. <= 8) and color is 1-based (>=1,<=9).
// A color of 0 indicates an empty field.
//
// If called without arguments, sudoku solves a built-in example sudoku
//

export grid_t, read_grid, solve_grid, write_grid;

// internal type of sudoku grids
type grid = ~[~[mut u8]];

// exported type of sudoku grids
enum grid_t { grid_ctor(grid), }

// read a sudoku problem from file f
fn read_grid(f: io::Reader) -> grid_t {
    assert f.read_line() == ~"9,9"; /* assert first line is exactly "9,9" */

    let g = vec::from_fn(10u, {|_i|
        vec::to_mut(vec::from_elem(10u, 0 as u8))
    });
    while !f.eof() {
        let comps = str::split_char(str::trim(f.read_line()), ',');
        if vec::len(comps) >= 3u {
            let row     = uint::from_str(comps[0]).get() as u8;
            let col     = uint::from_str(comps[1]).get() as u8;
            g[row][col] = uint::from_str(comps[2]).get() as u8;
        }
    }
    return grid_ctor(g);
}

// solve sudoku grid
fn solve_grid(g: grid_t) {
    fn next_color(g: grid, row: u8, col: u8, start_color: u8) -> bool {
        if start_color < 10u8 {
            // colors not yet used
            let avail = bitv::Bitv(10u, false);
            for u8::range(start_color, 10u8) |color| {
                avail.set(color as uint, true);
            }

            // drop colors already in use in neighbourhood
            drop_colors(g, avail, row, col);

            // find first remaining color that is available
            for uint::range(1u, 10u) |i| {
                if avail.get(i) {
                    g[row][col] = i as u8;
                    return true;
                }
            };
        }
        g[row][col] = 0u8;
        return false;
    }

    // find colors available in neighbourhood of (row, col)
    fn drop_colors(g: grid, avail: bitv::Bitv, row: u8, col: u8) {
        fn drop_color(g: grid, colors: bitv::Bitv, row: u8, col: u8) {
            let color = g[row][col];
            if color != 0u8 { colors.set(color as uint, false); }
        }

        let it = |a,b| drop_color(g, avail, a, b);

        for u8::range(0u8, 9u8) |idx| {
            it(idx, col); /* check same column fields */
            it(row, idx); /* check same row fields */
        }

        // check same block fields
        let row0 = (row / 3u8) * 3u8;
        let col0 = (col / 3u8) * 3u8;
        for u8::range(row0, row0 + 3u8) |alt_row| {
            for u8::range(col0, col0 + 3u8) |alt_col| { it(alt_row, alt_col); }
        }
    }

    let mut work: ~[(u8, u8)] = ~[]; /* queue of uncolored fields */
    for u8::range(0u8, 9u8) |row| {
        for u8::range(0u8, 9u8) |col| {
            let color = (*g)[row][col];
            if color == 0u8 { work += ~[(row, col)]; }
        }
    }

    let mut ptr = 0u;
    let end = vec::len(work);
    while (ptr < end) {
        let (row, col) = work[ptr];
        // is there another color to try?
        if next_color(*g, row, col, (*g)[row][col] + (1 as u8)) {
            //  yes: advance work list
            ptr = ptr + 1u;
        } else {
            // no: redo this field aft recoloring pred; unless there is none
            if ptr == 0u { fail ~"No solution found for this sudoku"; }
            ptr = ptr - 1u;
        }
    }
}

fn write_grid(f: io::Writer, g: grid_t) {
    for u8::range(0u8, 9u8) |row| {
        f.write_str(fmt!("%u", (*g)[row][0] as uint));
        for u8::range(1u8, 9u8) |col| {
            f.write_str(fmt!(" %u", (*g)[row][col] as uint));
        }
        f.write_char('\n');
     }
}

const default_grid: [[u8]] = [[0, 4, 0, 6, 0, 0, 0, 7, 2, 0], //0
                      [0, 0, 8, 0, 2, 0, 0, 0, 0, 0], //1
                      [7, 0, 0, 8, 0, 0, 0, 0, 0, 0], //2
                      [0, 0, 0, 5, 0, 0, 0, 0, 0, 0], //3
                      [0, 5, 0, 0, 0, 3, 6, 0, 0, 0], //4
                      [6, 8, 0, 0, 0, 0, 0, 9, 0, 0], //5
                      [0, 9, 5, 0, 0, 6, 0, 7, 0, 0], //6
                      [0, 0, 0, 0, 4, 0, 0, 6, 0, 0], //7
                      [4, 0, 0, 0, 0, 7, 2, 0, 3, 0], //8
                      [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];

fn main() {
    let args = os::args();
    let grid = if args.len() == 1 {
        default_grid;
    } else {
        read_grid(io::stdin())
    };
    solve_grid(grid);
    write_grid(io::stdout(), grid);
}

<commit_msg>Revert "Use a constant vector for the sudoku board, delete a FIXME"<commit_after>extern mod std;

use std::bitv;
use io::{ReaderUtil, WriterUtil};

// Computes a single solution to a given 9x9 sudoku
//
// Call with "-" to read input sudoku from stdin
//
// The expected line-based format is:
//
// 9,9
// <row>,<column>,<color>
// ...
//
// Row and column are 0-based (i.e. <= 8) and color is 1-based (>=1,<=9).
// A color of 0 indicates an empty field.
//
// If called without arguments, sudoku solves a built-in example sudoku
//

export grid_t, read_grid, solve_grid, write_grid;

// internal type of sudoku grids
type grid = ~[~[mut u8]];

// exported type of sudoku grids
enum grid_t { grid_ctor(grid), }

// read a sudoku problem from file f
fn read_grid(f: io::Reader) -> grid_t {
    assert f.read_line() == ~"9,9"; /* assert first line is exactly "9,9" */

    let g = vec::from_fn(10u, {|_i|
        vec::to_mut(vec::from_elem(10u, 0 as u8))
    });
    while !f.eof() {
        let comps = str::split_char(str::trim(f.read_line()), ',');
        if vec::len(comps) >= 3u {
            let row     = uint::from_str(comps[0]).get() as u8;
            let col     = uint::from_str(comps[1]).get() as u8;
            g[row][col] = uint::from_str(comps[2]).get() as u8;
        }
    }
    return grid_ctor(g);
}

// solve sudoku grid
fn solve_grid(g: grid_t) {
    fn next_color(g: grid, row: u8, col: u8, start_color: u8) -> bool {
        if start_color < 10u8 {
            // colors not yet used
            let avail = bitv::Bitv(10u, false);
            for u8::range(start_color, 10u8) |color| {
                avail.set(color as uint, true);
            }

            // drop colors already in use in neighbourhood
            drop_colors(g, avail, row, col);

            // find first remaining color that is available
            for uint::range(1u, 10u) |i| {
                if avail.get(i) {
                    g[row][col] = i as u8;
                    return true;
                }
            };
        }
        g[row][col] = 0u8;
        return false;
    }

    // find colors available in neighbourhood of (row, col)
    fn drop_colors(g: grid, avail: bitv::Bitv, row: u8, col: u8) {
        fn drop_color(g: grid, colors: bitv::Bitv, row: u8, col: u8) {
            let color = g[row][col];
            if color != 0u8 { colors.set(color as uint, false); }
        }

        let it = |a,b| drop_color(g, avail, a, b);

        for u8::range(0u8, 9u8) |idx| {
            it(idx, col); /* check same column fields */
            it(row, idx); /* check same row fields */
        }

        // check same block fields
        let row0 = (row / 3u8) * 3u8;
        let col0 = (col / 3u8) * 3u8;
        for u8::range(row0, row0 + 3u8) |alt_row| {
            for u8::range(col0, col0 + 3u8) |alt_col| { it(alt_row, alt_col); }
        }
    }

    let mut work: ~[(u8, u8)] = ~[]; /* queue of uncolored fields */
    for u8::range(0u8, 9u8) |row| {
        for u8::range(0u8, 9u8) |col| {
            let color = (*g)[row][col];
            if color == 0u8 { work += ~[(row, col)]; }
        }
    }

    let mut ptr = 0u;
    let end = vec::len(work);
    while (ptr < end) {
        let (row, col) = work[ptr];
        // is there another color to try?
        if next_color(*g, row, col, (*g)[row][col] + (1 as u8)) {
            //  yes: advance work list
            ptr = ptr + 1u;
        } else {
            // no: redo this field aft recoloring pred; unless there is none
            if ptr == 0u { fail ~"No solution found for this sudoku"; }
            ptr = ptr - 1u;
        }
    }
}

fn write_grid(f: io::Writer, g: grid_t) {
    for u8::range(0u8, 9u8) |row| {
        f.write_str(fmt!("%u", (*g)[row][0] as uint));
        for u8::range(1u8, 9u8) |col| {
            f.write_str(fmt!(" %u", (*g)[row][col] as uint));
        }
        f.write_char('\n');
     }
}

fn main() {
    let args = os::args();
    let grid = if vec::len(args) == 1u {
        // FIXME create sudoku inline since nested vec consts dont work yet
        // (#571)
        let g = vec::from_fn(10u, |_i| {
            vec::to_mut(vec::from_elem(10u, 0 as u8))
        });
        g[0][1] = 4u8;
        g[0][3] = 6u8;
        g[0][7] = 3u8;
        g[0][8] = 2u8;
        g[1][2] = 8u8;
        g[1][4] = 2u8;
        g[2][0] = 7u8;
        g[2][3] = 8u8;
        g[3][3] = 5u8;
        g[4][1] = 5u8;
        g[4][5] = 3u8;
        g[4][6] = 6u8;
        g[5][0] = 6u8;
        g[5][1] = 8u8;
        g[5][7] = 9u8;
        g[6][1] = 9u8;
        g[6][2] = 5u8;
        g[6][5] = 6u8;
        g[6][7] = 7u8;
        g[7][4] = 4u8;
        g[7][7] = 6u8;
        g[8][0] = 4u8;
        g[8][5] = 7u8;
        g[8][6] = 2u8;
        g[8][8] = 3u8;
        grid_ctor(g)
    } else {
        read_grid(io::stdin())
    };
    solve_grid(grid);
    write_grid(io::stdout(), grid);
}

<|endoftext|>


<commit_before>use std;
import std::math::*;
import std::float;

#[test]
fn test_sqrt() {
    assert sqrt(9.0) == 3.0;
    assert sqrt(4.0) == 2.0;
    assert sqrt(1.0) == 1.0;
    assert sqrt(0.0) == 0.0;
}

#[test]
fn test_max_min() {
    assert max(0, 1) == 1;
    assert min(0, 1) == 0;
    assert max(0, -1) == 0;
    assert min(0, -1) == -1;
    assert max(0.0, 1.0) == 1.0;
    assert min(0.0, 1.0) == 0.0;
}

#[test]
fn test_angle() {
    fn angle(vec: (float, float)) -> float {
        alt vec {
          (0f, y) when y < 0f { 1.5 * std::math::pi }
          (0f, y) { 0.5 * std::math::pi }
          (x, y) { std::math::atan(y / x) }
        }
    }
    assert angle((1f, 0f)) == 0f;
    assert angle((1f, 1f)) == 0.25 * pi;
    assert angle((0f, 1f)) == 0.5 * pi;
}

#[test]
fn test_log_functions() {
    assert ln(1.0) == 0.0;
    assert log2(1.0) == 0.0;
    assert log10(1.0) == 0.0;

    assert ln(e) == 1.0;
    assert log2(2.0) == 1.0;
    assert log10(10.0) == 1.0;

    assert ln(e*e*e*e) == 4.0;
    assert log2(256.0) == 8.0;
    assert log10(1000.0) == 3.0;

    assert ln(0.0) == float::neg_infinity;
    assert log2(0.0) == float::neg_infinity;
    assert log10(0.0) == float::neg_infinity;

    assert ln(-0.0) == float::neg_infinity;
    assert log2(-0.0) == float::neg_infinity;
    assert log10(-0.0) == float::neg_infinity;

    assert float::isNaN(ln(-1.0));
    assert float::isNaN(log2(-1.0));
    assert float::isNaN(log10(-1.0));

    assert ln(float::infinity) == float::infinity;
    assert log2(float::infinity) == float::infinity;
    assert log10(float::infinity) == float::infinity;

    assert ln1p(0.0) == 0.0;
    assert ln1p(-0.0) == 0.0;
    assert ln1p(-1.0) == float::neg_infinity;
    assert float::isNaN(ln1p(-2.0f));
    assert ln1p(float::infinity) == float::infinity;
}<commit_msg>Ignore test_log_functions test for now<commit_after>use std;
import std::math::*;
import std::float;

#[test]
fn test_sqrt() {
    assert sqrt(9.0) == 3.0;
    assert sqrt(4.0) == 2.0;
    assert sqrt(1.0) == 1.0;
    assert sqrt(0.0) == 0.0;
}

#[test]
fn test_max_min() {
    assert max(0, 1) == 1;
    assert min(0, 1) == 0;
    assert max(0, -1) == 0;
    assert min(0, -1) == -1;
    assert max(0.0, 1.0) == 1.0;
    assert min(0.0, 1.0) == 0.0;
}

#[test]
fn test_angle() {
    fn angle(vec: (float, float)) -> float {
        alt vec {
          (0f, y) when y < 0f { 1.5 * std::math::pi }
          (0f, y) { 0.5 * std::math::pi }
          (x, y) { std::math::atan(y / x) }
        }
    }
    assert angle((1f, 0f)) == 0f;
    assert angle((1f, 1f)) == 0.25 * pi;
    assert angle((0f, 1f)) == 0.5 * pi;
}

#[test]
#[ignore]
fn test_log_functions() {
    assert ln(1.0) == 0.0;
    assert log2(1.0) == 0.0;
    assert log10(1.0) == 0.0;

    assert ln(e) == 1.0;
    assert log2(2.0) == 1.0;
    assert log10(10.0) == 1.0;

    assert ln(e*e*e*e) == 4.0;
    assert log2(256.0) == 8.0;
    assert log10(1000.0) == 3.0;

    assert ln(0.0) == float::neg_infinity;
    assert log2(0.0) == float::neg_infinity;
    assert log10(0.0) == float::neg_infinity;

    assert ln(-0.0) == float::neg_infinity;
    assert log2(-0.0) == float::neg_infinity;
    assert log10(-0.0) == float::neg_infinity;

    assert float::isNaN(ln(-1.0));
    assert float::isNaN(log2(-1.0));
    assert float::isNaN(log10(-1.0));

    assert ln(float::infinity) == float::infinity;
    assert log2(float::infinity) == float::infinity;
    assert log10(float::infinity) == float::infinity;

    assert ln1p(0.0) == 0.0;
    assert ln1p(-0.0) == 0.0;
    assert ln1p(-1.0) == float::neg_infinity;
    assert float::isNaN(ln1p(-2.0f));
    assert ln1p(float::infinity) == float::infinity;
}<|endoftext|>


<commit_before>use std;
import std::task;

#[test]
#[ignore]
fn test_sleep() { task::sleep(1000000u); }

#[test]
fn test_unsupervise() {
    fn f() { task::unsupervise(); fail; }
    spawn f();
}

#[test]
fn test_join() {
    fn winner() { }

    let wintask = spawn winner();

    assert (task::join(wintask) == task::tr_success);

    fn failer() { task::unsupervise(); fail; }

    let failtask = spawn failer();

    assert (task::join(failtask) == task::tr_failure);
}

#[test]
fn test_send_recv() {
    let p = port[int]();
    let c = chan(p);
    task::send(c, 10);
    assert (task::recv(p) == 10);
}

<commit_msg>Un-ignore stdtest::task::test_sleep<commit_after>use std;
import std::task;

#[test]
fn test_sleep() { task::sleep(1000000u); }

#[test]
fn test_unsupervise() {
    fn f() { task::unsupervise(); fail; }
    spawn f();
}

#[test]
fn test_join() {
    fn winner() { }

    let wintask = spawn winner();

    assert (task::join(wintask) == task::tr_success);

    fn failer() { task::unsupervise(); fail; }

    let failtask = spawn failer();

    assert (task::join(failtask) == task::tr_failure);
}

#[test]
fn test_send_recv() {
    let p = port[int]();
    let c = chan(p);
    task::send(c, 10);
    assert (task::recv(p) == 10);
}

<|endoftext|>


<commit_before>extern crate ws;
extern crate clap;
extern crate serde;
extern crate serde_json;

use serde_json::Value;

use clap::{App, Arg};

const NULL_PAYLOAD: &'static Value = &Value::Null;

struct BenchHandler {
    ws: ws::Sender,
    count: u32,
}

impl ws::Handler for BenchHandler {
    fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
        if let Ok(Ok(Value::Object(obj))) = msg.as_text().map(serde_json::from_str::<Value>) {
            if let Some(&Value::String(ref s)) = obj.get("type") {
                if s == "echo" {
                    try!(self.ws.send(msg))
                } else if s == "broadcast" {
                    try!(self.ws.broadcast(msg));
                    try!(self.ws.send(format!(r#"{{"type":"broadcastResult","listenCount": {},"payload":{}}}"#,
                                              self.count,
                                              obj.get("payload").unwrap_or(NULL_PAYLOAD))))
                }
            }
        }
        Ok(())
    }

    fn on_open(&mut self, _: ws::Handshake) -> ws::Result<()> {
        self.count += 1;
        println!("Connection Open! {}", self.count);
        Ok(())
    }

    fn on_close(&mut self, _: ws::CloseCode, _: &str) {
        self.count -= 1;
        println!("Connection Closed! {}", self.count);
    }
}

fn main() {
    let matches = App::new("rust-ws-server")
                      .version("1.0")
                      .arg(Arg::with_name("address")
                               .short("a")
                               .long("address")
                               .required(true)
                               .takes_value(true)
                               .default_value("127.0.0.1"))
                      .arg(Arg::with_name("port")
                               .short("p")
                               .long("port")
                               .required(true)
                               .takes_value(true)
                               .default_value("3000"))
                      .get_matches();

    if let (Some(address), Some(port)) = (matches.value_of("address"), matches.value_of("port")) {
        ws::Builder::new()
            .with_settings(ws::Settings { max_connections: 500_000, ..Default::default() })
            .build(|out| {
                BenchHandler {
                    ws: out,
                    count: 0,
                }
            })
            .unwrap()
            .listen(&*format!("{}:{}", address, port))
            .unwrap();
    } else {
        println!("{}", matches.usage());
    }
}
<commit_msg>remove debug prints<commit_after>extern crate ws;
extern crate clap;
extern crate serde;
extern crate serde_json;

use serde_json::Value;

use clap::{App, Arg};

const NULL_PAYLOAD: &'static Value = &Value::Null;

struct BenchHandler {
    ws: ws::Sender,
    count: u32,
}

impl ws::Handler for BenchHandler {
    fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
        if let Ok(Ok(Value::Object(obj))) = msg.as_text().map(serde_json::from_str::<Value>) {
            if let Some(&Value::String(ref s)) = obj.get("type") {
                if s == "echo" {
                    try!(self.ws.send(msg))
                } else if s == "broadcast" {
                    try!(self.ws.broadcast(msg));
                    try!(self.ws.send(format!(r#"{{"type":"broadcastResult","listenCount": {},"payload":{}}}"#,
                                              self.count,
                                              obj.get("payload").unwrap_or(NULL_PAYLOAD))))
                }
            }
        }
        Ok(())
    }

    fn on_open(&mut self, _: ws::Handshake) -> ws::Result<()> {
        self.count += 1;
        Ok(())
    }

    fn on_close(&mut self, _: ws::CloseCode, _: &str) {
        self.count -= 1;
    }
}

fn main() {
    let matches = App::new("rust-ws-server")
                      .version("1.0")
                      .arg(Arg::with_name("address")
                               .short("a")
                               .long("address")
                               .required(true)
                               .takes_value(true)
                               .default_value("127.0.0.1"))
                      .arg(Arg::with_name("port")
                               .short("p")
                               .long("port")
                               .required(true)
                               .takes_value(true)
                               .default_value("3000"))
                      .get_matches();

    if let (Some(address), Some(port)) = (matches.value_of("address"), matches.value_of("port")) {
        ws::Builder::new()
            .with_settings(ws::Settings { max_connections: 500_000, ..Default::default() })
            .build(|out| {
                BenchHandler {
                    ws: out,
                    count: 0,
                }
            })
            .unwrap()
            .listen(&*format!("{}:{}", address, port))
            .unwrap();
    } else {
        println!("{}", matches.usage());
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 The xi-editor Authors.
//
// 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.

#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;

extern crate dirs;

extern crate xi_core_lib;
extern crate xi_rpc;

use std::collections::HashMap;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use xi_core_lib::XiCore;
use xi_rpc::RpcLoop;

const XI_LOG_DIR: &str = "xi-core";
const XI_LOG_FILE: &str = "xi-core.log";

fn get_logging_directory<P: AsRef<Path>>(directory: P) -> Result<PathBuf, io::Error> {
    match dirs::data_local_dir() {
        Some(mut log_dir) => {
            log_dir.push(directory);
            Ok(log_dir)
        }
        None => Err(io::Error::new(
            io::ErrorKind::NotFound,
            "No standard logging directory known for this platform",
        )),
    }
}

fn path_for_log_file<P: AsRef<Path>>(filename: P) -> Result<PathBuf, io::Error> {
    let mut logging_directory = get_logging_directory(get_logfile_directory_name())?;
    // Create the logging directory
    fs::create_dir_all(&logging_directory)?;
    // Pushing the filename to the end
    logging_directory.push(filename.as_ref());
    Ok(logging_directory)
}

fn setup_logging() -> Result<(), fern::InitError> {
    let level_filter = match std::env::var("XI_LOG") {
        Ok(level) => match level.to_lowercase().as_ref() {
            "trace" => log::LevelFilter::Trace,
            "debug" => log::LevelFilter::Debug,
            _ => log::LevelFilter::Info,
        },
        // Default to info
        Err(_) => log::LevelFilter::Info,
    };

    let mut fern_dispatch = fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{}[{}][{}] {}",
                chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
                record.target(),
                record.level(),
                message,
            ))
        }).level(level_filter)
        .chain(io::stderr());

    let path_result = path_for_log_file(get_logfile_file_name());
    // If the logging_file_path returned successfully, add the logfile capability to fern
    if let Ok(logging_file_path) = &path_result {
        fern_dispatch = fern_dispatch.chain(fern::log_file(logging_file_path)?);
    }

    // Start fern
    fern_dispatch.apply()?;

    // Log details of the fern setup using fern/log
    match &path_result {
        Err(e) => {
            let message = "There was an issue getting the path for the log file";
            warn!("{}: {:?}, falling back to stderr.", message, e);
        }
        Ok(logging_file_path) => info!("Logging to the following file: {:?}", logging_file_path),
    }

    info!("Logging with fern is setup");
    Ok(())
}

fn get_flags() -> HashMap<String, Option<String>> {
    let mut flags: HashMap<String, Option<String>> = HashMap::new();

    let flag_prefix = "-";
    let mut args_itterator = std::env::args().peekable();
    while let Some(arg) = args_itterator.next() {
        if arg.starts_with(flag_prefix) {
            let key = arg.trim_left_matches(flag_prefix).to_string();

            // Check the next argument doesn't start with the flag prefix
            // map_or accounts for peek returning an Option
            let next_arg_not_a_flag: bool = args_itterator.peek().map_or(false, |val| !val.starts_with(flag_prefix));
            if next_arg_not_a_flag {
                flags.insert(key, args_itterator.next());
            }
        }
    }
    flags
}

fn main() {
    let mut state = XiCore::new();
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut rpc_looper = RpcLoop::new(stdout);

    if let Err(e) = setup_logging() {
        eprintln!(
            "[ERROR] setup_logging returned error, logging disabled: {:?}",
            e
        );
    }

    match rpc_looper.mainloop(|| stdin.lock(), &mut state) {
        Ok(_) => (),
        Err(err) => error!("xi-core exited with error:\n{:?}", err),
    }
}
<commit_msg>Renamed get_logging_directory to make it's role clearer.<commit_after>// Copyright 2016 The xi-editor Authors.
//
// 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.

#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;

extern crate dirs;

extern crate xi_core_lib;
extern crate xi_rpc;

use std::collections::HashMap;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use xi_core_lib::XiCore;
use xi_rpc::RpcLoop;

const XI_LOG_DIR: &str = "xi-core";
const XI_LOG_FILE: &str = "xi-core.log";

fn get_logging_directory_path<P: AsRef<Path>>(directory: P) -> Result<PathBuf, io::Error> {
    match dirs::data_local_dir() {
        Some(mut log_dir) => {
            log_dir.push(directory);
            Ok(log_dir)
        }
        None => Err(
            io::Error::new(
                io::ErrorKind::NotFound,
                "No standard logging directory known for this platform",
            )
        ),
    }
}

fn path_for_log_file<P: AsRef<Path>>(filename: P) -> Result<PathBuf, io::Error> {
    let mut logging_directory = get_logging_directory_path(get_logfile_directory_name())?;
    // Create the logging directory
    fs::create_dir_all(&logging_directory)?;
    // Pushing the filename to the end
    logging_directory.push(filename.as_ref());
    Ok(logging_directory)
}

fn setup_logging() -> Result<(), fern::InitError> {
    let level_filter = match std::env::var("XI_LOG") {
        Ok(level) => match level.to_lowercase().as_ref() {
            "trace" => log::LevelFilter::Trace,
            "debug" => log::LevelFilter::Debug,
            _ => log::LevelFilter::Info,
        },
        // Default to info
        Err(_) => log::LevelFilter::Info,
    };

    let mut fern_dispatch = fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{}[{}][{}] {}",
                chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
                record.target(),
                record.level(),
                message,
            ))
        }).level(level_filter)
        .chain(io::stderr());

    let path_result = path_for_log_file(get_logfile_file_name());
    // If the logging_file_path returned successfully, add the logfile capability to fern
    if let Ok(logging_file_path) = &path_result {
        fern_dispatch = fern_dispatch.chain(fern::log_file(logging_file_path)?);
    }

    // Start fern
    fern_dispatch.apply()?;

    // Log details of the fern setup using fern/log
    match &path_result {
        Err(e) => {
            let message = "There was an issue getting the path for the log file";
            warn!("{}: {:?}, falling back to stderr.", message, e);
        }
        Ok(logging_file_path) => info!("Logging to the following file: {:?}", logging_file_path),
    }

    info!("Logging with fern is setup");
    Ok(())
}

fn get_flags() -> HashMap<String, Option<String>> {
    let mut flags: HashMap<String, Option<String>> = HashMap::new();

    let flag_prefix = "-";
    let mut args_itterator = std::env::args().peekable();
    while let Some(arg) = args_itterator.next() {
        if arg.starts_with(flag_prefix) {
            let key = arg.trim_left_matches(flag_prefix).to_string();

            // Check the next argument doesn't start with the flag prefix
            // map_or accounts for peek returning an Option
            let next_arg_not_a_flag: bool = args_itterator.peek().map_or(false, |val| !val.starts_with(flag_prefix));
            if next_arg_not_a_flag {
                flags.insert(key, args_itterator.next());
            }
        }
    }
    flags
}

fn main() {
    let mut state = XiCore::new();
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut rpc_looper = RpcLoop::new(stdout);

    if let Err(e) = setup_logging() {
        eprintln!(
            "[ERROR] setup_logging returned error, logging disabled: {:?}",
            e
        );
    }

    match rpc_looper.mainloop(|| stdin.lock(), &mut state) {
        Ok(_) => (),
        Err(err) => error!("xi-core exited with error:\n{:?}", err),
    }
}
<|endoftext|>


<commit_before>extern crate image2emblem;
extern crate image;
extern crate chrono;
extern crate byteorder;

use std::fs::File;
use std::path::Path;
use image::GenericImage;
use chrono::*;
use std::io::prelude::*;
use byteorder::{ByteOrder, BigEndian};

fn python_total_seconds(microseconds: i64) -> f64 {
    microseconds as f64 / 10i64.pow(6) as f64
}

fn seconds_since_2000(now: chrono::datetime::DateTime<UTC>) -> f64 {
    let year_2000 = chrono::UTC.ymd(2000, 1, 1).and_hms(0, 0, 0);
    let duration = now - year_2000;

    match duration.num_microseconds() {
        Some(ms) => python_total_seconds(ms),
        None => panic!("No microseconds!")
    }
}

fn icon() -> [u8; 2048] {
    let icon_path = Path::new("../../common/emblem_icon");
    let display = icon_path.display();
    let mut file = match File::open(&icon_path) {
        // The `description` method of `io::Error` returns a string that
        // describes the error
        Err(why) => panic!("couldn't open '{}': {}", display, why),
        Ok(file) => file,
    };

    let mut v: Vec<u8> = Vec::new();
    match file.read_to_end(&mut v) {
        Err(why) => panic!("couldn't read: {}", why),
        Ok(_) => {
            let mut arr: [u8; 2048] = [0x00; 2048];
            for index in 0..v.len() {
                arr[index] = v[index];
            }

            arr
        }
    }
}

fn setup_header_bytes(emblem: &mut image2emblem::emblem::Emblem, short_name: String, seconds: f64) {
    emblem.set_filename(short_name);
    emblem.set_timestamp(seconds as u32);
}

fn setup_more_info_bytes(emblem: &mut image2emblem::emblem::Emblem, now: DateTime<UTC>) {
    let comment = format!("{} (Created using Rust awesomeness)", now.format("%y/%m/%d %H:%M"));

    emblem.set_comment(comment);
}

fn main() {
    let path = Path::new("../../processing/source/ImageToEmblem1_01/data/resources/fzcLogo.png");
    let mut img = image::open(&path).unwrap();
    let now = chrono::UTC::now();
    let seconds_since_2000 = seconds_since_2000(now);
    let alpha_threshold = 1;
    let icon_bytes = icon();
    let mut emblem = image2emblem::emblem::Emblem::default();

    let short_name = image2emblem::short_name(None, seconds_since_2000);
    let full_name = image2emblem::full_name(&short_name);

    let img64 = img.crop(0, 0, 64, 64);
    let img32 = img64.resize(32, 32, image::FilterType::Lanczos3);

    setup_header_bytes(&mut emblem, short_name, seconds_since_2000);
    setup_more_info_bytes(&mut emblem, now);
    //
    // emblem_pixel_bytes = emblem(img64_data, alpha_threshold)
    // banner_bytes = banner(img32, alpha_threshold)
    //
    // # A bunch of zeros until the end of 3 Gamecube memory blocks
    // end_padding_bytes = bytearray(0x6040 - 0x40A0)
    //
    // post_checksum_bytes = more_info_bytes + banner_bytes \
    //   + icon_bytes + emblem_pixel_bytes + end_padding_bytes
    //
    // checksum_bytes = checksum(post_checksum_bytes)
    //
    // emblem_file = open(emblem_full_filename, 'wb')
    // emblem_file.write(header_bytes + checksum_bytes + post_checksum_bytes)
    // emblem_file.close()
}
<commit_msg>Inlines setup functions back into main()<commit_after>extern crate image2emblem;
extern crate image;
extern crate chrono;
extern crate byteorder;

use std::fs::File;
use std::path::Path;
use image::GenericImage;
use chrono::*;
use std::io::prelude::*;
use byteorder::{ByteOrder, BigEndian};

fn python_total_seconds(microseconds: i64) -> f64 {
    microseconds as f64 / 10i64.pow(6) as f64
}

fn seconds_since_2000(now: chrono::datetime::DateTime<UTC>) -> f64 {
    let year_2000 = chrono::UTC.ymd(2000, 1, 1).and_hms(0, 0, 0);
    let duration = now - year_2000;

    match duration.num_microseconds() {
        Some(ms) => python_total_seconds(ms),
        None => panic!("No microseconds!")
    }
}

fn icon() -> [u8; 2048] {
    let icon_path = Path::new("../../common/emblem_icon");
    let display = icon_path.display();
    let mut file = match File::open(&icon_path) {
        // The `description` method of `io::Error` returns a string that
        // describes the error
        Err(why) => panic!("couldn't open '{}': {}", display, why),
        Ok(file) => file,
    };

    let mut v: Vec<u8> = Vec::new();
    match file.read_to_end(&mut v) {
        Err(why) => panic!("couldn't read: {}", why),
        Ok(_) => {
            let mut arr: [u8; 2048] = [0x00; 2048];
            for index in 0..v.len() {
                arr[index] = v[index];
            }

            arr
        }
    }
}

fn main() {
    let path = Path::new("../../processing/source/ImageToEmblem1_01/data/resources/fzcLogo.png");
    let mut img = image::open(&path).unwrap();
    let now = chrono::UTC::now();
    let seconds_since_2000 = seconds_since_2000(now);
    let alpha_threshold = 1;
    let icon_bytes = icon();
    let mut emblem = image2emblem::emblem::Emblem::default();

    let short_name = image2emblem::short_name(None, seconds_since_2000);
    let full_name = image2emblem::full_name(&short_name);

    let img64 = img.crop(0, 0, 64, 64);
    let img32 = img64.resize(32, 32, image::FilterType::Lanczos3);

    emblem.set_filename(short_name);
    emblem.set_timestamp(seconds_since_2000 as u32);
    let comment = format!("{} (Created using Rust awesomeness)", now.format("%y/%m/%d %H:%M"));
    emblem.set_comment(comment);

    //
    // emblem_pixel_bytes = emblem(img64_data, alpha_threshold)
    // banner_bytes = banner(img32, alpha_threshold)
    //
    // # A bunch of zeros until the end of 3 Gamecube memory blocks
    // end_padding_bytes = bytearray(0x6040 - 0x40A0)
    //
    // post_checksum_bytes = more_info_bytes + banner_bytes \
    //   + icon_bytes + emblem_pixel_bytes + end_padding_bytes
    //
    // checksum_bytes = checksum(post_checksum_bytes)
    //
    // emblem_file = open(emblem_full_filename, 'wb')
    // emblem_file.write(header_bytes + checksum_bytes + post_checksum_bytes)
    // emblem_file.close()
}
<|endoftext|>


<commit_before>//! # Type-based Serialization and Deserialization
//!
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
//! from MessagePack via the serialization API. To be able to serialize a piece of data, it must
//! implement the `serde::Serialize` trait. To be able to deserialize a piece of data, it must
//! implement the `serde::Deserialize` trait. Serde provides provides an annotation to
//! automatically generate the code for these traits: `#[derive(Serialize, Deserialize)]`.
//!
//! # Examples
//!
//! Let's try to encode and decode some built-in types.
//!
//! ```rust
//! extern crate serde;
//! extern crate rmp_serde;
//!
//! use serde::{Deserialize, Serialize};
//! use rmp_serde::{Deserializer, Serializer};
//!
//! fn main() {
//!     let mut buf = Vec::new();
//!     let val = (42u8, "the Answer");
//!     val.serialize(&mut Serializer::new(&mut buf)).unwrap();
//!
//!     assert_eq!(vec![0x92, 0x2a, 0xaa, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72], buf);
//!
//!     let mut de = Deserializer::new(&buf[..]);
//!     assert_eq!((42, "the Answer".to_owned()), Deserialize::deserialize(&mut de).unwrap());
//! }
//! ```
//!
//! No one gonna hurt if we add some reflection magic.
//!
//! ```ignore
//! #![feature(proc_macro)]
//!
//! #[macro_use] extern crate serde_derive;
//! extern crate rmp_serde;
//!
//! use std::collections::HashMap;
//! use serde::{Deserialize, Serialize};
//! use rmp_serde::{Deserializer, Serializer};
//!
//! #[derive(Debug, PartialEq, Deserialize, Serialize)]
//! struct Human {
//!     age: u32,
//!     name: String,
//! }
//!
//! fn main() {
//!     let mut buf = Vec::new();
//!     let val = Human {
//!         age: 42,
//!         name: "John".into(),
//!     };
//!
//!     val.serialize(&mut Serializer::new(&mut buf)).unwrap();
//! }
//! ```

extern crate rmp;
extern crate byteorder;
#[macro_use]
extern crate serde;

use std::fmt::{self, Display, Formatter};
use std::str::{self, Utf8Error};

use serde::de::{self, Deserialize};

pub use decode::Deserializer;
pub use encode::Serializer;

pub mod decode;
pub mod encode;

/// Helper that allows to decode strings no matter whether they contain valid or invalid UTF-8.
#[derive(Clone, Debug, PartialEq)]
pub struct Raw {
    s: Result<String, (Vec<u8>, Utf8Error)>,
}

impl Raw {
    /// Returns `true` if the raw is valid UTF-8.
    pub fn is_str(&self) -> bool {
        self.s.is_ok()
    }

    /// Returns `true` if the raw contains invalid UTF-8 sequence.
    pub fn is_err(&self) -> bool {
        self.s.is_err()
    }

    /// Returns the string reference if the raw is valid UTF-8, or else `None`.
    pub fn as_str(&self) -> Option<&str> {
        match self.s {
            Ok(ref s) => Some(s.as_str()),
            Err(..) => None,
        }
    }

    /// Returns the underlying `Utf8Error` if the raw contains invalud UTF-8 sequence, or
    /// else `None`.
    pub fn as_err(&self) -> Option<&Utf8Error> {
        match self.s {
            Ok(..) => None,
            Err((.., ref err)) => Some(&err),
        }
    }

    /// Returns a byte slice of this raw's contents.
    pub fn as_bytes(&self) -> &[u8] {
        match self.s {
            Ok(ref s) => s.as_bytes(),
            Err(ref err) => &err.0[..],
        }
    }

    /// Consumes this object, yielding the string if the raw is valid UTF-8, or else `None`.
    pub fn into_str(self) -> Option<String> {
        self.s.ok()
    }

    /// Converts a `Raw` into a byte vector.
    pub fn into_bytes(self) -> Vec<u8> {
        match self.s {
            Ok(s) => s.into_bytes(),
            Err(err) => err.0,
        }
    }
}

struct RawVisitor;

impl de::Visitor for RawVisitor {
    type Value = Raw;

    fn expecting(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
        "string or bytes".fmt(fmt)
    }

    #[inline]
    fn visit_string<E>(self, v: String) -> Result<Self::Value, E> {
        Ok(Raw { s: Ok(v) })
    }

    #[inline]
    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
        where E: de::Error
    {
        Ok(Raw { s: Ok(v.into()) })
    }

    #[inline]
    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
        where E: serde::de::Error
    {
        let s = match str::from_utf8(v) {
            Ok(s) => Ok(s.into()),
            Err(err) => Err((v.into(), err)),
        };

        Ok(Raw { s: s })
    }

    #[inline]
    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
        where E: serde::de::Error
    {
        let s = match String::from_utf8(v) {
            Ok(s) => Ok(s),
            Err(err) => {
                let e = err.utf8_error();
                Err((err.into_bytes(), e))
            }
        };

        Ok(Raw { s: s })
    }
}

impl Deserialize for Raw {
    #[inline]
    fn deserialize<D>(de: D) -> Result<Self, D::Error>
        where D: de::Deserializer
    {
        de.deserialize(RawVisitor)
    }
}

/// Serializes a value to a byte vector.
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>, encode::Error>
    where T: serde::Serialize
{
    let mut buf = Vec::with_capacity(64);
    value.serialize(&mut Serializer::new(&mut buf))?;
    Ok(buf)
}

/// Deserializes a byte slice into the desired type.
pub fn from_slice<T>(input: &[u8]) -> Result<T, decode::Error>
    where T: serde::Deserialize
{
    let mut de = Deserializer::from_slice(input);
    serde::Deserialize::deserialize(&mut de)
}
<commit_msg>docs: minor fixes<commit_after>//! # Type-based Serialization and Deserialization
//!
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
//! from MessagePack via the serialization API. To be able to serialize a piece of data, it must
//! implement the `serde::Serialize` trait. To be able to deserialize a piece of data, it must
//! implement the `serde::Deserialize` trait. Serde provides provides an annotation to
//! automatically generate the code for these traits: `#[derive(Serialize, Deserialize)]`.
//!
//! # Examples
//!
//! Let's try to encode and decode some built-in types.
//!
//! ```rust
//! extern crate serde;
//! extern crate rmp_serde as rmps;
//!
//! use serde::{Deserialize, Serialize};
//! use rmps::{Deserializer, Serializer};
//!
//! fn main() {
//!     let mut buf = Vec::new();
//!     let val = (42u8, "the Answer");
//!     val.serialize(&mut Serializer::new(&mut buf)).unwrap();
//!
//!     assert_eq!(vec![0x92, 0x2a, 0xaa, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72], buf);
//!
//!     let mut de = Deserializer::new(&buf[..]);
//!     assert_eq!((42, "the Answer".to_owned()), Deserialize::deserialize(&mut de).unwrap());
//! }
//! ```
//!
//! No one gonna hurt if we add some reflection magic.
//!
//! ```ignore
//! extern crate serde;
//! #[macro_use]
//! extern crate serde_derive;
//! extern crate rmp_serde as rmps;
//!
//! use std::collections::HashMap;
//! use serde::{Deserialize, Serialize};
//! use rmps::{Deserializer, Serializer};
//!
//! #[derive(Debug, PartialEq, Deserialize, Serialize)]
//! struct Human {
//!     age: u32,
//!     name: String,
//! }
//!
//! fn main() {
//!     let mut buf = Vec::new();
//!     let val = Human {
//!         age: 42,
//!         name: "John".into(),
//!     };
//!
//!     val.serialize(&mut Serializer::new(&mut buf)).unwrap();
//! }
//! ```

extern crate rmp;
extern crate byteorder;
#[macro_use]
extern crate serde;

use std::fmt::{self, Display, Formatter};
use std::str::{self, Utf8Error};

use serde::de::{self, Deserialize};

pub use decode::Deserializer;
pub use encode::Serializer;

pub mod decode;
pub mod encode;

/// Helper that allows to decode strings no matter whether they contain valid or invalid UTF-8.
#[derive(Clone, Debug, PartialEq)]
pub struct Raw {
    s: Result<String, (Vec<u8>, Utf8Error)>,
}

impl Raw {
    /// Returns `true` if the raw is valid UTF-8.
    pub fn is_str(&self) -> bool {
        self.s.is_ok()
    }

    /// Returns `true` if the raw contains invalid UTF-8 sequence.
    pub fn is_err(&self) -> bool {
        self.s.is_err()
    }

    /// Returns the string reference if the raw is valid UTF-8, or else `None`.
    pub fn as_str(&self) -> Option<&str> {
        match self.s {
            Ok(ref s) => Some(s.as_str()),
            Err(..) => None,
        }
    }

    /// Returns the underlying `Utf8Error` if the raw contains invalud UTF-8 sequence, or
    /// else `None`.
    pub fn as_err(&self) -> Option<&Utf8Error> {
        match self.s {
            Ok(..) => None,
            Err((.., ref err)) => Some(&err),
        }
    }

    /// Returns a byte slice of this raw's contents.
    pub fn as_bytes(&self) -> &[u8] {
        match self.s {
            Ok(ref s) => s.as_bytes(),
            Err(ref err) => &err.0[..],
        }
    }

    /// Consumes this object, yielding the string if the raw is valid UTF-8, or else `None`.
    pub fn into_str(self) -> Option<String> {
        self.s.ok()
    }

    /// Converts a `Raw` into a byte vector.
    pub fn into_bytes(self) -> Vec<u8> {
        match self.s {
            Ok(s) => s.into_bytes(),
            Err(err) => err.0,
        }
    }
}

struct RawVisitor;

impl de::Visitor for RawVisitor {
    type Value = Raw;

    fn expecting(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
        "string or bytes".fmt(fmt)
    }

    #[inline]
    fn visit_string<E>(self, v: String) -> Result<Self::Value, E> {
        Ok(Raw { s: Ok(v) })
    }

    #[inline]
    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
        where E: de::Error
    {
        Ok(Raw { s: Ok(v.into()) })
    }

    #[inline]
    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
        where E: serde::de::Error
    {
        let s = match str::from_utf8(v) {
            Ok(s) => Ok(s.into()),
            Err(err) => Err((v.into(), err)),
        };

        Ok(Raw { s: s })
    }

    #[inline]
    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
        where E: serde::de::Error
    {
        let s = match String::from_utf8(v) {
            Ok(s) => Ok(s),
            Err(err) => {
                let e = err.utf8_error();
                Err((err.into_bytes(), e))
            }
        };

        Ok(Raw { s: s })
    }
}

impl Deserialize for Raw {
    #[inline]
    fn deserialize<D>(de: D) -> Result<Self, D::Error>
        where D: de::Deserializer
    {
        de.deserialize(RawVisitor)
    }
}

/// Serializes a value to a byte vector.
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>, encode::Error>
    where T: serde::Serialize
{
    let mut buf = Vec::with_capacity(64);
    value.serialize(&mut Serializer::new(&mut buf))?;
    Ok(buf)
}

/// Deserializes a byte slice into the desired type.
pub fn from_slice<T>(input: &[u8]) -> Result<T, decode::Error>
    where T: serde::Deserialize
{
    let mut de = Deserializer::from_slice(input);
    serde::Deserialize::deserialize(&mut de)
}
<|endoftext|>


<commit_before><commit_msg>structs<commit_after>
struct Point {
    x: i32,
    y: i32,
}

// tuple structs
// field dont have names
struct Color(i32, i32, i32);

// can be useful in situations
struct Inches(f64);

// unit like struct
struct None;

fn main() {
    let mut origin = Point { x: 0, y: 0 };

    println!("Point Origin x: {}, y: {}", origin.x, origin.y);

    let point = Point { x: 56, .. origin };

    println!("Point x: {}, y: {}", point.x, point.y);

    let black = Color(0, 0, 0);

    let length_in_inches = Inches(10.2);
}
<|endoftext|>


<commit_before>use orbclient::Color;
use std::cell::{Cell, RefCell};
use std::sync::Arc;

use cell::{CloneCell, CheckSet};
use event::Event;
use point::Point;
use rect::Rect;
use renderer::Renderer;
use theme::{BUTTON_BACKGROUND, BUTTON_FOREGROUND, BUTTON_GRADIENT_STOP, BUTTON_BORDER};
use traits::{Border, Click, Place, Text};
use widgets::Widget;

pub struct Button {
    pub rect: Cell<Rect>,
    pub bg: Color,
    pub bg_gradient_stop: Color,
    pub fg: Color,
    pub fg_border: Color,
    pub border: Cell<bool>,
    pub border_radius: Cell<u32>,
    pub text: CloneCell<String>,
    pub text_offset: Cell<Point>,
    click_callback: RefCell<Option<Arc<Fn(&Button, Point)>>>,
    pressed: Cell<bool>,
}

impl Button {
    pub fn new() -> Arc<Self> {
        Arc::new(Button {
            rect: Cell::new(Rect::default()),
            bg: BUTTON_BACKGROUND,
            bg_gradient_stop: BUTTON_GRADIENT_STOP,
            fg: BUTTON_FOREGROUND,
            fg_border: BUTTON_BORDER,
            border: Cell::new(true),
            border_radius: Cell::new(0),
            text: CloneCell::new(String::new()),
            text_offset: Cell::new(Point::default()),
            click_callback: RefCell::new(None),
            pressed: Cell::new(false),
        })
    }
}

impl Border for Button {
    fn border(&self, enabled: bool) -> &Self {
        self.border.set(enabled);
        self
    }

    fn border_radius(&self, radius: u32) -> &Self {
        self.border_radius.set(radius);
        self
    }
}

impl Click for Button {
    fn emit_click(&self, point: Point) {
        if let Some(ref click_callback) = *self.click_callback.borrow() {
            click_callback(self, point);
        }
    }

    fn on_click<T: Fn(&Self, Point) + 'static>(&self, func: T) -> &Self {
        *self.click_callback.borrow_mut() = Some(Arc::new(func));
        self
    }
}

impl Place for Button {}

impl Text for Button {
    fn text<S: Into<String>>(&self, text: S) -> &Self {
        self.text.set(text.into());
        self
    }

    fn text_offset(&self, x: i32, y: i32) -> &Self {
        self.text_offset.set(Point::new(x, y));
        self
    }
}

impl Widget for Button {
    fn rect(&self) -> &Cell<Rect> {
        &self.rect
    }

    fn draw(&self, renderer: &mut Renderer, _focused: bool) {
        let rect = self.rect.get();

        let w = rect.width as i32;
        let h = rect.height as i32;

        let fg = self.fg;

        let b_r = self.border_radius.get();
        renderer.rounded_rect(rect, b_r, true, self.bg);

        if ! self.pressed.get() {
            renderer.linear_gradient(rect, Point::new(rect.x, rect.y), Point::new(0, rect.y + rect.height as i32),
                                     self.bg, self.bg_gradient_stop);
        }
        if self.border.get() {
            renderer.rounded_rect(rect, b_r, false, self.fg_border);
        }

        let text = self.text.borrow();

        let mut point = self.text_offset.get();
        for c in text.chars() {
            if c == '\n' {
                point.x = 0;
                point.y += 16;
            } else {
                if point.x + 8 <= w && point.y + 16 <= h {
                    renderer.char(point + rect.point(), c, fg);
                }
                point.x += 8;
            }
        }
    }

    fn event(&self, event: Event, focused: bool, redraw: &mut bool) -> bool {
        match event {
            Event::Mouse { point, left_button, .. } => {
                let mut click = false;

                let rect = self.rect.get();
                if rect.contains(point) {
                    if left_button {
                        if self.pressed.check_set(true) {
                            *redraw = true;
                        }
                    } else {
                        if self.pressed.check_set(false) {
                            click = true;
                            *redraw = true;
                        }
                    }
                } else {
                    if !left_button {
                        if self.pressed.check_set(false) {
                            *redraw = true;
                        }
                    }
                }

                if click {
                    let click_point: Point = point - rect.point();
                    self.emit_click(click_point);
                }
            }
            _ => (),
        }

        focused
    }
}
<commit_msg>Fix the noob mistake (#36)<commit_after>use orbclient::Color;
use std::cell::{Cell, RefCell};
use std::sync::Arc;

use cell::{CloneCell, CheckSet};
use event::Event;
use point::Point;
use rect::Rect;
use renderer::Renderer;
use theme::{BUTTON_BACKGROUND, BUTTON_FOREGROUND, BUTTON_GRADIENT_STOP, BUTTON_BORDER};
use traits::{Border, Click, Place, Text};
use widgets::Widget;

pub struct Button {
    pub rect: Cell<Rect>,
    pub bg: Color,
    pub bg_gradient_stop: Color,
    pub fg: Color,
    pub fg_border: Color,
    pub border: Cell<bool>,
    pub border_radius: Cell<u32>,
    pub text: CloneCell<String>,
    pub text_offset: Cell<Point>,
    click_callback: RefCell<Option<Arc<Fn(&Button, Point)>>>,
    pressed: Cell<bool>,
}

impl Button {
    pub fn new() -> Arc<Self> {
        Arc::new(Button {
            rect: Cell::new(Rect::default()),
            bg: BUTTON_BACKGROUND,
            bg_gradient_stop: BUTTON_GRADIENT_STOP,
            fg: BUTTON_FOREGROUND,
            fg_border: BUTTON_BORDER,
            border: Cell::new(true),
            border_radius: Cell::new(0),
            text: CloneCell::new(String::new()),
            text_offset: Cell::new(Point::default()),
            click_callback: RefCell::new(None),
            pressed: Cell::new(false),
        })
    }
}

impl Border for Button {
    fn border(&self, enabled: bool) -> &Self {
        self.border.set(enabled);
        self
    }

    fn border_radius(&self, radius: u32) -> &Self {
        self.border_radius.set(radius);
        self
    }
}

impl Click for Button {
    fn emit_click(&self, point: Point) {
        if let Some(ref click_callback) = *self.click_callback.borrow() {
            click_callback(self, point);
        }
    }

    fn on_click<T: Fn(&Self, Point) + 'static>(&self, func: T) -> &Self {
        *self.click_callback.borrow_mut() = Some(Arc::new(func));
        self
    }
}

impl Place for Button {}

impl Text for Button {
    fn text<S: Into<String>>(&self, text: S) -> &Self {
        self.text.set(text.into());
        self
    }

    fn text_offset(&self, x: i32, y: i32) -> &Self {
        self.text_offset.set(Point::new(x, y));
        self
    }
}

impl Widget for Button {
    fn rect(&self) -> &Cell<Rect> {
        &self.rect
    }

    fn draw(&self, renderer: &mut Renderer, _focused: bool) {
        let rect = self.rect.get();

        let w = rect.width as i32;
        let h = rect.height as i32;

        let fg = self.fg;

        let b_r = self.border_radius.get();
        renderer.rounded_rect(rect, b_r, true, self.bg);

        if ! self.pressed.get() {
            renderer.linear_gradient(rect, Point::new(rect.x, rect.y), Point::new(rect.x, rect.y + rect.height as i32),
                                     self.bg, self.bg_gradient_stop);
        }
        if self.border.get() {
            renderer.rounded_rect(rect, b_r, false, self.fg_border);
        }

        let text = self.text.borrow();

        let mut point = self.text_offset.get();
        for c in text.chars() {
            if c == '\n' {
                point.x = 0;
                point.y += 16;
            } else {
                if point.x + 8 <= w && point.y + 16 <= h {
                    renderer.char(point + rect.point(), c, fg);
                }
                point.x += 8;
            }
        }
    }

    fn event(&self, event: Event, focused: bool, redraw: &mut bool) -> bool {
        match event {
            Event::Mouse { point, left_button, .. } => {
                let mut click = false;

                let rect = self.rect.get();
                if rect.contains(point) {
                    if left_button {
                        if self.pressed.check_set(true) {
                            *redraw = true;
                        }
                    } else {
                        if self.pressed.check_set(false) {
                            click = true;
                            *redraw = true;
                        }
                    }
                } else {
                    if !left_button {
                        if self.pressed.check_set(false) {
                            *redraw = true;
                        }
                    }
                }

                if click {
                    let click_point: Point = point - rect.point();
                    self.emit_click(click_point);
                }
            }
            _ => (),
        }

        focused
    }
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]
#![deny(missing_copy_implementations)]

//! Window abstraction

extern crate input;
extern crate shader_version;

use shader_version::OpenGL;
use input::Input;

/// The type of an OpenGL function address.
pub type ProcAddress = *const ();

/// Size in pixels.
#[derive(Debug, Copy, Clone)]
pub struct Size {
    /// The width in pixels.
    pub width: u32,
    /// The height in pixels.
    pub height: u32,
}

impl From<[u32; 2]> for Size {
    #[inline(always)]
    fn from(value: [u32; 2]) -> Size {
        Size { width: value[0], height: value[1] }
    }
}

impl From<(u32, u32)> for Size {
    #[inline(always)]
    fn from(value: (u32, u32)) -> Size {
        Size { width: value.0, height: value.1 }
    }
}

/// Builds window from window settings.
pub trait BuildFromWindowSettings: Sized {
    /// Builds window from window settings.
    fn build_from_window_settings(settings: &WindowSettings)
    -> Result<Self, String>;
}

/// Required to use the event loop.
pub trait Window {
    /// The event type emitted by `poll_event`
    type Event;

    /// Tells the window to close or stay open.
    fn set_should_close(&mut self, value: bool);

    /// Returns true if window should close.
    fn should_close(&self) -> bool;

    /// Gets the size of the window in user coordinates.
    fn size(&self) -> Size;

    /// Swaps render buffers.
    fn swap_buffers(&mut self);

    /// Polls event from window.
    fn poll_event(&mut self) -> Option<Self::Event>;

    /// Gets draw size of the window.
    /// This is equal to the size of the frame buffer of the inner window,
    /// excluding the title bar and borders.
    fn draw_size(&self) -> Size;
}

/// Implemented by fully supported window back-ends.
pub trait AdvancedWindow: Window + Sized {
    /// Gets a copy of the title of the window.
    fn get_title(&self) -> String;

    /// Sets the title of the window.
    fn set_title(&mut self, value: String);

    /// Sets title on window.
    fn title(mut self, value: String) -> Self {
        self.set_title(value);
        self
    }

    /// Gets whether to exit when pressing esc.
    fn get_exit_on_esc(&self) -> bool;

    /// Sets whether to exit when pressing esc.
    fn set_exit_on_esc(&mut self, value: bool);

    /// Sets whether to exit when pressing esc.
    fn exit_on_esc(mut self, value: bool) -> Self {
        self.set_exit_on_esc(value);
        self
    }

    /// Sets whether to capture/grab cursor.
    /// This is used to lock and hide cursor to the window,
    /// for example in a first-person shooter game.
    fn set_capture_cursor(&mut self, value: bool);

    /// Sets whether to capture/grab cursor (see `set_capture_cursor`).
    fn capture_cursor(mut self, value: bool) -> Self {
        self.set_capture_cursor(value);
        self
    }
}

/// Trait for OpenGL specific operations.
pub trait OpenGLWindow: Window {
    /// Returns the address of an OpenGL function if it exist, else returns null pointer.
    fn get_proc_address(&mut self, proc_name: &str) -> ProcAddress;

    /// Returns true if this context is the current context.
    fn is_current(&self) -> bool;

    /// Make this context current.
    fn make_current(&mut self);
}

/// Settings for window behavior.
#[derive(Clone)]
pub struct WindowSettings {
    /// Title of the window.
    title: String,
    /// The size of the window.
    size: Size,
    /// Number samples per pixel (anti-aliasing).
    samples: u8,
    /// If true, the window is fullscreen.
    fullscreen: bool,
    /// If true, exit when pressing Esc.
    exit_on_esc: bool,
    /// If true, enable vsync.
    vsync: bool,
    /// An optional OpenGL version.
    opengl: Option<OpenGL>,
    /// Whether sRGB is enabled.
    srgb: bool,
}

impl WindowSettings {
    /// Creates window settings with defaults.
    ///
    /// - samples: 0
    /// - fullscreen: false
    /// - exit_on_esc: false
    /// - vsync: false
    /// - srgb: true
    pub fn new<T: Into<String>, S: Into<Size>>(
        title: T, size: S) -> WindowSettings
    {
        WindowSettings {
            title: title.into(),
            size: size.into(),
            samples: 0,
            fullscreen: false,
            exit_on_esc: false,
            vsync: false,
            opengl: None,
            srgb: true,
        }
    }

    /// Builds window.
    pub fn build<W: BuildFromWindowSettings>(&self) -> Result<W, String> {
        BuildFromWindowSettings::build_from_window_settings(self)
    }

    /// Gets title.
    pub fn get_title(&self) -> String { self.title.clone() }

    /// Sets title.
    pub fn set_title(&mut self, value: String) {
        self.title = value;
    }

    /// Sets title.
    pub fn title(mut self, value: String) -> Self {
        self.set_title(value);
        self
    }

    /// Gets size.
    pub fn get_size(&self) -> Size { self.size }

    /// Sets size.
    pub fn set_size(&mut self, value: Size) {
        self.size = value;
    }

    /// Sets size.
    pub fn size(mut self, value: Size) -> Self {
        self.set_size(value);
        self
    }

    /// Gets fullscreen.
    pub fn get_fullscreen(&self) -> bool { self.fullscreen }

    /// Sets fullscreen.
    pub fn set_fullscreen(&mut self, value: bool) {
        self.fullscreen = value;
    }

    /// Sets fullscreen.
    pub fn fullscreen(mut self, value: bool) -> Self {
        self.set_fullscreen(value);
        self
    }

    /// Gets exit on esc.
    pub fn get_exit_on_esc(&self) -> bool { self.exit_on_esc }

    /// Sets exit on esc.
    pub fn set_exit_on_esc(&mut self, value: bool) {
        self.exit_on_esc = value;
    }

    /// Sets exit on esc.
    pub fn exit_on_esc(mut self, value: bool) -> Self {
        self.set_exit_on_esc(value);
        self
    }

    /// Gets samples.
    ///
    /// See https://en.wikipedia.org/wiki/Multisample_anti-aliasing
    /// for more information.
    pub fn get_samples(&self) -> u8 { self.samples }

    /// Sets samples.
    pub fn set_samples(&mut self, value: u8) {
        self.samples = value;
    }

    /// Sets samples.
    pub fn samples(mut self, value: u8) -> Self {
        self.set_samples(value);
        self
    }

    /// Gets vsync.
    ///
    /// See https://en.wikipedia.org/wiki/Screen_tearing for more information.
    pub fn get_vsync(&self) -> bool { self.vsync }

    /// Sets vsync.
    pub fn set_vsync(&mut self, value: bool) {
        self.vsync = value;
    }

    /// Sets vsync.
    pub fn vsync(mut self, value: bool) -> Self {
        self.set_vsync(value);
        self
    }

    /// Gets OpenGL version.
    pub fn get_maybe_opengl(&self) -> Option<OpenGL> { self.opengl }

    /// Sets OpenGL version.
    pub fn set_maybe_opengl(&mut self, value: Option<OpenGL>) {
        self.opengl = value;
    }

    /// Sets OpenGL version.
    pub fn maybe_opengl(mut self, value: Option<OpenGL>) -> Self {
        self.set_maybe_opengl(value);
        self
    }

    /// Sets OpenGL version.
    pub fn set_opengl(&mut self, value: OpenGL) {
        self.opengl = Some(value);
    }

    /// Sets OpenGL version.
    pub fn opengl(mut self, value: OpenGL) -> Self {
        self.set_opengl(value);
        self
    }

    /// Gets sRGB.
    ///
    /// See https://en.wikipedia.org/wiki/SRGB for more information.
    pub fn get_srgb(&self) -> bool { self.srgb }

    /// Sets sRGB.
    pub fn set_srgb(&mut self, value: bool) {
        self.srgb = value;
    }

    /// Sets sRGB.
    pub fn srgb(mut self, value: bool) -> Self {
        self.set_srgb(value);
        self
    }
}

/// An implementation of Window that runs without a window at all.
pub struct NoWindow {
    should_close: bool,
    title: String,
    size: Size
}

impl NoWindow {
    /// Returns a new `NoWindow`.
    pub fn new(settings: &WindowSettings) -> NoWindow {
        NoWindow {
            should_close: false,
            title: settings.get_title(),
            size: settings.get_size(),
        }
    }
}

impl Window for NoWindow {
    type Event = Input;
    fn should_close(&self) -> bool { self.should_close }
    fn set_should_close(&mut self, value: bool) { self.should_close = value; }
    fn size(&self) -> Size { self.size }
    fn swap_buffers(&mut self) {}
    fn poll_event(&mut self) -> Option<Input> { None }
    fn draw_size(&self) -> Size { self.size() }
}

impl BuildFromWindowSettings for NoWindow {
    fn build_from_window_settings(settings: &WindowSettings)
    -> Result<Self, String> {
        Ok(NoWindow::new(settings))
    }
}

impl AdvancedWindow for NoWindow {
    fn get_title(&self) -> String { self.title.clone() }
    fn set_title(&mut self, value: String) { self.title = value; }
    fn get_exit_on_esc(&self) -> bool { false }
    fn set_exit_on_esc(&mut self, _value: bool) {}
    fn set_capture_cursor(&mut self, _value: bool) {}
}
<commit_msg>Added `resizable` and `decorated`<commit_after>#![deny(missing_docs)]
#![deny(missing_copy_implementations)]

//! Window abstraction

extern crate input;
extern crate shader_version;

use shader_version::OpenGL;
use input::Input;

/// The type of an OpenGL function address.
pub type ProcAddress = *const ();

/// Size in pixels.
#[derive(Debug, Copy, Clone)]
pub struct Size {
    /// The width in pixels.
    pub width: u32,
    /// The height in pixels.
    pub height: u32,
}

impl From<[u32; 2]> for Size {
    #[inline(always)]
    fn from(value: [u32; 2]) -> Size {
        Size { width: value[0], height: value[1] }
    }
}

impl From<(u32, u32)> for Size {
    #[inline(always)]
    fn from(value: (u32, u32)) -> Size {
        Size { width: value.0, height: value.1 }
    }
}

/// Builds window from window settings.
pub trait BuildFromWindowSettings: Sized {
    /// Builds window from window settings.
    fn build_from_window_settings(settings: &WindowSettings)
    -> Result<Self, String>;
}

/// Required to use the event loop.
pub trait Window {
    /// The event type emitted by `poll_event`
    type Event;

    /// Tells the window to close or stay open.
    fn set_should_close(&mut self, value: bool);

    /// Returns true if window should close.
    fn should_close(&self) -> bool;

    /// Gets the size of the window in user coordinates.
    fn size(&self) -> Size;

    /// Swaps render buffers.
    fn swap_buffers(&mut self);

    /// Polls event from window.
    fn poll_event(&mut self) -> Option<Self::Event>;

    /// Gets draw size of the window.
    /// This is equal to the size of the frame buffer of the inner window,
    /// excluding the title bar and borders.
    fn draw_size(&self) -> Size;
}

/// Implemented by fully supported window back-ends.
pub trait AdvancedWindow: Window + Sized {
    /// Gets a copy of the title of the window.
    fn get_title(&self) -> String;

    /// Sets the title of the window.
    fn set_title(&mut self, value: String);

    /// Sets title on window.
    fn title(mut self, value: String) -> Self {
        self.set_title(value);
        self
    }

    /// Gets whether to exit when pressing esc.
    fn get_exit_on_esc(&self) -> bool;

    /// Sets whether to exit when pressing esc.
    fn set_exit_on_esc(&mut self, value: bool);

    /// Sets whether to exit when pressing esc.
    fn exit_on_esc(mut self, value: bool) -> Self {
        self.set_exit_on_esc(value);
        self
    }

    /// Sets whether to capture/grab cursor.
    /// This is used to lock and hide cursor to the window,
    /// for example in a first-person shooter game.
    fn set_capture_cursor(&mut self, value: bool);

    /// Sets whether to capture/grab cursor (see `set_capture_cursor`).
    fn capture_cursor(mut self, value: bool) -> Self {
        self.set_capture_cursor(value);
        self
    }
}

/// Trait for OpenGL specific operations.
pub trait OpenGLWindow: Window {
    /// Returns the address of an OpenGL function if it exist, else returns null pointer.
    fn get_proc_address(&mut self, proc_name: &str) -> ProcAddress;

    /// Returns true if this context is the current context.
    fn is_current(&self) -> bool;

    /// Make this context current.
    fn make_current(&mut self);
}

/// Settings for window behavior.
#[derive(Clone)]
pub struct WindowSettings {
    title: String,
    size: Size,
    samples: u8,
    fullscreen: bool,
    exit_on_esc: bool,
    vsync: bool,
    opengl: Option<OpenGL>,
    srgb: bool,
    resizable: bool,
    decorated: bool,
}

impl WindowSettings {
    /// Creates window settings with defaults.
    ///
    /// - samples: 0
    /// - fullscreen: false
    /// - exit_on_esc: false
    /// - vsync: false
    /// - srgb: true
    /// - resizable: true
    /// - decorated: true
    pub fn new<T: Into<String>, S: Into<Size>>(
        title: T, size: S) -> WindowSettings
    {
        WindowSettings {
            title: title.into(),
            size: size.into(),
            samples: 0,
            fullscreen: false,
            exit_on_esc: false,
            vsync: false,
            opengl: None,
            srgb: true,
            resizable: true,
            decorated: true,
        }
    }

    /// Builds window.
    pub fn build<W: BuildFromWindowSettings>(&self) -> Result<W, String> {
        BuildFromWindowSettings::build_from_window_settings(self)
    }

    /// Gets title.
    pub fn get_title(&self) -> String { self.title.clone() }

    /// Sets title.
    pub fn set_title(&mut self, value: String) {
        self.title = value;
    }

    /// Sets title.
    pub fn title(mut self, value: String) -> Self {
        self.set_title(value);
        self
    }

    /// Gets size.
    pub fn get_size(&self) -> Size { self.size }

    /// Sets size.
    pub fn set_size(&mut self, value: Size) {
        self.size = value;
    }

    /// Sets size.
    pub fn size(mut self, value: Size) -> Self {
        self.set_size(value);
        self
    }

    /// Gets fullscreen.
    pub fn get_fullscreen(&self) -> bool { self.fullscreen }

    /// Sets fullscreen.
    pub fn set_fullscreen(&mut self, value: bool) {
        self.fullscreen = value;
    }

    /// Sets fullscreen.
    pub fn fullscreen(mut self, value: bool) -> Self {
        self.set_fullscreen(value);
        self
    }

    /// Gets exit on esc.
    pub fn get_exit_on_esc(&self) -> bool { self.exit_on_esc }

    /// Sets exit on esc.
    pub fn set_exit_on_esc(&mut self, value: bool) {
        self.exit_on_esc = value;
    }

    /// Sets exit on esc.
    pub fn exit_on_esc(mut self, value: bool) -> Self {
        self.set_exit_on_esc(value);
        self
    }

    /// Gets samples.
    ///
    /// See https://en.wikipedia.org/wiki/Multisample_anti-aliasing
    /// for more information.
    pub fn get_samples(&self) -> u8 { self.samples }

    /// Sets samples.
    pub fn set_samples(&mut self, value: u8) {
        self.samples = value;
    }

    /// Sets samples.
    pub fn samples(mut self, value: u8) -> Self {
        self.set_samples(value);
        self
    }

    /// Gets vsync.
    ///
    /// See https://en.wikipedia.org/wiki/Screen_tearing for more information.
    pub fn get_vsync(&self) -> bool { self.vsync }

    /// Sets vsync.
    pub fn set_vsync(&mut self, value: bool) {
        self.vsync = value;
    }

    /// Sets vsync.
    pub fn vsync(mut self, value: bool) -> Self {
        self.set_vsync(value);
        self
    }

    /// Gets OpenGL version.
    pub fn get_maybe_opengl(&self) -> Option<OpenGL> { self.opengl }

    /// Sets OpenGL version.
    pub fn set_maybe_opengl(&mut self, value: Option<OpenGL>) {
        self.opengl = value;
    }

    /// Sets OpenGL version.
    pub fn maybe_opengl(mut self, value: Option<OpenGL>) -> Self {
        self.set_maybe_opengl(value);
        self
    }

    /// Sets OpenGL version.
    pub fn set_opengl(&mut self, value: OpenGL) {
        self.opengl = Some(value);
    }

    /// Sets OpenGL version.
    pub fn opengl(mut self, value: OpenGL) -> Self {
        self.set_opengl(value);
        self
    }

    /// Gets sRGB.
    ///
    /// See https://en.wikipedia.org/wiki/SRGB for more information.
    pub fn get_srgb(&self) -> bool { self.srgb }

    /// Sets sRGB.
    pub fn set_srgb(&mut self, value: bool) {
        self.srgb = value;
    }

    /// Sets sRGB.
    pub fn srgb(mut self, value: bool) -> Self {
        self.set_srgb(value);
        self
    }

    /// Gets whether window should be resizable.
    pub fn get_resizable(&self) -> bool { self.resizable }

    /// Sets whether window should be resizable.
    pub fn set_resizable(&mut self, value: bool) {
        self.resizable = value;
    }

    /// Sets whether window should be resizable.
    pub fn resizable(mut self, value: bool) -> Self {
        self.set_resizable(value);
        self
    }

    /// Gets whether window should be decorated.
    pub fn get_decorated(&self) -> bool { self.decorated }

    /// Sets whether window should be decorated.
    pub fn set_decorated(&mut self, value: bool) {
        self.decorated = value;
    }

    /// Sets whether window should be decorated.
    pub fn decorated(mut self, value: bool) -> Self {
        self.set_decorated(value);
        self
    }
}

/// An implementation of Window that runs without a window at all.
pub struct NoWindow {
    should_close: bool,
    title: String,
    size: Size
}

impl NoWindow {
    /// Returns a new `NoWindow`.
    pub fn new(settings: &WindowSettings) -> NoWindow {
        NoWindow {
            should_close: false,
            title: settings.get_title(),
            size: settings.get_size(),
        }
    }
}

impl Window for NoWindow {
    type Event = Input;
    fn should_close(&self) -> bool { self.should_close }
    fn set_should_close(&mut self, value: bool) { self.should_close = value; }
    fn size(&self) -> Size { self.size }
    fn swap_buffers(&mut self) {}
    fn poll_event(&mut self) -> Option<Input> { None }
    fn draw_size(&self) -> Size { self.size() }
}

impl BuildFromWindowSettings for NoWindow {
    fn build_from_window_settings(settings: &WindowSettings)
    -> Result<Self, String> {
        Ok(NoWindow::new(settings))
    }
}

impl AdvancedWindow for NoWindow {
    fn get_title(&self) -> String { self.title.clone() }
    fn set_title(&mut self, value: String) { self.title = value; }
    fn get_exit_on_esc(&self) -> bool { false }
    fn set_exit_on_esc(&mut self, _value: bool) {}
    fn set_capture_cursor(&mut self, _value: bool) {}
}
<|endoftext|>


<commit_before>//
// Sysinfo
//
// Copyright (c) 2017 Guillaume Gomez
//

#[macro_export]
macro_rules! auto_cast {
    ($t:expr, $cast:ty) => {{
        #[cfg(target_pointer_width = "32")]
        {
            $t as $cast
        }
        #[cfg(not(target_pointer_width = "32"))]
        {
            $t
        }
    }}
}
<commit_msg>Add missing documentation<commit_after>//
// Sysinfo
//
// Copyright (c) 2017 Guillaume Gomez
//

/// Allows to cast only when needed.
#[macro_export]
macro_rules! auto_cast {
    ($t:expr, $cast:ty) => {{
        #[cfg(target_pointer_width = "32")]
        {
            $t as $cast
        }
        #[cfg(not(target_pointer_width = "32"))]
        {
            $t
        }
    }}
}
<|endoftext|>


<commit_before>extern crate winreg;

use std::env;
use std::ffi::OsStr;
use std::i32;
use std::path::Path;

use self::winreg::RegKey;
use self::winreg::enums::HKEY_CURRENT_USER;

pub fn pre_init() {
    let exe_name = env::current_exe()
        .ok()
        .as_ref()
        .map(Path::new)
        .and_then(Path::file_name)
        .and_then(OsStr::to_str)
        .map(String::from)
        .map(|mut x| {
            let last_dot = x.rfind('.').unwrap_or(0);
            x.truncate(last_dot);
            x
        });

    if exe_name.is_none() {
        warn!("Could not determine name of exe");
        return;
    }
    let exe_name = exe_name.unwrap();

    // The format of the registry value is:
    // <cols>x<rows>,<font_size>,<x_loc>,<y_loc>,<menu_shown>;<min_lines>,<max_lines>,<min_cols>,<max_cols>:<font_name>
    // Example: 80x25,12,312,312,1;2,2147483647,2,2147483647:Courier New
    let hkcu = RegKey::predef(HKEY_CURRENT_USER);
    let existing_value = hkcu.open_subkey("Software\\PDCurses")
        .and_then(|reg_key| reg_key.get_value::<String, &str>(&exe_name))
        .unwrap_or("80x25,12,0,0,1;25,25,80,80:Courier New".to_string());

    let rejoined_menu: String;
    let maxi32 = format!("{}", i32::MAX);
    let mut split: Vec<&str> = existing_value.split(',').collect();

    // The value at index 4 will be <menu_shown>;<min_lines> because we split on ,
    let mut menu_split: Vec<&str> = split[4].split(';').collect();

    // Set the menu_shown value to 0 to always hide it
    #[cfg(not(feature = "show_menu"))]
    {
        menu_split[0] = "0";
    }

    // Set the resize limits to 2 - i32::MAX to allow unlimited resizing
    #[cfg(not(feature = "disable_resize"))]
    {
        menu_split[1] = "2";
        split[5] = &maxi32;
        split[6] = "2";
        split[7] = &maxi32;
    }

    // Re-join the values back into a string
    rejoined_menu = menu_split.join(";");
    split[4] = &rejoined_menu;

    // Write the modified values back into the registry
    match hkcu.open_subkey("Software\\PDCurses").and_then(|reg_key| {
        reg_key.set_value::<String, &str>(&exe_name, &split.join(","))
    }) {
        Err(e) => warn!("Failed to set registry value: {}", e),
        _ => (),
    }
}
<commit_msg>Don't allocate a string if not needed when opening the PDCurses registry value<commit_after>extern crate winreg;

use std::env;
use std::ffi::OsStr;
use std::i32;
use std::path::Path;

use self::winreg::RegKey;
use self::winreg::enums::HKEY_CURRENT_USER;

pub fn pre_init() {
    let exe_name = env::current_exe()
        .ok()
        .as_ref()
        .map(Path::new)
        .and_then(Path::file_name)
        .and_then(OsStr::to_str)
        .map(String::from)
        .map(|mut x| {
            let last_dot = x.rfind('.').unwrap_or(0);
            x.truncate(last_dot);
            x
        });

    if exe_name.is_none() {
        warn!("Could not determine name of exe");
        return;
    }
    let exe_name = exe_name.unwrap();

    // The format of the registry value is:
    // <cols>x<rows>,<font_size>,<x_loc>,<y_loc>,<menu_shown>;<min_lines>,<max_lines>,<min_cols>,<max_cols>:<font_name>
    // Example: 80x25,12,312,312,1;2,2147483647,2,2147483647:Courier New
    let hkcu = RegKey::predef(HKEY_CURRENT_USER);
    let existing_value =
        hkcu.open_subkey("Software\\PDCurses")
            .and_then(|reg_key| reg_key.get_value::<String, &str>(&exe_name))
            .unwrap_or_else(|_| "80x25,12,0,0,1;25,25,80,80:Courier New".to_string());

    let rejoined_menu: String;
    let maxi32 = format!("{}", i32::MAX);
    let mut split: Vec<&str> = existing_value.split(',').collect();

    // The value at index 4 will be <menu_shown>;<min_lines> because we split on ,
    let mut menu_split: Vec<&str> = split[4].split(';').collect();

    // Set the menu_shown value to 0 to always hide it
    #[cfg(not(feature = "show_menu"))]
    {
        menu_split[0] = "0";
    }

    // Set the resize limits to 2 - i32::MAX to allow unlimited resizing
    #[cfg(not(feature = "disable_resize"))]
    {
        menu_split[1] = "2";
        split[5] = &maxi32;
        split[6] = "2";
        split[7] = &maxi32;
    }

    // Re-join the values back into a string
    rejoined_menu = menu_split.join(";");
    split[4] = &rejoined_menu;

    // Write the modified values back into the registry
    if let Err(e) = hkcu.open_subkey("Software\\PDCurses").and_then(|reg_key| {
        reg_key.set_value::<String, &str>(&exe_name, &split.join(","))
    })
    {
        warn!("Failed to set registry value: {}", e);
    }
}
<|endoftext|>


<commit_before><commit_msg>test_install: Add sleeps<commit_after><|endoftext|>


<commit_before><commit_msg>install: add tests for error handling<commit_after><|endoftext|>


<commit_before><commit_msg>tests ~ suppress failing WSL logname test (add investigate ToDO)<commit_after><|endoftext|>