<commit_before>// http://rosettacode.org/wiki/Continued_fraction

use std::iter;

// Calculating a continued fraction is quite easy with iterators, however
// writing a proper iterator adapter is less so. We settle for a macro which
// for most purposes works well enough.
//
// One limitation with this iterator based approach is that we cannot reverse
// input iterators since they are not usually DoubleEnded. To circumvent this
// we can collect the elements and then reverse them, however this isn't ideal
// as we now have to store elements equal to the number of iterations.
//
// Another is that iterators cannot be resused once consumed, so it is often
// required to make many clones of iterators.
macro_rules! continued_fraction {
    ($a:expr, $b:expr ; $iterations:expr) => (
        ($a).zip($b)
            .take($iterations)
            .collect::<Vec<_>>().iter()
            .rev()
            .fold(0 as f64, |acc: f64, &(x, y)| {
                x as f64 + (y as f64 / acc)
            })
    );

    ($a:expr, $b:expr) => (continued_fraction!($a, $b ; 1000));
}

fn main() {
    // Sqrt(2)
    let sqrt2a = (1..2).chain(iter::repeat(2));
    let sqrt2b = iter::repeat(1);
    println!("{}", continued_fraction!(sqrt2a, sqrt2b));

    // Napier's Constant
    let napiera = (2..3).chain(1..);
    let napierb = (1..2).chain(1..);
    println!("{}", continued_fraction!(napiera, napierb));

    // Pi
    let pia = (3..4).chain(iter::repeat(6));
    let pib = (1i64..).map(|x| (2 * x - 1).pow(2));
    println!("{}", continued_fraction!(pia, pib));
}

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

    #[test]
    fn test_sqrt2() {
        let sqrt2a = (1..2).chain(iter::repeat(2));
        let sqrt2b = iter::repeat(1);

        // Note that we must clone the iterator here if we want to reuse
        assert_eq!(continued_fraction!(sqrt2a.clone(), sqrt2b.clone() ; 10),
                   1.4142131979695431f64);

        assert_eq!(continued_fraction!(sqrt2a.clone(), sqrt2b.clone()),
                   continued_fraction!(sqrt2a.clone(), sqrt2b.clone() ; 1000));

        assert_eq!(continued_fraction!(sqrt2a, sqrt2b ; 73),
                   1.4142135623730951f64);
    }
}
<commit_msg>rename variables with similar bindings<commit_after>// http://rosettacode.org/wiki/Continued_fraction

use std::iter;

// Calculating a continued fraction is quite easy with iterators, however
// writing a proper iterator adapter is less so. We settle for a macro which
// for most purposes works well enough.
//
// One limitation with this iterator based approach is that we cannot reverse
// input iterators since they are not usually DoubleEnded. To circumvent this
// we can collect the elements and then reverse them, however this isn't ideal
// as we now have to store elements equal to the number of iterations.
//
// Another is that iterators cannot be resused once consumed, so it is often
// required to make many clones of iterators.
macro_rules! continued_fraction {
    ($a:expr, $b:expr ; $iterations:expr) => (
        ($a).zip($b)
            .take($iterations)
            .collect::<Vec<_>>().iter()
            .rev()
            .fold(0 as f64, |acc: f64, &(x, y)| {
                x as f64 + (y as f64 / acc)
            })
    );

    ($a:expr, $b:expr) => (continued_fraction!($a, $b ; 1000));
}

fn main() {
    // Sqrt(2)
    let sqrt2_a = (1..2).chain(iter::repeat(2));
    let sqrt2_b = iter::repeat(1);
    println!("{}", continued_fraction!(sqrt2_a, sqrt2_b));

    // Napier's Constant
    let napier_a = (2..3).chain(1..);
    let napier_b = (1..2).chain(1..);
    println!("{}", continued_fraction!(napier_a, napier_b));

    // Pi
    let pi_a = (3..4).chain(iter::repeat(6));
    let pi_b = (1i64..).map(|x| (2 * x - 1).pow(2));
    println!("{}", continued_fraction!(pi_a, pi_b));
}

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

    #[test]
    fn test_sqrt2() {
        let sqrt2_a = (1..2).chain(iter::repeat(2));
        let sqrt2_b = iter::repeat(1);

        // Note that we must clone the iterator here if we want to reuse
        assert_eq!(continued_fraction!(sqrt2_a.clone(), sqrt2_b.clone() ; 10),
                   1.4142131979695431f64);

        assert_eq!(continued_fraction!(sqrt2_a.clone(), sqrt2_b.clone()),
                   continued_fraction!(sqrt2_a.clone(), sqrt2_b.clone() ; 1000));

        assert_eq!(continued_fraction!(sqrt2_a, sqrt2_b ; 73),
                   1.4142135623730951f64);
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

use borrow_check::nll::region_infer::values::{PointIndex, RegionValueElements};
use borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap};
use rustc::mir::visit::{PlaceContext, Visitor};
use rustc::mir::{Local, Location, Mir};
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc_data_structures::vec_linked_list as vll;
use util::liveness::{categorize, DefUse, LiveVariableMap};

/// A map that cross references each local with the locations where it
/// is defined (assigned), used, or dropped. Used during liveness
/// computation.
crate struct LocalUseMap<'me> {
    liveness_map: &'me NllLivenessMap,

    /// Head of a linked list of **definitions** of each variable --
    /// definition in this context means assignment, e.g. `x` is
    /// defined in `x = y` but not `y`; that first def is the head of
    /// a linked list that lets you enumerate all places the variable
    /// is assigned.
    first_def_at: IndexVec<LiveVar, Option<AppearanceIndex>>,

    /// Head of a linked list of **uses** of each variable -- use in
    /// this context means that the existing value of the variable is
    /// read or modified. e.g., `y` is used in `x = y` but not `x`.
    /// Note that `DROP(x)` terminators are excluded from this list.
    first_use_at: IndexVec<LiveVar, Option<AppearanceIndex>>,

    /// Head of a linked list of **drops** of each variable -- these
    /// are a special category of uses corresponding to the drop that
    /// we add for each local variable.
    first_drop_at: IndexVec<LiveVar, Option<AppearanceIndex>>,

    appearances: IndexVec<AppearanceIndex, Appearance>,
}

struct Appearance {
    point_index: PointIndex,
    next: Option<AppearanceIndex>,
}

newtype_index!(AppearanceIndex);

impl vll::LinkElem for Appearance {
    type LinkIndex = AppearanceIndex;

    fn next(elem: &Self) -> Option<AppearanceIndex> {
        elem.next
    }
}

impl LocalUseMap<'me> {
    crate fn build(
        liveness_map: &'me NllLivenessMap,
        elements: &RegionValueElements,
        mir: &Mir<'_>,
    ) -> Self {
        let nones = IndexVec::from_elem_n(None, liveness_map.num_variables());
        let mut local_use_map = LocalUseMap {
            liveness_map,
            first_def_at: nones.clone(),
            first_use_at: nones.clone(),
            first_drop_at: nones,
            appearances: IndexVec::new(),
        };

        LocalUseMapBuild {
            local_use_map: &mut local_use_map,
            elements,
        }.visit_mir(mir);

        local_use_map
    }

    crate fn defs(&self, local: LiveVar) -> impl Iterator<Item = PointIndex> + '_ {
        vll::iter(self.first_def_at[local], &self.appearances)
            .map(move |aa| self.appearances[aa].point_index)
    }

    crate fn uses(&self, local: LiveVar) -> impl Iterator<Item = PointIndex> + '_ {
        vll::iter(self.first_use_at[local], &self.appearances)
            .map(move |aa| self.appearances[aa].point_index)
    }

    crate fn drops(&self, local: LiveVar) -> impl Iterator<Item = PointIndex> + '_ {
        vll::iter(self.first_drop_at[local], &self.appearances)
            .map(move |aa| self.appearances[aa].point_index)
    }
}

struct LocalUseMapBuild<'me, 'map> {
    local_use_map: &'me mut LocalUseMap<'map>,
    elements: &'me RegionValueElements,
}

impl LocalUseMapBuild<'_, '_> {
    fn insert_def(&mut self, local: LiveVar, location: Location) {
        Self::insert(
            self.elements,
            &mut self.local_use_map.first_def_at[local],
            &mut self.local_use_map.appearances,
            location,
        );
    }

    fn insert_use(&mut self, local: LiveVar, location: Location) {
        Self::insert(
            self.elements,
            &mut self.local_use_map.first_use_at[local],
            &mut self.local_use_map.appearances,
            location,
        );
    }

    fn insert_drop(&mut self, local: LiveVar, location: Location) {
        Self::insert(
            self.elements,
            &mut self.local_use_map.first_drop_at[local],
            &mut self.local_use_map.appearances,
            location,
        );
    }

    fn insert(
        elements: &RegionValueElements,
        first_appearance: &mut Option<AppearanceIndex>,
        appearances: &mut IndexVec<AppearanceIndex, Appearance>,
        location: Location,
    ) {
        let point_index = elements.point_from_location(location);
        let appearance_index = appearances.push(Appearance {
            point_index,
            next: *first_appearance,
        });
        *first_appearance = Some(appearance_index);
    }
}

impl Visitor<'tcx> for LocalUseMapBuild<'_, '_> {
    fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, location: Location) {
        if let Some(local_with_region) = self.local_use_map.liveness_map.from_local(local) {
            match categorize(context) {
                Some(DefUse::Def) => self.insert_def(local_with_region, location),
                Some(DefUse::Use) => self.insert_use(local_with_region, location),
                Some(DefUse::Drop) => self.insert_drop(local_with_region, location),
                _ => (),
            }
        }
    }
}
<commit_msg>Fix definition of `LocalUseMapBuild` so that it can build under stage0, which does not have as many feature gates enabled.<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

use borrow_check::nll::region_infer::values::{PointIndex, RegionValueElements};
use borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap};
use rustc::mir::visit::{PlaceContext, Visitor};
use rustc::mir::{Local, Location, Mir};
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc_data_structures::vec_linked_list as vll;
use util::liveness::{categorize, DefUse, LiveVariableMap};

