<commit_before>use bullet::{BulletDrawable, bullets::Bullets};
use cgmath::Point2;
use character::controls::CharacterInputState;
use critter::CritterData;
use data;
use game::constants::{ASPECT_RATIO, NORMAL_DEATH_SPRITE_OFFSET, SPRITE_OFFSET, VIEW_DISTANCE, ZOMBIE_SHEET_TOTAL_WIDTH, ZOMBIE_STILL_SPRITE_OFFSET};
use game::get_random_bool;
use gfx;
use gfx_app::{ColorFormat, DepthFormat};
use graphics::{add_random_offset_to_screen_pos,
               calc_hypotenuse,
               can_move_to_tile,
               camera::CameraInputState, dimensions::{Dimensions, get_projection, get_view_matrix},
               direction,
               direction_movement,
               direction_movement_180,
               GameTime,
               orientation::{Orientation, Stance},
               orientation_to_direction,
               overlaps,
               texture::load_texture};
use shaders::{CharacterSheet, critter_pipeline, Position, Projection, VertexData};
use specs;
use specs::prelude::{Read, ReadStorage, WriteStorage};
use terrain::path_finding::calc_next_movement;
use zombie::zombies::Zombies;

pub mod zombies;

const SHADER_VERT: &[u8] = include_bytes!("../shaders/character.v.glsl");
const SHADER_FRAG: &[u8] = include_bytes!("../shaders/character.f.glsl");

#[derive(Debug, Clone)]
pub struct ZombieDrawable {
  projection: Projection,
  pub position: Position,
  previous_position: Position,
  orientation: Orientation,
  pub stance: Stance,
  direction: Orientation,
  last_decision: u64,
  pub movement_direction: Point2<f32>,
  zombie_idx: usize,
  zombie_death_idx: usize,
  is_colliding: bool,
  movement_speed: f32,
}

impl ZombieDrawable {
  pub fn new(position: Position) -> ZombieDrawable {
    let view = get_view_matrix(VIEW_DISTANCE);
    let projection = get_projection(view, ASPECT_RATIO);
    ZombieDrawable {
      projection,
      position,
      previous_position: Position::new(0.0, 0.0),
      orientation: Orientation::Left,
      stance: Stance::Still,
      direction: Orientation::Left,
      last_decision: 2,
      movement_direction: Point2::new(0.0, 0.0),
      zombie_idx: 0,
      zombie_death_idx: 0,
      is_colliding: false,
      movement_speed: 0.0,
    }
  }

  pub fn update(&mut self, world_to_clip: &Projection, ci: &CharacterInputState, game_time: u64) {
    self.projection = *world_to_clip;

    let offset_delta =
      Position::new(
        ci.x_movement - self.previous_position.position[0],
        ci.y_movement - self.previous_position.position[1]);

    self.previous_position = Position::new(ci.x_movement, ci.y_movement);

    let x_y_distance_to_player = Point2::new(
      self.position.position[0] - offset_delta.position[0],
      self.position.position[1] - offset_delta.position[1]);

    let distance_to_player = calc_hypotenuse(x_y_distance_to_player.x.abs(), x_y_distance_to_player.y.abs());

    let is_alive = self.stance != Stance::NormalDeath && self.stance != Stance::CriticalDeath;

    if is_alive {
      let zombie_pos = Position::new(ci.x_movement - self.position.position[0], ci.y_movement - self.position.position[1]);

      if distance_to_player < 300.0 {
        let dir = calc_next_movement(zombie_pos, self.previous_position) as f32;
        self.direction = orientation_to_direction(dir);
        self.movement_direction = direction_movement(dir);
        self.stance = Stance::Walking;
        self.movement_speed = 1.4;
      } else {
        self.idle_direction_movement(zombie_pos, game_time);
        self.movement_speed = 1.0;
      }
    } else {
      self.movement_direction = Point2::new(0.0, 0.0);
    }

    self.position = Position::new(
      self.movement_direction.x * self.movement_speed,
      self.movement_direction.y * self.movement_speed) + self.position + offset_delta;
  }

  fn idle_direction_movement(&mut self, zombie_pos: Position, game_time: u64) {
    if !can_move_to_tile(zombie_pos) {
      let dir = direction(Point2::new(0.0, 0.0), self.movement_direction);
      self.movement_direction = direction_movement_180(self.movement_direction);
      self.orientation = orientation_to_direction(dir);
    }

    if self.last_decision + 2 < game_time {
      self.stance = Stance::Walking;
      self.last_decision = game_time;
      let end_point = add_random_offset_to_screen_pos(zombie_pos);
      let dir = calc_next_movement(zombie_pos, end_point) as f32;
      self.movement_direction = direction_movement(dir);
      self.direction = orientation_to_direction(dir);
    }
  }

  fn check_bullet_hits(&mut self, bullets: &[BulletDrawable]) {
    bullets.iter().for_each(|bullet| {
      if overlaps(self.position, bullet.position, 15.0, 15.0) && self.stance != Stance::NormalDeath && self.stance != Stance::CriticalDeath {
        self.stance =
          if get_random_bool() {
            Stance::NormalDeath
          } else {
            Stance::CriticalDeath
          };
      }
    });
  }

  pub fn update_alive_idx(&mut self, max_idx: usize) {
    if self.zombie_idx < max_idx {
      self.zombie_idx += 1;
    } else {
      self.zombie_idx = 0;
    }
  }

  pub fn update_death_idx(&mut self, max_idx: usize) {
    if self.zombie_death_idx < max_idx {
      self.zombie_death_idx += 1;
    }
  }
}

pub struct ZombieDrawSystem<R: gfx::Resources> {
  bundle: gfx::pso::bundle::Bundle<R, critter_pipeline::Data<R>>,
  data: Vec<CritterData>,
}

impl<R: gfx::Resources> ZombieDrawSystem<R> {
  pub fn new<F>(factory: &mut F,
                rtv: gfx::handle::RenderTargetView<R, ColorFormat>,
                dsv: gfx::handle::DepthStencilView<R, DepthFormat>) -> ZombieDrawSystem<R>
                where F: gfx::Factory<R> {
    use gfx::traits::FactoryExt;

    let zombie_bytes = include_bytes!("../../assets/zombie.png");

    let vertex_data: [VertexData; 4] = [
      VertexData::new([-25.0, -35.0], [0.0, 1.0]),
      VertexData::new([25.0, -35.0], [1.0, 1.0]),
      VertexData::new([25.0, 35.0], [1.0, 0.0]),
      VertexData::new([-25.0, 35.0], [0.0, 0.0]),
    ];

    let index_data: [u16; 6] = [0, 1, 2, 2, 3, 0];

    let (vertex_buf, slice) = factory.create_vertex_buffer_with_slice(&vertex_data[..], &index_data[..]);

    let char_texture = load_texture(factory, zombie_bytes);
    let pso = factory
      .create_pipeline_simple(SHADER_VERT,
                              SHADER_FRAG,
                              critter_pipeline::new())
      .unwrap();

    let pipeline_data = critter_pipeline::Data {
      vbuf: vertex_buf,
      projection_cb: factory.create_constant_buffer(1),
      position_cb: factory.create_constant_buffer(1),
      character_sprite_cb: factory.create_constant_buffer(1),
      charactersheet: (char_texture, factory.create_sampler_linear()),
      out_color: rtv,
      out_depth: dsv,
    };

    let data = data::load_zombie();

    ZombieDrawSystem {
      bundle: gfx::Bundle::new(slice, pso, pipeline_data),
      data,
    }
  }

  fn get_next_sprite(&self, drawable: &mut ZombieDrawable) -> CharacterSheet {
    let zombie_sprite = match drawable.stance {
      Stance::Still => {
        let sprite_idx = (drawable.direction as usize * 4 + drawable.zombie_idx) as usize;
        (&self.data[sprite_idx], sprite_idx)
      },
      Stance::Walking if drawable.orientation != Orientation::Still => {
        let sprite_idx = (drawable.direction as usize * 8 + drawable.zombie_idx + ZOMBIE_STILL_SPRITE_OFFSET) as usize;
        (&self.data[sprite_idx], sprite_idx)
      },
      Stance::NormalDeath if drawable.orientation != Orientation::Still => {
        let sprite_idx = (drawable.direction as usize * 6 + drawable.zombie_death_idx + NORMAL_DEATH_SPRITE_OFFSET) as usize;
        (&self.data[sprite_idx], sprite_idx)
      },
      Stance::CriticalDeath if drawable.orientation != Orientation::Still => {
        let sprite_idx = (drawable.direction as usize * 8 + drawable.zombie_death_idx) as usize;
        (&self.data[sprite_idx], sprite_idx)
      },
      _ => {
        drawable.direction = drawable.orientation;
        let sprite_idx = (drawable.orientation as usize * 8 + drawable.zombie_idx + ZOMBIE_STILL_SPRITE_OFFSET) as usize;
        (&self.data[sprite_idx], sprite_idx)
      },
    };

    let (y_div, row_idx) =
      if drawable.stance == Stance::NormalDeath || drawable.stance == Stance::CriticalDeath {
        (0.0, 2)
      } else {
        (1.0, 2)
      };

    let elements_x = ZOMBIE_SHEET_TOTAL_WIDTH / (zombie_sprite.0.data[2] + SPRITE_OFFSET);
    CharacterSheet {
      x_div: elements_x,
      y_div,
      row_idx,
      index: zombie_sprite.1 as f32,
    }
  }

  pub fn draw<C>(&mut self,
                 mut drawable: &mut ZombieDrawable,
                 encoder: &mut gfx::Encoder<R, C>)
                 where C: gfx::CommandBuffer<R> {
    encoder.update_constant_buffer(&self.bundle.data.projection_cb, &drawable.projection);
    encoder.update_constant_buffer(&self.bundle.data.position_cb, &drawable.position);
    encoder.update_constant_buffer(&self.bundle.data.character_sprite_cb,
                                   &self.get_next_sprite(&mut drawable));
    self.bundle.encode(encoder);
  }
}

#[derive(Debug)]
pub struct PreDrawSystem;

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

