<commit_before>/*!
Embedded / programmable migrations

*/
use std;
use std::path::{Path, PathBuf};
use chrono::{DateTime, Utc};

use drivers;
use migratable::Migratable;
use config::Config;
use connection::DbConn;
use {DbKind, invalid_tag, Direction, DT_FORMAT};
use errors::*;

/// Define a migration that uses files
///
/// Files defined in this migration must be present at run-time
#[derive(Clone, Debug)]
pub struct FileMigration {
    pub tag: String,
    pub up: Option<PathBuf>,
    pub down: Option<PathBuf>,
    pub stamp: Option<DateTime<Utc>>,
}
impl FileMigration {
    /// Create a new `FileMigration` with a given tag
    ///
    /// Tags may contain [a-z0-9-]
    pub fn with_tag(tag: &str) -> Result<Self> {
        if invalid_tag(tag) {
            bail_fmt!(ErrorKind::Migration, "Invalid tag `{}`. Tags can contain [a-z0-9-]", tag);
        }
        Ok(Self {
            tag: tag.to_owned(),
            up: None,
            down: None,
            stamp: None,
        })
    }

    fn check_path(path: &Path) -> Result<()> {
        if !path.exists() {
            bail_fmt!(ErrorKind::MigrationNotFound, "Migration file not found: {:?}", path)
        }
        Ok(())
    }

    /// Define the file to use for running `up` migrations
    pub fn up<T: AsRef<Path>>(&mut self, up_file: T) -> Result<&mut Self> {
        let path = up_file.as_ref();
        Self::check_path(path)?;
        self.up = Some(path.to_owned());
        Ok(self)
    }

    /// Define the file to use for running `down` migrations
    pub fn down<T: AsRef<Path>>(&mut self, down_file: T) -> Result<&mut Self> {
        let path = down_file.as_ref();
        Self::check_path(path)?;
        self.down = Some(path.to_owned());
        Ok(self)
    }

    /// Box this migration up so it can be stored with other migrations
    pub fn boxed(&self) -> Box<Migratable> {
        Box::new(self.clone())
    }
}