/// A map that cross references each local with the locations where it
/// is defined (assigned), used, or dropped. Used during liveness
/// computation.
crate struct LocalUseMap<'me> {
    liveness_map: &'me NllLivenessMap,

    /// Head of a linked list of **definitions** of each variable --
    /// definition in this context means assignment, e.g. `x` is
    /// defined in `x = y` but not `y`; that first def is the head of
    /// a linked list that lets you enumerate all places the variable
    /// is assigned.
    first_def_at: IndexVec<LiveVar, Option<AppearanceIndex>>,

    /// Head of a linked list of **uses** of each variable -- use in
    /// this context means that the existing value of the variable is
    /// read or modified. e.g., `y` is used in `x = y` but not `x`.
    /// Note that `DROP(x)` terminators are excluded from this list.
    first_use_at: IndexVec<LiveVar, Option<AppearanceIndex>>,

    /// Head of a linked list of **drops** of each variable -- these
    /// are a special category of uses corresponding to the drop that
    /// we add for each local variable.
    first_drop_at: IndexVec<LiveVar, Option<AppearanceIndex>>,

    appearances: IndexVec<AppearanceIndex, Appearance>,
}

struct Appearance {
    point_index: PointIndex,
    next: Option<AppearanceIndex>,
}

newtype_index!(AppearanceIndex);

impl vll::LinkElem for Appearance {
    type LinkIndex = AppearanceIndex;

    fn next(elem: &Self) -> Option<AppearanceIndex> {
        elem.next
    }
}

impl LocalUseMap<'me> {
    crate fn build(
        liveness_map: &'me NllLivenessMap,
        elements: &RegionValueElements,
        mir: &Mir<'_>,
    ) -> Self {
        let nones = IndexVec::from_elem_n(None, liveness_map.num_variables());
        let mut local_use_map = LocalUseMap {
            liveness_map,
            first_def_at: nones.clone(),
            first_use_at: nones.clone(),
            first_drop_at: nones,
            appearances: IndexVec::new(),
        };

        LocalUseMapBuild {
            local_use_map: &mut local_use_map,
            elements,
        }.visit_mir(mir);

        local_use_map
    }

    crate fn defs(&self, local: LiveVar) -> impl Iterator<Item = PointIndex> + '_ {
        vll::iter(self.first_def_at[local], &self.appearances)
            .map(move |aa| self.appearances[aa].point_index)
    }

    crate fn uses(&self, local: LiveVar) -> impl Iterator<Item = PointIndex> + '_ {
        vll::iter(self.first_use_at[local], &self.appearances)
            .map(move |aa| self.appearances[aa].point_index)
    }

    crate fn drops(&self, local: LiveVar) -> impl Iterator<Item = PointIndex> + '_ {
        vll::iter(self.first_drop_at[local], &self.appearances)
            .map(move |aa| self.appearances[aa].point_index)
    }
}

struct LocalUseMapBuild<'me, 'map: 'me> {
    local_use_map: &'me mut LocalUseMap<'map>,
    elements: &'me RegionValueElements,
}

impl LocalUseMapBuild<'_, '_> {
    fn insert_def(&mut self, local: LiveVar, location: Location) {
        Self::insert(
            self.elements,
            &mut self.local_use_map.first_def_at[local],
            &mut self.local_use_map.appearances,
            location,
        );
    }

    fn insert_use(&mut self, local: LiveVar, location: Location) {
        Self::insert(
            self.elements,
            &mut self.local_use_map.first_use_at[local],
            &mut self.local_use_map.appearances,
            location,
        );
    }

    fn insert_drop(&mut self, local: LiveVar, location: Location) {
        Self::insert(
            self.elements,
            &mut self.local_use_map.first_drop_at[local],
            &mut self.local_use_map.appearances,
            location,
        );
    }

    fn insert(
        elements: &RegionValueElements,
        first_appearance: &mut Option<AppearanceIndex>,
        appearances: &mut IndexVec<AppearanceIndex, Appearance>,
        location: Location,
    ) {
        let point_index = elements.point_from_location(location);
        let appearance_index = appearances.push(Appearance {
            point_index,
            next: *first_appearance,
        });
        *first_appearance = Some(appearance_index);
    }
}

impl Visitor<'tcx> for LocalUseMapBuild<'_, '_> {
    fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, location: Location) {
        if let Some(local_with_region) = self.local_use_map.liveness_map.from_local(local) {
            match categorize(context) {
                Some(DefUse::Def) => self.insert_def(local_with_region, location),
                Some(DefUse::Use) => self.insert_use(local_with_region, location),
                Some(DefUse::Drop) => self.insert_drop(local_with_region, location),
                _ => (),
            }
        }
    }
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Flipping_bits_game

// For random generation
extern crate rand;

// For fmt::Display
use std::fmt;
// For I/O (stdin, stdout, etc)
use std::io::prelude::*;

// A simple struct for our board
struct Board {
    cells: Vec<bool>,
    size: usize,
}

// Functions for the Board struct
impl Board {
    // Generate a new, empty board
    fn new(size: usize) -> Board {
        // Ensure we make a board with a non-zero size
        if size == 0 {
            // Don't make a board of size 0
            Board {
                cells: vec![false; 1],
                size: 1,
            }
        } else {
            Board {
                cells: vec![false; size*size],
                size: size,
            }
        }
    }

    // Flip the specified row
    fn fliprow(&mut self, row: usize) -> bool {
        // Check constraints
        if row > self.size {
            return false;
        }
        // Starting position in the vector
        let start = row * self.size;
        // Loop through the vector row
        for i in start..start + self.size {
            self.cells[i] = !self.cells[i];
        }
        true
    }

    // Flip the specified column
    fn flipcol(&mut self, col: usize) -> bool {
        // Check constraints
        if col > self.size {
            return false;
        }
        // Loop through the vector column
        for i in 0..self.size {
            self.cells[col + i * self.size] = !self.cells[col + i * self.size];
        }
        true
    }

    // Generate a random board
    fn random(size: usize) -> Board {
        // Make a vector of the board size
        let mut r: Vec<bool> = vec![false; size*size];
        // Loop through all the cells
        for i in 0..size * size {
            // Give it a random state
            r[i] = rand::random::<bool>();
        }
        // Return the random board
        Board {
            cells: r.clone(),
            size: size,
        }
    }

    // Check if a board is equal to another
    fn eq(&self, rhs: &Board) -> bool {
        // Has to be a board of the same size
        if self.size != rhs.size {
            return false;
        }
        // Loop through the board
        for i in 0..self.size * self.size {
            // If cells do not match, not equal
            if self.cells[i] != rhs.cells[i] {
                return false;
            }
        }
        // If we get here, boards are equal
        true
    }
}

// Implement the Display format, used with `print!("{}", &board);`
impl fmt::Display for Board {
    // Example output:
    //   0 1 2
    // 0 0 1 0
    // 1 1 0 0
    // 2 0 1 1
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Get the string width of the size of the board
        let width = (self.size - 1).to_string().len();
        // Write the initial spaces (upper left)
        try!(write!(f, "{space: >0$}", width, space = " "));
        // Write the column numbers
        for i in 0..self.size {
            try!(write!(f, " {offset:>0$}", width, offset = i));
        }
        // Newline for rows
        try!(write!(f, "\n"));
        // Loop through the rows
        for row in 0..self.size {
            // Write the row number
            try!(write!(f, "{row:>0$}", width, row = row));
            // Loop through the columns
            for col in 0..self.size {
                // Get the value of the cell as 1 or 0
                let p = if self.cells[row * self.size + col] {
                    1
                } else {
                    0
                };
                // Write the column value
                try!(write!(f, " {col:>0$}", width, col = p));
            }
            // Newline for next row
            try!(write!(f, "\n"));
        }
        // Return Formatter result
        write!(f, "")
    }
}

fn main() {
    // The board size
    let size: usize = 3;
    // The target board
    let target: Board = Board::random(size);
    // The user board
    let mut board: Board = Board::new(size);
    // How many moves taken
    let mut moves: u32 = 0;
    // Loop until win or quit
    'mainloop: loop {
        // User input
        let mut input: String;
        // Write the boards
        println!("Target:\n{}\nBoard:\n{}", &target, &board);
        // User input loop
        'userinput: loop {
            // Prompt
            print!("\nFlip? [q|[r|c]#] ");
            // Flush stdout to write the previous print, if we can't then exit
            match std::io::stdout().flush() {
                Ok(_) => {}
                Err(e) => {
                    println!("Error: cannot flush stdout: {}", e);
                    break 'mainloop;
                }
            };
            // Reset input for each loop
            input = String::new();
            // Read user input
            match std::io::stdin().read_line(&mut input) {
                Ok(_) => {
                    input = input.trim().to_string();
                    // Get the first character
                    let rc: char = match input.chars().nth(0) {
                        Some(c) => c,
                        None => {
                            println!("Error: No input");
                            continue 'userinput;
                        }
                    };
                    // Make sure input is r, c, or q
                    if rc != 'r' && rc != 'c' && rc != 'q' {
                        println!("Error: '{}': Must use 'r'ow or 'c'olumn or 'q'uit", rc);
                        continue 'userinput;
                    }
                    // If input is q, exit game
                    if rc == 'q' {
                        println!("Thanks for playing!");
                        break 'mainloop;
                    }
                    // If input is r or c, get the number after
                    let n: usize = match input[1..].to_string().parse() {
                        Ok(x) => {
                            // If we're within bounds, return the parsed number
                            if x < size {
                                x
                            } else {
                                println!("Error: Must specify a row or column within size({})",
                                         size);
                                continue 'userinput;
                            }
                        }
                        Err(_) => {
                            println!("Error: '{}': Unable to parse row or column number",
                                     input[1..].to_string());
                            continue 'userinput;
                        }
                    };
                    // Flip the row or column specified
                    match rc {
                        'r' => board.fliprow(n),
                        'c' => board.flipcol(n),
                        _ => {
                            // We want to panic here because should NEVER
                            // have anything other than 'r' or 'c' here
                            panic!("How did you end up here?");
                        }
                    };
                    // Increment moves
                    moves += 1;
                    println!("Moves taken: {}", moves);
                    break 'userinput;
                }
                Err(e) => {
                    println!("Error reading input: {}", e);
                    break 'mainloop;
                }
            }
        } // 'userinput
        if board.eq(&target) {
            println!("You win!");
            break;
        }
    } // 'mainloop
}
<commit_msg>Change function comments to doc comments; add size 0 check to Board::random<commit_after>// http://rosettacode.org/wiki/Flipping_bits_game