impl<'a> specs::prelude::System<'a> for PreDrawSystem {
  #[cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
  type SystemData = (WriteStorage<'a, Zombies>,
                     ReadStorage<'a, CameraInputState>,
                     ReadStorage<'a, CharacterInputState>,
                     ReadStorage<'a, Bullets>,
                     Read<'a, Dimensions>,
                     Read<'a, GameTime>);

  fn run(&mut self, (mut zombies, camera_input, character_input, bullets, dim, gt): Self::SystemData) {
    use specs::join::Join;

    for (zs, camera, ci, bs) in (&mut zombies, &camera_input, &character_input, &bullets).join() {
      let world_to_clip = dim.world_to_projection(camera);

      for z in &mut zs.zombies {
        z.update(&world_to_clip, ci, gt.0);
        z.check_bullet_hits(&bs.bullets);
      }
    }
  }
}
<commit_msg>Tweak ZombieDrawable properties<commit_after>use bullet::{BulletDrawable, bullets::Bullets};
use cgmath::Point2;
use character::controls::CharacterInputState;
use critter::CritterData;
use data;
use game::constants::{ASPECT_RATIO, NORMAL_DEATH_SPRITE_OFFSET, SPRITE_OFFSET, VIEW_DISTANCE, ZOMBIE_SHEET_TOTAL_WIDTH, ZOMBIE_STILL_SPRITE_OFFSET};
use game::get_random_bool;
use gfx;
use gfx_app::{ColorFormat, DepthFormat};
use graphics::{add_random_offset_to_screen_pos,
               calc_hypotenuse,
               can_move_to_tile,
               camera::CameraInputState, dimensions::{Dimensions, get_projection, get_view_matrix},
               direction,
               direction_movement,
               direction_movement_180,
               GameTime,
               orientation::{Orientation, Stance},
               orientation_to_direction,
               overlaps,
               texture::load_texture};
use shaders::{CharacterSheet, critter_pipeline, Position, Projection, VertexData};
use specs;
use specs::prelude::{Read, ReadStorage, WriteStorage};
use terrain::path_finding::calc_next_movement;
use zombie::zombies::Zombies;

pub mod zombies;

const SHADER_VERT: &[u8] = include_bytes!("../shaders/character.v.glsl");
const SHADER_FRAG: &[u8] = include_bytes!("../shaders/character.f.glsl");

#[derive(Debug, Clone)]
pub struct ZombieDrawable {
  projection: Projection,
  pub position: Position,
  previous_position: Position,
  orientation: Orientation,
  pub stance: Stance,
  direction: Orientation,
  last_decision: u64,
  pub movement_direction: Point2<f32>,
  zombie_idx: usize,
  zombie_death_idx: usize,
  is_colliding: bool,
  movement_speed: f32,
}

impl ZombieDrawable {
  pub fn new(position: Position) -> ZombieDrawable {
    let view = get_view_matrix(VIEW_DISTANCE);
    let projection = get_projection(view, ASPECT_RATIO);
    ZombieDrawable {
      projection,
      position,
      previous_position: Position::new(0.0, 0.0),
      orientation: Orientation::Left,
      stance: Stance::Still,
      direction: Orientation::Left,
      last_decision: 0,
      movement_direction: Point2::new(0.0, 0.0),
      zombie_idx: 0,
      zombie_death_idx: 0,
      is_colliding: false,
      movement_speed: 0.0,
    }
  }

  pub fn update(&mut self, world_to_clip: &Projection, ci: &CharacterInputState, game_time: u64) {
    self.projection = *world_to_clip;

    let offset_delta =
      Position::new(
        ci.x_movement - self.previous_position.position[0],
        ci.y_movement - self.previous_position.position[1]);

    self.previous_position = Position::new(ci.x_movement, ci.y_movement);

    let x_y_distance_to_player = Point2::new(
      self.position.position[0] - offset_delta.position[0],
      self.position.position[1] - offset_delta.position[1]);

    let distance_to_player = calc_hypotenuse(x_y_distance_to_player.x.abs(), x_y_distance_to_player.y.abs());

    let is_alive = self.stance != Stance::NormalDeath && self.stance != Stance::CriticalDeath;

    if is_alive {
      let zombie_pos = Position::new(ci.x_movement - self.position.position[0], ci.y_movement - self.position.position[1]);

      if distance_to_player < 300.0 {
        let dir = calc_next_movement(zombie_pos, self.previous_position) as f32;
        self.direction = orientation_to_direction(dir);
        self.movement_direction = direction_movement(dir);
        self.stance = Stance::Walking;
        self.movement_speed = 1.4;
      } else {
        self.idle_direction_movement(zombie_pos, game_time);
        self.movement_speed = 1.0;
      }
    } else {
      self.movement_direction = Point2::new(0.0, 0.0);
    }

    self.position = Position::new(
      self.movement_direction.x * self.movement_speed,
      self.movement_direction.y * self.movement_speed) + self.position + offset_delta;
  }

  fn idle_direction_movement(&mut self, zombie_pos: Position, game_time: u64) {
    if !can_move_to_tile(zombie_pos) {
      let dir = direction(Point2::new(0.0, 0.0), self.movement_direction);
      self.movement_direction = direction_movement_180(self.movement_direction);
      self.orientation = orientation_to_direction(dir);
    }

    if self.last_decision + 2 < game_time || game_time == 0 {
      self.stance = Stance::Walking;
      self.last_decision = game_time;
      let end_point = add_random_offset_to_screen_pos(zombie_pos);
      let dir = calc_next_movement(zombie_pos, end_point) as f32;
      self.movement_direction = direction_movement(dir);
      self.direction = orientation_to_direction(dir);
    }
  }

  fn check_bullet_hits(&mut self, bullets: &[BulletDrawable]) {
    bullets.iter().for_each(|bullet| {
      if overlaps(self.position, bullet.position, 15.0, 15.0) && self.stance != Stance::NormalDeath && self.stance != Stance::CriticalDeath {
        self.stance =
          if get_random_bool() {
            Stance::NormalDeath
          } else {
            Stance::CriticalDeath
          };
      }
    });
  }

  pub fn update_alive_idx(&mut self, max_idx: usize) {
    if self.zombie_idx < max_idx {
      self.zombie_idx += 1;
    } else {
      self.zombie_idx = 0;
    }
  }

  pub fn update_death_idx(&mut self, max_idx: usize) {
    if self.zombie_death_idx < max_idx {
      self.zombie_death_idx += 1;
    }
  }
}

pub struct ZombieDrawSystem<R: gfx::Resources> {
  bundle: gfx::pso::bundle::Bundle<R, critter_pipeline::Data<R>>,
  data: Vec<CritterData>,
}

impl<R: gfx::Resources> ZombieDrawSystem<R> {
  pub fn new<F>(factory: &mut F,
                rtv: gfx::handle::RenderTargetView<R, ColorFormat>,
                dsv: gfx::handle::DepthStencilView<R, DepthFormat>) -> ZombieDrawSystem<R>
                where F: gfx::Factory<R> {
    use gfx::traits::FactoryExt;

    let zombie_bytes = include_bytes!("../../assets/zombie.png");

    let vertex_data: [VertexData; 4] = [
      VertexData::new([-25.0, -35.0], [0.0, 1.0]),
      VertexData::new([25.0, -35.0], [1.0, 1.0]),
      VertexData::new([25.0, 35.0], [1.0, 0.0]),
      VertexData::new([-25.0, 35.0], [0.0, 0.0]),
    ];

    let index_data: [u16; 6] = [0, 1, 2, 2, 3, 0];

    let (vertex_buf, slice) = factory.create_vertex_buffer_with_slice(&vertex_data[..], &index_data[..]);

    let char_texture = load_texture(factory, zombie_bytes);
    let pso = factory
      .create_pipeline_simple(SHADER_VERT,
                              SHADER_FRAG,
                              critter_pipeline::new())
      .unwrap();

    let pipeline_data = critter_pipeline::Data {
      vbuf: vertex_buf,
      projection_cb: factory.create_constant_buffer(1),
      position_cb: factory.create_constant_buffer(1),
      character_sprite_cb: factory.create_constant_buffer(1),
      charactersheet: (char_texture, factory.create_sampler_linear()),
      out_color: rtv,
      out_depth: dsv,
    };

    let data = data::load_zombie();

    ZombieDrawSystem {
      bundle: gfx::Bundle::new(slice, pso, pipeline_data),
      data,
    }
  }

  fn get_next_sprite(&self, drawable: &mut ZombieDrawable) -> CharacterSheet {
    let zombie_sprite = match drawable.stance {
      Stance::Still => {
        let sprite_idx = (drawable.direction as usize * 4 + drawable.zombie_idx) as usize;
        (&self.data[sprite_idx], sprite_idx)
      },
      Stance::Walking if drawable.orientation != Orientation::Still => {
        let sprite_idx = (drawable.direction as usize * 8 + drawable.zombie_idx + ZOMBIE_STILL_SPRITE_OFFSET) as usize;
        (&self.data[sprite_idx], sprite_idx)
      },
      Stance::NormalDeath if drawable.orientation != Orientation::Still => {
        let sprite_idx = (drawable.direction as usize * 6 + drawable.zombie_death_idx + NORMAL_DEATH_SPRITE_OFFSET) as usize;
        (&self.data[sprite_idx], sprite_idx)
      },
      Stance::CriticalDeath if drawable.orientation != Orientation::Still => {
        let sprite_idx = (drawable.direction as usize * 8 + drawable.zombie_death_idx) as usize;
        (&self.data[sprite_idx], sprite_idx)
      },
      _ => {
        drawable.direction = drawable.orientation;
        let sprite_idx = (drawable.orientation as usize * 8 + drawable.zombie_idx + ZOMBIE_STILL_SPRITE_OFFSET) as usize;
        (&self.data[sprite_idx], sprite_idx)
      },
    };

    let (y_div, row_idx) =
      if drawable.stance == Stance::NormalDeath || drawable.stance == Stance::CriticalDeath {
        (0.0, 2)
      } else {
        (1.0, 2)
      };

    let elements_x = ZOMBIE_SHEET_TOTAL_WIDTH / (zombie_sprite.0.data[2] + SPRITE_OFFSET);
    CharacterSheet {
      x_div: elements_x,
      y_div,
      row_idx,
      index: zombie_sprite.1 as f32,
    }
  }