impl Migratable for FileMigration {
    fn apply_up(&self, db_kind: DbKind, config: &Config) -> std::result::Result<(), Box<std::error::Error>> {
        if let Some(ref up) = self.up {
            match db_kind {
                DbKind::Sqlite => {
                    let db_path = config.database_path()?;
                    drivers::sqlite::run_migration(&db_path, up)?;
                }
                DbKind::Postgres => {
                    let conn_str = config.connect_string()?;
                    drivers::pg::run_migration(&conn_str, up)?;
                }
            }
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }
    fn apply_down(&self, db_kind: DbKind, config: &Config) -> std::result::Result<(), Box<std::error::Error>> {
        if let Some(ref down) = self.down {
            match db_kind {
                DbKind::Sqlite => {
                    let db_path = config.database_path()?;
                    drivers::sqlite::run_migration(&db_path, down)?;
                }
                DbKind::Postgres => {
                    let conn_str = config.connect_string()?;
                    drivers::pg::run_migration(&conn_str, down)?;
                }
            }
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }
    fn tag(&self) -> String {
        match self.stamp.as_ref() {
            Some(dt) => {
                let dt_string = dt.format(DT_FORMAT).to_string();
                format!("{}_{}", dt_string, self.tag)
            }
            None => self.tag.to_owned(),
        }
    }
    fn description(&self, direction: &Direction) -> String {
        match *direction {
            Direction::Up   => self.up.as_ref().map(|p| format!("{:?}", p)).unwrap_or_else(|| self.tag()),
            Direction::Down => self.down.as_ref().map(|p| format!("{:?}", p)).unwrap_or_else(|| self.tag()),
        }
    }
}

/// Define an embedded migration
///
/// Statements provided to `EmbeddedMigration` will be embedded in
/// the executable so no files are required at run-time. The
/// standard `include_str!` macro can be used to embed contents of files
/// Database specific features (`postgresql`/`sqlite`) are required to use
/// this functionality.
///
/// # Example
///
/// ```rust,ignore
/// EmbeddedMigration::with_tag("initial")?
///     .up(include_str!("../migrations/initial/up.sql"))
///     .down(include_str!("../migrations/initial/down.sql"))
/// ```
#[derive(Clone, Debug)]
pub struct EmbeddedMigration {
    pub tag: String,
    pub up: Option<&'static str>,
    pub down: Option<&'static str>,
}
impl EmbeddedMigration {
    /// Create a new `EmbeddedMigration` with the given tag
    ///
    /// Tags may contain [a-z0-9-]
    pub fn with_tag(tag: &str) -> Result<Self> {
        if invalid_tag(tag) {
            bail_fmt!(ErrorKind::Migration, "Invalid tag `{}`. Tags can contain [a-z0-9-]", tag);
        }
        Ok(Self {
            tag: tag.to_owned(),
            up: None,
            down: None,
        })
    }

    /// Statement to use for `up` migrations
    pub fn up(&mut self, stmt: &'static str) -> &mut Self {
        self.up = Some(stmt);
        self
    }

    /// Statement to use for `down` migrations
    pub fn down(&mut self, stmt: &'static str) -> &mut Self {
        self.down = Some(stmt);
        self
    }

    /// Box this migration up so it can be stored with other migrations
    pub fn boxed(&self) -> Box<Migratable> {
        Box::new(self.clone())
    }
}

impl Migratable for EmbeddedMigration {
    fn apply_up(&self, _db_kind: DbKind, _config: &Config) -> std::result::Result<(), Box<std::error::Error>> {
        if let Some(ref _up) = self.up {
            #[cfg(any(feature="postgresql", feature="sqlite"))]
            match _db_kind {
                DbKind::Sqlite => {
                    let db_path = _config.database_path()?;
                    drivers::sqlite::run_migration_str(&db_path, _up)?;
                }
                DbKind::Postgres => {
                    let conn_str = _config.connect_string()?;
                    drivers::pg::run_migration_str(&conn_str, _up)?;
                }
            }
            #[cfg(not(any(feature="postgresql", feature="sqlite")))]
            panic!("** Migrant ERROR: Database specific feature required to run embedded-file migration **");
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }
    fn apply_down(&self, db_kind: DbKind, config: &Config) -> std::result::Result<(), Box<std::error::Error>> {
        if let Some(ref down) = self.down {
            match db_kind {
                DbKind::Sqlite => {
                    let db_path = config.database_path()?;
                    drivers::sqlite::run_migration_str(&db_path, down)?;
                }
                DbKind::Postgres => {
                    let conn_str = config.connect_string()?;
                    drivers::pg::run_migration_str(&conn_str, down)?;
                }
            }
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }
    fn tag(&self) -> String {
        self.tag.to_owned()
    }
    fn description(&self, _: &Direction) -> String {
        self.tag()
    }
}

/// Define a programmable migration
///
/// `FnMigration`s have full database access. Database specific
/// features (`postgresql`/`sqlite`) are required to use this functionality.
/// A full re-export of database specific crates are available in `migrant_lib::types`
#[derive(Clone, Debug)]
pub struct FnMigration<T, U> {
    pub tag: String,
    pub up: Option<T>,
    pub down: Option<U>,
}

impl<T, U> FnMigration<T, U>
    where T: 'static + Clone + Fn(DbConn) -> std::result::Result<(), Box<std::error::Error>>,
          U: 'static + Clone + Fn(DbConn) -> std::result::Result<(), Box<std::error::Error>>
{
    /// Create a new `FnMigration` with the given tag
    ///
    /// Tags may contain [a-z0-9-]
    pub fn with_tag(tag: &str) -> Result<Self> {
        if invalid_tag(tag) {
            bail_fmt!(ErrorKind::Migration, "Invalid tag `{}`. Tags can contain [a-z0-9-]", tag);
        }
        Ok(Self {
            tag: tag.to_owned(),
            up: None,
            down: None,
        })
    }

    /// Function to use for `up` migrations
    pub fn up(&mut self, f_up: T) -> &mut Self {
        self.up = Some(f_up);
        self
    }

    /// Function to use for `down` migrations
    pub fn down(&mut self, f_down: U) -> &mut Self {
        self.down = Some(f_down);
        self
    }

    /// Box this migration up so it can be stored with other migrations
    pub fn boxed(&self) -> Box<Migratable> {
        Box::new(self.clone())
    }
}

impl<T, U> Migratable for FnMigration<T, U>
    where T: 'static + Clone + Fn(DbConn) -> std::result::Result<(), Box<std::error::Error>>,
          U: 'static + Clone + Fn(DbConn) -> std::result::Result<(), Box<std::error::Error>>
{
    fn apply_up(&self, _: DbKind, config: &Config) -> std::result::Result<(), Box<::std::error::Error>> {
        if let Some(ref up) = self.up {
            up(DbConn::new(config))?;
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }

    fn apply_down(&self, _: DbKind, config: &Config) -> std::result::Result<(), Box<::std::error::Error>> {
        if let Some(ref down) = self.down {
            down(DbConn::new(config))?;
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }

    fn tag(&self) -> String {
        self.tag.to_owned()
    }

    fn description(&self, _: &Direction) -> String {
        self.tag()
    }
}

<commit_msg>update migration struct documentation and examples<commit_after>/*!
Embedded / programmable migrations

*/
use std;
use std::path::{Path, PathBuf};
use chrono::{DateTime, Utc};

use drivers;
use migratable::Migratable;
use config::Config;
use connection::DbConn;
use {DbKind, invalid_tag, Direction, DT_FORMAT};
use errors::*;

/// Define a migration that uses SQL statements saved in files.
///
/// Files defined in this migration must be present at run-time
#[derive(Clone, Debug)]
pub struct FileMigration {
    pub tag: String,
    pub up: Option<PathBuf>,
    pub down: Option<PathBuf>,
    pub stamp: Option<DateTime<Utc>>,
}
impl FileMigration {
    /// Create a new `FileMigration` with a given tag
    ///
    /// Tags may contain [a-z0-9-]
    pub fn with_tag(tag: &str) -> Result<Self> {
        if invalid_tag(tag) {
            bail_fmt!(ErrorKind::Migration, "Invalid tag `{}`. Tags can contain [a-z0-9-]", tag);
        }
        Ok(Self {
            tag: tag.to_owned(),
            up: None,
            down: None,
            stamp: None,
        })
    }

    fn check_path(path: &Path) -> Result<()> {
        if !path.exists() {
            bail_fmt!(ErrorKind::MigrationNotFound, "Migration file not found: {:?}", path)
        }
        Ok(())
    }

    /// Define the file to use for running `up` migrations
    pub fn up<T: AsRef<Path>>(&mut self, up_file: T) -> Result<&mut Self> {
        let path = up_file.as_ref();
        Self::check_path(path)?;
        self.up = Some(path.to_owned());
        Ok(self)
    }

    /// Define the file to use for running `down` migrations
    pub fn down<T: AsRef<Path>>(&mut self, down_file: T) -> Result<&mut Self> {
        let path = down_file.as_ref();
        Self::check_path(path)?;
        self.down = Some(path.to_owned());
        Ok(self)
    }

    /// Box this migration up so it can be stored with other migrations
    pub fn boxed(&self) -> Box<Migratable> {
        Box::new(self.clone())
    }
}

impl Migratable for FileMigration {
    fn apply_up(&self, db_kind: DbKind, config: &Config) -> std::result::Result<(), Box<std::error::Error>> {
        if let Some(ref up) = self.up {
            match db_kind {
                DbKind::Sqlite => {
                    let db_path = config.database_path()?;
                    drivers::sqlite::run_migration(&db_path, up)?;
                }
                DbKind::Postgres => {
                    let conn_str = config.connect_string()?;
                    drivers::pg::run_migration(&conn_str, up)?;
                }
            }
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }
    fn apply_down(&self, db_kind: DbKind, config: &Config) -> std::result::Result<(), Box<std::error::Error>> {
        if let Some(ref down) = self.down {
            match db_kind {
                DbKind::Sqlite => {
                    let db_path = config.database_path()?;
                    drivers::sqlite::run_migration(&db_path, down)?;
                }
                DbKind::Postgres => {
                    let conn_str = config.connect_string()?;
                    drivers::pg::run_migration(&conn_str, down)?;
                }
            }
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }
    fn tag(&self) -> String {
        match self.stamp.as_ref() {
            Some(dt) => {
                let dt_string = dt.format(DT_FORMAT).to_string();
                format!("{}_{}", dt_string, self.tag)
            }
            None => self.tag.to_owned(),
        }
    }
    fn description(&self, direction: &Direction) -> String {
        match *direction {
            Direction::Up   => self.up.as_ref().map(|p| format!("{:?}", p)).unwrap_or_else(|| self.tag()),
            Direction::Down => self.down.as_ref().map(|p| format!("{:?}", p)).unwrap_or_else(|| self.tag()),
        }
    }
}

/// Define an embedded migration
///
/// SQL statements provided to `EmbeddedMigration` will be embedded in
/// the executable so no files are required at run-time. The
/// standard `include_str!` macro can be used to embed contents of files.
/// Database specific features (`postgresql`/`sqlite`) are required to use
/// this functionality.
///
/// # Example
///
/// ```rust,no_run
/// # extern crate migrant_lib;
/// # use migrant_lib::EmbeddedMigration;
/// # fn main() { run().unwrap(); }
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// EmbeddedMigration::with_tag("initial")?
///     .up(include_str!("../migrations/initial/up.sql"))
///     .down(include_str!("../migrations/initial/down.sql"));
/// # Ok(())
/// # }
/// ```
#[derive(Clone, Debug)]
pub struct EmbeddedMigration {
    pub tag: String,
    pub up: Option<&'static str>,
    pub down: Option<&'static str>,
}
impl EmbeddedMigration {
    /// Create a new `EmbeddedMigration` with the given tag
    ///
    /// Tags may contain [a-z0-9-]
    pub fn with_tag(tag: &str) -> Result<Self> {
        if invalid_tag(tag) {
            bail_fmt!(ErrorKind::Migration, "Invalid tag `{}`. Tags can contain [a-z0-9-]", tag);
        }
        Ok(Self {
            tag: tag.to_owned(),
            up: None,
            down: None,
        })
    }

    /// Statement to use for `up` migrations
    pub fn up(&mut self, stmt: &'static str) -> &mut Self {
        self.up = Some(stmt);
        self
    }

    /// Statement to use for `down` migrations
    pub fn down(&mut self, stmt: &'static str) -> &mut Self {
        self.down = Some(stmt);
        self
    }

    /// Box this migration up so it can be stored with other migrations
    pub fn boxed(&self) -> Box<Migratable> {
        Box::new(self.clone())
    }
}

impl Migratable for EmbeddedMigration {
    fn apply_up(&self, _db_kind: DbKind, _config: &Config) -> std::result::Result<(), Box<std::error::Error>> {
        if let Some(ref _up) = self.up {
            #[cfg(any(feature="postgresql", feature="sqlite"))]
            match _db_kind {
                DbKind::Sqlite => {
                    let db_path = _config.database_path()?;
                    drivers::sqlite::run_migration_str(&db_path, _up)?;
                }
                DbKind::Postgres => {
                    let conn_str = _config.connect_string()?;
                    drivers::pg::run_migration_str(&conn_str, _up)?;
                }
            }
            #[cfg(not(any(feature="postgresql", feature="sqlite")))]
            panic!("** Migrant ERROR: Database specific feature required to run embedded-file migration **");
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }
    fn apply_down(&self, db_kind: DbKind, config: &Config) -> std::result::Result<(), Box<std::error::Error>> {
        if let Some(ref down) = self.down {
            match db_kind {
                DbKind::Sqlite => {
                    let db_path = config.database_path()?;
                    drivers::sqlite::run_migration_str(&db_path, down)?;
                }
                DbKind::Postgres => {
                    let conn_str = config.connect_string()?;
                    drivers::pg::run_migration_str(&conn_str, down)?;
                }
            }
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }
    fn tag(&self) -> String {
        self.tag.to_owned()
    }
    fn description(&self, _: &Direction) -> String {
        self.tag()
    }
}

/// Define a programmable migration
///
/// `FnMigration`s have full database access. Database specific
/// features (`postgresql`/`sqlite`) are required to use this functionality.
/// A full re-export of database specific crates are available in `migrant_lib::types`
#[derive(Clone, Debug)]
pub struct FnMigration<T, U> {
    pub tag: String,
    pub up: Option<T>,
    pub down: Option<U>,
}

impl<T, U> FnMigration<T, U>
    where T: 'static + Clone + Fn(DbConn) -> std::result::Result<(), Box<std::error::Error>>,
          U: 'static + Clone + Fn(DbConn) -> std::result::Result<(), Box<std::error::Error>>
{
    /// Create a new `FnMigration` with the given tag
    ///
    /// Tags may contain [a-z0-9-]
    pub fn with_tag(tag: &str) -> Result<Self> {
        if invalid_tag(tag) {
            bail_fmt!(ErrorKind::Migration, "Invalid tag `{}`. Tags can contain [a-z0-9-]", tag);
        }
        Ok(Self {
            tag: tag.to_owned(),
            up: None,
            down: None,
        })
    }

    /// Function to use for `up` migrations
    pub fn up(&mut self, f_up: T) -> &mut Self {
        self.up = Some(f_up);
        self
    }

    /// Function to use for `down` migrations
    pub fn down(&mut self, f_down: U) -> &mut Self {
        self.down = Some(f_down);
        self
    }

    /// Box this migration up so it can be stored with other migrations
    pub fn boxed(&self) -> Box<Migratable> {
        Box::new(self.clone())
    }
}

impl<T, U> Migratable for FnMigration<T, U>
    where T: 'static + Clone + Fn(DbConn) -> std::result::Result<(), Box<std::error::Error>>,
          U: 'static + Clone + Fn(DbConn) -> std::result::Result<(), Box<std::error::Error>>
{
    fn apply_up(&self, _: DbKind, config: &Config) -> std::result::Result<(), Box<::std::error::Error>> {
        if let Some(ref up) = self.up {
            up(DbConn::new(config))?;
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }

    fn apply_down(&self, _: DbKind, config: &Config) -> std::result::Result<(), Box<::std::error::Error>> {
        if let Some(ref down) = self.down {
            down(DbConn::new(config))?;
        } else {
            print_flush!("(empty) ...");
        }
        Ok(())
    }

    fn tag(&self) -> String {
        self.tag.to_owned()
    }

    fn description(&self, _: &Direction) -> String {
        self.tag()
    }
}

<|endoftext|>


<commit_before>use std::fmt;
use super::super::interconnect::Interconnect;

const SCREEN_WIDTH: usize = 256;
const SCREEN_HEIGHT: usize = 240;
const CPU_CYCLES_PER_SCANLINE: u64 = 114;
const LAST_VISIBLE_SCANLINE: u8 = 239;
const VBLANK_SCANLINES: u64 = 20;

const VBLANK_FLAG: u8 = (1 << 7);

// Shamlessly copied from SprocketNES...too much typing
static PALETTE: [u8; 192] = [
    124,124,124,    0,0,252,        0,0,188,        68,40,188,
    148,0,132,      168,0,32,       168,16,0,       136,20,0,
    80,48,0,        0,120,0,        0,104,0,        0,88,0,
    0,64,88,        0,0,0,          0,0,0,          0,0,0,
    188,188,188,    0,120,248,      0,88,248,       104,68,252,
    216,0,204,      228,0,88,       248,56,0,       228,92,16,
    172,124,0,      0,184,0,        0,168,0,        0,168,68,
    0,136,136,      0,0,0,          0,0,0,          0,0,0,
    248,248,248,    60,188,252,     104,136,252,    152,120,248,
    248,120,248,    248,88,152,     248,120,88,     252,160,68,
    248,184,0,      184,248,24,     88,216,84,      88,248,152,
    0,232,216,      120,120,120,    0,0,0,          0,0,0,
    252,252,252,    164,228,252,    184,184,248,    216,184,248,
    248,184,248,    248,164,192,    240,208,176,    252,224,168,
    248,216,120,    216,248,120,    184,248,184,    184,248,216,
    0,252,252,      248,216,248,    0,0,0,          0,0,0
];

#[derive(Debug, PartialEq)]
enum Scanline {
    PreRender,
    Visible(u8),
    PostRender,
    VBlank,
}

pub struct Ppu {
    ppuctrl: u8,
    ppumask: u8,
    ppustatus: u8,
    oamaddr: u8,
    oamdata: u8,
    ppuscroll: u8,
    ppuaddr: u8,
    ppudata: u8,
    oamdma: u8,

    // oam: Box<[u8; 0xff]>,

    cycles: u64,
    scanline: Scanline,
    pub frame: Box<[u8; SCREEN_WIDTH*SCREEN_HEIGHT*3]>,
}

impl Ppu {
    pub fn new() -> Ppu {
        Ppu {
            ppuctrl: 0,
            ppumask: 0,
            ppustatus: 0,
            oamaddr: 0,
            oamdata: 0,
            ppuscroll: 0,
            ppuaddr: 0,
            ppudata: 0,
            oamdma: 0,

            // oam: Box::new([0u8; 0xff]),

            cycles: 0,
            scanline: Scanline::PreRender,
            frame: Box::new([0u8; SCREEN_WIDTH*SCREEN_HEIGHT*3]),
        }
    }

    pub fn read_reg(&self, addr: u16) -> u8 {
        if addr == 0x4014 {
            self.oamdma
        } else {
            match addr & 1<<0 {
                0x0 => self.ppuctrl,
                0x1 => self.ppumask,
                0x2 => self.ppustatus,
                0x3 => self.oamaddr,
                0x4 => self.oamdata,
                0x5 => self.ppuscroll,
                0x6 => self.ppuaddr,
                0x7 => self.ppudata,
                _ => panic!("Attemped access of nonexistent PPU register: {:#x}", addr),
            }
        }
    }

    pub fn write_to_reg(&mut self, addr: u16, val: u8) {
        if addr == 0x4014 {
            self.oamdma = val;
        } else {
            match addr & 1<<0 {
                0x0 => self.ppuctrl = val,
                0x1 => self.ppumask = val,
                0x2 => self.ppustatus = val,
                0x3 => self.oamaddr = val,
                0x4 => self.oamdata = val,
                0x5 => self.ppuscroll = val,
                0x6 => self.ppuaddr = val,
                0x7 => self.ppudata = val,
                _ => panic!("Attemped write to nonexistent PPU register: {:#x}", addr),
            }
        }
    }

    pub fn power_up(&mut self) {
        self.ppustatus = 0b10100000;
    }

    // Returns whether the NMI is currently allowed
    pub fn step(&mut self, interconnect: &mut Interconnect, current_cpu_cycle: &u64) -> bool {
        let mut vblank = false;
        while self.cycles < *current_cpu_cycle {
            match self.scanline {
                Scanline::PreRender => {
                    self.prerender();
                    vblank = false;
                },
                Scanline::Visible(line) => {
                    self.render_scanline(interconnect, line);
                    vblank = false;
                },
                Scanline::PostRender => {
                    self.postrender();
                    vblank = false;
                },
                Scanline::VBlank => {
                    println!("###################### V Blank ########################");
                    self.vblank(&mut vblank);
                },
            }
            self.cycles += CPU_CYCLES_PER_SCANLINE; // It's easier to just deal in cpu cycles.
        }
        vblank
    }

    fn prerender(&mut self) {
        self.set_vblank(false);
        self.scanline= Scanline::Visible(0);
        self.cycles += CPU_CYCLES_PER_SCANLINE;
    }

    fn render_scanline(&mut self, interconnect: &mut Interconnect, line: u8) {
        // TODO: Refactor
        println!("################# Rendering scanline ##################: {:?}", self.scanline);
        let mut background_buffer = 0u8;
        for pixel in 0..SCREEN_WIDTH {
            if pixel % 8 == 0 {
                background_buffer = self.refresh_background_buffer(interconnect);
            }
        }
        self.cycles += CPU_CYCLES_PER_SCANLINE;
        if self.scanline == Scanline::Visible(LAST_VISIBLE_SCANLINE) {
            self.scanline = Scanline::PostRender;
        } else {
            self.scanline = Scanline::Visible(line + 1);
        }
    }

    fn postrender(&mut self) {
        self.scanline = Scanline::VBlank;
        self.cycles += CPU_CYCLES_PER_SCANLINE;
    }

    fn vblank(&mut self, vblank_nmi: &mut bool) {
        self.set_vblank(true);
        self.cycles += CPU_CYCLES_PER_SCANLINE * VBLANK_SCANLINES;
        self.scanline = Scanline::PreRender;
        *vblank_nmi = self.throw_nmi();
    }

    fn set_vblank(&mut self, status: bool) {
        match status {
            true => {
                self.ppustatus |= VBLANK_FLAG;
            }
            false => {
                self.ppustatus &= !VBLANK_FLAG;
                }
        }
    }

    fn throw_nmi(&self) -> bool {
        if (self.ppuctrl & (1<<7)) != 0 {
            true
        } else {
            false
        }
    }

    fn refresh_background_buffer(&mut self, interconnect: &Interconnect) -> u8 {
        // TODO
        0
    }

    fn fetch_nametable_byte(&mut self, interconnect: &Interconnect) -> u8 {
        // TODO
        let byte = interconnect.ppu_read_byte(0x2000) as u8;
        println!("Fetched nametable byte: {:#X}", byte);
        byte
    }
    fn fetch_attribute_byte(&mut self, interconnect: &Interconnect) -> u8 {
        // TODO
        let byte = interconnect.ppu_read_byte(0) as u8;
        println!("Fetched attribute byte: {:#X}", byte);
        byte
    }
    fn fetch_tile_bitmap(&mut self, interconnect: &Interconnect) -> u16 {
        // TODO
        /* let addr = {
            if self.ppuctrl & (1<<5) != 0 {
                (self.ppuctrl & (1<<3)) |
            } else {

            }
        } */
        let bytes = interconnect.ppu_read_byte(0);
        println!("Fetched tile bitmap bytes");
        bytes as u16
    }
}

impl fmt::Debug for Ppu {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "PPU: ppuctrl: {:#x}, ppumask: {:#x}, ppustatus: {:#x}, oamaddr: {:#x}, oamdata: \
                {:#x}, ppuscroll: {:#x}, ppuaddr: {:#x},  ppudata: {:#x}, oamdma: {:#x}",
               self.ppuctrl,
               self.ppumask,
               self.ppustatus,
               self.oamaddr,
               self.oamdata,
               self.ppuscroll,
               self.ppuaddr,
               self.ppudata,
               self.oamdma)
    }
}
<commit_msg>Ran rustfmt (ruined PALETTE)<commit_after>use std::fmt;
use super::super::interconnect::Interconnect;

const SCREEN_WIDTH: usize = 256;
const SCREEN_HEIGHT: usize = 240;
const CPU_CYCLES_PER_SCANLINE: u64 = 114;
const LAST_VISIBLE_SCANLINE: u8 = 239;
const VBLANK_SCANLINES: u64 = 20;

const VBLANK_FLAG: u8 = (1 << 7);

// Shamlessly copied from SprocketNES...too much typing
static PALETTE: [u8; 192] =
    [124, 124, 124, 0, 0, 252, 0, 0, 188, 68, 40, 188, 148, 0, 132, 168, 0, 32, 168, 16, 0, 136,
     20, 0, 80, 48, 0, 0, 120, 0, 0, 104, 0, 0, 88, 0, 0, 64, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188,
     188, 188, 0, 120, 248, 0, 88, 248, 104, 68, 252, 216, 0, 204, 228, 0, 88, 248, 56, 0, 228,
     92, 16, 172, 124, 0, 0, 184, 0, 0, 168, 0, 0, 168, 68, 0, 136, 136, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 248, 248, 248, 60, 188, 252, 104, 136, 252, 152, 120, 248, 248, 120, 248, 248, 88, 152,
     248, 120, 88, 252, 160, 68, 248, 184, 0, 184, 248, 24, 88, 216, 84, 88, 248, 152, 0, 232,
     216, 120, 120, 120, 0, 0, 0, 0, 0, 0, 252, 252, 252, 164, 228, 252, 184, 184, 248, 216, 184,
     248, 248, 184, 248, 248, 164, 192, 240, 208, 176, 252, 224, 168, 248, 216, 120, 216, 248,
     120, 184, 248, 184, 184, 248, 216, 0, 252, 252, 248, 216, 248, 0, 0, 0, 0, 0, 0];

#[derive(Debug, PartialEq)]
enum Scanline {
    PreRender,
    Visible(u8),
    PostRender,
    VBlank,
}

pub struct Ppu {
    ppuctrl: u8,
    ppumask: u8,
    ppustatus: u8,
    oamaddr: u8,
    oamdata: u8,
    ppuscroll: u8,
    ppuaddr: u8,
    ppudata: u8,
    oamdma: u8,

    // oam: Box<[u8; 0xff]>,
    cycles: u64,
    scanline: Scanline,
    pub frame: Box<[u8; SCREEN_WIDTH * SCREEN_HEIGHT * 3]>,
}

impl Ppu {
    pub fn new() -> Ppu {
        Ppu {
            ppuctrl: 0,
            ppumask: 0,
            ppustatus: 0,
            oamaddr: 0,
            oamdata: 0,
            ppuscroll: 0,
            ppuaddr: 0,
            ppudata: 0,
            oamdma: 0,

            // oam: Box::new([0u8; 0xff]),
            cycles: 0,
            scanline: Scanline::PreRender,
            frame: Box::new([0u8; SCREEN_WIDTH * SCREEN_HEIGHT * 3]),
        }
    }

    pub fn read_reg(&self, addr: u16) -> u8 {
        if addr == 0x4014 {
            self.oamdma
        } else {
            match addr & 1 << 0 {
                0x0 => self.ppuctrl,
                0x1 => self.ppumask,
                0x2 => self.ppustatus,
                0x3 => self.oamaddr,
                0x4 => self.oamdata,
                0x5 => self.ppuscroll,
                0x6 => self.ppuaddr,
                0x7 => self.ppudata,
                _ => panic!("Attemped access of nonexistent PPU register: {:#x}", addr),
            }
        }
    }

    pub fn write_to_reg(&mut self, addr: u16, val: u8) {
        if addr == 0x4014 {
            self.oamdma = val;
        } else {
            match addr & 1 << 0 {
                0x0 => self.ppuctrl = val,
                0x1 => self.ppumask = val,
                0x2 => self.ppustatus = val,
                0x3 => self.oamaddr = val,
                0x4 => self.oamdata = val,
                0x5 => self.ppuscroll = val,
                0x6 => self.ppuaddr = val,
                0x7 => self.ppudata = val,
                _ => panic!("Attemped write to nonexistent PPU register: {:#x}", addr),
            }
        }
    }

    pub fn power_up(&mut self) {
        self.ppustatus = 0b10100000;
    }

    // Returns whether the NMI is currently allowed
    pub fn step(&mut self, interconnect: &mut Interconnect, current_cpu_cycle: &u64) -> bool {
        let mut vblank = false;
        while self.cycles < *current_cpu_cycle {
            match self.scanline {
                Scanline::PreRender => {
                    self.prerender();
                    vblank = false;
                }
                Scanline::Visible(line) => {
                    self.render_scanline(interconnect, line);
                    vblank = false;
                }
                Scanline::PostRender => {
                    self.postrender();
                    vblank = false;
                }
                Scanline::VBlank => {
                    println!("###################### V Blank ########################");
                    self.vblank(&mut vblank);
                }
            }
            self.cycles += CPU_CYCLES_PER_SCANLINE; // It's easier to just deal in cpu cycles.
        }
        vblank
    }

    fn prerender(&mut self) {
        self.set_vblank(false);
        self.scanline = Scanline::Visible(0);
        self.cycles += CPU_CYCLES_PER_SCANLINE;
    }

    fn render_scanline(&mut self, interconnect: &mut Interconnect, line: u8) {
        // TODO: Refactor
        println!("################# Rendering scanline ##################: {:?}",
                 self.scanline);
        for pixel in 0..SCREEN_WIDTH {
            // I could probably just buffer the whole scanline, but this is more accurate
            let pixel_loc = pixel % 8;
            if pixel_loc == 0 {
                let (pattern_table_low, pattern_table_high, attribute_low, attribute_high) =
                    self.refresh_buffer(interconnect);
            }

        }
        self.cycles += CPU_CYCLES_PER_SCANLINE;
        if self.scanline == Scanline::Visible(LAST_VISIBLE_SCANLINE) {
            self.scanline = Scanline::PostRender;
        } else {
            self.scanline = Scanline::Visible(line + 1);
        }
    }

    fn postrender(&mut self) {
        self.scanline = Scanline::VBlank;
        self.cycles += CPU_CYCLES_PER_SCANLINE;
    }

    fn vblank(&mut self, vblank_nmi: &mut bool) {
        self.set_vblank(true);
        self.cycles += CPU_CYCLES_PER_SCANLINE * VBLANK_SCANLINES;
        self.scanline = Scanline::PreRender;
        *vblank_nmi = self.throw_nmi();
    }

    fn set_vblank(&mut self, status: bool) {
        match status {
            true => {
                self.ppustatus |= VBLANK_FLAG;
            }
            false => {
                self.ppustatus &= !VBLANK_FLAG;
            }
        }
    }

    fn throw_nmi(&self) -> bool {
        if (self.ppuctrl & (1 << 7)) != 0 {
            true
        } else {
            false
        }
    }

    fn refresh_buffer(&mut self, interconnect: &Interconnect) -> (u8, u8, u8, u8) {
        // TODO
        let pattern_table_low = self.fetch_pattern_table_low(interconnect);
        let pattern_table_high = self.fetch_pattern_table_high(interconnect);
        let attribute_low = self.fetch_attribute_low(interconnect);
        let attribute_high = self.fetch_attribute_high(interconnect);
        (pattern_table_low, pattern_table_high, attribute_low, attribute_high)
    }

    fn fetch_nametable_byte(&mut self, interconnect: &Interconnect) -> u8 {
        // TODO
        let byte = interconnect.ppu_read_byte(0x2000) as u8;
        println!("Fetched nametable byte: {:#X}", byte);
        byte
    }
    fn fetch_attribute_low(&mut self, interconnect: &Interconnect) -> u8 {
        // TODO
        let byte = interconnect.ppu_read_byte(0) as u8;
        println!("Fetched attribute byte: {:#X}", byte);
        byte
    }
    fn fetch_attribute_high(&mut self, interconnect: &Interconnect) -> u8 {
        // TODO
        let byte = interconnect.ppu_read_byte(0) as u8;
        println!("Fetched attribute byte: {:#X}", byte);
        byte
    }
    fn fetch_pattern_table_low(&mut self, interconnect: &Interconnect) -> u8 {
        // TODO
        let bytes = interconnect.ppu_read_byte(0);
        println!("Fetched tile bitmap bytes");
        bytes
    }
    fn fetch_pattern_table_high(&mut self, interconnect: &Interconnect) -> u8 {
        // TODO
        let bytes = interconnect.ppu_read_byte(0);
        println!("Fetched tile bitmap bytes");
        bytes
    }
}

impl fmt::Debug for Ppu {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "PPU: ppuctrl: {:#x}, ppumask: {:#x}, ppustatus: {:#x}, oamaddr: {:#x}, oamdata: \
                {:#x}, ppuscroll: {:#x}, ppuaddr: {:#x},  ppudata: {:#x}, oamdma: {:#x}",
               self.ppuctrl,
               self.ppumask,
               self.ppustatus,
               self.oamaddr,
               self.oamdata,
               self.ppuscroll,
               self.ppuaddr,
               self.ppudata,
               self.oamdma)
    }
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;

use std::cmp::min;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::hash::Hash;
use std::io::prelude::*;
use std::fs::File;

use self::rustc_serialize::json;

use ngrams::ngrams;

pub type StringCountPair = (String, usize);
pub struct Profile {
    pub ngram_ranks: HashMap<String, usize>,
}

impl Profile {
    pub fn build_from_text(text: &str) -> Profile {
        let mut ngram_counts = HashMap::new();
        for n in 1..6 {
            for ngram in ngrams(text, n) {
                *ngram_counts.entry(ngram).or_insert(0usize) += 1;
            }
        }

        let mut ngrams_and_counts = vec_from_hashmap(&ngram_counts);
        ngrams_and_counts.sort_by(cmp_counts_reverse);

        let mut ngram_ranks = HashMap::new();
        for (index, item) in ngrams_and_counts.iter().enumerate() {
            ngram_ranks.insert((*item).clone().0, index);
        }

        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn load_from_file(path: &str) -> Profile {
        let mut f = File::open(path).unwrap();
        let mut encoded_profile = String::new();
        f.read_to_string(&mut encoded_profile);
        let ngram_ranks = json::decode(&encoded_profile).unwrap();
        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn save_to_file(&self, path: &str) {
        let encoded_profile = json::encode(&self.ngram_ranks).unwrap();
        let mut f = File::create(path).unwrap();
        f.write_all(encoded_profile.as_bytes()).unwrap();
    }

    pub fn compare(&self, other: &Profile) -> usize {
        let max_difference = other.ngram_ranks.len();
        let mut difference = 0;
        for (ngram, index) in self.ngram_ranks.iter() {
            difference += match other.ngram_ranks.get(ngram) {
                Some(other_index) => get_difference(*index, *other_index),
                None => max_difference,
            }
        }
        difference
    }
}

// useful utils

fn get_difference(a: usize, b: usize) -> usize {
    if a > b { a - b } else { b - a }
}

fn vec_from_hashmap<K, V> (hashmap: &HashMap<K, V>) -> Vec<(K, V)>
         where K: Eq + Hash + Clone, V: Clone {
    let mut vec: Vec<(K, V)> = Vec::new();
    for (key, value) in hashmap.iter() {
        let item = ((*key).clone(), (*value).clone());
        vec.push(item);
    }
    vec
}

fn cmp_counts_reverse(a: &StringCountPair, b: &StringCountPair) -> Ordering {
    b.1.cmp(&a.1)
}
<commit_msg>Remove unneeded use<commit_after>extern crate rustc_serialize;

use std::cmp::Ordering;
use std::collections::HashMap;
use std::hash::Hash;
use std::io::prelude::*;
use std::fs::File;

use self::rustc_serialize::json;

use ngrams::ngrams;

pub type StringCountPair = (String, usize);
pub struct Profile {
    pub ngram_ranks: HashMap<String, usize>,
}

impl Profile {
    pub fn build_from_text(text: &str) -> Profile {
        let mut ngram_counts = HashMap::new();
        for n in 1..6 {
            for ngram in ngrams(text, n) {
                *ngram_counts.entry(ngram).or_insert(0usize) += 1;
            }
        }

        let mut ngrams_and_counts = vec_from_hashmap(&ngram_counts);
        ngrams_and_counts.sort_by(cmp_counts_reverse);

        let mut ngram_ranks = HashMap::new();
        for (index, item) in ngrams_and_counts.iter().enumerate() {
            ngram_ranks.insert((*item).clone().0, index);
        }

        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn load_from_file(path: &str) -> Profile {
        let mut f = File::open(path).unwrap();
        let mut encoded_profile = String::new();
        f.read_to_string(&mut encoded_profile);
        let ngram_ranks = json::decode(&encoded_profile).unwrap();
        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn save_to_file(&self, path: &str) {
        let encoded_profile = json::encode(&self.ngram_ranks).unwrap();
        let mut f = File::create(path).unwrap();
        f.write_all(encoded_profile.as_bytes()).unwrap();
    }

    pub fn compare(&self, other: &Profile) -> usize {
        let max_difference = other.ngram_ranks.len();
        let mut difference = 0;
        for (ngram, index) in self.ngram_ranks.iter() {
            difference += match other.ngram_ranks.get(ngram) {
                Some(other_index) => get_difference(*index, *other_index),
                None => max_difference,
            }
        }
        difference
    }
}

// useful utils

fn get_difference(a: usize, b: usize) -> usize {
    if a > b { a - b } else { b - a }
}

fn vec_from_hashmap<K, V> (hashmap: &HashMap<K, V>) -> Vec<(K, V)>
         where K: Eq + Hash + Clone, V: Clone {
    let mut vec: Vec<(K, V)> = Vec::new();
    for (key, value) in hashmap.iter() {
        let item = ((*key).clone(), (*value).clone());
        vec.push(item);
    }
    vec
}

fn cmp_counts_reverse(a: &StringCountPair, b: &StringCountPair) -> Ordering {
    b.1.cmp(&a.1)
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>Update<commit_after>// use std::io;
// use std::fmt;

struct ObjectNode<'a> {
    key: String,
    value: &'a ValueNode,
}

trait ValueNode {
    fn to_json(&self) -> String;
}

impl<'a> ValueNode for ObjectNode<'a> {
    fn to_json(&self) -> String {
        format!("{{\"{}\": {}}}", self.key, self.value.to_json())
    }
}
impl<'a> ValueNode for String {
    fn to_json(&self) -> String {
        format!("\"{}\"", self)
    }
}

fn main() {
    let root: ObjectNode = ObjectNode {
        key: "foo".to_string(),
        value: &"bar".to_string(),
    };
    let obj: &ValueNode = &root;

    println!("{}", root.to_json());
    println!("{}", obj.to_json());
}
<|endoftext|>


<commit_before>extern crate failure;
#[macro_use]
extern crate failure_derive;
#[macro_use]
extern crate nom;
#[macro_use]
extern crate log;
pub mod errors;
pub mod keywords;
pub mod parser;
pub mod scc;
pub mod types;

use errors::{Error, Result};
use std::path::{Path, PathBuf};
use types::Config;

/// A builder for Config
///
/// # Example buld.rs
///
/// ```rust,no_run
/// extern crate pb_rs;
/// extern crate walkdir;
///
/// use pb_rs::{types::FileDescriptor, ConfigBuilder};
/// use std::path::{Path, PathBuf};
/// use walkdir::WalkDir;
///
/// fn main() {
///     let out_dir = std::env::var("OUT_DIR").unwrap();
///     let out_dir = Path::new(&out_dir).join("protos");
///
///     let in_dir = PathBuf::from(::std::env::var("CARGO_MANIFEST_DIR").unwrap()).join("protos");
///     // Re-run this build.rs if the protos dir changes (i.e. a new file is added)
///     println!("cargo:rerun-if-changed={}", in_dir.to_str().unwrap());
///
///     // Find all *.proto files in the `in_dir` and add them to the list of files
///     let mut protos = Vec::new();
///     let proto_ext = Some(Path::new("proto").as_os_str());
///     for entry in WalkDir::new(&in_dir) {
///         let path = entry.unwrap().into_path();
///         if path.extension() == proto_ext {
///             // Re-run this build.rs if any of the files in the protos dir change
///             println!("cargo:rerun-if-changed={}", path.to_str().unwrap());
///             protos.push(path);
///         }
///     }
///
///     // Delete all old generated files before re-generating new ones
///     if out_dir.exists() {
///         std::fs::remove_dir_all(&out_dir).unwrap();
///     }
///     std::fs::DirBuilder::new().create(&out_dir).unwrap();
///     let config_builder = ConfigBuilder::new(&protos, None, Some(&out_dir), &[in_dir]).unwrap();
///     FileDescriptor::run(&config_builder.build()).unwrap()
/// }
/// ```

#[derive(Debug, Default)]
pub struct ConfigBuilder {
    in_files: Vec<PathBuf>,
    out_file: Option<PathBuf>,
    include_paths: Vec<PathBuf>,
    single_module: bool,
    no_output: bool,
    error_cycle: bool,
    headers: bool,
    dont_use_cow: bool,
    custom_struct_derive: Vec<String>,
}

impl ConfigBuilder {
    pub fn new<P: AsRef<Path>>(
        in_files: &[P],
        output: Option<&P>,
        output_dir: Option<&P>,
        include_paths: &[P],
    ) -> Result<ConfigBuilder> {
        let in_files = in_files
            .iter()
            .map(|f| f.as_ref().into())
            .collect::<Vec<PathBuf>>();
        let output = output.map(|f| f.as_ref().into());
        let output_dir: Option<PathBuf> = output_dir.map(|f| f.as_ref().into());
        let mut include_paths = include_paths
            .iter()
            .map(|f| f.as_ref().into())
            .collect::<Vec<PathBuf>>();

        if in_files.is_empty() {
            return Err(Error::NoProto);
        }

        for f in &in_files {
            if !f.exists() {
                return Err(Error::InputFile(format!("{}", f.display())));
            }
        }

        let out_file = match (output, output_dir) {
            (Some(_), None) if in_files.len() > 1 => return Err(Error::OutputMultipleInputs),
            (Some(output), None) => Some(output),
            (None, Some(output_dir)) => {
                if !output_dir.is_dir() {
                    return Err(Error::OutputDirectory(format!("{}", output_dir.display())));
                }
                Some(output_dir)
            }
            (Some(_), Some(_)) => return Err(Error::OutputAndOutputDir),
            (None, None) => None,
        };

        let default = PathBuf::from(".");
        if include_paths.is_empty() || !include_paths.contains(&default) {
            include_paths.push(default);
        }

        Ok(ConfigBuilder {
            in_files: in_files,
            out_file: out_file,
            include_paths: include_paths,
            headers: true,
            ..Default::default()
        })
    }

    /// Omit generation of modules for each package when there is only one package
    pub fn single_module(mut self, val: bool) -> Self {
        self.single_module = val;
        self
    }

    /// Show enums and messages in this .proto file, including those imported. No code generated.
    /// `no_output` should probably only be used by the pb-rs cli.
    pub fn no_output(mut self, val: bool) -> Self {
        self.no_output = val;
        self
    }

    /// Error out if recursive messages do not have optional fields
    pub fn error_cycle(mut self, val: bool) -> Self {
        self.error_cycle = val;
        self
    }

    /// Enable module comments and module attributes in generated file (default = true)
    pub fn headers(mut self, val: bool) -> Self {
        self.headers = val;
        self
    }

    /// Add custom values to #[derive(...)] at the beginning of every structure
    pub fn custom_struct_derive(mut self, val: Vec<String>) -> Self {
        self.custom_struct_derive = val;
        self
    }

    /// Use Cow<_,_> for Strings and Bytes
    pub fn dont_use_cow(mut self, val: bool) -> Self {
        self.dont_use_cow = val;
        self
    }

    /// Build Config from this ConfigBuilder
    pub fn build(self) -> Vec<Config> {
        self.in_files
            .iter()
            .map(|in_file| {
                let mut out_file = in_file.with_extension("rs");

                if let Some(ref ofile) = self.out_file {
                    if ofile.is_dir() {
                        out_file = ofile.join(out_file.file_name().unwrap());
                    } else {
                        out_file = ofile.into();
                    }
                }

                Config {
                    in_file: in_file.to_owned(),
                    out_file: out_file,
                    import_search_path: self.include_paths.clone(),
                    single_module: self.single_module,
                    no_output: self.no_output,
                    error_cycle: self.error_cycle,
                    headers: self.headers,
                    dont_use_cow: self.dont_use_cow, //Change this to false to not use cow for v2 and v3 tests
                    custom_struct_derive: self.custom_struct_derive.clone(),
                    custom_rpc_generator: Box::new(|_,_| Ok(())),
                    custom_includes: Vec::new(),
                }
            })
            .collect()
    }
}
<commit_msg>Updated comment.<commit_after>extern crate failure;
#[macro_use]
extern crate failure_derive;
#[macro_use]
extern crate nom;
#[macro_use]
extern crate log;
pub mod errors;
pub mod keywords;
pub mod parser;
pub mod scc;
pub mod types;

use errors::{Error, Result};
use std::path::{Path, PathBuf};
use types::Config;

/// A builder for Config
///
/// # Example buld.rs
///
/// ```rust,no_run
/// extern crate pb_rs;
/// extern crate walkdir;
///
/// use pb_rs::{types::FileDescriptor, ConfigBuilder};
/// use std::path::{Path, PathBuf};
/// use walkdir::WalkDir;
///
/// fn main() {
///     let out_dir = std::env::var("OUT_DIR").unwrap();
///     let out_dir = Path::new(&out_dir).join("protos");
///
///     let in_dir = PathBuf::from(::std::env::var("CARGO_MANIFEST_DIR").unwrap()).join("protos");
///     // Re-run this build.rs if the protos dir changes (i.e. a new file is added)
///     println!("cargo:rerun-if-changed={}", in_dir.to_str().unwrap());
///
///     // Find all *.proto files in the `in_dir` and add them to the list of files
///     let mut protos = Vec::new();
///     let proto_ext = Some(Path::new("proto").as_os_str());
///     for entry in WalkDir::new(&in_dir) {
///         let path = entry.unwrap().into_path();
///         if path.extension() == proto_ext {
///             // Re-run this build.rs if any of the files in the protos dir change
///             println!("cargo:rerun-if-changed={}", path.to_str().unwrap());
///             protos.push(path);
///         }
///     }
///
///     // Delete all old generated files before re-generating new ones
///     if out_dir.exists() {
///         std::fs::remove_dir_all(&out_dir).unwrap();
///     }
///     std::fs::DirBuilder::new().create(&out_dir).unwrap();
///     let config_builder = ConfigBuilder::new(&protos, None, Some(&out_dir), &[in_dir]).unwrap();
///     FileDescriptor::run(&config_builder.build()).unwrap()
/// }
/// ```

#[derive(Debug, Default)]
pub struct ConfigBuilder {
    in_files: Vec<PathBuf>,
    out_file: Option<PathBuf>,
    include_paths: Vec<PathBuf>,
    single_module: bool,
    no_output: bool,
    error_cycle: bool,
    headers: bool,
    dont_use_cow: bool,
    custom_struct_derive: Vec<String>,
}

impl ConfigBuilder {
    pub fn new<P: AsRef<Path>>(
        in_files: &[P],
        output: Option<&P>,
        output_dir: Option<&P>,
        include_paths: &[P],
    ) -> Result<ConfigBuilder> {
        let in_files = in_files
            .iter()
            .map(|f| f.as_ref().into())
            .collect::<Vec<PathBuf>>();
        let output = output.map(|f| f.as_ref().into());
        let output_dir: Option<PathBuf> = output_dir.map(|f| f.as_ref().into());
        let mut include_paths = include_paths
            .iter()
            .map(|f| f.as_ref().into())
            .collect::<Vec<PathBuf>>();

        if in_files.is_empty() {
            return Err(Error::NoProto);
        }

        for f in &in_files {
            if !f.exists() {
                return Err(Error::InputFile(format!("{}", f.display())));
            }
        }

        let out_file = match (output, output_dir) {
            (Some(_), None) if in_files.len() > 1 => return Err(Error::OutputMultipleInputs),
            (Some(output), None) => Some(output),
            (None, Some(output_dir)) => {
                if !output_dir.is_dir() {
                    return Err(Error::OutputDirectory(format!("{}", output_dir.display())));
                }
                Some(output_dir)
            }
            (Some(_), Some(_)) => return Err(Error::OutputAndOutputDir),
            (None, None) => None,
        };

        let default = PathBuf::from(".");
        if include_paths.is_empty() || !include_paths.contains(&default) {
            include_paths.push(default);
        }

        Ok(ConfigBuilder {
            in_files: in_files,
            out_file: out_file,
            include_paths: include_paths,
            headers: true,
            ..Default::default()
        })
    }

    /// Omit generation of modules for each package when there is only one package
    pub fn single_module(mut self, val: bool) -> Self {
        self.single_module = val;
        self
    }

    /// Show enums and messages in this .proto file, including those imported. No code generated.
    /// `no_output` should probably only be used by the pb-rs cli.
    pub fn no_output(mut self, val: bool) -> Self {
        self.no_output = val;
        self
    }

    /// Error out if recursive messages do not have optional fields
    pub fn error_cycle(mut self, val: bool) -> Self {
        self.error_cycle = val;
        self
    }

    /// Enable module comments and module attributes in generated file (default = true)
    pub fn headers(mut self, val: bool) -> Self {
        self.headers = val;
        self
    }

    /// Add custom values to #[derive(...)] at the beginning of every structure
    pub fn custom_struct_derive(mut self, val: Vec<String>) -> Self {
        self.custom_struct_derive = val;
        self
    }

    /// Use Cow<_,_> for Strings and Bytes
    pub fn dont_use_cow(mut self, val: bool) -> Self {
        self.dont_use_cow = val;
        self
    }

    /// Build Config from this ConfigBuilder
    pub fn build(self) -> Vec<Config> {
        self.in_files
            .iter()
            .map(|in_file| {
                let mut out_file = in_file.with_extension("rs");

                if let Some(ref ofile) = self.out_file {
                    if ofile.is_dir() {
                        out_file = ofile.join(out_file.file_name().unwrap());
                    } else {
                        out_file = ofile.into();
                    }
                }

                Config {
                    in_file: in_file.to_owned(),
                    out_file: out_file,
                    import_search_path: self.include_paths.clone(),
                    single_module: self.single_module,
                    no_output: self.no_output,
                    error_cycle: self.error_cycle,
                    headers: self.headers,
                    dont_use_cow: self.dont_use_cow, //Change this to true to not use cow for v2 and v3 tests
                    custom_struct_derive: self.custom_struct_derive.clone(),
                    custom_rpc_generator: Box::new(|_,_| Ok(())),
                    custom_includes: Vec::new(),
                }
            })
            .collect()
    }
}
<|endoftext|>


<commit_before>use crate::*;

pub fn update_new_ratings() {
    let mut players = PLAYERS.lock().unwrap();

    for g in get_games() {
        let away_rating = players[&g.away].rating.clone();
        let home_rating = players[&g.home].rating.clone();

        {
            let home_player = players.get_mut(&g.home).unwrap();
            home_player.duel(g.dato.clone(), away_rating, g.home_win);
            if g.ace {
                if g.home_win {
                    home_player.aces += 1;
                } else {
                    home_player.eggs += 1;
                }
            }
        }
        {
            let away_player = players.get_mut(&g.away).unwrap();
            away_player.duel(g.dato, home_rating, !g.home_win);
            if g.ace {
                if g.home_win {
                    away_player.eggs += 1;
                } else {
                    away_player.aces += 1;
                }
            }
        }
    }
}

fn get_and_update_new_ratings() -> Vec<PlayerData> {
    update_new_ratings();
    let players = PLAYERS.lock().unwrap();

    let mut ps: Vec<_> = players.values().map(PlayerRating::to_data).filter(|p| p.kampe > 0).collect();
    ps.sort_by(|a, b| if b.rating.score < a.rating.score {
        Less
    } else {
        Greater
    });
    ps
}

#[get("/")]
pub fn root<'a>() -> ContRes<'a> {
    let mut context = create_context("root");
    context.insert("players", &get_and_update_new_ratings());

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

    context.insert("games", &games);

     respond_page("root", context)
}

#[derive(Debug, Serialize)]
struct Homeawaystats {
    homewins: i32,
    awaywins: i32,
    homegoals: i32,
    awaygoals: i32,
}

#[get("/ratings")]
pub fn ratings<'a>() -> ContRes<'a> {
    let mut context = create_context("rating");
    context.insert("players", &get_and_update_new_ratings());
    context.insert("ace_egg_modifier", &CONFIG.ace_egg_modifier);
    context.insert("streak_modifier", &CONFIG.streak_modifier);
    let conn = lock_database();
    let mut stmt =
        conn.prepare("select (select count(id) from games where dato > date('now', 'start of month') and home_score > away_score) as homewins, \
        (select count(id) from games where dato > date('now', 'start of month') and home_score < away_score) as awaywins, \
        (select sum(home_score) ) as homegoals, (select sum(away_score) ) as awaygoals from games where dato > date('now', 'start of month');")
            .unwrap();
    let homeawaystats: Vec<_> = stmt.query_map(&[], |row| {
        Homeawaystats {
            homewins: row.get(0),
            awaywins: row.get(1),
            homegoals: row.get(2),
            awaygoals: row.get(3),
        }
    })
    .unwrap()
    .map(Result::unwrap)
    .collect();
    context.insert("homeawaystats", &homeawaystats);
    respond_page("ratings", context)
}

#[get("/reset/ratings")]
pub fn reset() -> Redirect {
    reset_ratings();
    Redirect::to("/")
}
<commit_msg>Fix indentation<commit_after>use crate::*;

pub fn update_new_ratings() {
    let mut players = PLAYERS.lock().unwrap();

    for g in get_games() {
        let away_rating = players[&g.away].rating.clone();
        let home_rating = players[&g.home].rating.clone();

        {
            let home_player = players.get_mut(&g.home).unwrap();
            home_player.duel(g.dato.clone(), away_rating, g.home_win);
            if g.ace {
                if g.home_win {
                    home_player.aces += 1;
                } else {
                    home_player.eggs += 1;
                }
            }
        }
        {
            let away_player = players.get_mut(&g.away).unwrap();
            away_player.duel(g.dato, home_rating, !g.home_win);
            if g.ace {
                if g.home_win {
                    away_player.eggs += 1;
                } else {
                    away_player.aces += 1;
                }
            }
        }
    }
}

fn get_and_update_new_ratings() -> Vec<PlayerData> {
    update_new_ratings();
    let players = PLAYERS.lock().unwrap();

    let mut ps: Vec<_> = players.values().map(PlayerRating::to_data).filter(|p| p.kampe > 0).collect();
    ps.sort_by(|a, b| if b.rating.score < a.rating.score {
        Less
    } else {
        Greater
    });
    ps
}

#[get("/")]
pub fn root<'a>() -> ContRes<'a> {
    let mut context = create_context("root");
    context.insert("players", &get_and_update_new_ratings());

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

    context.insert("games", &games);

    respond_page("root", context)
}

#[derive(Debug, Serialize)]
struct Homeawaystats {
    homewins: i32,
    awaywins: i32,
    homegoals: i32,
    awaygoals: i32,
}

#[get("/ratings")]
pub fn ratings<'a>() -> ContRes<'a> {
    let mut context = create_context("rating");
    context.insert("players", &get_and_update_new_ratings());
    context.insert("ace_egg_modifier", &CONFIG.ace_egg_modifier);
    context.insert("streak_modifier", &CONFIG.streak_modifier);
    let conn = lock_database();
    let mut stmt =
        conn.prepare("select (select count(id) from games where dato > date('now', 'start of month') and home_score > away_score) as homewins, \
        (select count(id) from games where dato > date('now', 'start of month') and home_score < away_score) as awaywins, \
        (select sum(home_score) ) as homegoals, (select sum(away_score) ) as awaygoals from games where dato > date('now', 'start of month');")
            .unwrap();
    let homeawaystats: Vec<_> = stmt.query_map(&[], |row| {
        Homeawaystats {
            homewins: row.get(0),
            awaywins: row.get(1),
            homegoals: row.get(2),
            awaygoals: row.get(3),
        }
    })
    .unwrap()
    .map(Result::unwrap)
    .collect();
    context.insert("homeawaystats", &homeawaystats);
    respond_page("ratings", context)
}

#[get("/reset/ratings")]
pub fn reset() -> Redirect {
    reset_ratings();
    Redirect::to("/")
}
<|endoftext|>


<commit_before>use std::ops::Range;

use byteorder::{ByteOrder, LittleEndian};

use gameboy::{CPU_FREQUENCY, MAX_CPU_CYCLES, MAX_DIV_REG_CYCLES, Gpu, Irq, Memory, Timer};
use gameboy::cartridge::{Cartridge, CartridgeDetails};
use super::memory_map::{self, Address};

const MAIN_MEM_SIZE: usize = 0x2000;
const ZRAM_SIZE: usize = 0x80;
const MMAP_SIZE: usize = 0x80;

pub struct Interconnect {
    pub gpu: Gpu,
    pub ram: Memory,
    pub zram: Memory,
    pub mmap_io: Memory,
    pub timer: Timer,
    pub irq: Irq,
    pub cart: Option<Cartridge>,
    pub interrupt: u8,
}

impl Interconnect {
    pub fn new() -> Interconnect {
        Interconnect {
            gpu: Gpu::new(),
            ram: Memory::new(MAIN_MEM_SIZE),
            zram: Memory::new(ZRAM_SIZE),
            mmap_io: Memory::new(MMAP_SIZE),
            timer: Timer::new(),
            irq: Irq::new(),
            cart: None,
            interrupt: 0x00,
        }
    }

    pub fn with_cart(cart: Cartridge) -> Interconnect {
        Interconnect {
            gpu: Gpu::new(),
            ram: Memory::new(MAIN_MEM_SIZE),
            zram: Memory::new(ZRAM_SIZE),
            mmap_io: Memory::new(MMAP_SIZE),
            timer: Timer::new(),
            irq: Irq::new(),
            cart: Some(cart),
            interrupt: 0x00,
        }
    }

    pub fn step(&mut self, cycles: usize) {
        self.gpu.step(&mut self.irq, cycles);
        self.timer.step(&mut self.irq, cycles);
    }

    pub fn cart_details(&self) -> CartridgeDetails {
        let cart = self.cart.as_ref().expect("Cartridge is empty");

        cart.details(&self)
    }

    pub fn write_u8(&mut self, addr: u16, byte: u8) {
        let cart = self.cart.as_mut().expect("Cartridge is empty");

        match memory_map::map_address(addr) {
            Address::Ram(a) |
            Address::RamShadow(a) => self.ram.write_u8(a, byte),
            Address::Gfx(a) => self.gpu.ram.write_u8(a, byte),
            Address::CartRam(a) => cart.ram.write_u8(a, byte),
            Address::CartRom(a) => cart.rom.write_u8(a, byte),
            Address::ZRam(a) => self.zram.write_u8(a, byte),
            Address::Oam(a) => self.gpu.sprite_data.write_u8(a, byte),
            Address::Unused(_) => (),
            Address::Io(a) => {
                match a {
                    0x01...0x02 => println!("err: write to serial driver not supported"),
                    0x04...0x07 => self.timer.write_u8(a, byte),
                    0x0F => self.irq.request_flag = byte,
                    0x10...0x26 => println!("err: write to sound driver not supported"),
                    0x40...0x45 => self.gpu.write_u8(a, byte),
                    0x47...0x49 => self.gpu.write_u8(a, byte),
                    0x4A...0x4B => self.gpu.write_u8(a, byte),
                    0x7F => self.mmap_io.write_u8(a, byte),
                    0xFF => self.irq.enable_flag = byte,
                    _ => panic!("write memory mapped I/O in unsupported range: {:04X}", a),
                }
            }
            Address::InterruptEnableRegister(a) => self.interrupt = byte,
            _ => {
                panic!("Unable to write byte to: {:#X}, invalid memory region.",
                       addr)
            }
        }
    }

    pub fn read_u8(&self, addr: u16) -> u8 {
        let cart = self.cart.as_ref().expect("Cartridge is empty");

        match memory_map::map_address(addr) {
            Address::Ram(addr) |
            Address::RamShadow(addr) => self.ram.read_u8(addr),
            Address::CartRom(addr) |
            Address::CartRomOtherBank(addr) => cart.rom.read_u8(addr),
            Address::Gfx(value) => self.gpu.ram.read_u8(value),
            Address::CartRam(a) => cart.ram.read_u8(a),
            Address::ZRam(a) => self.zram.read_u8(a),
            Address::Oam(a) => self.gpu.sprite_data.read_u8(a),
            Address::Unused(_) => 0xFF, // Always return high
            Address::Io(a) => {
                match a {
                    0x01...0x02 => {
                        println!("err: read from serial driver not supported");
                        0
                    }
                    0x04...0x07 => self.timer.read_u8(a),
                    0x0F => self.irq.request_flag,
                    0x10...0x26 => {
                        println!("err: read from sound driver not supported");
                        0
                    }
                    0x40...0x45 => self.gpu.read_u8(a),
                    0x47...0x49 => self.gpu.read_u8(a),
                    0x4A...0x4B => self.gpu.read_u8(a),
                    0x7F => self.mmap_io.read_u8(a),
                    0xFF => self.irq.enable_flag,
                    _ => panic!("read memory mapped I/O in unsupported range"),
                }
            }
            Address::InterruptEnableRegister(a) => self.interrupt,
            _ => panic!("Unable to read address: {:#X}", addr),
        }
    }

    pub fn read_bytes(&self, r: Range<u16>) -> &[u8] {
        let cart = self.cart.as_ref().expect("Cartridge is empty");

        match memory_map::map_address(r.start) {
            Address::Ram(_) |
            Address::RamShadow(_) => self.ram.read_bytes(r),
            Address::CartRom(_) |
            Address::CartRomOtherBank(_) => cart.rom.read_bytes(r),
            Address::Gfx(_) => self.gpu.ram.read_bytes(r),
            Address::CartRam(_) => cart.ram.read_bytes(r),
            Address::ZRam(_) => self.zram.read_bytes(r),
            Address::Io(a) => self.mmap_io.read_bytes(r),
            _ => panic!("Unable to read address range: {:?}", r),
        }
    }

    pub fn write_u16(&mut self, addr: u16, val: u16) {
        let cart = self.cart.as_ref().expect("Cartridge is empty");

        match memory_map::map_address(addr) {
            Address::ZRam(a) => self.zram.write_u16(a, val),
            _ => panic!("Unable to read address: {:#X}", addr),
        }
    }

    pub fn read_u16(&self, addr: u16) -> u16 {
        let cart = self.cart.as_ref().expect("Cartridge is empty");

        match memory_map::map_address(addr) {
            Address::Ram(addr) |
            Address::RamShadow(addr) => self.ram.read_u16(addr),
            Address::CartRom(addr) |
            Address::CartRomOtherBank(addr) => cart.rom.read_u16(addr),
            Address::Gfx(value) => self.gpu.ram.read_u16(value),
            Address::CartRam(a) => cart.ram.read_u16(a),
            Address::ZRam(a) => self.zram.read_u16(a),
            Address::Io(a) => self.mmap_io.read_u16(a),
            _ => panic!("Unable to read address: {:#X}", addr),
        }
    }
}
<commit_msg>Add support for writing imm16's to wram<commit_after>use std::ops::Range;

use byteorder::{ByteOrder, LittleEndian};

use gameboy::{CPU_FREQUENCY, MAX_CPU_CYCLES, MAX_DIV_REG_CYCLES, Gpu, Irq, Memory, Timer};
use gameboy::cartridge::{Cartridge, CartridgeDetails};
use super::memory_map::{self, Address};

const MAIN_MEM_SIZE: usize = 0x2000;
const ZRAM_SIZE: usize = 0x80;
const MMAP_SIZE: usize = 0x80;

pub struct Interconnect {
    pub gpu: Gpu,
    pub ram: Memory,
    pub zram: Memory,
    pub mmap_io: Memory,
    pub timer: Timer,
    pub irq: Irq,
    pub cart: Option<Cartridge>,
    pub interrupt: u8,
}

impl Interconnect {
    pub fn new() -> Interconnect {
        Interconnect {
            gpu: Gpu::new(),
            ram: Memory::new(MAIN_MEM_SIZE),
            zram: Memory::new(ZRAM_SIZE),
            mmap_io: Memory::new(MMAP_SIZE),
            timer: Timer::new(),
            irq: Irq::new(),
            cart: None,
            interrupt: 0x00,
        }
    }

    pub fn with_cart(cart: Cartridge) -> Interconnect {
        Interconnect {
            gpu: Gpu::new(),
            ram: Memory::new(MAIN_MEM_SIZE),
            zram: Memory::new(ZRAM_SIZE),
            mmap_io: Memory::new(MMAP_SIZE),
            timer: Timer::new(),
            irq: Irq::new(),
            cart: Some(cart),
            interrupt: 0x00,
        }
    }

    pub fn step(&mut self, cycles: usize) {
        self.gpu.step(&mut self.irq, cycles);
        self.timer.step(&mut self.irq, cycles);
    }

    pub fn cart_details(&self) -> CartridgeDetails {
        let cart = self.cart.as_ref().expect("Cartridge is empty");

        cart.details(&self)
    }

    pub fn write_u8(&mut self, addr: u16, byte: u8) {
        let cart = self.cart.as_mut().expect("Cartridge is empty");

        match memory_map::map_address(addr) {
            Address::Ram(a) |
            Address::RamShadow(a) => self.ram.write_u8(a, byte),
            Address::Gfx(a) => self.gpu.ram.write_u8(a, byte),
            Address::CartRam(a) => cart.ram.write_u8(a, byte),
            Address::CartRom(a) => cart.rom.write_u8(a, byte),
            Address::ZRam(a) => self.zram.write_u8(a, byte),
            Address::Oam(a) => self.gpu.sprite_data.write_u8(a, byte),
            Address::Unused(_) => (),
            Address::Io(a) => {
                match a {
                    0x01...0x02 => println!("err: write to serial driver not supported"),
                    0x04...0x07 => self.timer.write_u8(a, byte),
                    0x0F => self.irq.request_flag = byte,
                    0x10...0x26 => println!("err: write to sound driver not supported"),
                    0x40...0x45 => self.gpu.write_u8(a, byte),
                    0x47...0x49 => self.gpu.write_u8(a, byte),
                    0x4A...0x4B => self.gpu.write_u8(a, byte),
                    0x7F => self.mmap_io.write_u8(a, byte),
                    0xFF => self.irq.enable_flag = byte,
                    _ => panic!("write memory mapped I/O in unsupported range: {:04X}", a),
                }
            }
            Address::InterruptEnableRegister(a) => self.interrupt = byte,
            _ => {
                panic!("Unable to write byte to: {:#X}, invalid memory region.",
                       addr)
            }
        }
    }

    pub fn read_u8(&self, addr: u16) -> u8 {
        let cart = self.cart.as_ref().expect("Cartridge is empty");

        match memory_map::map_address(addr) {
            Address::Ram(addr) |
            Address::RamShadow(addr) => self.ram.read_u8(addr),
            Address::CartRom(addr) |
            Address::CartRomOtherBank(addr) => cart.rom.read_u8(addr),
            Address::Gfx(value) => self.gpu.ram.read_u8(value),
            Address::CartRam(a) => cart.ram.read_u8(a),
            Address::ZRam(a) => self.zram.read_u8(a),
            Address::Oam(a) => self.gpu.sprite_data.read_u8(a),
            Address::Unused(_) => 0xFF, // Always return high
            Address::Io(a) => {
                match a {
                    0x01...0x02 => {
                        println!("err: read from serial driver not supported");
                        0
                    }
                    0x04...0x07 => self.timer.read_u8(a),
                    0x0F => self.irq.request_flag,
                    0x10...0x26 => {
                        println!("err: read from sound driver not supported");
                        0
                    }
                    0x40...0x45 => self.gpu.read_u8(a),
                    0x47...0x49 => self.gpu.read_u8(a),
                    0x4A...0x4B => self.gpu.read_u8(a),
                    0x7F => self.mmap_io.read_u8(a),
                    0xFF => self.irq.enable_flag,
                    _ => panic!("read memory mapped I/O in unsupported range"),
                }
            }
            Address::InterruptEnableRegister(a) => self.interrupt,
            _ => panic!("Unable to read address: {:#X}", addr),
        }
    }

    pub fn read_bytes(&self, r: Range<u16>) -> &[u8] {
        let cart = self.cart.as_ref().expect("Cartridge is empty");

        match memory_map::map_address(r.start) {
            Address::Ram(_) |
            Address::RamShadow(_) => self.ram.read_bytes(r),
            Address::CartRom(_) |
            Address::CartRomOtherBank(_) => cart.rom.read_bytes(r),
            Address::Gfx(_) => self.gpu.ram.read_bytes(r),
            Address::CartRam(_) => cart.ram.read_bytes(r),
            Address::ZRam(_) => self.zram.read_bytes(r),
            Address::Io(a) => self.mmap_io.read_bytes(r),
            _ => panic!("Unable to read address range: {:?}", r),
        }
    }

    pub fn write_u16(&mut self, addr: u16, val: u16) {
        let cart = self.cart.as_ref().expect("Cartridge is empty");

        match memory_map::map_address(addr) {
            Address::Ram(a) |
            Address::RamShadow(a) => self.ram.write_u16(a, val),
            Address::ZRam(a) => self.zram.write_u16(a, val),
            _ => panic!("Unable to write address: {:#X}", addr),
        }
    }

    pub fn read_u16(&self, addr: u16) -> u16 {
        let cart = self.cart.as_ref().expect("Cartridge is empty");

        match memory_map::map_address(addr) {
            Address::Ram(addr) |
            Address::RamShadow(addr) => self.ram.read_u16(addr),
            Address::CartRom(addr) |
            Address::CartRomOtherBank(addr) => cart.rom.read_u16(addr),
            Address::Gfx(value) => self.gpu.ram.read_u16(value),
            Address::CartRam(a) => cart.ram.read_u16(a),
            Address::ZRam(a) => self.zram.read_u16(a),
            Address::Io(a) => self.mmap_io.read_u16(a),
            _ => panic!("Unable to read address: {:#X}", addr),
        }
    }
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Gaussian_elimination
#![allow(unused_variables)]
#![allow(dead_code)]

struct Matrix<'a, T:'a> {
	m : &'a mut Vec<T>,
	n : usize
}

struct Idx(usize, usize);

impl<'a, T> Matrix<'a, T> {
	fn new<'c> (_m : &'c mut Vec<T>, _n : usize) -> Matrix<'c, T> {
		Matrix{m : &mut _m, n : _n}
	}

	fn val(&self, idx : Idx) -> & T
	{
		& self.m[idx.0 + idx.1 * self.n]
	}

	fn val_mut<'b>(&'b mut self, idx : Idx) -> &'b mut T
	{
		let r : &mut T =	& mut (*self.m)[idx.0 + idx.1 * self.n];
		r
	}

	fn get_row_slice(&self, row: usize) -> &[T]
	{
	  & self.m[row * self.n .. row * self.n + self.n ]
	}
}

struct MatrixRowIter<'a, T:'a> {
	m : &'a Matrix<'a, T>,
	row : usize,
	col : usize,
	used: &'a Vec<bool>
}

impl<'a, T> MatrixRowIter<'a, T> {
	fn new (_m : &'a Matrix<'a, T>, _used: &'a mut Vec<bool>, _col : usize) -> MatrixRowIter<'a, T> {
		MatrixRowIter{m : _m, row : 0, col : _col, used : _used }
	}

}

impl<'a, T:Copy> Iterator for MatrixRowIter<'a, T> {
    type Item = (T, usize);
    fn next(&mut self) -> Option<(T, usize)> {
    	loop {
	    	if self.row >= self.m.n {
	    	  return None
	    	}
	    	if !self.used[self.row] {
	    		break;
	    	}
    		self.row += 1;
    	}

    	let v = *self.m.val(Idx(self.col, self.row));
    	let ret = self.row;
    	self.row += 1;
      Some((v, ret))
    }
}

fn main() {

	let mut v : Vec<f32> = vec![
		1.00, 0.00, 0.00,  0.00,  0.00, 0.00,
		1.00, 0.63, 0.39,  0.25,  0.16, 0.10,
		1.00, 1.26, 1.58,  1.98,  2.49, 3.13,
		1.00, 1.88, 3.55,  6.70, 12.62, 230.80,
		1.00, 2.51, 6.32, 15.88, 39.90, 100.28,
		1.00, 3.14, 9.87, 31.01, 97.41, 306.02];

	let mat = Matrix::new(&mut v, 6);

	let mut r = Vec::new();
	let mut used: Vec<bool> = vec![false; mat.n];

	for i in 0..mat.n {

		let max;
		{
			let mat_iter = MatrixRowIter::new(&mat, &mut used, i);

			max = mat_iter
										.inspect(|&item| println!("{} {}", item.0, item.1) )
										.fold((0.0, -1),
											|max, item| if item.0.abs() > max.0 { item } else { max } )
										;
		}

		used[max.1] = true;
		println!("max {} {}", max.0, max.1);
		println!("=======");

		r.extend(mat.get_row_slice(max.1).iter());
	}

	let mut mat_out = Matrix::new(&mut r, mat.n);
	for i in 0..mat_out.n {
		for j in 0..mat_out.n {
			print!("{} ", mat_out.val(Idx(j, i)));
		}
		println!("  ");
	}

	let n= mat_out.n;
	for dia in 0..n {
		for row in dia+1..n {
			//let tmp = *mat_out.val(Idx(dia, row)) / *mat_out.val(Idx(dia, dia));
			for col in dia+1..n {
				//(*mat_out.val(Idx(col, row))) -= tmp;// * *mat_out.val(Idx(col, dia));
				//mat_out.val_mut(Idx(dia, row)) = 0.0;
				//let ref mut  rr : &mut &f32 = mat_out.val_mut(Idx(dia, row));
				let rr : & mut f32   = &mut mat_out.val_mut(Idx(dia, row));
				println!("{}", rr);
				//*mat_out.val_mut(Idx(dia, row)) = 0.0;
				//*rr = 0.0;
			}
		}
	}

}
<commit_msg>try workaround borrowcheker<commit_after>// http://rosettacode.org/wiki/Gaussian_elimination
#![allow(unused_variables)]
#![allow(dead_code)]

struct Matrix<'a, T:'a> {
	m : &'a mut Vec<T>,
	n : usize
}

struct Idx(usize, usize);

impl<'a, T:'a> Matrix<'a, T> {
	fn new<'b> (_m : &'b mut Vec<T>, _n : usize) -> Matrix<'b, T> {
		Matrix{m : /*&mut*/ _m, n : _n}
	}

	fn val(&self, idx : Idx) -> & T
	{
		& self.m[idx.0 + idx.1 * self.n]
	}

	// fn val_mut<'b>(&'b mut self, idx : Idx) -> &'b mut T
	// {
	// 	let r : &mut T =	& mut (*self.m)[idx.0 + idx.1 * self.n];
	// 	r
	// }

	fn set(&mut self, idx : Idx, v : T)
	{
		self.m[idx.0 + idx.1 * self.n] = v;
	}

	fn get_row_slice(&self, row: usize) -> &[T]
	{
	  & self.m[row * self.n .. row * self.n + self.n ]
	}
}

struct MatrixRowIter<'a, T:'a> {
	m : &'a Matrix<'a, T>,
	row : usize,
	col : usize,
	used: &'a Vec<bool>
}

impl<'a, T> MatrixRowIter<'a, T> {
	fn new (_m : &'a Matrix<'a, T>, _used: &'a mut Vec<bool>, _col : usize) -> MatrixRowIter<'a, T> {
		MatrixRowIter{m : _m, row : 0, col : _col, used : _used }
	}

}

impl<'a, T:Copy> Iterator for MatrixRowIter<'a, T> {
    type Item = (T, usize);
    fn next(&mut self) -> Option<(T, usize)> {
    	loop {
	    	if self.row >= self.m.n {
	    	  return None
	    	}
	    	if !self.used[self.row] {
	    		break;
	    	}
    		self.row += 1;
    	}

    	let v = *self.m.val(Idx(self.col, self.row));
    	let ret = self.row;
    	self.row += 1;
      Some((v, ret))
    }
}

fn main() {

	let mut v : Vec<f32> = vec![
		1.00, 0.00, 0.00,  0.00,  0.00, 0.00,
		1.00, 0.63, 0.39,  0.25,  0.16, 0.10,
		1.00, 1.26, 1.58,  1.98,  2.49, 3.13,
		1.00, 1.88, 3.55,  6.70, 12.62, 230.80,
		1.00, 2.51, 6.32, 15.88, 39.90, 100.28,
		1.00, 3.14, 9.87, 31.01, 97.41, 306.02];

	let mat = Matrix::new(&mut v, 6);

	let zero:f32 = 0.0;
	let mut r = Vec::new();
	let mut used: Vec<bool> = vec![false; mat.n];

	for i in 0..mat.n {

		let max;
		{
			let mat_iter = MatrixRowIter::new(&mat, &mut used, i);

			max = mat_iter
						.inspect(|&item| println!("{} {}", item.0, item.1) )
						.fold((0.0, -1),
							|max, item| if item.0.abs() > max.0 { item } else { max } )
						;
		}

		used[max.1] = true;
		println!("max {} {}", max.0, max.1);
		println!("=======");

		r.extend(mat.get_row_slice(max.1).iter());
	}

	let mut mat_out = Matrix::new(&mut r, mat.n);
	for i in 0..mat_out.n {
		for j in 0..mat_out.n {
			print!("{} ", mat_out.val(Idx(j, i)));
		}
		println!("  ");
	}

	let n= mat_out.n;
	for dia in 0..n {
		for row in dia+1..n {
			//let tmp = *mat_out.val(Idx(dia, row)) / *mat_out.val(Idx(dia, dia));
			for col in dia+1..n {
				//(*mat_out.val(Idx(col, row))) -= tmp;// * *mat_out.val(Idx(col, dia));
				//mat_out.val_mut(Idx(dia, row)) = 0.0;
				//let ref mut  rr : &mut &f32 = mat_out.val_mut(Idx(dia, row));
//				let rr : & mut f32   = &mut mat_out.val_mut(Idx(dia, row));
	//			println!("{}", rr);
				//*mat_out.val_mut(Idx(dia, row)) = 0.0;
				mat_out.set(Idx(dia, row), &zero);
				//*rr = 0.0;
			}
		}
	}

}
<|endoftext|>


<commit_before>extern crate libc;
extern crate libnfqueue as nfq;

use libc::*;
use std::ptr::null;
use std::mem;
use nfq::nfq_q_handle;
use nfq::handle::{Handle, ProtocolFamily};
use nfq::queue::{CopyMode, VerdictHandler};
use nfq::message::Message;
use nfq::verdict::Verdict;

fn main() {
    let mut handle = Handle::new().ok().unwrap();
    let mut queue = handle.queue(0, Decider).unwrap();

    handle.bind(ProtocolFamily::INET);
    queue.mode(CopyMode::Packet(4096)).ok();

    println!("Listen for packets...");
    handle.start(4096);

    println!("Finished...");
}

struct Decider;

impl VerdictHandler for Decider {
    fn decide(&mut self, message: &mut Message) -> Verdict {
        let id = message.header.id();
        println!("Handling packet (ID: {})", id);

        Verdict::Accept
    }
}
<commit_msg>Clean up examples/accept.rs imports<commit_after>extern crate libnfqueue as nfq;

use nfq::{Handle, ProtocolFamily, CopyMode, VerdictHandler, Message, Verdict};

fn main() {
    let mut handle = Handle::new().ok().unwrap();
    let mut queue = handle.queue(0, Decider).unwrap();

    handle.bind(ProtocolFamily::INET);
    queue.mode(CopyMode::Packet(4096)).ok();

    println!("Listen for packets...");
    handle.start(4096);

    println!("Finished...");
}

struct Decider;

impl VerdictHandler for Decider {
    fn decide(&mut self, message: &mut Message) -> Verdict {
        let id = message.header.id();
        println!("Handling packet (ID: {})", id);

        Verdict::Accept
    }
}
<|endoftext|>


<commit_before>use hyper::server::Request as UnwrappedRequest;
use hyper::uri::RequestUri::AbsolutePath;
use hyper::method::Method;
use url::{Url, ParseError};

pub struct Request<'a, 'b: 'a> {
    pub req: UnwrappedRequest<'a, 'b>,
    parsed_url: Url
}

impl<'a, 'b> Request<'a, 'b> {
    pub fn wrap_request(req: UnwrappedRequest<'a, 'b>, base_url: &Url) -> Request<'a, 'b> {
        let request_url = match req.uri {
            AbsolutePath(ref path) => base_url.join(path.as_str()),
            _ => Err(ParseError::RelativeUrlWithoutBase)
        };
        Request {
            req: req,
            parsed_url: request_url.unwrap()
        }
    }

    pub fn path(&self) -> &str {
        self.parsed_url.path()
    }

    pub fn method(&self) -> &Method {
        &self.req.method
    }
}
<commit_msg>request struct methods<commit_after>use std::io::{self, Read};
use std::net::SocketAddr;
use std::time::Duration;
use hyper::server::Request as UnwrappedRequest;
use hyper::uri::RequestUri::AbsolutePath;
use hyper::method::Method;
use hyper::header::Headers;
use url::{Url, ParseError};

pub struct Request<'a, 'b: 'a> {
    pub req: UnwrappedRequest<'a, 'b>,
    parsed_url: Url
}

impl<'a, 'b> Request<'a, 'b> {
    pub fn wrap_request(req: UnwrappedRequest<'a, 'b>, base_url: &Url) -> Request<'a, 'b> {
        let request_url = match req.uri {
            AbsolutePath(ref path) => base_url.join(path.as_str()),
            _ => Err(ParseError::RelativeUrlWithoutBase)
        };
        Request {
            req: req,
            parsed_url: request_url.unwrap()
        }
    }

    #[inline]
    pub fn path(&self) -> &str {
        self.parsed_url.path()
    }

    #[inline]
    pub fn method(&self) -> &Method {
        &self.req.method
    }

    #[inline]
    pub fn remote_addr(&self) -> &SocketAddr {
        &self.req.remote_addr
    }

    #[inline]
    pub fn headers(&self) -> &Headers {
        &self.req.headers
    }

    #[inline]
    pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
        self.req.set_read_timeout(timeout)
    }
}

impl<'a, 'b> Read for Request<'a, 'b> {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.req.read(buf)
    }
}
<|endoftext|>


<commit_before>extern crate url;

pub use hyper::header as header;
use header::{Cookie as CookieHeader, ContentType};
pub use header::CookiePair as Cookie;
pub use hyper::status::StatusCode as Status;

use hyper::{Headers, Method};
use hyper::uri::RequestUri::{AbsolutePath, Star};
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::server::Request as HttpRequest;

use std::collections::BTreeMap;
use std::io::{Error, ErrorKind, Result};
use std::result::Result as StdResult;
use std::slice::Iter;

use buffer::Buffer;

use url::{ParseError, Url};

/// A request, with a path, query, and fragment (accessor methods not yet implemented for the last two).
///
/// Can be queried for the parameters that were matched by the router.
pub struct Request {
    inner: HttpRequest,
    path: Vec<String>,
    query: Option<String>,
    fragment: Option<String>,

    params: Option<BTreeMap<String, String>>,
    body: Option<Buffer>
}

pub fn new(base_url: &Url, inner: HttpRequest) -> StdResult<Request, ParseError> {
    let (path, query, fragment) = match *inner.uri() {
        AbsolutePath(ref path) => {
            match base_url.join(path) {
                Ok(url) => (url.path_segments().unwrap().map(|s| s.to_string()).collect(),
                    url.query().map(|s| s.to_string()),
                    url.fragment().map(|s| s.to_string())),
                Err(e) => return Err(e)
            }
        },
        Star => (vec!["*".to_owned()], None, None),
        _ => panic!("unsupported request URI")
    };

    Ok(Request {
        inner: inner,
        path: path,
        query: query,
        fragment: fragment,
        params: None,
        body: None})
}

pub fn set_body(request: Option<&mut Request>, body: Option<Buffer>) {
    if let Some(req) = request {
        req.body = body;
    }
}

impl Request {
    /// Returns this request's body as a vector of bytes.
    pub fn body(&self) -> Result<&[u8]> {
        match self.body {
            Some(ref buffer) => Ok(buffer.as_ref()),
            None => Err(Error::new(ErrorKind::UnexpectedEof, "empty body"))
        }
    }

    /// Returns an iterator over the cookies of this request.
    pub fn cookies(&self) -> Iter<Cookie> {
        self.headers().get::<CookieHeader>().map_or([].iter(),
            |&CookieHeader(ref cookies)| cookies.iter()
        )
    }

    /// Reads the body of this request, parses it as an application/x-www-form-urlencoded format,
    /// and returns it as a vector of (name, value) pairs.
    pub fn form(&mut self) -> Result<Vec<(String, String)>> {
        let body = try!(self.body());

        match self.headers().get::<ContentType>() {
            Some(&ContentType(Mime(TopLevel::Application, SubLevel::WwwFormUrlEncoded, _))) => {
                let parse = url::form_urlencoded::parse(body);
                Ok(parse.into_owned().collect())
            }
            Some(_) => Err(Error::new(ErrorKind::InvalidInput, "invalid Content-Type, expected application/x-www-form-urlencoded")),
            None => Err(Error::new(ErrorKind::InvalidInput, "missing Content-Type header"))
        }
    }

    /// Returns the method
    pub fn method(&self) -> &Method {
        self.inner.method()
    }

    /// Returns headers
    #[inline]
    pub fn headers(&self) -> &Headers { self.inner.headers() }

    /// Returns the parameter with the given name declared by the route that matched the URL of this request (if any).
    pub fn param(&self, key: &str) -> Option<&str> {
        self.params.as_ref().map_or(None, |map| map.get(key).map(String::as_str))
    }

    /// Returns the path of this request, i.e. the list of segments of the URL.
    pub fn path(&self) -> &[String] {
        &self.path
    }

    /// Returns the query of this request (if any).
    pub fn query(&self) -> Option<&str> {
        self.query.as_ref().map(String::as_str)
    }

    /// Returns the fragment of this request (if any).
    pub fn fragment(&self) -> Option<&str> {
        self.fragment.as_ref().map(String::as_str)
    }
}

/// Sets the parameters declared by the route that matched the URL of this request.
pub fn set_params(request: &mut Request, params: BTreeMap<String, String>) {
    request.params = Some(params);
}
<commit_msg>Request::query now returns the value of the given query parameter (if any)<commit_after>extern crate url;

pub use hyper::header as header;
use header::{Cookie as CookieHeader, ContentType};
pub use header::CookiePair as Cookie;
pub use hyper::status::StatusCode as Status;

use hyper::{Headers, Method};
use hyper::uri::RequestUri::{AbsolutePath, Star};
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::server::Request as HttpRequest;

use std::collections::BTreeMap;
use std::io::{Error, ErrorKind, Result};
use std::result::Result as StdResult;
use std::slice::Iter;

use buffer::Buffer;

use url::{ParseError, Url};

/// A request, with a path, query, and fragment (accessor methods not yet implemented for the last two).
///
/// Can be queried for the parameters that were matched by the router.
pub struct Request {
    inner: HttpRequest,
    url: Option<Url>,
    path: Vec<String>,
    query: Option<BTreeMap<String, String>>,
    params: Option<BTreeMap<String, String>>,
    body: Option<Buffer>
}

pub fn new(base_url: &Url, inner: HttpRequest) -> StdResult<Request, ParseError> {
    let url = match *inner.uri() {
        AbsolutePath(ref path) => Some(try!(base_url.join(path))),
        Star => None,
        _ => panic!("unsupported request URI")
    };

    let path = match url {
        None => vec!["*".to_owned()],
        Some(ref url) => url.path_segments().unwrap().map(|s| s.to_string()).collect()
    };

    let query = match url {
        None => None,
        Some(ref url) => Some(url.query_pairs().into_owned().collect())
    };

    Ok(Request {
        inner: inner,
        url: url,
        path: path,
        query: query,
        params: None,
        body: None})
}

pub fn set_body(request: Option<&mut Request>, body: Option<Buffer>) {
    if let Some(req) = request {
        req.body = body;
    }
}

impl Request {
    /// Returns this request's body as a vector of bytes.
    pub fn body(&self) -> Result<&[u8]> {
        match self.body {
            Some(ref buffer) => Ok(buffer.as_ref()),
            None => Err(Error::new(ErrorKind::UnexpectedEof, "empty body"))
        }
    }

    /// Returns an iterator over the cookies of this request.
    pub fn cookies(&self) -> Iter<Cookie> {
        self.headers().get::<CookieHeader>().map_or([].iter(),
            |&CookieHeader(ref cookies)| cookies.iter()
        )
    }

    /// Reads the body of this request, parses it as an application/x-www-form-urlencoded format,
    /// and returns it as a vector of (name, value) pairs.
    pub fn form(&mut self) -> Result<Vec<(String, String)>> {
        let body = try!(self.body());

        match self.headers().get::<ContentType>() {
            Some(&ContentType(Mime(TopLevel::Application, SubLevel::WwwFormUrlEncoded, _))) => {
                let parse = url::form_urlencoded::parse(body);
                Ok(parse.into_owned().collect())
            }
            Some(_) => Err(Error::new(ErrorKind::InvalidInput, "invalid Content-Type, expected application/x-www-form-urlencoded")),
            None => Err(Error::new(ErrorKind::InvalidInput, "missing Content-Type header"))
        }
    }

    /// Returns the method
    pub fn method(&self) -> &Method {
        self.inner.method()
    }

    /// Returns headers
    #[inline]
    pub fn headers(&self) -> &Headers { self.inner.headers() }

    /// Returns the parameter with the given name declared by the route that matched the URL of this request (if any).
    pub fn param(&self, key: &str) -> Option<&str> {
        self.params.as_ref().map_or(None, |map| map.get(key).map(String::as_str))
    }

    /// Returns the path of this request, i.e. the list of segments of the URL.
    pub fn path(&self) -> &[String] {
        &self.path
    }

    /// Returns the parameter with the given name in this request's query (if any).
    pub fn query(&self, key: &str) -> Option<&str> {
        self.query.as_ref().map_or(None, |map| map.get(key).map(String::as_str))
    }

    /// Returns the fragment of this request (if any).
    pub fn fragment(&self) -> Option<&str> {
        match self.url {
            None => None,
            Some(ref url) => url.fragment()
        }
    }
}

/// Sets the parameters declared by the route that matched the URL of this request.
pub fn set_params(request: &mut Request, params: BTreeMap<String, String>) {
    request.params = Some(params);
}
<|endoftext|>