// For random generation
extern crate rand;

// For fmt::Display
use std::fmt;
// For I/O (stdin, stdout, etc)
use std::io::prelude::*;

/// A simple struct for a board
struct Board {
    /// The cells of the board
    cells: Vec<bool>,
    /// The size of the board
    size: usize,
}

// Functions for the Board struct
impl Board {
    /// Generate a new, empty board, of size >= 1
    ///
    /// Returns a Board in the "off" state, where all cells are 0.
    /// If a size of 0 is given, a Board of size 1 will be created instead.
    fn new(size: usize) -> Board {
        // Ensure we make a board with a non-zero size
        if size > 0 {
            Board {
                cells: vec![false; size*size],
                size: size,
            }
        } else {
            Board::new(1)
        }
    }

    /// Flip the specified row
    ///
    /// Returns true if the row is within the size, false otherwise.
    ///
    /// ```
    /// let mut board: Board = Board::new();
    /// board.fliprow(1);
    /// ```
    fn fliprow(&mut self, row: usize) -> bool {
        // Check constraints
        if row > self.size {
            return false;
        }
        // Starting position in the vector
        let start = row * self.size;
        // Loop through the vector row
        for i in start..start + self.size {
            self.cells[i] = !self.cells[i];
        }
        true
    }

    /// Flip the specified column
    ///
    /// Returns true if the column is within the size, false otherwise.
    ///
    /// ```
    /// let mut board: Board = Board::new();
    /// board.flipcol(0);
    /// ```
    fn flipcol(&mut self, col: usize) -> bool {
        // Check constraints
        if col > self.size {
            return false;
        }
        // Loop through the vector column
        for i in 0..self.size {
            self.cells[col + i * self.size] = !self.cells[col + i * self.size];
        }
        true
    }

    /// Generate a random board
    ///
    /// Returns a Board in a random state.
    /// If a size of 0 is given, a Board of size 1 will be created instead.
    fn random(size: usize) -> Board {
        // Ensure we make a board with a non-zero size
        if size > 0 {
            // Make a vector of the board size
            let mut r: Vec<bool> = vec![false; size*size];
            // Loop through all the cells
            for i in 0..size * size {
                // Give it a random state
                r[i] = rand::random::<bool>();
            }
            // Return the random board
            Board {
                cells: r.clone(),
                size: size,
            }
        } else {
            Board::random(1)
        }
    }

    /// Check if a board is equal to another
    ///
    /// Returns true if boards are of equal size and contents, false otherwise.
    fn eq(&self, rhs: &Board) -> bool {
        // Has to be a board of the same size
        if self.size != rhs.size {
            return false;
        }
        // Loop through the board
        for i in 0..self.size * self.size {
            // If cells do not match, not equal
            if self.cells[i] != rhs.cells[i] {
                return false;
            }
        }
        // If we get here, boards are equal
        true
    }
}

// Implement the Display format, used with `print!("{}", &board);`
impl fmt::Display for Board {
    // Example output:
    //   0 1 2
    // 0 0 1 0
    // 1 1 0 0
    // 2 0 1 1
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Get the string width of the size of the board
        let width = (self.size - 1).to_string().len();
        // Write the initial spaces (upper left)
        try!(write!(f, "{space: >0$}", width, space = " "));
        // Write the column numbers
        for i in 0..self.size {
            try!(write!(f, " {offset:>0$}", width, offset = i));
        }
        // Newline for rows
        try!(write!(f, "\n"));
        // Loop through the rows
        for row in 0..self.size {
            // Write the row number
            try!(write!(f, "{row:>0$}", width, row = row));
            // Loop through the columns
            for col in 0..self.size {
                // Get the value of the cell as 1 or 0
                let p = if self.cells[row * self.size + col] {
                    1
                } else {
                    0
                };
                // Write the column value
                try!(write!(f, " {col:>0$}", width, col = p));
            }
            // Newline for next row
            try!(write!(f, "\n"));
        }
        // Return Formatter result
        write!(f, "")
    }
}

fn main() {
    // The board size
    let size: usize = 3;
    // The target board
    let target: Board = Board::random(size);
    // The user board
    let mut board: Board = Board::new(size);
    // How many moves taken
    let mut moves: u32 = 0;
    // Loop until win or quit
    'mainloop: loop {
        // User input
        let mut input: String;
        // Write the boards
        println!("Target:\n{}\nBoard:\n{}", &target, &board);
        // User input loop
        'userinput: loop {
            // Prompt
            print!("\nFlip? [q|[r|c]#] ");
            // Flush stdout to write the previous print, if we can't then exit
            match std::io::stdout().flush() {
                Ok(_) => {}
                Err(e) => {
                    println!("Error: cannot flush stdout: {}", e);
                    break 'mainloop;
                }
            };
            // Reset input for each loop
            input = String::new();
            // Read user input
            match std::io::stdin().read_line(&mut input) {
                Ok(_) => {
                    input = input.trim().to_string();
                    // Get the first character
                    let rc: char = match input.chars().nth(0) {
                        Some(c) => c,
                        None => {
                            println!("Error: No input");
                            continue 'userinput;
                        }
                    };
                    // Make sure input is r, c, or q
                    if rc != 'r' && rc != 'c' && rc != 'q' {
                        println!("Error: '{}': Must use 'r'ow or 'c'olumn or 'q'uit", rc);
                        continue 'userinput;
                    }
                    // If input is q, exit game
                    if rc == 'q' {
                        println!("Thanks for playing!");
                        break 'mainloop;
                    }
                    // If input is r or c, get the number after
                    let n: usize = match input[1..].to_string().parse() {
                        Ok(x) => {
                            // If we're within bounds, return the parsed number
                            if x < size {
                                x
                            } else {
                                println!("Error: Must specify a row or column within size({})",
                                         size);
                                continue 'userinput;
                            }
                        }
                        Err(_) => {
                            println!("Error: '{}': Unable to parse row or column number",
                                     input[1..].to_string());
                            continue 'userinput;
                        }
                    };
                    // Flip the row or column specified
                    match rc {
                        'r' => board.fliprow(n),
                        'c' => board.flipcol(n),
                        _ => {
                            // We want to panic here because should NEVER
                            // have anything other than 'r' or 'c' here
                            panic!("How did you end up here?");
                        }
                    };
                    // Increment moves
                    moves += 1;
                    println!("Moves taken: {}", moves);
                    break 'userinput;
                }
                Err(e) => {
                    println!("Error reading input: {}", e);
                    break 'mainloop;
                }
            }
        } // 'userinput
        if board.eq(&target) {
            println!("You win!");
            break;
        }
    } // 'mainloop
}
<|endoftext|>


<commit_before>// Copyright (c) 2020-present, Gregory Szorc
// All rights reserved.
//
// This software may be modified and distributed under the terms
// of the BSD license. See the LICENSE file for details.

#![feature(try_reserve)]

use pyo3::{prelude::*, types::PySet};

mod buffers;
mod compression_chunker;
mod compression_dict;
mod compression_parameters;
mod compression_reader;
mod compression_writer;
mod compressionobj;
mod compressor;
mod compressor_iterator;
mod compressor_multi;
mod constants;
mod decompression_reader;
mod decompression_writer;
mod decompressionobj;
mod decompressor;
mod decompressor_iterator;
mod decompressor_multi;
mod exceptions;
mod frame_parameters;
mod stream;
mod zstd_safe;

use exceptions::ZstdError;

// Remember to change the string in c-ext/python-zstandard.h, zstandard/__init__.py,
// and debian/changelog as well.
const VERSION: &'static str = "0.18.0.dev0";

#[pymodule]
fn backend_rust(py: Python, module: &PyModule) -> PyResult<()> {
    let features = PySet::new(
        py,
        &[
            "buffer_types",
            "multi_compress_to_buffer",
            "multi_decompress_to_buffer",
        ],
    )?;
    module.add("backend_features", features)?;

    crate::buffers::init_module(module)?;
    crate::compression_dict::init_module(module)?;
    crate::compression_parameters::init_module(module)?;
    crate::compressor::init_module(module)?;
    crate::constants::init_module(py, module)?;
    crate::decompressor::init_module(module)?;
    crate::exceptions::init_module(py, module)?;
    crate::frame_parameters::init_module(module)?;

    Ok(())
}
<commit_msg>rust: remove try_reserve feature<commit_after>// Copyright (c) 2020-present, Gregory Szorc
// All rights reserved.
//
// This software may be modified and distributed under the terms
// of the BSD license. See the LICENSE file for details.

use pyo3::{prelude::*, types::PySet};

mod buffers;
mod compression_chunker;
mod compression_dict;
mod compression_parameters;
mod compression_reader;
mod compression_writer;
mod compressionobj;
mod compressor;
mod compressor_iterator;
mod compressor_multi;
mod constants;
mod decompression_reader;
mod decompression_writer;
mod decompressionobj;
mod decompressor;
mod decompressor_iterator;
mod decompressor_multi;
mod exceptions;
mod frame_parameters;
mod stream;
mod zstd_safe;

use exceptions::ZstdError;

// Remember to change the string in c-ext/python-zstandard.h, zstandard/__init__.py,
// and debian/changelog as well.
const VERSION: &'static str = "0.18.0.dev0";

#[pymodule]
fn backend_rust(py: Python, module: &PyModule) -> PyResult<()> {
    let features = PySet::new(
        py,
        &[
            "buffer_types",
            "multi_compress_to_buffer",
            "multi_decompress_to_buffer",
        ],
    )?;
    module.add("backend_features", features)?;

    crate::buffers::init_module(module)?;
    crate::compression_dict::init_module(module)?;
    crate::compression_parameters::init_module(module)?;
    crate::compressor::init_module(module)?;
    crate::constants::init_module(py, module)?;
    crate::decompressor::init_module(module)?;
    crate::exceptions::init_module(py, module)?;
    crate::frame_parameters::init_module(module)?;

    Ok(())
}
<|endoftext|>


<commit_before>// Copyright (C) 2018, Cloudflare, Inc.
// Copyright (C) 2018, Alessandro Ghedini
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#[macro_use]
extern crate log;