  pub fn draw<C>(&mut self,
                 mut drawable: &mut ZombieDrawable,
                 encoder: &mut gfx::Encoder<R, C>)
                 where C: gfx::CommandBuffer<R> {
    encoder.update_constant_buffer(&self.bundle.data.projection_cb, &drawable.projection);
    encoder.update_constant_buffer(&self.bundle.data.position_cb, &drawable.position);
    encoder.update_constant_buffer(&self.bundle.data.character_sprite_cb,
                                   &self.get_next_sprite(&mut drawable));
    self.bundle.encode(encoder);
  }
}

#[derive(Debug)]
pub struct PreDrawSystem;

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

impl<'a> specs::prelude::System<'a> for PreDrawSystem {
  #[cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
  type SystemData = (WriteStorage<'a, Zombies>,
                     ReadStorage<'a, CameraInputState>,
                     ReadStorage<'a, CharacterInputState>,
                     ReadStorage<'a, Bullets>,
                     Read<'a, Dimensions>,
                     Read<'a, GameTime>);

  fn run(&mut self, (mut zombies, camera_input, character_input, bullets, dim, gt): Self::SystemData) {
    use specs::join::Join;

    for (zs, camera, ci, bs) in (&mut zombies, &camera_input, &character_input, &bullets).join() {
      let world_to_clip = dim.world_to_projection(camera);

      for z in &mut zs.zombies {
        z.update(&world_to_clip, ci, gt.0);
        z.check_bullet_hits(&bs.bullets);
      }
    }
  }
}
<|endoftext|>


<commit_before>//! A flat grid with square cells.

use vecmath::Scalar;
use {
    AddLine,
    AddSquareBorder,
    BackEnd,
    ColorContext,
    Draw,
    ImageSize,
};

/// Represents a flat grid with square cells.
pub struct Grid {
    /// Number of columns.
    pub cols: u32,
    /// Number of rows.
    pub rows: u32,
    /// The width and height of each grid cell.
    pub units: Scalar,
    /// The line radius.
    pub radius: Scalar,
}

/// Iterates through the cells of a grid as (uint, uint)
pub struct GridIterator {
    cols: u32,
    rows: u32,
    state: u64,
}

impl Grid {
    /// Draws the grid.
    pub fn draw<B: BackEnd<I>, I: ImageSize>(
        &self,
        c: &ColorContext,
        g: &mut B
    ) {
        let &Grid {
            cols, rows, units, radius
        } = self;
        for x in range(0, cols + 1) {
            let x1 = x as Scalar * units;
            let y1 = 0.0;
            let x2 = x1;
            let y2 = rows as Scalar * units;
            c.line(x1, y1, x2, y2).square_border_radius(radius).draw(g);
        }
        for y in range(0, rows + 1) {
            let x1 = 0.0;
            let y1 = y as Scalar * units;
            let x2 = cols as Scalar * units;
            let y2 = y1;
            c.line(x1, y1, x2, y2).square_border_radius(radius).draw(g);
        }
    }

    /// Get a GridIterator for the grid
    pub fn cells(&self) -> GridIterator {
        GridIterator {
            cols: self.cols,
            rows: self.rows,
            state: 0,
        }
    }
}

impl Iterator<(u32, u32)> for GridIterator {

    fn next(&mut self) -> Option<(u32, u32)> {
        let cols = self.cols as u64;
        let rows = self.rows as u64;

        if self.state == cols * rows {
            return None
        }
        let ret = (
            (self.state % cols) as u32,
            (self.state / rows) as u32,
        );
        self.state += 1;

        return Some(ret);
    }

}

#[test]
fn test_grid_iterator() {
    let g = Grid {cols: 2, rows: 2, units: 2.0, radius: 1.0};
    let expected : Vec<(u32, u32)> = vec![(0, 0), (1, 0), (0, 1), (1, 1)];
    assert_eq!(expected, g.cells().collect());
}
<commit_msg>Fixed doc comment<commit_after>//! A flat grid with square cells.

use vecmath::Scalar;
use {
    AddLine,
    AddSquareBorder,
    BackEnd,
    ColorContext,
    Draw,
    ImageSize,
};

/// Represents a flat grid with square cells.
pub struct Grid {
    /// Number of columns.
    pub cols: u32,
    /// Number of rows.
    pub rows: u32,
    /// The width and height of each grid cell.
    pub units: Scalar,
    /// The line radius.
    pub radius: Scalar,
}

/// Iterates through the cells of a grid as (u32, u32).
pub struct GridIterator {
    cols: u32,
    rows: u32,
    state: u64,
}

impl Grid {
    /// Draws the grid.
    pub fn draw<B: BackEnd<I>, I: ImageSize>(
        &self,
        c: &ColorContext,
        g: &mut B
    ) {
        let &Grid {
            cols, rows, units, radius
        } = self;
        for x in range(0, cols + 1) {
            let x1 = x as Scalar * units;
            let y1 = 0.0;
            let x2 = x1;
            let y2 = rows as Scalar * units;
            c.line(x1, y1, x2, y2).square_border_radius(radius).draw(g);
        }
        for y in range(0, rows + 1) {
            let x1 = 0.0;
            let y1 = y as Scalar * units;
            let x2 = cols as Scalar * units;
            let y2 = y1;
            c.line(x1, y1, x2, y2).square_border_radius(radius).draw(g);
        }
    }

    /// Get a GridIterator for the grid
    pub fn cells(&self) -> GridIterator {
        GridIterator {
            cols: self.cols,
            rows: self.rows,
            state: 0,
        }
    }
}

impl Iterator<(u32, u32)> for GridIterator {

    fn next(&mut self) -> Option<(u32, u32)> {
        let cols = self.cols as u64;
        let rows = self.rows as u64;

        if self.state == cols * rows {
            return None
        }
        let ret = (
            (self.state % cols) as u32,
            (self.state / rows) as u32,
        );
        self.state += 1;

        return Some(ret);
    }

}

#[test]
fn test_grid_iterator() {
    let g = Grid {cols: 2, rows: 2, units: 2.0, radius: 1.0};
    let expected : Vec<(u32, u32)> = vec![(0, 0), (1, 0), (0, 1), (1, 1)];
    assert_eq!(expected, g.cells().collect());
}
<|endoftext|>


<commit_before>use util::{ZOPFLI_WINDOW_MASK, ZOPFLI_MIN_MATCH};

const HASH_SHIFT: i32 = 5;
const HASH_MASK: i32 = 32767;

pub struct ZopfliHash {
    head: Vec<i32>,  /* Hash value to index of its most recent occurrence. */
    prev: Vec<u16>,  /* Index to index of prev. occurrence of same hash. */
    hashval: Vec<i32>,  /* Index to hash value at this index. */
    val: i32,  /* Current hash value. */

    /* Fields with similar purpose as the above hash, but for the second hash with
    a value that is calculated differently.  */
    head2: Vec<i32>,  /* Hash value to index of its most recent occurrence. */
    prev2: Vec<u16>,  /* Index to index of prev. occurrence of same hash. */
    hashval2: Vec<i32>,  /* Index to hash value at this index. */
    val2: i32,  /* Current hash value. */

    pub same: Vec<u16>,  /* Amount of repetitions of same byte after this .*/
}

impl ZopfliHash {
    pub fn new(window_size: usize) -> ZopfliHash {
        ZopfliHash {
           head: vec![-1; 65536],
           prev: (0..window_size as u16).collect::<Vec<_>>(),
           hashval: vec![-1; window_size],
           val: 0,

           /* Fields with similar purpose as the above hash, but for the second hash with
           a value that is calculated differently.  */
           head2: vec![-1; 65536],
           prev2: (0..window_size as u16).collect::<Vec<_>>(),
           hashval2: vec![-1; window_size],
           val2: 0,

           same: vec![0; window_size],
       }
    }

    pub fn reset(&mut self, window_size: usize) {
        self.val = 0;
        self.head = vec![-1; 65536];
        self.prev = (0..window_size as u16).collect::<Vec<_>>();
        self.hashval = vec![-1; window_size];

        self.same = vec![0; window_size];
        self.val2 = 0;
        self.head2 = vec![-1; 65536];
        self.prev2 = (0..window_size as u16).collect::<Vec<_>>();
        self.hashval2 = vec![-1; window_size];
    }

    pub fn warmup(&mut self, arr: &[u8], pos: usize, end: usize) {
        let c = arr[pos];
        self.update_val(c);

        if pos + 1 < end {
            let c = arr[pos + 1];
            self.update_val(c);
        }
    }

    /// Update the sliding hash value with the given byte. All calls to this function
    /// must be made on consecutive input characters. Since the hash value exists out
    /// of multiple input bytes, a few warmups with this function are needed initially.
    fn update_val(&mut self, c: u8) {
        self.val = ((self.val << HASH_SHIFT) ^ c as i32) & HASH_MASK;
    }

    pub fn update(&mut self, array: &[u8], pos: usize) {
        let hpos = pos & ZOPFLI_WINDOW_MASK;
        let mut amount = 0;

        let hash_value = array.iter().nth(pos + ZOPFLI_MIN_MATCH - 1).cloned().unwrap_or(0);
        self.update_val(hash_value);

        self.hashval[hpos] = self.val;

        let index = self.val as usize;

        if self.head[index] != -1 && self.hashval[self.head[index] as usize] == self.val {
            self.prev[hpos] = self.head[index] as u16;
        } else {
            self.prev[hpos] = hpos as u16;
        }

        self.head[index] = hpos as i32;

        // Update "same".
        if self.same[pos.wrapping_sub(1) & ZOPFLI_WINDOW_MASK] > 1 {
            amount = self.same[pos.wrapping_sub(1) & ZOPFLI_WINDOW_MASK] as i32 - 1;
        }

        while pos + amount as usize + 1 < array.len() && array[pos] == array[pos + amount as usize + 1] && amount < -1 {
            amount += 1;
        }
        self.same[hpos] = amount as u16;

        self.val2 = ((self.same[hpos].wrapping_sub(ZOPFLI_MIN_MATCH as u16) & 255) ^ self.val as u16) as i32;
        self.hashval2[hpos] = self.val2;

        let index2 = self.val2 as usize;
        if self.head2[index2] != -1 && self.hashval2[self.head2[index2] as usize] == self.val2 {
            self.prev2[hpos] = self.head2[index2] as u16;
        } else {
            self.prev2[hpos] = hpos as u16;
        }
        self.head2[index2] = hpos as i32;
    }

    pub fn head_at(&self, index: usize, which_hash: usize) -> i32 {
        if which_hash == 1 {
            self.head[index]
        } else {
            self.head2[index]
        }
    }

    pub fn prev_at(&self, index: usize, which_hash: usize) -> u16 {
        if which_hash == 1 {
            self.prev[index]
        } else {
            self.prev2[index]
        }
    }

    pub fn hash_val_at(&self, index: usize, which_hash: usize) -> i32 {
        if which_hash == 1 {
            self.hashval[index]
        } else {
            self.hashval2[index]
        }
    }

    pub fn val(&self, which_hash: usize) -> i32 {
        if which_hash == 1 {
            self.val
        } else {
            self.val2
        }
    }
}
<commit_msg>Use `get` to see if we're in the array's range or not<commit_after>use util::{ZOPFLI_WINDOW_MASK, ZOPFLI_MIN_MATCH};

const HASH_SHIFT: i32 = 5;
const HASH_MASK: i32 = 32767;

pub struct ZopfliHash {
    head: Vec<i32>,  /* Hash value to index of its most recent occurrence. */
    prev: Vec<u16>,  /* Index to index of prev. occurrence of same hash. */
    hashval: Vec<i32>,  /* Index to hash value at this index. */
    val: i32,  /* Current hash value. */

    /* Fields with similar purpose as the above hash, but for the second hash with
    a value that is calculated differently.  */
    head2: Vec<i32>,  /* Hash value to index of its most recent occurrence. */
    prev2: Vec<u16>,  /* Index to index of prev. occurrence of same hash. */
    hashval2: Vec<i32>,  /* Index to hash value at this index. */
    val2: i32,  /* Current hash value. */

    pub same: Vec<u16>,  /* Amount of repetitions of same byte after this .*/
}

impl ZopfliHash {
    pub fn new(window_size: usize) -> ZopfliHash {
        ZopfliHash {
           head: vec![-1; 65536],
           prev: (0..window_size as u16).collect::<Vec<_>>(),
           hashval: vec![-1; window_size],
           val: 0,

           /* Fields with similar purpose as the above hash, but for the second hash with
           a value that is calculated differently.  */
           head2: vec![-1; 65536],
           prev2: (0..window_size as u16).collect::<Vec<_>>(),
           hashval2: vec![-1; window_size],
           val2: 0,

           same: vec![0; window_size],
       }
    }

    pub fn reset(&mut self, window_size: usize) {
        self.val = 0;
        self.head = vec![-1; 65536];
        self.prev = (0..window_size as u16).collect::<Vec<_>>();
        self.hashval = vec![-1; window_size];

        self.same = vec![0; window_size];
        self.val2 = 0;
        self.head2 = vec![-1; 65536];
        self.prev2 = (0..window_size as u16).collect::<Vec<_>>();
        self.hashval2 = vec![-1; window_size];
    }

    pub fn warmup(&mut self, arr: &[u8], pos: usize, end: usize) {
        let c = arr[pos];
        self.update_val(c);

        if pos + 1 < end {
            let c = arr[pos + 1];
            self.update_val(c);
        }
    }

    /// Update the sliding hash value with the given byte. All calls to this function
    /// must be made on consecutive input characters. Since the hash value exists out
    /// of multiple input bytes, a few warmups with this function are needed initially.
    fn update_val(&mut self, c: u8) {
        self.val = ((self.val << HASH_SHIFT) ^ c as i32) & HASH_MASK;
    }

    pub fn update(&mut self, array: &[u8], pos: usize) {
        let hpos = pos & ZOPFLI_WINDOW_MASK;
        let mut amount = 0;

        let hash_value = array.get(pos + ZOPFLI_MIN_MATCH - 1).cloned().unwrap_or(0);
        self.update_val(hash_value);

        self.hashval[hpos] = self.val;

        let index = self.val as usize;

        if self.head[index] != -1 && self.hashval[self.head[index] as usize] == self.val {
            self.prev[hpos] = self.head[index] as u16;
        } else {
            self.prev[hpos] = hpos as u16;
        }

        self.head[index] = hpos as i32;

        // Update "same".
        if self.same[pos.wrapping_sub(1) & ZOPFLI_WINDOW_MASK] > 1 {
            amount = self.same[pos.wrapping_sub(1) & ZOPFLI_WINDOW_MASK] as i32 - 1;
        }

        while pos + amount as usize + 1 < array.len() && array[pos] == array[pos + amount as usize + 1] && amount < -1 {
            amount += 1;
        }
        self.same[hpos] = amount as u16;

        self.val2 = ((self.same[hpos].wrapping_sub(ZOPFLI_MIN_MATCH as u16) & 255) ^ self.val as u16) as i32;
        self.hashval2[hpos] = self.val2;

        let index2 = self.val2 as usize;
        if self.head2[index2] != -1 && self.hashval2[self.head2[index2] as usize] == self.val2 {
            self.prev2[hpos] = self.head2[index2] as u16;
        } else {
            self.prev2[hpos] = hpos as u16;
        }
        self.head2[index2] = hpos as i32;
    }

    pub fn head_at(&self, index: usize, which_hash: usize) -> i32 {
        if which_hash == 1 {
            self.head[index]
        } else {
            self.head2[index]
        }
    }

    pub fn prev_at(&self, index: usize, which_hash: usize) -> u16 {
        if which_hash == 1 {
            self.prev[index]
        } else {
            self.prev2[index]
        }
    }

    pub fn hash_val_at(&self, index: usize, which_hash: usize) -> i32 {
        if which_hash == 1 {
            self.hashval[index]
        } else {
            self.hashval2[index]
        }
    }

    pub fn val(&self, which_hash: usize) -> i32 {
        if which_hash == 1 {
            self.val
        } else {
            self.val2
        }
    }
}
<|endoftext|>


<commit_before>//! This module implements middleware for adding secuirty headers to
//! http responses in production.

use conduit::{Request, Response};
use conduit_middleware::Middleware;

use std::error::Error;
use std::collections::HashMap;

use Uploader;

#[derive(Clone, Debug)]
pub struct SecurityHeadersMiddleware {
    headers: HashMap<String, Vec<String>>,
}

impl SecurityHeadersMiddleware {
    pub fn new(uploader: &Uploader) -> Self {
        let mut headers = HashMap::new();

        headers.insert("X-Content-Type-Options".into(), vec!["nosniff".into()]);

        headers.insert("X-Frame-Options".into(), vec!["SAMEORIGIN".into()]);

        headers.insert("X-XSS-Protection".into(), vec!["1; mode=block".into()]);

        let s3_host = match *uploader {
            Uploader::S3 { ref bucket, .. } => bucket.host(),
            _ => unreachable!(
                "This middleware should only be used in the production environment, \
                 which should also require an S3 uploader, QED"
            ),
        };

        // It would be better if we didn't have to have 'unsafe-eval' in the `script-src`
        // policy, but google charts (used for the download graph on crate pages) uses `eval`
        // to load scripts. Remove 'unsafe-eval' if google fixes the issue:
        // https://github.com/google/google-visualization-issues/issues/1356
        // or if we switch to a different graph generation library.
        headers.insert(
            "Content-Security-Policy".into(),
            vec![
                format!(
                    "default-src 'self'; \
                     connect-src 'self' https://docs.rs https://{}; \
                     script-src 'self' 'unsafe-eval' \
                     https://www.google-analytics.com https://www.google.com; \
                     style-src 'self' https://www.google.com https://ajax.googleapis.com; \
                     img-src *; \
                     object-src 'none'",
                    s3_host
                ),
            ],
        );

        SecurityHeadersMiddleware { headers }
    }
}

impl Middleware for SecurityHeadersMiddleware {
    fn after(
        &self,
        _: &mut Request,
        mut res: Result<Response, Box<Error + Send>>,
    ) -> Result<Response, Box<Error + Send>> {
        if let Ok(ref mut response) = res {
            response.headers.extend(self.headers.clone());
        }
        res
    }
}
<commit_msg>Add the CDN to the whitelist in the content security policy<commit_after>//! This module implements middleware for adding secuirty headers to
//! http responses in production.

use conduit::{Request, Response};
use conduit_middleware::Middleware;

use std::error::Error;
use std::collections::HashMap;

use Uploader;

#[derive(Clone, Debug)]
pub struct SecurityHeadersMiddleware {
    headers: HashMap<String, Vec<String>>,
}

impl SecurityHeadersMiddleware {
    pub fn new(uploader: &Uploader) -> Self {
        let mut headers = HashMap::new();

        headers.insert("X-Content-Type-Options".into(), vec!["nosniff".into()]);

        headers.insert("X-Frame-Options".into(), vec!["SAMEORIGIN".into()]);

        headers.insert("X-XSS-Protection".into(), vec!["1; mode=block".into()]);

        let s3_host = match *uploader {
            Uploader::S3 {
                ref bucket,
                ref cdn,
                ..
            } => match *cdn {
                Some(ref s) => s.clone(),
                None => bucket.host(),
            },
            _ => unreachable!(
                "This middleware should only be used in the production environment, \
                 which should also require an S3 uploader, QED"
            ),
        };

        // It would be better if we didn't have to have 'unsafe-eval' in the `script-src`
        // policy, but google charts (used for the download graph on crate pages) uses `eval`
        // to load scripts. Remove 'unsafe-eval' if google fixes the issue:
        // https://github.com/google/google-visualization-issues/issues/1356
        // or if we switch to a different graph generation library.
        headers.insert(
            "Content-Security-Policy".into(),
            vec![
                format!(
                    "default-src 'self'; \
                     connect-src 'self' https://docs.rs https://{}; \
                     script-src 'self' 'unsafe-eval' \
                     https://www.google-analytics.com https://www.google.com; \
                     style-src 'self' https://www.google.com https://ajax.googleapis.com; \
                     img-src *; \
                     object-src 'none'",
                    s3_host
                ),
            ],
        );

        SecurityHeadersMiddleware { headers }
    }
}

impl Middleware for SecurityHeadersMiddleware {
    fn after(
        &self,
        _: &mut Request,
        mut res: Result<Response, Box<Error + Send>>,
    ) -> Result<Response, Box<Error + Send>> {
        if let Ok(ref mut response) = res {
            response.headers.extend(self.headers.clone());
        }
        res
    }
}
<|endoftext|>


<commit_before>#[cfg(unix)]
include!(concat!(env!("OUT_DIR"), "/skeptic-tests.rs"));
<commit_msg>remove skeptic tests<commit_after><|endoftext|>


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

pub struct PoolStats {}

impl PoolStats {
    pub fn new() -> Self {
        Self {}
    }
}

impl ::std::fmt::Display for PoolStats {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "PoolStats")
    }
}