use ring::rand::*;

const LOCAL_CONN_ID_LEN: usize = 16;

const HTTP_REQ_STREAM_ID: u64 = 4;

const USAGE: &str = "Usage: client [options] URL

Options:
  -h --help          Show this screen.
  --no-verify        Don't verify server's certificate.
";

fn main() {
    let mut buf = [0; 65535];
    let mut out = [0; 1400];

    env_logger::init();

    let args = docopt::Docopt::new(USAGE)
                      .and_then(|dopt| dopt.parse())
                      .unwrap_or_else(|e| e.exit());

    let url = url::Url::parse(args.get_str("URL")).unwrap();

    let socket = std::net::UdpSocket::bind("0.0.0.0:0").unwrap();
    socket.connect(&url).unwrap();

    let poll = mio::Poll::new().unwrap();
    let mut events = mio::Events::with_capacity(1024);

    let socket = mio::net::UdpSocket::from_socket(socket).unwrap();
    poll.register(&socket, mio::Token(0),
                  mio::Ready::readable(),
                  mio::PollOpt::edge()).unwrap();

    let mut scid: [u8; LOCAL_CONN_ID_LEN] = [0; LOCAL_CONN_ID_LEN];
    SystemRandom::new().fill(&mut scid[..]).unwrap();

    let mut config = quiche::Config::new(0xbabababa).unwrap();

    config.verify_peer(true);

    config.set_idle_timeout(30);
    config.set_max_packet_size(1460);
    config.set_initial_max_data(10_000_000);
    config.set_initial_max_stream_data_bidi_local(1_000_000);
    config.set_initial_max_stream_data_bidi_remote(1_000_000);
    config.set_initial_max_streams_bidi(100);
    config.set_disable_migration(true);

    if args.get_bool("--no-verify") {
        config.verify_peer(false);
    }

    if std::env::var_os("SSLKEYLOGFILE").is_some() {
        config.log_keys();
    }

    let mut conn = quiche::connect(url.domain(), &scid, &mut config).unwrap();

    let write = match conn.send(&mut out) {
        Ok(v) => v,

        Err(e) => panic!("{} initial send failed: {:?}", conn.trace_id(), e),
    };

    socket.send(&out[..write]).unwrap();

    debug!("{} written {}", conn.trace_id(), write);

    let mut req_sent = false;

    loop {
        poll.poll(&mut events, conn.timeout()).unwrap();

        'read: loop {
            if events.is_empty() {
                debug!("timed out");

                conn.on_timeout();

                break 'read;
            }

            let len = match socket.recv(&mut buf) {
                Ok(v) => v,

                Err(e) => {
                    if e.kind() == std::io::ErrorKind::WouldBlock {
                        debug!("recv() would block");
                        break 'read;
                    }

                    panic!("recv() failed: {:?}", e);
                },
            };

            debug!("{} got {} bytes", conn.trace_id(), len);

            // Process potentially coalesced packets.
            let read = match conn.recv(&mut buf[..len]) {
                Ok(v)  => v,

                Err(quiche::Error::Done) => {
                    debug!("{} done reading", conn.trace_id());
                    break;
                },

                Err(e) => {
                    error!("{} recv failed: {:?}", conn.trace_id(), e);
                    conn.close(false, e.to_wire(), b"fail").unwrap();
                    break 'read;
                },
            };

            debug!("{} processed {} bytes", conn.trace_id(), read);
        }

        if conn.is_closed() {
            debug!("{} connection closed", conn.trace_id());
            break;
        }

        if conn.is_established() && !req_sent {
            info!("{} sending HTTP request for {}", conn.trace_id(), url.path());

            let req = format!("GET {}\r\n", url.path());
            conn.stream_send(HTTP_REQ_STREAM_ID, req.as_bytes(), true).unwrap();

            req_sent = true;
        }

        let streams: Vec<u64> = conn.readable().collect();
        for s in streams {
            let data = conn.stream_recv(s, std::usize::MAX).unwrap();

            info!("{} stream {} has {} bytes (fin? {})",
                  conn.trace_id(), s, data.len(), data.fin());

            print!("{}", unsafe { std::str::from_utf8_unchecked(&data) });

            if s == HTTP_REQ_STREAM_ID && data.fin() {
                conn.close(true, 0x00, b"kthxbye").unwrap();
            }
        }

        loop {
            let write = match conn.send(&mut out) {
                Ok(v) => v,

                Err(quiche::Error::Done) => {
                    debug!("{} done writing", conn.trace_id());
                    break;
                },

                Err(e) => {
                    error!("{} send failed: {:?}", conn.trace_id(), e);
                    conn.close(false, e.to_wire(), b"fail").unwrap();
                    break;
                },
            };

            // TODO: coalesce packets.
            socket.send(&out[..write]).unwrap();

            debug!("{} written {}", conn.trace_id(), write);
        }

        if conn.is_closed() {
            debug!("{} connection closed", conn.trace_id());
            break;
        }
    }
}
<commit_msg>client: add option to set custom wire version<commit_after>// Copyright (C) 2018, Cloudflare, Inc.
// Copyright (C) 2018, Alessandro Ghedini
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#[macro_use]
extern crate log;

use ring::rand::*;

const LOCAL_CONN_ID_LEN: usize = 16;

const HTTP_REQ_STREAM_ID: u64 = 4;

const USAGE: &str = "Usage: client [options] URL

Options:
  -h --help               Show this screen.
  --wire-version VERSION  The version number to send to the server [default: babababa].
  --no-verify             Don't verify server's certificate.
";