impl super::Action for PoolStats {
    fn on_oom(&self, mut jni_env: ::env::JniEnv, resource_exhaustion_flags: ::jvmti::jint) -> Result<(), ::err::Error> {
        // Do not attempt to obtain pool stats on thread exhaustion as this fails abruptly.
        const threads_exhausted: ::jvmti::jint = ::jvmti::JVMTI_RESOURCE_EXHAUSTED_THREADS as ::jvmti::jint;
        if resource_exhaustion_flags & threads_exhausted == threads_exhausted {
            return Err(::err::Error::ActionUnavailableOnThreadExhaustion("determine memory usage statistics".to_string()));
        }

        let mf_class = jni_env.find_class("java/lang/management/ManagementFactory")?;
        let get_memory_mxbean_method_id = jni_env.get_static_method_id(mf_class, "getMemoryMXBean", "()Ljava/lang/management/MemoryMXBean;")?;
        let memory_mxbean = jni_env.call_static_object_method(mf_class, get_memory_mxbean_method_id)?;

        let memory_mxbean_class = jni_env.get_object_class(memory_mxbean)?;

        let heap_memory_usage_method_id = jni_env.get_method_id(memory_mxbean_class, "getHeapMemoryUsage", "()Ljava/lang/management/MemoryUsage;")?;
        let heap_usage = jni_env.call_object_method(memory_mxbean, heap_memory_usage_method_id)?;

        let non_heap_memory_usage_method_id = jni_env.get_method_id(memory_mxbean_class, "getNonHeapMemoryUsage", "()Ljava/lang/management/MemoryUsage;")?;
        let non_heap_usage = jni_env.call_object_method(memory_mxbean, non_heap_memory_usage_method_id)?;

        let heap_usage_stats = usage_stats(jni_env, heap_usage)?;
        let non_heap_usage_stats = usage_stats(jni_env, non_heap_usage)?;
        let output = &mut ::std::io::stdout();
        writeln_paced!(output, "\nMemory usage:\n   Heap memory: {}\n   Non-heap memory: {}", heap_usage_stats, non_heap_usage_stats);

        writeln_paced!(output, "\nMemory pool usage:");

        let get_mem_pool_mxbeans_method_id = jni_env.get_static_method_id(mf_class, "getMemoryPoolMXBeans", "()Ljava/util/List;")?;
        let mem_pool_mxbeans = jni_env.call_static_object_method(mf_class, get_mem_pool_mxbeans_method_id)?;
        let list_class = jni_env.find_class("java/util/List")?;
        let size_method_id = jni_env.get_method_id(list_class, "size", "()I")?;
        let get_method_id = jni_env.get_method_id(list_class, "get", "(I)Ljava/lang/Object;")?;
        let mem_pool_mxbean_class = jni_env.find_class("java/lang/management/MemoryPoolMXBean")?;
        let get_name_method_id = jni_env.get_method_id(mem_pool_mxbean_class, "getName", "()Ljava/lang/String;")?;
        let get_usage_method_id = jni_env.get_method_id(mem_pool_mxbean_class, "getUsage", "()Ljava/lang/management/MemoryUsage;")?;
        let size = jni_env.call_int_method(mem_pool_mxbeans, size_method_id);

        for i in 0..size {
            let pool_mxbean = jni_env.call_object_method_with_int(mem_pool_mxbeans, get_method_id, i)?;
            let name = jni_env.call_object_method(pool_mxbean, get_name_method_id)? as ::jvmti::jstring;
            let usage = jni_env.call_object_method(pool_mxbean, get_usage_method_id)?;
            let (name_utf_chars, name_cstr) = jni_env.get_string_utf_chars(name);
            let stats = usage_stats(jni_env, usage)?;
            writeln_paced!(output, "   {}: {}", name_cstr.to_string_lossy().into_owned(), stats);
            jni_env.release_string_utf_chars(name, name_utf_chars);
        }
        Ok(())
    }
}