fn main() {
    let mut buf = [0; 65535];
    let mut out = [0; 1400];

    env_logger::init();

    let args = docopt::Docopt::new(USAGE)
                      .and_then(|dopt| dopt.parse())
                      .unwrap_or_else(|e| e.exit());

    let url = url::Url::parse(args.get_str("URL")).unwrap();

    let socket = std::net::UdpSocket::bind("0.0.0.0:0").unwrap();
    socket.connect(&url).unwrap();

    let poll = mio::Poll::new().unwrap();
    let mut events = mio::Events::with_capacity(1024);

    let socket = mio::net::UdpSocket::from_socket(socket).unwrap();
    poll.register(&socket, mio::Token(0),
                  mio::Ready::readable(),
                  mio::PollOpt::edge()).unwrap();

    let mut scid: [u8; LOCAL_CONN_ID_LEN] = [0; LOCAL_CONN_ID_LEN];
    SystemRandom::new().fill(&mut scid[..]).unwrap();

    let version = args.get_str("--wire-version");
    let version = u32::from_str_radix(version, 16).unwrap();

    let mut config = quiche::Config::new(version).unwrap();

    config.verify_peer(true);

    config.set_idle_timeout(30);
    config.set_max_packet_size(1460);
    config.set_initial_max_data(10_000_000);
    config.set_initial_max_stream_data_bidi_local(1_000_000);
    config.set_initial_max_stream_data_bidi_remote(1_000_000);
    config.set_initial_max_streams_bidi(100);
    config.set_disable_migration(true);

    if args.get_bool("--no-verify") {
        config.verify_peer(false);
    }

    if std::env::var_os("SSLKEYLOGFILE").is_some() {
        config.log_keys();
    }

    let mut conn = quiche::connect(url.domain(), &scid, &mut config).unwrap();

    let write = match conn.send(&mut out) {
        Ok(v) => v,

        Err(e) => panic!("{} initial send failed: {:?}", conn.trace_id(), e),
    };

    socket.send(&out[..write]).unwrap();

    debug!("{} written {}", conn.trace_id(), write);

    let mut req_sent = false;

    loop {
        poll.poll(&mut events, conn.timeout()).unwrap();

        'read: loop {
            if events.is_empty() {
                debug!("timed out");

                conn.on_timeout();

                break 'read;
            }

            let len = match socket.recv(&mut buf) {
                Ok(v) => v,

                Err(e) => {
                    if e.kind() == std::io::ErrorKind::WouldBlock {
                        debug!("recv() would block");
                        break 'read;
                    }

                    panic!("recv() failed: {:?}", e);
                },
            };

            debug!("{} got {} bytes", conn.trace_id(), len);

            // Process potentially coalesced packets.
            let read = match conn.recv(&mut buf[..len]) {
                Ok(v)  => v,

                Err(quiche::Error::Done) => {
                    debug!("{} done reading", conn.trace_id());
                    break;
                },

                Err(e) => {
                    error!("{} recv failed: {:?}", conn.trace_id(), e);
                    conn.close(false, e.to_wire(), b"fail").unwrap();
                    break 'read;
                },
            };

            debug!("{} processed {} bytes", conn.trace_id(), read);
        }

        if conn.is_closed() {
            debug!("{} connection closed", conn.trace_id());
            break;
        }

        if conn.is_established() && !req_sent {
            info!("{} sending HTTP request for {}", conn.trace_id(), url.path());

            let req = format!("GET {}\r\n", url.path());
            conn.stream_send(HTTP_REQ_STREAM_ID, req.as_bytes(), true).unwrap();

            req_sent = true;
        }

        let streams: Vec<u64> = conn.readable().collect();
        for s in streams {
            let data = conn.stream_recv(s, std::usize::MAX).unwrap();

            info!("{} stream {} has {} bytes (fin? {})",
                  conn.trace_id(), s, data.len(), data.fin());

            print!("{}", unsafe { std::str::from_utf8_unchecked(&data) });

            if s == HTTP_REQ_STREAM_ID && data.fin() {
                conn.close(true, 0x00, b"kthxbye").unwrap();
            }
        }

        loop {
            let write = match conn.send(&mut out) {
                Ok(v) => v,

                Err(quiche::Error::Done) => {
                    debug!("{} done writing", conn.trace_id());
                    break;
                },

                Err(e) => {
                    error!("{} send failed: {:?}", conn.trace_id(), e);
                    conn.close(false, e.to_wire(), b"fail").unwrap();
                    break;
                },
            };

            // TODO: coalesce packets.
            socket.send(&out[..write]).unwrap();

            debug!("{} written {}", conn.trace_id(), write);
        }

        if conn.is_closed() {
            debug!("{} connection closed", conn.trace_id());
            break;
        }
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use arrayvec::ArrayString;
use async_trait::async_trait;
use devp2p::*;
use ethereum_types::*;
use futures::stream::BoxStream;
use hex_literal::hex;
use k256::ecdsa::SigningKey;
use maplit::btreemap;
use parking_lot::RwLock;
use rand::rngs::OsRng;
use rlp_derive::{RlpDecodable, RlpEncodable};
use std::{
    collections::{BTreeSet, HashMap},
    sync::{
        atomic::{AtomicUsize, Ordering},
        Arc,
    },
};
use task_group::TaskGroup;
use tokio::{
    stream::StreamExt,
    sync::{
        mpsc::{channel, Sender},
        Mutex as AsyncMutex,
    },
};
use tracing::*;
use tracing_subscriber::EnvFilter;
use trust_dns_resolver::{config::*, TokioAsyncResolver};
use uuid::Uuid;

const DNS_BOOTNODE: &str = "all.mainnet.ethdisco.net";

fn eth() -> CapabilityName {
    CapabilityName(ArrayString::from("eth").unwrap())
}

#[derive(Debug, Default)]
struct TaskMetrics {
    count: AtomicUsize,
}

impl task_group::Metrics for TaskMetrics {
    fn task_started(&self, id: Uuid, name: String) {
        let c = self.count.fetch_add(1, Ordering::Relaxed);
        trace!("Current tasks: {}. Started task {}/{}", c + 1, name, id)
    }

    fn task_stopped(&self, id: Uuid, name: String) {
        let c = self.count.fetch_sub(1, Ordering::Relaxed);
        trace!("Current tasks: {}. Stopped task {}/{}", c - 1, name, id)
    }
}

#[derive(Debug, RlpEncodable, RlpDecodable)]
struct StatusMessage {
    protocol_version: usize,
    network_id: usize,
    total_difficulty: U256,
    best_hash: H256,
    genesis_hash: H256,
}

#[derive(Clone)]
struct Pipes {
    sender: Sender<OutboundEvent>,
    receiver: Arc<AsyncMutex<BoxStream<'static, OutboundEvent>>>,
}

#[derive(Default)]
struct CapabilityServerImpl {
    on_event_pipes: Arc<RwLock<HashMap<PeerId, Pipes>>>,
}

impl CapabilityServerImpl {
    fn setup_pipes(&self, peer: PeerId, pipes: Pipes) {
        assert!(self.on_event_pipes.write().insert(peer, pipes).is_none());
    }
    fn get_pipes(&self, peer: PeerId) -> Pipes {
        self.on_event_pipes.read().get(&peer).unwrap().clone()
    }
    fn connected_peers(&self) -> usize {
        self.on_event_pipes.read().len()
    }
}

#[async_trait]
impl CapabilityServer for CapabilityServerImpl {
    #[instrument(skip(self))]
    fn on_peer_connect(&self, peer: PeerId, _: BTreeSet<CapabilityId>) {
        info!("Settting up peer state");
        let status_message = StatusMessage {
            protocol_version: 63,
            network_id: 1,
            total_difficulty: 17608636743620256866935_u128.into(),
            best_hash: H256::from(hex!(
                "28042e7e4d35a3482bf5f0d862501868b04c1734f483ceae3bf1393561951829"
            )),
            genesis_hash: H256::from(hex!(
                "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
            )),
        };

        let (sender, receiver) = channel(1);
        let receiver = Box::pin(
            tokio::stream::iter(std::iter::once(OutboundEvent::Message {
                capability_name: eth(),
                message: Message {
                    id: 0,
                    data: rlp::encode(&status_message).into(),
                },
            }))
            .chain(receiver),
        );
        self.setup_pipes(
            peer,
            Pipes {
                sender,
                receiver: Arc::new(AsyncMutex::new(receiver)),
            },
        );
    }
    #[instrument(skip(self))]
    async fn on_peer_event(&self, peer: PeerId, event: InboundEvent) {
        match event {
            InboundEvent::Disconnect { .. } => {
                self.on_event_pipes.write().remove(&peer);
            }
            InboundEvent::Message { message, .. } => {
                info!(
                    "Received message with id {}, data {}",
                    message.id,
                    hex::encode(&message.data)
                );

                if message.id == 0 {
                    match rlp::decode::<StatusMessage>(&message.data) {
                        Ok(v) => {
                            info!("Decoded status message: {:?}", v);
                        }
                        Err(e) => {
                            info!("Failed to decode status message: {}! Kicking peer.", e);
                            let _ = self
                                .get_pipes(peer)
                                .sender
                                .send(OutboundEvent::Disconnect {
                                    reason: DisconnectReason::ProtocolBreach,
                                })
                                .await;

                            return;
                        }
                    }
                }

                let out_id = match message.id {
                    3 => Some(4),
                    5 => Some(6),
                    _ => None,
                };

                if let Some(id) = out_id {
                    let _ = self
                        .get_pipes(peer)
                        .sender
                        .send(OutboundEvent::Message {
                            capability_name: eth(),
                            message: Message {
                                id,
                                data: rlp::encode_list::<String, String>(&[]).into(),
                            },
                        })
                        .await;
                }
            }
        }
    }
    #[instrument(skip(self))]
    async fn next(&self, peer_id: PeerId) -> OutboundEvent {
        let outbound = self
            .get_pipes(peer_id)
            .receiver
            .lock()
            .await
            .next()
            .await
            .unwrap_or(OutboundEvent::Disconnect {
                reason: DisconnectReason::DisconnectRequested,
            });

        info!("Sending outbound event {:?}", outbound);

        outbound
    }
}

#[tokio::main]
async fn main() {
    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .init();

    let secret_key = SigningKey::random(&mut OsRng);

    let task_metrics = Arc::new(TaskMetrics::default());
    let task_group = Arc::new(TaskGroup::new_with_metrics(task_metrics.clone()));

    let mut dns_resolver = dnsdisc::Resolver::new(Arc::new(
        TokioAsyncResolver::tokio(ResolverConfig::default(), ResolverOpts::default())
            .await
            .unwrap(),
    ));
    dns_resolver.with_task_group(task_group.clone());

    let discovery = DnsDiscovery::new(Arc::new(dns_resolver), DNS_BOOTNODE.to_string(), None);

    let discovery: Arc<AsyncMutex<dyn Discovery>> = Arc::new(AsyncMutex::new(discovery));

    let capability_server = Arc::new(CapabilityServerImpl::default());

    let swarm = Swarm::builder()
        .with_task_group(task_group.clone())
        .with_listen_options(ListenOptions {
            discovery_tasks: std::iter::repeat(discovery).take(1).collect(),
            max_peers: 50,
            addr: "0.0.0.0:30303".parse().unwrap(),
        })
        .build(
            btreemap! { CapabilityId {
                name: eth(),
                version: 63,
            } => 17 },
            capability_server,
            secret_key,
        )
        .await
        .unwrap();

    loop {
        tokio::time::delay_for(std::time::Duration::from_secs(5)).await;
        info!("Peers: {}.", swarm.connected_peers());
    }
}
<commit_msg>sentry: more concise code, teardown<commit_after>#![allow(dead_code)]

use arrayvec::ArrayString;
use async_trait::async_trait;
use devp2p::*;
use ethereum_types::*;
use futures::stream::BoxStream;
use hex_literal::hex;
use k256::ecdsa::SigningKey;
use maplit::btreemap;
use parking_lot::RwLock;
use rand::rngs::OsRng;
use rlp_derive::{RlpDecodable, RlpEncodable};
use std::{
    collections::{BTreeSet, HashMap},
    sync::{
        atomic::{AtomicUsize, Ordering},
        Arc,
    },
};
use task_group::TaskGroup;
use tokio::{
    stream::StreamExt,
    sync::{
        mpsc::{channel, Sender},
        Mutex as AsyncMutex,
    },
};
use tracing::*;
use tracing_subscriber::EnvFilter;
use trust_dns_resolver::{config::*, TokioAsyncResolver};
use uuid::Uuid;

const DNS_BOOTNODE: &str = "all.mainnet.ethdisco.net";

fn eth() -> CapabilityName {
    CapabilityName(ArrayString::from("eth").unwrap())
}

#[derive(Debug, Default)]
struct TaskMetrics {
    count: AtomicUsize,
}

impl task_group::Metrics for TaskMetrics {
    fn task_started(&self, id: Uuid, name: String) {
        let c = self.count.fetch_add(1, Ordering::Relaxed);
        trace!("Current tasks: {}. Started task {}/{}", c + 1, name, id)
    }

    fn task_stopped(&self, id: Uuid, name: String) {
        let c = self.count.fetch_sub(1, Ordering::Relaxed);
        trace!("Current tasks: {}. Stopped task {}/{}", c - 1, name, id)
    }
}

#[derive(Debug, RlpEncodable, RlpDecodable)]
struct StatusMessage {
    protocol_version: usize,
    network_id: usize,
    total_difficulty: U256,
    best_hash: H256,
    genesis_hash: H256,
}

#[derive(Clone)]
struct Pipes {
    sender: Sender<OutboundEvent>,
    receiver: Arc<AsyncMutex<BoxStream<'static, OutboundEvent>>>,
}

#[derive(Default)]
struct CapabilityServerImpl {
    peer_pipes: Arc<RwLock<HashMap<PeerId, Pipes>>>,
}

impl CapabilityServerImpl {
    fn setup_pipes(&self, peer: PeerId, pipes: Pipes) {
        assert!(self.peer_pipes.write().insert(peer, pipes).is_none());
    }
    fn get_pipes(&self, peer: PeerId) -> Pipes {
        self.peer_pipes.read().get(&peer).unwrap().clone()
    }
    fn teardown(&self, peer: PeerId) {
        self.peer_pipes.write().remove(&peer);
    }
    fn connected_peers(&self) -> usize {
        self.peer_pipes.read().len()
    }
}

#[async_trait]
impl CapabilityServer for CapabilityServerImpl {
    #[instrument(skip(self))]
    fn on_peer_connect(&self, peer: PeerId, _: BTreeSet<CapabilityId>) {
        info!("Settting up peer state");
        let status_message = StatusMessage {
            protocol_version: 63,
            network_id: 1,
            total_difficulty: 17608636743620256866935_u128.into(),
            best_hash: H256::from(hex!(
                "28042e7e4d35a3482bf5f0d862501868b04c1734f483ceae3bf1393561951829"
            )),
            genesis_hash: H256::from(hex!(
                "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
            )),
        };

        let first_message = OutboundEvent::Message {
            capability_name: eth(),
            message: Message {
                id: 0,
                data: rlp::encode(&status_message).into(),
            },
        };

        let (sender, receiver) = channel(1);
        let receiver =
            Box::pin(tokio::stream::iter(std::iter::once(first_message)).chain(receiver));
        self.setup_pipes(
            peer,
            Pipes {
                sender,
                receiver: Arc::new(AsyncMutex::new(receiver)),
            },
        );
    }
    #[instrument(skip(self))]
    async fn on_peer_event(&self, peer: PeerId, event: InboundEvent) {
        match event {
            InboundEvent::Disconnect { .. } => {
                self.teardown(peer);
            }
            InboundEvent::Message { message, .. } => {
                info!(
                    "Received message with id {}, data {}",
                    message.id,
                    hex::encode(&message.data)
                );

                if message.id == 0 {
                    match rlp::decode::<StatusMessage>(&message.data) {
                        Ok(v) => {
                            info!("Decoded status message: {:?}", v);
                        }
                        Err(e) => {
                            info!("Failed to decode status message: {}! Kicking peer.", e);
                            let _ = self
                                .get_pipes(peer)
                                .sender
                                .send(OutboundEvent::Disconnect {
                                    reason: DisconnectReason::ProtocolBreach,
                                })
                                .await;

                            return;
                        }
                    }
                }

                let out_id = match message.id {
                    3 => Some(4),
                    5 => Some(6),
                    _ => None,
                };

                if let Some(id) = out_id {
                    let _ = self
                        .get_pipes(peer)
                        .sender
                        .send(OutboundEvent::Message {
                            capability_name: eth(),
                            message: Message {
                                id,
                                data: rlp::encode_list::<String, String>(&[]).into(),
                            },
                        })
                        .await;
                }
            }
        }
    }
    #[instrument(skip(self))]
    async fn next(&self, peer_id: PeerId) -> OutboundEvent {
        let outbound = self
            .get_pipes(peer_id)
            .receiver
            .lock()
            .await
            .next()
            .await
            .unwrap_or(OutboundEvent::Disconnect {
                reason: DisconnectReason::DisconnectRequested,
            });

        info!("Sending outbound event {:?}", outbound);

        outbound
    }
}

#[tokio::main]
async fn main() {
    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .init();

    let secret_key = SigningKey::random(&mut OsRng);

    let task_metrics = Arc::new(TaskMetrics::default());
    let task_group = Arc::new(TaskGroup::new_with_metrics(task_metrics.clone()));

    let mut dns_resolver = dnsdisc::Resolver::new(Arc::new(
        TokioAsyncResolver::tokio(ResolverConfig::default(), ResolverOpts::default())
            .await
            .unwrap(),
    ));
    dns_resolver.with_task_group(task_group.clone());

    let discovery = DnsDiscovery::new(Arc::new(dns_resolver), DNS_BOOTNODE.to_string(), None);

    let discovery: Arc<AsyncMutex<dyn Discovery>> = Arc::new(AsyncMutex::new(discovery));

    let capability_server = Arc::new(CapabilityServerImpl::default());

    let swarm = Swarm::builder()
        .with_task_group(task_group.clone())
        .with_listen_options(ListenOptions {
            discovery_tasks: std::iter::repeat(discovery).take(1).collect(),
            max_peers: 50,
            addr: "0.0.0.0:30303".parse().unwrap(),
        })
        .build(
            btreemap! { CapabilityId {
                name: eth(),
                version: 63,
            } => 17 },
            capability_server,
            secret_key,
        )
        .await
        .unwrap();

    loop {
        tokio::time::delay_for(std::time::Duration::from_secs(5)).await;
        info!("Peers: {}.", swarm.connected_peers());
    }
}
<|endoftext|>


<commit_before>//! Multivariate linear regression using gradient descent
//!
//! Model:
//!
//! ```
//! y = x * theta + e
//!
//! y      Dependent variable     (scalar)
//! x      Independent variables  (1-by-n matrix)
//! theta  Parameters to estimate (n-by-1 matrix)
//! e      Error                  (scalar)
//! ```
//!
//! Cost function: Half of the mean squared error (MSE)
//!
//! ```
//! E = X * theta - Y
//! J = E' * E / 2 / m
//!
//! E      Error per observation          (m-by-1 matrix)
//! X      Observed independent variables (m-by-n matrix)
//! Y      Observed dependent variables   (m-by-1 matrix)
//! m      Number of observations          (integer)
//! theta  Parameters to estimate         (n-by-1 matrix)
//! ```
//!
//! Estimator: Gradient descent
//!
//! ```
//! loop
//!     E = X * theta - Y
//!     theta = theta - alpha / m * X' * E
//! until stop_condition
//!
//! E                (m-by-1 matrix)
//! X                (m-by-n matrix)
//! Y                (m-by-1 matrix)
//! alpha  Step size (scalar)
//! theta            (n-by-1 matrix)
//! ```

#![allow(non_snake_case)]
#![deny(warnings)]
#![feature(plugin)]
#![plugin(linalg_macros)]

extern crate cast;
extern crate env_logger;
extern crate linalg;
extern crate lines;
extern crate stats;
extern crate time;

#[macro_use]
extern crate log;

use std::fs::File;
use std::io::{BufReader, self};
use std::path::Path;

use cast::From as _0;
use linalg::prelude::*;
use linalg::{Col, ColMut, SubMat, SubMatMut, Transposed};
use lines::Lines;
use stats::univariate::Sample;

macro_rules! timeit {
    ($msg:expr, $e:expr) => {{
        let now = time::precise_time_ns();
        let out = $e;
        let elapsed = time::precise_time_ns() - now;
        println!(concat!($msg, " took {} ms"), f64::from_(elapsed) / 1_000_000.);
        out
    }}
}

fn main() {
    env_logger::init().unwrap();

    // Some dummy operation to force the initialization of OpenBLAS' runtime (~90 ms) here rather
    // than during the measurements below
    (&mat![1., 2.; 3., 4.].inv() * &mat![1., 2.; 3., 4.]).eval();

    let data = timeit!("Loading data", {
        load("mpg.tsv").unwrap()
    });

    // Number of observations
    let m = data.nrows();

    println!("{} observations", m);

    // Number of independent variables
    let n = data.ncols() - 1;

    println!("{} independent variables\n", n);

    let mut X = Mat::ones((m, n + 1));
    X.slice_mut((.., 1..)).set(data.slice((.., 1..)));
    let y = data.col(0);

    let (mu, sigma) = timeit!("Normalization", {
        normalize(X.slice_mut((.., 1..)))
    });

    println!("mean: {:?}", mu);
    println!("std deviation: {:?}\n", sigma);

    let mut theta = ColVec::zeros(n + 1);

    let alpha = 0.01;
    let max_niters = 100_000;

    let niters = timeit!("Gradient descent", {
        descent(X.slice(..), y, theta.slice_mut(..), alpha, max_niters)
    });

    println!("Estimated parameters: {:?}", theta);
    println!("Iterations required: {}", niters);
}

/// Evaluates the cost function for `theta`
///
/// X      (m, n)
/// y      (m, 1)  (Will be modified by this function to avoid allocations)
/// theta  (n, 1)
fn cost(X: SubMat<f64>, mut y: ColMut<f64>, theta: Col<f64>) -> f64 {
    let m = f64::from_(X.nrows());
    y.sub_assign(X * theta);
    (&y).t() * &y / 2.0 / m
}

/// Normalizes the independent variables
///
/// X  (m, n)
///
/// -> Returns a vector of means and a vector of standard deviations
fn normalize(mut X: SubMatMut<f64>) -> (Vec<f64>, Vec<f64>) {
    let n = usize::from_(X.ncols());

    let mut mu = Vec::with_capacity(n);
    let mut sigma = Vec::with_capacity(n);

    for col in X.cols() {
        let sample = Sample::new(col.as_slice().unwrap());
        let mean = sample.mean();
        mu.push(mean);
        sigma.push(sample.std_dev(Some(mean)));
    }

    for (mut col, i) in X.cols_mut().zip(0..) {
        col.sub_assign(mu[i]);
        col.div_assign(sigma[i]);
    }

    (mu, sigma)
}

/// Performs the gradient descent algorithm to find the value of `theta` that minimizes the cost
/// function.
///
/// X           (m, n)
/// y           (m, 1)
/// theta       (n, 1)
/// alpha       scalar   Step size
/// max_niters  integer  Maximum number of iterations
///
/// -> Returns the number of iterations required to converge to a solution
fn descent(
    X: SubMat<f64>,
    y: Col<f64>,
    mut theta: ColMut<f64>,
    alpha: f64,
    max_niters: u32,
) -> u32 {
    const TOL: f64 = 1e-5;

    let m = f64::from_(X.nrows());

    // Pre-allocate a column vector to avoid allocations in the loop
    let mut z = ColVec::zeros(X.nrows());

    z.set(y);
    let mut last_J = cost(X, z.slice_mut(..), theta.slice(..));
    for i in 0..max_niters {
        // z = e = y - x * theta
        z.set(y);
        z.sub_assign(X * &theta);

        // theta = theta + alpha / m * x' * e
        theta.add_assign((alpha / m) * X.t() * &z);

        z.set(y);
        let J = cost(X, z.slice_mut(..), theta.slice(..));

        debug!("i: {}, J: {}, theta: {:?}", i, J, theta);

        // Stop condition: `cost` reduced by less than `TOL`% in last iteration
        if (J - last_J).abs() / J.max(last_J) < TOL {
            return i
        }

        last_J = J;
    }

    max_niters
}

/// Loads data from a TSV file
fn load<P>(path: P) -> io::Result<Transposed<Mat<f64>>> where P: AsRef<Path> {
    fn load(path: &Path) -> io::Result<Transposed<Mat<f64>>> {
        let mut lines = Lines::from(BufReader::new(try!(File::open(path))));

        let mut v = vec![];

        let ncols = {
            let mut ncols = 0;

            for number in try!(lines.next().unwrap()).split_whitespace() {
                ncols += 1;
                v.push(number.parse().unwrap());
            }

            ncols
        };

        let mut nrows = 1;
        while let Some(line) = lines.next() {
            let line = try!(line);

            for number in line.split_whitespace() {
                v.push(number.parse().unwrap());
            }

            nrows += 1;
        }

        unsafe {
            Ok(Mat::from_raw_parts(v.into_boxed_slice(), (ncols, nrows)).t())
        }
    }

    load(path.as_ref())
}
<commit_msg>refactor(descent): simplify normalize function<commit_after>//! Multivariate linear regression using gradient descent
//!
//! Model:
//!
//! ```
//! y = x * theta + e
//!
//! y      Dependent variable     (scalar)
//! x      Independent variables  (1-by-n matrix)
//! theta  Parameters to estimate (n-by-1 matrix)
//! e      Error                  (scalar)
//! ```
//!
//! Cost function: Half of the mean squared error (MSE)
//!
//! ```
//! E = X * theta - Y
//! J = E' * E / 2 / m
//!
//! E      Error per observation          (m-by-1 matrix)
//! X      Observed independent variables (m-by-n matrix)
//! Y      Observed dependent variables   (m-by-1 matrix)
//! m      Number of observations          (integer)
//! theta  Parameters to estimate         (n-by-1 matrix)
//! ```
//!
//! Estimator: Gradient descent
//!
//! ```
//! loop
//!     E = X * theta - Y
//!     theta = theta - alpha / m * X' * E
//! until stop_condition
//!
//! E                (m-by-1 matrix)
//! X                (m-by-n matrix)
//! Y                (m-by-1 matrix)
//! alpha  Step size (scalar)
//! theta            (n-by-1 matrix)
//! ```

#![allow(non_snake_case)]
#![deny(warnings)]
#![feature(plugin)]
#![plugin(linalg_macros)]

extern crate cast;
extern crate env_logger;
extern crate linalg;
extern crate lines;
extern crate stats;
extern crate time;

#[macro_use]
extern crate log;

use std::fs::File;
use std::io::{BufReader, self};
use std::path::Path;

use cast::From as _0;
use linalg::prelude::*;
use linalg::{Col, ColMut, SubMat, SubMatMut, Transposed};
use lines::Lines;
use stats::univariate::Sample;

macro_rules! timeit {
    ($msg:expr, $e:expr) => {{
        let now = time::precise_time_ns();
        let out = $e;
        let elapsed = time::precise_time_ns() - now;
        println!(concat!($msg, " took {} ms"), f64::from_(elapsed) / 1_000_000.);
        out
    }}
}

fn main() {
    env_logger::init().unwrap();

    // Some dummy operation to force the initialization of OpenBLAS' runtime (~90 ms) here rather
    // than during the measurements below
    (&mat![1., 2.; 3., 4.].inv() * &mat![1., 2.; 3., 4.]).eval();

    let data = timeit!("Loading data", {
        load("mpg.tsv").unwrap()
    });

    // Number of observations
    let m = data.nrows();

    println!("{} observations", m);

    // Number of independent variables
    let n = data.ncols() - 1;

    println!("{} independent variables\n", n);

    let mut X = Mat::ones((m, n + 1));
    X.slice_mut((.., 1..)).set(data.slice((.., 1..)));
    let y = data.col(0);

    let (mu, sigma) = timeit!("Normalization", {
        normalize(X.slice_mut((.., 1..)))
    });

    println!("mean: {:?}", mu);
    println!("std deviation: {:?}\n", sigma);

    let mut theta = ColVec::zeros(n + 1);

    let alpha = 0.01;
    let max_niters = 100_000;

    let niters = timeit!("Gradient descent", {
        descent(X.slice(..), y, theta.slice_mut(..), alpha, max_niters)
    });

    println!("Estimated parameters: {:?}", theta);
    println!("Iterations required: {}", niters);
}

/// Evaluates the cost function for `theta`
///
/// X      (m, n)
/// y      (m, 1)  (Will be modified by this function to avoid allocations)
/// theta  (n, 1)
fn cost(X: SubMat<f64>, mut y: ColMut<f64>, theta: Col<f64>) -> f64 {
    let m = f64::from_(X.nrows());
    y.sub_assign(X * theta);
    (&y).t() * &y / 2.0 / m
}

/// Normalizes the independent variables
///
/// X  (m, n)
///
/// -> Returns a vector of means and a vector of standard deviations
fn normalize(mut X: SubMatMut<f64>) -> (Vec<f64>, Vec<f64>) {
    let n = usize::from_(X.ncols());

    let mut mu = Vec::with_capacity(n);
    let mut sigma = Vec::with_capacity(n);

    for mut col in X.cols_mut() {
        let (mean, sd) = {
            let sample = Sample::new(col.as_slice().unwrap());
            let mean = sample.mean();

            (mean, sample.std_dev(Some(mean)))
        };

        mu.push(mean);
        sigma.push(sd);

        col.sub_assign(mean);
        col.div_assign(sd);
    }

    (mu, sigma)
}

/// Performs the gradient descent algorithm to find the value of `theta` that minimizes the cost
/// function.
///
/// X           (m, n)
/// y           (m, 1)
/// theta       (n, 1)
/// alpha       scalar   Step size
/// max_niters  integer  Maximum number of iterations
///
/// -> Returns the number of iterations required to converge to a solution
fn descent(
    X: SubMat<f64>,
    y: Col<f64>,
    mut theta: ColMut<f64>,
    alpha: f64,
    max_niters: u32,
) -> u32 {
    const TOL: f64 = 1e-5;

    let m = f64::from_(X.nrows());

    // Pre-allocate a column vector to avoid allocations in the loop
    let mut z = ColVec::zeros(X.nrows());

    z.set(y);
    let mut last_J = cost(X, z.slice_mut(..), theta.slice(..));
    for i in 0..max_niters {
        // z = e = y - x * theta
        z.set(y);
        z.sub_assign(X * &theta);

        // theta = theta + alpha / m * x' * e
        theta.add_assign((alpha / m) * X.t() * &z);

        z.set(y);
        let J = cost(X, z.slice_mut(..), theta.slice(..));

        debug!("i: {}, J: {}, theta: {:?}", i, J, theta);

        // Stop condition: `cost` reduced by less than `TOL`% in last iteration
        if (J - last_J).abs() / J.max(last_J) < TOL {
            return i
        }

        last_J = J;
    }

    max_niters
}

/// Loads data from a TSV file
fn load<P>(path: P) -> io::Result<Transposed<Mat<f64>>> where P: AsRef<Path> {
    fn load(path: &Path) -> io::Result<Transposed<Mat<f64>>> {
        let mut lines = Lines::from(BufReader::new(try!(File::open(path))));

        let mut v = vec![];

        let ncols = {
            let mut ncols = 0;

            for number in try!(lines.next().unwrap()).split_whitespace() {
                ncols += 1;
                v.push(number.parse().unwrap());
            }

            ncols
        };

        let mut nrows = 1;
        while let Some(line) = lines.next() {
            let line = try!(line);

            for number in line.split_whitespace() {
                v.push(number.parse().unwrap());
            }

            nrows += 1;
        }

        unsafe {
            Ok(Mat::from_raw_parts(v.into_boxed_slice(), (ncols, nrows)).t())
        }
    }

    load(path.as_ref())
}
<|endoftext|>


<commit_before>extern crate cef;

use cef::Settings;
use cef::BrowserHost;
use cef::WindowInfo;
use cef::BrowserClientWrapper;
use cef::BrowserSettings;
use cef::CefRc;
use cef::Browser;
use cef::string::CefString;

fn main() {
    let result_code = cef::execute_process::<()>(None);
    if result_code >= 0 {
        std::os::set_exit_status(result_code as isize);
        return;
    }

    let mut settings = Settings::new();
    settings.log_file = CefString::from_str("log.log");
    settings.locale = CefString::from_str("en_GB");
    println!("initialising");
    if !cef::initialize::<()>(&settings, None) {
        panic!("Initialising CEF failed. Please check the logfile.")
    }
    let mut window_info = WindowInfo::new();
    //window_info.windowless_rendering_enabled.set(true);
    //window_info.transparent_painting_enabled.set(true);
    let settings = BrowserSettings::new();
    let url = CefString::from_str("http://www.google.com");
    let browser = BrowserHost::create_browser_sync(
        &window_info,
        BrowserClientWrapper::new(()),
        &url,
        &settings,
        None);

    cef::run_message_loop();

    cef::shutdown();
}
<commit_msg>Updated example for new API<commit_after>extern crate cef;

use cef::Settings;
use cef::BrowserHost;
use cef::WindowInfo;
use cef::BrowserClientWrapper;
use cef::BrowserSettings;
use cef::CefRc;
use cef::Browser;
use cef::string::CefString;
use cef::Void;

fn main() {
    let result_code = cef::execute_process::<Void>(None);
    if result_code >= 0 {
        std::os::set_exit_status(result_code as isize);
        return;
    }

    let mut settings = Settings::new();
    settings.log_file = CefString::from_str("log.log");
    settings.locale = CefString::from_str("en_GB");
    println!("initialising");
    if !cef::initialize::<Void>(&settings, None) {
        panic!("Initialising CEF failed. Please check the logfile.")
    }
    let mut window_info = WindowInfo::new();
    //window_info.windowless_rendering_enabled.set(true);
    //window_info.transparent_painting_enabled.set(true);
    let settings = BrowserSettings::new();
    let url = CefString::from_str("http://www.google.com");
    struct MyClient;
    let browser = BrowserHost::create_browser_sync(
        &window_info,
        BrowserClientWrapper::new(()),
        &url,
        &settings,
        None);

    cef::run_message_loop();

    cef::shutdown();
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::io;
use std::rc::{Rc, Weak};
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
use mio::{Event, PollOpt, Ready};

use super::client::Client;
use super::connection::{self, Connection};
use super::datagram_buffer::DatagramBuffer;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};
use super::packetizer::Packetizer;
use super::route::RouteKey;
use super::selector::Selector;

pub struct UDPConnection {
    client: Weak<RefCell<Client>>,
    route_key: RouteKey,
    socket: UdpSocket,
    client_to_network: DatagramBuffer,
    network_to_client: Packetizer,
}

impl UDPConnection {
    pub fn new(selector: &mut Selector, client: Weak<RefCell<Client>>, route_key: RouteKey, reference_packet: &IPv4Packet) -> io::Result<Rc<RefCell<Self>>> {
        let socket = UDPConnection::create_socket(&route_key)?;
        let raw: &[u8] = reference_packet.raw();
        let ipv4_header = reference_packet.ipv4_header().clone();
        let transport_header = reference_packet.transport_header().as_ref().unwrap().clone();
        let rc = Rc::new(RefCell::new(Self {
            client: client,
            route_key: route_key,
            socket: socket,
            client_to_network: DatagramBuffer::new(4 * MAX_PACKET_LENGTH),
            network_to_client: Packetizer::new(raw, ipv4_header, transport_header),
        }));

        {
            let rc_clone = rc.clone();
            let handler = move |selector: &mut Selector, ready| {
                let mut self_ref = rc_clone.borrow_mut();
                self_ref.on_ready(selector, ready);
            };
            let mut self_ref = rc.borrow_mut();
            //let token = selector.register(&self_ref.socket, handler, Ready::readable(), PollOpt::level())?;
        }
        Ok(rc)
    }

    fn create_socket(route_key: &RouteKey) -> io::Result<UdpSocket> {
        let autobind_addr = SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 0);
        let udp_socket = UdpSocket::bind(autobind_addr)?;
        let rewritten_destination = connection::rewritten_destination(route_key.destination_ip(), route_key.destination_port());
        udp_socket.connect(rewritten_destination)?;
        Ok(udp_socket)
    }

    fn on_ready(&mut self, selector: &mut Selector, event: Event) {

    }
}

impl Connection for UDPConnection {
    fn send_to_network(&mut self, selector: &mut Selector, ipv4_packet: &IPv4Packet) {
        // TODO
    }

    fn disconnect(&mut self) {
        // TODO
    }

    fn is_expired(&self) -> bool {
        // TODO
        false
    }
}
<commit_msg>Register UDP socket on Selector<commit_after>use std::cell::RefCell;
use std::io;
use std::rc::{Rc, Weak};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use mio::{Event, PollOpt, Ready};
use mio::net::UdpSocket;

use super::client::Client;
use super::connection::{self, Connection};
use super::datagram_buffer::DatagramBuffer;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};
use super::packetizer::Packetizer;
use super::route::RouteKey;
use super::selector::Selector;

pub struct UDPConnection {
    client: Weak<RefCell<Client>>,
    route_key: RouteKey,
    socket: UdpSocket,
    client_to_network: DatagramBuffer,
    network_to_client: Packetizer,
}

impl UDPConnection {
    pub fn new(selector: &mut Selector, client: Weak<RefCell<Client>>, route_key: RouteKey, reference_packet: &IPv4Packet) -> io::Result<Rc<RefCell<Self>>> {
        let socket = UDPConnection::create_socket(&route_key)?;
        let raw: &[u8] = reference_packet.raw();
        let ipv4_header = reference_packet.ipv4_header().clone();
        let transport_header = reference_packet.transport_header().as_ref().unwrap().clone();
        let rc = Rc::new(RefCell::new(Self {
            client: client,
            route_key: route_key,
            socket: socket,
            client_to_network: DatagramBuffer::new(4 * MAX_PACKET_LENGTH),
            network_to_client: Packetizer::new(raw, ipv4_header, transport_header),
        }));

        {
            let rc_clone = rc.clone();
            let handler = move |selector: &mut Selector, ready| {
                let mut self_ref = rc_clone.borrow_mut();
                self_ref.on_ready(selector, ready);
            };
            let mut self_ref = rc.borrow_mut();
            let token = selector.register(&self_ref.socket, handler, Ready::readable(), PollOpt::level())?;
        }
        Ok(rc)
    }