fn usage_stats(mut jni_env: ::env::JniEnv, usage: ::jvmti::jobject) -> Result<String, ::err::Error> {
    let memory_usage_class = jni_env.get_object_class(usage)?;
    let get_init_method_id = jni_env.get_method_id(memory_usage_class, "getInit", "()J")?;
    let get_used_method_id = jni_env.get_method_id(memory_usage_class, "getUsed", "()J")?;
    let get_committed_method_id = jni_env.get_method_id(memory_usage_class, "getCommitted", "()J")?;
    let get_max_method_id = jni_env.get_method_id(memory_usage_class, "getMax", "()J")?;

    Ok(format!("init {}, used {}, committed {}, max {}",
               jni_env.call_long_method(usage, get_init_method_id),
               jni_env.call_long_method(usage, get_used_method_id),
               jni_env.call_long_method(usage, get_committed_method_id),
               jni_env.call_long_method(usage, get_max_method_id)))
}
<commit_msg>Add hints when memory pools are nearly full<commit_after>/*
 * Copyright (c) 2015-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
use std::collections::HashMap;
use std::io::Write;

pub struct PoolStats {
    pool_hint: HashMap<String, String>
}

impl PoolStats {
    pub fn new() -> Self {
        let mut pool_hint = HashMap::new();
        pool_hint.insert(String::from("Heap memory"), String::from("increase the container size"));
        pool_hint.insert(String::from("Metaspace"), String::from("set -XX:MaxMetaspaceSize to a suitable value"));
        pool_hint.insert(String::from("Compressed Class Space"), String::from("set -XX:CompressedClassSpaceSize to a suitable value"));
        Self {
            pool_hint: pool_hint
        }
    }

    fn print_stats(&self, name: String, stats: Stats, output: &mut Write) {
        let (stats_line, pool_nearly_full) = usage_stats(stats);
        writeln_paced!(output, "   {}: {}", name, stats_line);
        if pool_nearly_full {
            let sw = self.pool_hint.get(&name);
            if let Some(sw_string) = sw {
                writeln_paced!(output, "      Hint: {} is over 95% full. To increase it, {}.", name, sw_string);
            }
        }
    }
}

impl ::std::fmt::Display for PoolStats {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "PoolStats")
    }
}

impl super::Action for PoolStats {
    fn on_oom(&self, mut jni_env: ::env::JniEnv, resource_exhaustion_flags: ::jvmti::jint) -> Result<(), ::err::Error> {
        // Do not attempt to obtain pool stats on thread exhaustion as this fails abruptly.
        const threads_exhausted: ::jvmti::jint = ::jvmti::JVMTI_RESOURCE_EXHAUSTED_THREADS as ::jvmti::jint;
        if resource_exhaustion_flags & threads_exhausted == threads_exhausted {
            return Err(::err::Error::ActionUnavailableOnThreadExhaustion("determine memory usage statistics".to_string()));
        }

        let mut output = &mut ::std::io::stdout();

        let mf_class = jni_env.find_class("java/lang/management/ManagementFactory")?;

        writeln_paced!(output, "\nMemory usage:");
        let get_memory_mxbean_method_id = jni_env.get_static_method_id(mf_class, "getMemoryMXBean", "()Ljava/lang/management/MemoryMXBean;")?;
        let memory_mxbean = jni_env.call_static_object_method(mf_class, get_memory_mxbean_method_id)?;

        let memory_mxbean_class = jni_env.get_object_class(memory_mxbean)?;

        let heap_memory_usage_method_id = jni_env.get_method_id(memory_mxbean_class, "getHeapMemoryUsage", "()Ljava/lang/management/MemoryUsage;")?;
        let heap_usage = jni_env.call_object_method(memory_mxbean, heap_memory_usage_method_id)?;
        self.print_stats(String::from("Heap memory"), usage_statistics(jni_env, heap_usage)?, &mut output);

        let non_heap_memory_usage_method_id = jni_env.get_method_id(memory_mxbean_class, "getNonHeapMemoryUsage", "()Ljava/lang/management/MemoryUsage;")?;
        let non_heap_usage = jni_env.call_object_method(memory_mxbean, non_heap_memory_usage_method_id)?;
        self.print_stats(String::from("Non-heap memory"), usage_statistics(jni_env, non_heap_usage)?, &mut output);

        writeln_paced!(output, "\nMemory pool usage:");

        let get_mem_pool_mxbeans_method_id = jni_env.get_static_method_id(mf_class, "getMemoryPoolMXBeans", "()Ljava/util/List;")?;
        let mem_pool_mxbeans = jni_env.call_static_object_method(mf_class, get_mem_pool_mxbeans_method_id)?;
        let list_class = jni_env.find_class("java/util/List")?;
        let size_method_id = jni_env.get_method_id(list_class, "size", "()I")?;
        let get_method_id = jni_env.get_method_id(list_class, "get", "(I)Ljava/lang/Object;")?;
        let mem_pool_mxbean_class = jni_env.find_class("java/lang/management/MemoryPoolMXBean")?;
        let get_name_method_id = jni_env.get_method_id(mem_pool_mxbean_class, "getName", "()Ljava/lang/String;")?;
        let get_usage_method_id = jni_env.get_method_id(mem_pool_mxbean_class, "getUsage", "()Ljava/lang/management/MemoryUsage;")?;
        let size = jni_env.call_int_method(mem_pool_mxbeans, size_method_id);

        for i in 0..size {
            let pool_mxbean = jni_env.call_object_method_with_int(mem_pool_mxbeans, get_method_id, i)?;
            let name = jni_env.call_object_method(pool_mxbean, get_name_method_id)? as ::jvmti::jstring;
            let usage = jni_env.call_object_method(pool_mxbean, get_usage_method_id)?;
            let (name_utf_chars, name_cstr) = jni_env.get_string_utf_chars(name);
            let name_string = name_cstr.to_string_lossy().into_owned();
            let statistics = usage_statistics(jni_env, usage)?;

            self.print_stats(name_string, statistics, &mut output);
            jni_env.release_string_utf_chars(name, name_utf_chars);
        }
        Ok(())
    }
}

type Stats = (i64, i64, i64, i64);

fn usage_statistics(mut jni_env: ::env::JniEnv, usage: ::jvmti::jobject) -> Result<Stats, ::err::Error> {
    let memory_usage_class = jni_env.get_object_class(usage)?;
    let get_init_method_id = jni_env.get_method_id(memory_usage_class, "getInit", "()J")?;
    let get_used_method_id = jni_env.get_method_id(memory_usage_class, "getUsed", "()J")?;
    let get_committed_method_id = jni_env.get_method_id(memory_usage_class, "getCommitted", "()J")?;
    let get_max_method_id = jni_env.get_method_id(memory_usage_class, "getMax", "()J")?;

    Ok((jni_env.call_long_method(usage, get_init_method_id),
        jni_env.call_long_method(usage, get_used_method_id),
        jni_env.call_long_method(usage, get_committed_method_id),
        jni_env.call_long_method(usage, get_max_method_id)))
}

fn usage_stats(usage: Stats) -> (String, bool) {
    let (init, used, committed, max) = usage;

    let nearly_full = (committed as f32) / (max as f32) >= 0.95;

    ((format!("init {}, used {}, committed {}, max {}", init, used, committed, max), nearly_full))
}

#[cfg(test)]
mod tests {
    #[test]
    fn no_hint_by_default() {
        let mut output = Vec::new();

        let pool_stats = super::PoolStats::new();
        pool_stats.print_stats(String::from("some pool"), (0i64, 1i64, 95i64, 100i64), &mut output);
        assert_eq!(String::from_utf8(output).unwrap(), "   some pool: init 0, used 1, committed 95, max 100\n")
    }

    #[test]
    fn no_heap_hint_by_default() {
        let mut output = Vec::new();

        let pool_stats = super::PoolStats::new();
        pool_stats.print_stats(String::from("Heap memory"), (0i64, 1i64, 94i64, 100i64), &mut output);
        assert_eq!(String::from_utf8(output).unwrap(), "   Heap memory: init 0, used 1, committed 94, max 100\n")
    }

    #[test]
    fn heap_hint_when_nearly_full() {
        let mut output = Vec::new();

        let pool_stats = super::PoolStats::new();
        pool_stats.print_stats(String::from("Heap memory"), (0i64, 1i64, 95i64, 100i64), &mut output);
        assert_eq!(String::from_utf8(output).unwrap(), "   Heap memory: init 0, used 1, committed 95, max 100\n      Hint: Heap memory is over 95% full. To increase it, increase the container size.\n")
    }

    #[test]
    fn metaspace_hint_when_nearly_full() {
        let mut output = Vec::new();

        let pool_stats = super::PoolStats::new();
        pool_stats.print_stats(String::from("Metaspace"), (0i64, 1i64, 95i64, 100i64), &mut output);
        assert_eq!(String::from_utf8(output).unwrap(), "   Metaspace: init 0, used 1, committed 95, max 100\n      Hint: Metaspace is over 95% full. To increase it, set -XX:MaxMetaspaceSize to a suitable value.\n")
    }

    #[test]
    fn compressed_class_space_hint_when_nearly_full() {
        let mut output = Vec::new();

        let pool_stats = super::PoolStats::new();
        pool_stats.print_stats(String::from("Compressed Class Space"), (0i64, 1i64, 95i64, 100i64), &mut output);
        assert_eq!(String::from_utf8(output).unwrap(), "   Compressed Class Space: init 0, used 1, committed 95, max 100\n      Hint: Compressed Class Space is over 95% full. To increase it, set -XX:CompressedClassSpaceSize to a suitable value.\n")
    }
}
<|endoftext|>


<commit_before>#![allow(
    clippy::cast_lossless,
    clippy::cast_possible_wrap,
    clippy::derive_partial_eq_without_eq
)]

use indoc::indoc;
use serde_derive::Deserialize;
use serde_yaml::Value;
use std::collections::BTreeMap;
use std::fmt::Debug;

fn test_de<T>(yaml: &str, expected: &T)
where
    T: serde::de::DeserializeOwned + PartialEq + Debug,
{
    let deserialized: T = serde_yaml::from_str(yaml).unwrap();
    assert_eq!(*expected, deserialized);

    serde_yaml::from_str::<serde_yaml::Value>(yaml).unwrap();
    serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
}

fn test_de_seed<T, S>(yaml: &str, seed: S, expected: &T)
where
    T: PartialEq + Debug,
    S: for<'de> serde::de::DeserializeSeed<'de, Value = T>,
{
    let deserialized: T = serde_yaml::seed::from_str_seed(yaml, seed).unwrap();
    assert_eq!(*expected, deserialized);

    serde_yaml::from_str::<serde_yaml::Value>(yaml).unwrap();
    serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
}

#[test]
fn test_alias() {
    let yaml = indoc! {"
        first:
          &alias
          1
        second:
          *alias
        third: 3
    "};
    let mut expected = BTreeMap::new();
    {
        expected.insert(String::from("first"), 1);
        expected.insert(String::from("second"), 1);
        expected.insert(String::from("third"), 3);
    }
    test_de(yaml, &expected);
}

#[test]
fn test_option() {
    #[derive(Deserialize, PartialEq, Debug)]
    struct Data {
        a: Option<f64>,
        b: Option<String>,
        c: Option<bool>,
    }
    let yaml = indoc! {"
        b:
        c: true
    "};
    let expected = Data {
        a: None,
        b: None,
        c: Some(true),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_option_alias() {
    #[derive(Deserialize, PartialEq, Debug)]
    struct Data {
        a: Option<f64>,
        b: Option<String>,
        c: Option<bool>,
        d: Option<f64>,
        e: Option<String>,
        f: Option<bool>,
    }
    let yaml = indoc! {"
        none_f:
          &none_f
          ~
        none_s:
          &none_s
          ~
        none_b:
          &none_b
          ~

        some_f:
          &some_f
          1.0
        some_s:
          &some_s
          x
        some_b:
          &some_b
          true

        a: *none_f
        b: *none_s
        c: *none_b
        d: *some_f
        e: *some_s
        f: *some_b
    "};
    let expected = Data {
        a: None,
        b: None,
        c: None,
        d: Some(1.0),
        e: Some("x".to_owned()),
        f: Some(true),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_enum_alias() {
    #[derive(Deserialize, PartialEq, Debug)]
    enum E {
        A,
        B(u8, u8),
    }
    #[derive(Deserialize, PartialEq, Debug)]
    struct Data {
        a: E,
        b: E,
    }
    let yaml = indoc! {"
        aref:
          &aref
          A
        bref:
          &bref
          B:
            - 1
            - 2

        a: *aref
        b: *bref
    "};
    let expected = Data {
        a: E::A,
        b: E::B(1, 2),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_enum_tag() {
    #[derive(Deserialize, PartialEq, Debug)]
    enum E {
        A(String),
        B(String),
    }
    #[derive(Deserialize, PartialEq, Debug)]
    struct Data {
        a: E,
        b: E,
    }
    let yaml = indoc! {"
        a: !A foo
        b: !B bar
    "};
    let expected = Data {
        a: E::A("foo".into()),
        b: E::B("bar".into()),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_number_as_string() {
    #[derive(Deserialize, PartialEq, Debug)]
    struct Num {
        value: String,
    }
    let yaml = indoc! {"
        # Cannot be represented as u128
        value: 340282366920938463463374607431768211457
    "};
    let expected = Num {
        value: "340282366920938463463374607431768211457".to_owned(),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_i128_big() {
    let expected: i128 = i64::MIN as i128 - 1;
    let yaml = indoc! {"
        -9223372036854775809
    "};
    assert_eq!(expected, serde_yaml::from_str::<i128>(yaml).unwrap());

    let octal = indoc! {"
        -0o1000000000000000000001
    "};
    assert_eq!(expected, serde_yaml::from_str::<i128>(octal).unwrap());
}

#[test]
fn test_u128_big() {
    let expected: u128 = u64::MAX as u128 + 1;
    let yaml = indoc! {"
        18446744073709551616
    "};
    assert_eq!(expected, serde_yaml::from_str::<u128>(yaml).unwrap());

    let octal = indoc! {"
        0o2000000000000000000000
    "};
    assert_eq!(expected, serde_yaml::from_str::<u128>(octal).unwrap());
}

#[test]
fn test_number_alias_as_string() {
    #[derive(Deserialize, PartialEq, Debug)]
    struct Num {
        version: String,
        value: String,
    }
    let yaml = indoc! {"
        version: &a 1.10
        value: *a
    "};
    let expected = Num {
        version: "1.10".to_owned(),
        value: "1.10".to_owned(),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_de_mapping() {
    #[derive(Debug, Deserialize, PartialEq)]
    struct Data {
        pub substructure: serde_yaml::Mapping,
    }
    let yaml = indoc! {"
        substructure:
          a: 'foo'
          b: 'bar'
    "};

    let mut expected = Data {
        substructure: serde_yaml::Mapping::new(),
    };
    expected.substructure.insert(
        serde_yaml::Value::String("a".to_owned()),
        serde_yaml::Value::String("foo".to_owned()),
    );
    expected.substructure.insert(
        serde_yaml::Value::String("b".to_owned()),
        serde_yaml::Value::String("bar".to_owned()),
    );

    test_de(yaml, &expected);
}

#[test]
fn test_bomb() {
    #[derive(Debug, Deserialize, PartialEq)]
    struct Data {
        expected: String,
    }

    // This would deserialize an astronomical number of elements if we were
    // vulnerable.
    let yaml = indoc! {"
        a: &a ~
        b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
        c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
        d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
        e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
        f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
        g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
        h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
        i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
        j: &j [*i,*i,*i,*i,*i,*i,*i,*i,*i]
        k: &k [*j,*j,*j,*j,*j,*j,*j,*j,*j]
        l: &l [*k,*k,*k,*k,*k,*k,*k,*k,*k]
        m: &m [*l,*l,*l,*l,*l,*l,*l,*l,*l]
        n: &n [*m,*m,*m,*m,*m,*m,*m,*m,*m]
        o: &o [*n,*n,*n,*n,*n,*n,*n,*n,*n]
        p: &p [*o,*o,*o,*o,*o,*o,*o,*o,*o]
        q: &q [*p,*p,*p,*p,*p,*p,*p,*p,*p]
        r: &r [*q,*q,*q,*q,*q,*q,*q,*q,*q]
        s: &s [*r,*r,*r,*r,*r,*r,*r,*r,*r]
        t: &t [*s,*s,*s,*s,*s,*s,*s,*s,*s]
        u: &u [*t,*t,*t,*t,*t,*t,*t,*t,*t]
        v: &v [*u,*u,*u,*u,*u,*u,*u,*u,*u]
        w: &w [*v,*v,*v,*v,*v,*v,*v,*v,*v]
        x: &x [*w,*w,*w,*w,*w,*w,*w,*w,*w]
        y: &y [*x,*x,*x,*x,*x,*x,*x,*x,*x]
        z: &z [*y,*y,*y,*y,*y,*y,*y,*y,*y]
        expected: string
    "};

    let expected = Data {
        expected: "string".to_owned(),
    };

    assert_eq!(expected, serde_yaml::from_str::<Data>(yaml).unwrap());
}

#[test]
fn test_numbers() {
    let cases = [
        ("0xF0", "240"),
        ("+0xF0", "240"),
        ("-0xF0", "-240"),
        ("0o70", "56"),
        ("+0o70", "56"),
        ("-0o70", "-56"),
        ("0b10", "2"),
        ("+0b10", "2"),
        ("-0b10", "-2"),
        ("127", "127"),
        ("+127", "127"),
        ("-127", "-127"),
        (".inf", ".inf"),
        (".Inf", ".inf"),
        (".INF", ".inf"),
        ("-.inf", "-.inf"),
        ("-.Inf", "-.inf"),
        ("-.INF", "-.inf"),
        (".nan", ".nan"),
        (".NaN", ".nan"),
        (".NAN", ".nan"),
        ("0.1", "0.1"),
    ];
    for &(yaml, expected) in &cases {
        let value = serde_yaml::from_str::<Value>(yaml).unwrap();
        match value {
            Value::Number(number) => assert_eq!(number.to_string(), expected),
            _ => panic!("expected number. input={:?}, result={:?}", yaml, value),
        }
    }

    // NOT numbers.
    let cases = ["0127", "+0127", "-0127"];
    for yaml in &cases {
        let value = serde_yaml::from_str::<Value>(yaml).unwrap();
        match value {
            Value::String(string) => assert_eq!(string, *yaml),
            _ => panic!("expected string. input={:?}, result={:?}", yaml, value),
        }
    }
}

#[test]
fn test_stateful() {
    struct Seed(i64);

    impl<'de> serde::de::DeserializeSeed<'de> for Seed {
        type Value = i64;
        fn deserialize<D>(self, deserializer: D) -> Result<i64, D::Error>
        where
            D: serde::de::Deserializer<'de>,
        {
            struct Visitor(i64);
            impl<'de> serde::de::Visitor<'de> for Visitor {
                type Value = i64;

                fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
                    write!(formatter, "an integer")
                }

                fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<i64, E> {
                    Ok(v * self.0)
                }

                fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<i64, E> {
                    Ok(v as i64 * self.0)
                }
            }

            deserializer.deserialize_any(Visitor(self.0))
        }
    }

    let cases = [("3", 5, 15), ("6", 7, 42), ("-5", 9, -45)];
    for &(yaml, seed, expected) in &cases {
        test_de_seed(yaml, Seed(seed), &expected);
    }
}
<commit_msg>Eliminate unneeded block from test_alias<commit_after>#![allow(
    clippy::cast_lossless,
    clippy::cast_possible_wrap,
    clippy::derive_partial_eq_without_eq
)]

use indoc::indoc;
use serde_derive::Deserialize;
use serde_yaml::Value;
use std::collections::BTreeMap;
use std::fmt::Debug;

fn test_de<T>(yaml: &str, expected: &T)
where
    T: serde::de::DeserializeOwned + PartialEq + Debug,
{
    let deserialized: T = serde_yaml::from_str(yaml).unwrap();
    assert_eq!(*expected, deserialized);

    serde_yaml::from_str::<serde_yaml::Value>(yaml).unwrap();
    serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
}

fn test_de_seed<T, S>(yaml: &str, seed: S, expected: &T)
where
    T: PartialEq + Debug,
    S: for<'de> serde::de::DeserializeSeed<'de, Value = T>,
{
    let deserialized: T = serde_yaml::seed::from_str_seed(yaml, seed).unwrap();
    assert_eq!(*expected, deserialized);

    serde_yaml::from_str::<serde_yaml::Value>(yaml).unwrap();
    serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
}

#[test]
fn test_alias() {
    let yaml = indoc! {"
        first:
          &alias
          1
        second:
          *alias
        third: 3
    "};
    let mut expected = BTreeMap::new();
    expected.insert(String::from("first"), 1);
    expected.insert(String::from("second"), 1);
    expected.insert(String::from("third"), 3);
    test_de(yaml, &expected);
}

#[test]
fn test_option() {
    #[derive(Deserialize, PartialEq, Debug)]
    struct Data {
        a: Option<f64>,
        b: Option<String>,
        c: Option<bool>,
    }
    let yaml = indoc! {"
        b:
        c: true
    "};
    let expected = Data {
        a: None,
        b: None,
        c: Some(true),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_option_alias() {
    #[derive(Deserialize, PartialEq, Debug)]
    struct Data {
        a: Option<f64>,
        b: Option<String>,
        c: Option<bool>,
        d: Option<f64>,
        e: Option<String>,
        f: Option<bool>,
    }
    let yaml = indoc! {"
        none_f:
          &none_f
          ~
        none_s:
          &none_s
          ~
        none_b:
          &none_b
          ~

        some_f:
          &some_f
          1.0
        some_s:
          &some_s
          x
        some_b:
          &some_b
          true

        a: *none_f
        b: *none_s
        c: *none_b
        d: *some_f
        e: *some_s
        f: *some_b
    "};
    let expected = Data {
        a: None,
        b: None,
        c: None,
        d: Some(1.0),
        e: Some("x".to_owned()),
        f: Some(true),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_enum_alias() {
    #[derive(Deserialize, PartialEq, Debug)]
    enum E {
        A,
        B(u8, u8),
    }
    #[derive(Deserialize, PartialEq, Debug)]
    struct Data {
        a: E,
        b: E,
    }
    let yaml = indoc! {"
        aref:
          &aref
          A
        bref:
          &bref
          B:
            - 1
            - 2

        a: *aref
        b: *bref
    "};
    let expected = Data {
        a: E::A,
        b: E::B(1, 2),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_enum_tag() {
    #[derive(Deserialize, PartialEq, Debug)]
    enum E {
        A(String),
        B(String),
    }
    #[derive(Deserialize, PartialEq, Debug)]
    struct Data {
        a: E,
        b: E,
    }
    let yaml = indoc! {"
        a: !A foo
        b: !B bar
    "};
    let expected = Data {
        a: E::A("foo".into()),
        b: E::B("bar".into()),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_number_as_string() {
    #[derive(Deserialize, PartialEq, Debug)]
    struct Num {
        value: String,
    }
    let yaml = indoc! {"
        # Cannot be represented as u128
        value: 340282366920938463463374607431768211457
    "};
    let expected = Num {
        value: "340282366920938463463374607431768211457".to_owned(),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_i128_big() {
    let expected: i128 = i64::MIN as i128 - 1;
    let yaml = indoc! {"
        -9223372036854775809
    "};
    assert_eq!(expected, serde_yaml::from_str::<i128>(yaml).unwrap());

    let octal = indoc! {"
        -0o1000000000000000000001
    "};
    assert_eq!(expected, serde_yaml::from_str::<i128>(octal).unwrap());
}

#[test]
fn test_u128_big() {
    let expected: u128 = u64::MAX as u128 + 1;
    let yaml = indoc! {"
        18446744073709551616
    "};
    assert_eq!(expected, serde_yaml::from_str::<u128>(yaml).unwrap());

    let octal = indoc! {"
        0o2000000000000000000000
    "};
    assert_eq!(expected, serde_yaml::from_str::<u128>(octal).unwrap());
}

#[test]
fn test_number_alias_as_string() {
    #[derive(Deserialize, PartialEq, Debug)]
    struct Num {
        version: String,
        value: String,
    }
    let yaml = indoc! {"
        version: &a 1.10
        value: *a
    "};
    let expected = Num {
        version: "1.10".to_owned(),
        value: "1.10".to_owned(),
    };
    test_de(yaml, &expected);
}

#[test]
fn test_de_mapping() {
    #[derive(Debug, Deserialize, PartialEq)]
    struct Data {
        pub substructure: serde_yaml::Mapping,
    }
    let yaml = indoc! {"
        substructure:
          a: 'foo'
          b: 'bar'
    "};

    let mut expected = Data {
        substructure: serde_yaml::Mapping::new(),
    };
    expected.substructure.insert(
        serde_yaml::Value::String("a".to_owned()),
        serde_yaml::Value::String("foo".to_owned()),
    );
    expected.substructure.insert(
        serde_yaml::Value::String("b".to_owned()),
        serde_yaml::Value::String("bar".to_owned()),
    );

    test_de(yaml, &expected);
}

#[test]
fn test_bomb() {
    #[derive(Debug, Deserialize, PartialEq)]
    struct Data {
        expected: String,
    }

    // This would deserialize an astronomical number of elements if we were
    // vulnerable.
    let yaml = indoc! {"
        a: &a ~
        b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
        c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
        d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
        e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
        f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
        g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
        h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
        i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
        j: &j [*i,*i,*i,*i,*i,*i,*i,*i,*i]
        k: &k [*j,*j,*j,*j,*j,*j,*j,*j,*j]
        l: &l [*k,*k,*k,*k,*k,*k,*k,*k,*k]
        m: &m [*l,*l,*l,*l,*l,*l,*l,*l,*l]
        n: &n [*m,*m,*m,*m,*m,*m,*m,*m,*m]
        o: &o [*n,*n,*n,*n,*n,*n,*n,*n,*n]
        p: &p [*o,*o,*o,*o,*o,*o,*o,*o,*o]
        q: &q [*p,*p,*p,*p,*p,*p,*p,*p,*p]
        r: &r [*q,*q,*q,*q,*q,*q,*q,*q,*q]
        s: &s [*r,*r,*r,*r,*r,*r,*r,*r,*r]
        t: &t [*s,*s,*s,*s,*s,*s,*s,*s,*s]
        u: &u [*t,*t,*t,*t,*t,*t,*t,*t,*t]
        v: &v [*u,*u,*u,*u,*u,*u,*u,*u,*u]
        w: &w [*v,*v,*v,*v,*v,*v,*v,*v,*v]
        x: &x [*w,*w,*w,*w,*w,*w,*w,*w,*w]
        y: &y [*x,*x,*x,*x,*x,*x,*x,*x,*x]
        z: &z [*y,*y,*y,*y,*y,*y,*y,*y,*y]
        expected: string
    "};

    let expected = Data {
        expected: "string".to_owned(),
    };

    assert_eq!(expected, serde_yaml::from_str::<Data>(yaml).unwrap());
}

#[test]
fn test_numbers() {
    let cases = [
        ("0xF0", "240"),
        ("+0xF0", "240"),
        ("-0xF0", "-240"),
        ("0o70", "56"),
        ("+0o70", "56"),
        ("-0o70", "-56"),
        ("0b10", "2"),
        ("+0b10", "2"),
        ("-0b10", "-2"),
        ("127", "127"),
        ("+127", "127"),
        ("-127", "-127"),
        (".inf", ".inf"),
        (".Inf", ".inf"),
        (".INF", ".inf"),
        ("-.inf", "-.inf"),
        ("-.Inf", "-.inf"),
        ("-.INF", "-.inf"),
        (".nan", ".nan"),
        (".NaN", ".nan"),
        (".NAN", ".nan"),
        ("0.1", "0.1"),
    ];
    for &(yaml, expected) in &cases {
        let value = serde_yaml::from_str::<Value>(yaml).unwrap();
        match value {
            Value::Number(number) => assert_eq!(number.to_string(), expected),
            _ => panic!("expected number. input={:?}, result={:?}", yaml, value),
        }
    }

    // NOT numbers.
    let cases = ["0127", "+0127", "-0127"];
    for yaml in &cases {
        let value = serde_yaml::from_str::<Value>(yaml).unwrap();
        match value {
            Value::String(string) => assert_eq!(string, *yaml),
            _ => panic!("expected string. input={:?}, result={:?}", yaml, value),
        }
    }
}

#[test]
fn test_stateful() {
    struct Seed(i64);

    impl<'de> serde::de::DeserializeSeed<'de> for Seed {
        type Value = i64;
        fn deserialize<D>(self, deserializer: D) -> Result<i64, D::Error>
        where
            D: serde::de::Deserializer<'de>,
        {
            struct Visitor(i64);
            impl<'de> serde::de::Visitor<'de> for Visitor {
                type Value = i64;

                fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
                    write!(formatter, "an integer")
                }

                fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<i64, E> {
                    Ok(v * self.0)
                }

                fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<i64, E> {
                    Ok(v as i64 * self.0)
                }
            }

            deserializer.deserialize_any(Visitor(self.0))
        }
    }

    let cases = [("3", 5, 15), ("6", 7, 42), ("-5", 9, -45)];
    for &(yaml, seed, expected) in &cases {
        test_de_seed(yaml, Seed(seed), &expected);
    }
}
<|endoftext|>


<commit_before>extern crate identicon;
extern crate openssl;
extern crate image;

use std::io;
use std::io::{Read, Write, Result};

use image::ColorType;
use image::png::PNGEncoder;
use openssl::crypto::hash::{Hasher, Type};

use identicon::Identicon;

fn main() {
    let bytes = hash().unwrap();
    generate(&bytes[..]).unwrap();
}

fn generate(input: &[u8]) -> Result<()> {
    let identicon = Identicon::new(input);
    let image = identicon.image();
    let (width, height) = image.dimensions();
    let output = &mut io::stdout();
    let mut encoder = PNGEncoder::new(output);
    encoder.encode(image.as_ref(), width, height, ColorType::RGB(8))
}

fn hash() -> Result<Vec<u8>> {
    let mut hash = Hasher::new(Type::MD5);
    let input = io::stdin();
    let mut reader = input.lock();
    match pipe(&mut reader, &mut hash) {
        Ok(..) => Ok(hash.finish()),
        Err(e) => Err(e),
    }
}

fn pipe(input: &mut Read, output: &mut Write) -> Result<usize> {
    let mut total = 0;
    let mut buf = [0; 1024];
    loop {
        match try!(input.read(&mut buf)) {
            0 => break,
            n => {
                try!(output.write(&buf[0..n]));
                total += n;
            },
        }
    }
    Ok(total)
}
<commit_msg>Let try! unwrap the pipe result.<commit_after>extern crate identicon;
extern crate openssl;
extern crate image;

use std::io;
use std::io::{Read, Write, Result};

use image::ColorType;
use image::png::PNGEncoder;
use openssl::crypto::hash::{Hasher, Type};

use identicon::Identicon;

fn main() {
    let bytes = hash().unwrap();
    generate(&bytes[..]).unwrap();
}

fn generate(input: &[u8]) -> Result<()> {
    let identicon = Identicon::new(input);
    let image = identicon.image();
    let (width, height) = image.dimensions();
    let output = &mut io::stdout();
    let mut encoder = PNGEncoder::new(output);
    encoder.encode(image.as_ref(), width, height, ColorType::RGB(8))
}

fn hash() -> Result<Vec<u8>> {
    let mut hash = Hasher::new(Type::MD5);
    let input = io::stdin();
    let mut reader = input.lock();
    try!(pipe(&mut reader, &mut hash));
    Ok(hash.finish())
}

fn pipe(input: &mut Read, output: &mut Write) -> Result<usize> {
    let mut total = 0;
    let mut buf = [0; 1024];
    loop {
        match try!(input.read(&mut buf)) {
            0 => break,
            n => {
                try!(output.write(&buf[0..n]));
                total += n;
            },
        }
    }
    Ok(total)
}
<|endoftext|>


<commit_before>#[macro_use] extern crate nickel;
extern crate handlebars;
extern crate ws;

use ws::{ listen, CloseCode, Sender, Handler, Message, Result, Handshake };
use nickel::{Nickel, HttpRouter};
use handlebars::Handlebars;

use std::collections::HashMap;
use std::thread;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
use std::error::Error;

struct WebsocketServer {
    out: Sender
}

impl Handler for WebsocketServer {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        println!("herp: {}", msg);
        self.out.send(msg)
    }

    fn on_open(&mut self, handshake: Handshake) -> Result<()> {
        println!("connection: {:?}", handshake);
        self.out.send("sup")
    }

    fn on_close(&mut self, code: CloseCode, reason: &str) {
        println!("Closing: ({:?}) {}", code, reason);
        println!("Shutting down");
        self.out.shutdown().unwrap()
    }
}

fn main() {
    let mut handlebars = Handlebars::new();

    handlebars.register_template_string("index", &Path::new("templates/index.hbs")).ok().unwrap();

    let mut server = Nickel::new();

    let websocket_server = thread::spawn(move || {
        listen("127.0.0.1:3012", |out| {
            WebsocketServer { out: out }
        }).unwrap()
    });

    server.get("/bar", middleware!("This is the /bar handler"));
    server.get("/user/:herp", middleware! { |req, res|
        let mut data = HashMap::new();
        data.insert("test".to_string(), req.param("herp").unwrap().to_string());
        handlebars.render("index", &data).ok().unwrap()
    });

    server.listen("127.0.0.1:6767");

    let _ = websocket_server.join();
}
<commit_msg>Fix for new changes<commit_after>#[macro_use] extern crate nickel;
extern crate handlebars;
extern crate ws;

use ws::{ listen, CloseCode, Sender, Handler, Message, Result, Handshake };
use nickel::{Nickel, HttpRouter};
use handlebars::Handlebars;

use std::collections::HashMap;
use std::thread;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
use std::error::Error;

struct WebsocketServer {
    out: Sender
}

impl Handler for WebsocketServer {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        println!("herp: {}", msg);
        self.out.send(msg)
    }

    fn on_open(&mut self, handshake: Handshake) -> Result<()> {
        println!("connection: {:?}", handshake);
        self.out.send("sup")
    }

    fn on_close(&mut self, code: CloseCode, reason: &str) {
        println!("Closing: ({:?}) {}", code, reason);
        println!("Shutting down");
        self.out.shutdown().unwrap()
    }
}

fn main() {
    let mut handlebars = Handlebars::new();

    handlebars.register_template_file("index", &Path::new("templates/index.hbs")).ok().unwrap();

    let mut server = Nickel::new();

    let websocket_server = thread::spawn(move || {
        listen("127.0.0.1:3012", |out| {
            WebsocketServer { out: out }
        }).unwrap()
    });

    server.get("/bar", middleware!("This is the /bar handler"));
    server.get("/user/:herp", middleware! { |req, res|
        let mut data = HashMap::new();
        data.insert("test".to_string(), req.param("herp").unwrap().to_string());
        handlebars.render("index", &data).ok().unwrap()
    });

    server.listen("127.0.0.1:6767");

    let _ = websocket_server.join();
}
<|endoftext|>