    fn create_socket(route_key: &RouteKey) -> io::Result<UdpSocket> {
        let autobind_addr = SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 0);
        let udp_socket = UdpSocket::bind(&autobind_addr)?;
        let rewritten_destination = connection::rewritten_destination(route_key.destination_ip(), route_key.destination_port()).into();
        udp_socket.connect(rewritten_destination)?;
        Ok(udp_socket)
    }

    fn on_ready(&mut self, selector: &mut Selector, event: Event) {

    }
}

impl Connection for UDPConnection {
    fn send_to_network(&mut self, selector: &mut Selector, ipv4_packet: &IPv4Packet) {
        // TODO
    }

    fn disconnect(&mut self) {
        // TODO
    }

    fn is_expired(&self) -> bool {
        // TODO
        false
    }
}
<|endoftext|>


<commit_before>#![feature(io, path)]
#![feature(plugin)]
#![plugin(gfx_macros)]

extern crate geometry;
extern crate start_piston;
#[macro_use]
extern crate piston;
extern crate shader_version;
extern crate wavefront_obj;
extern crate cam;
extern crate gfx;

use std::default::Default;
use piston::quack::{ Get, Action };

fn main() {
    start_piston::start(
        shader_version::OpenGL::_3_2,
        piston::window::WindowSettings {
            title: "Piston-Shaders Demo: Viewer".to_string(),
            size: [640, 480],
            samples: 0,
            fullscreen: false,
            exit_on_esc: true
        },
        || start()
    );
}

#[vertex_format]
pub struct Vertex {
    pos: [f32; 3],
    uv: [f32; 2],
    normal: [f32; 3],
}

impl Default for Vertex {
    fn default() -> Vertex {
        Vertex {
            pos: [0.0; 3],
            uv: [0.0; 2],
            normal: [0.0; 3],
        }
    }
}

quack! {
    obj: Vertex[]
    get:
    set:
        fn (val: geometry::Position) [] { obj.pos = val.0 }
        fn (val: geometry::TextureCoords) [] { obj.uv = val.0 }
        fn (val: geometry::Normal) [] { obj.normal = val.0 }
    action:
}

pub struct App {
    geometries: geometry::Geometry,
    objects: geometry::Object,
    models: geometry::Model,
    vertices: Vec<Vertex>,
    indices: Vec<u32>,
    projection: cam::CameraPerspective,
}

impl App {
    fn new(win_size: [u32; 2]) -> App {
        App {
            geometries: geometry::Geometry::new(),
            objects: geometry::Object::new(),
            models: geometry::Model::new(),
            vertices: Vec::new(),
            indices: Vec::new(),
            projection: cam::CameraPerspective {
                fov: 90.0f32,
                near_clip: 0.1,
                far_clip: 1000.0,
                aspect_ratio: (win_size[0] as f32) / (win_size[1] as f32)
            }
        }
    }

    fn load_asset(&mut self, asset: &str) {
        use std::old_io::File;

        let txt = File::open(&Path::new(asset)).unwrap().read_to_string().unwrap();
        let obj_set = wavefront_obj::obj::parse(txt).unwrap();
        self.models.action(geometry::Model::add_model(
            &obj_set,
            &mut self.vertices,
            &mut self.indices,
            &mut self.geometries,
            &mut self.objects,
        ));
    }
}

fn start() {
    use piston::window::Size;

    let Size(size) = start_piston::current_window().get();
    let mut app = App::new(size);
    app.load_asset("./assets/red-cube.obj");

    for e in start_piston::events() {

    }
}
<commit_msg>Upgraded viewer example<commit_after>#![feature(plugin)]
#![feature(custom_attribute)]
#![plugin(gfx_macros)]

extern crate geometry;
extern crate start_piston;
extern crate piston;
extern crate shader_version;
extern crate wavefront_obj;
extern crate cam;
extern crate gfx;

use std::default::Default;
use std::path::Path;
use piston::window::{ WindowSettings, Size };

fn main() {
    start_piston::start(
        shader_version::OpenGL::_3_2,
        WindowSettings::new(
            "Piston-Shaders Demo: Viewer".to_string(),
            Size { width: 640, height: 480 }
        )
        .samples(0)
        .fullscreen(false)
        .exit_on_esc(true)
        ,
        || start()
    );
}

#[vertex_format]
pub struct Vertex {
    pos: [f32; 3],
    uv: [f32; 2],
    normal: [f32; 3],
}

impl Default for Vertex {
    fn default() -> Vertex {
        Vertex {
            pos: [0.0; 3],
            uv: [0.0; 2],
            normal: [0.0; 3],
        }
    }
}

impl geometry::Vertex for Vertex {
    fn set_position(&mut self, value: [f32; 3]) { self.pos = value }
    fn set_texture_coords(&mut self, value: [f32; 2]) { self.uv = value }
    fn set_normal(&mut self, value: [f32; 3]) { self.normal = value }
}

pub struct App {
    geometries: geometry::Geometry,
    objects: geometry::Object,
    models: geometry::Model,
    vertices: Vec<Vertex>,
    indices: Vec<u32>,
    projection: cam::CameraPerspective,
}

impl App {
    fn new(win_size: [u32; 2]) -> App {
        App {
            geometries: geometry::Geometry::new(),
            objects: geometry::Object::new(),
            models: geometry::Model::new(),
            vertices: Vec::new(),
            indices: Vec::new(),
            projection: cam::CameraPerspective {
                fov: 90.0f32,
                near_clip: 0.1,
                far_clip: 1000.0,
                aspect_ratio: (win_size[0] as f32) / (win_size[1] as f32)
            }
        }
    }

    fn load_asset(&mut self, asset: &str) {
        use std::fs::File;
        use std::io::Read;

        let mut txt = String::new();
        File::open(&Path::new(asset)).unwrap().read_to_string(&mut txt).unwrap();
        let obj_set = wavefront_obj::obj::parse(txt).unwrap();
        self.models.add_range(geometry::Model::new_model(
            &obj_set,
            &mut self.vertices,
            &mut self.indices,
            &mut self.geometries,
            &mut self.objects,
        ));
    }
}

fn start() {
    use piston::window::Window;

    let mut app = {
        let window = start_piston::current_window();
        let window = window.borrow();
        let size = window.size();
        App::new([size.width, size.height])
    };
    app.load_asset("./assets/red-cube.obj");

    for e in start_piston::events() {

    }
}
<|endoftext|>