<commit_before>use alto::{self, SourceTrait};
use std::fs::File;
use std::path::Path;
use std::sync::mpsc::{Receiver, SyncSender, sync_channel};
use std::thread::spawn;
use vorbis::Decoder;

/// The device is responsible of managing synchronization and audio playback by providing a playback
/// cursor to a closure used as demo.
///
/// You shouldn’t have more than one Device per program.
pub struct Device {
  /// Playback length.
  len: f32,
  /// Sender used to send requests to audio thread.
  req_sx: SyncSender<Request>,
  /// Receiver used to receive responses from the audio thread.
  resp_rx: Receiver<Response>
}

enum Request {
  Toggle,
  PlaybackLength,
  PlaybackCursor,
  SetCursor(f32)
}

enum Response {
  PlaybackLength(f32),
  PlaybackCursor(f32)
}

impl Device {
  pub fn new<P>(track_path: P) -> Self where P: AsRef<Path> {
    info!("loading soundtrack {:?}", track_path.as_ref());

    // FIXME: stream the file instead?
    // load PCM data from the file
    let vorbis_decoder = Decoder::new(File::open(track_path).unwrap()).unwrap();
    let mut pcm_buffer = Vec::new();

    for packet in vorbis_decoder.into_packets().map(Result::unwrap) {
      pcm_buffer.extend(packet.data);
    }

    // create a channel to send requests to / retrieve them from the audio thread
    let (req_sx, req_rx) = sync_channel(0);
    // create a channel to receive responses / to send responses from the audio thread
    let (mut resp_sx, resp_rx) = sync_channel(0);

    info!("starting audio thread");

    let _ = spawn(move || {
      deb!("initializing OpenAL");

      let alto = alto::Alto::load_default().unwrap();
      let al_device = alto.open(None).unwrap();
      let al_ctx = al_device.new_context(None).unwrap();

      // create the required objects to play the soundtrack
      let mut al_buffer = al_ctx.new_buffer().unwrap();
      let mut al_source = al_ctx.new_streaming_source().unwrap();

      // fill the OpenAL buffers with the PCM data
      let _ = al_buffer.set_data::<alto::Stereo<_>, _>(&pcm_buffer[..], 44100);

      // compute the length of soundtrack
      let l = (al_buffer.size().unwrap() * 8 / (al_buffer.channels().unwrap() * al_buffer.bits().unwrap())) as f32 / al_buffer.frequency().unwrap() as f32;

      let _ = al_source.queue_buffer(al_buffer);

      loop {
        match req_rx.recv() {
          Ok(req) => dispatch_request(&mut al_source, l, req, &mut resp_sx),
          Err(_) => break
        }
      }

      info!("leaving the audio thread");
    });

    // get the length
    let _ = req_sx.send(Request::PlaybackLength);

    let len = match resp_rx.recv() {
      Ok(Response::PlaybackLength(len)) => len,
      _ => unimplemented!()
    };

    Device {
      len: len,
      req_sx: req_sx,
      resp_rx: resp_rx
    }
  }

  pub fn toggle(&self) {
    let _ = self.req_sx.send(Request::Toggle);
  }

  pub fn playback_len(&self) -> f32 {
    self.len
  }

  pub fn playback_cursor(&self) -> f32 {
    let _ = self.req_sx.send(Request::PlaybackCursor);

    match self.resp_rx.recv() {
      Ok(Response::PlaybackCursor(c)) => c,
      _ => unimplemented!()
    }
  }

  pub fn set_playback_cursor(&self, t: f32) {
    let _ = self.req_sx.send(Request::SetCursor(t));
  }
}

fn dispatch_request(source: &mut alto::StreamingSource, len: f32, req: Request, resp_sx: &mut SyncSender<Response>) {
  match req {
    Request::Toggle => {
      toggle_source(source);
    },

    Request::PlaybackLength => {
      let _ = resp_sx.send(Response::PlaybackLength(len));
    },

    Request::PlaybackCursor => {
      let _ = resp_sx.send(Response::PlaybackCursor(playback_cursor_source(source, len)));
    },

    Request::SetCursor(t) => {
      set_playback_cursor_source(source, t, len);
    }
  }
}

fn toggle_source(source: &mut alto::StreamingSource) {
  if source.state().unwrap() == alto::SourceState::Playing {
    // pause the OpenAL source
    let _ = source.pause();
  } else {
    // unpause the OpenAL source
    let _ = source.play();
  }
}

fn playback_cursor_source(source: &mut alto::StreamingSource, len: f32) -> f32 {
  let cursor = source.sec_offset().unwrap();

  // loop the device if we hit the end of the demo
  if cursor > len {
    let _ = source.rewind();
    0.
  } else {
    cursor
  }
}

pub fn set_playback_cursor_source(source: &mut alto::StreamingSource, t: f32, len: f32) {
  assert!(t >= 0. && t <= 1.);
  let _ = source.set_sec_offset(t * len);
}
<commit_msg>Space.<commit_after>use alto::{self, SourceTrait};
use std::fs::File;
use std::path::Path;
use std::sync::mpsc::{Receiver, SyncSender, sync_channel};
use std::thread::spawn;
use vorbis::Decoder;

/// The device is responsible of managing synchronization and audio playback by providing a playback
/// cursor to a closure used as demo.
///
/// You shouldn’t have more than one Device per program.
pub struct Device {
  /// Playback length.
  len: f32,
  /// Sender used to send requests to audio thread.
  req_sx: SyncSender<Request>,
  /// Receiver used to receive responses from the audio thread.
  resp_rx: Receiver<Response>
}

enum Request {
  Toggle,
  PlaybackLength,
  PlaybackCursor,
  SetCursor(f32)
}

enum Response {
  PlaybackLength(f32),
  PlaybackCursor(f32)
}

impl Device {
  pub fn new<P>(track_path: P) -> Self where P: AsRef<Path> {
    info!("loading soundtrack {:?}", track_path.as_ref());

    // FIXME: stream the file instead?
    // load PCM data from the file
    let vorbis_decoder = Decoder::new(File::open(track_path).unwrap()).unwrap();
    let mut pcm_buffer = Vec::new();

    for packet in vorbis_decoder.into_packets().map(Result::unwrap) {
      pcm_buffer.extend(packet.data);
    }

    // create a channel to send requests to / retrieve them from the audio thread
    let (req_sx, req_rx) = sync_channel(0);
    // create a channel to receive responses / to send responses from the audio thread
    let (mut resp_sx, resp_rx) = sync_channel(0);

    info!("starting audio thread");

    let _ = spawn(move || {
      deb!("initializing OpenAL");

      let alto = alto::Alto::load_default().unwrap();
      let al_device = alto.open(None).unwrap();
      let al_ctx = al_device.new_context(None).unwrap();

      // create the required objects to play the soundtrack
      let mut al_buffer = al_ctx.new_buffer().unwrap();
      let mut al_source = al_ctx.new_streaming_source().unwrap();

      // fill the OpenAL buffers with the PCM data
      let _ = al_buffer.set_data::<alto::Stereo<_>, _>(&pcm_buffer[..], 44100);

      // compute the length of soundtrack
      let l = (al_buffer.size().unwrap() * 8 / (al_buffer.channels().unwrap() * al_buffer.bits().unwrap())) as f32 / al_buffer.frequency().unwrap() as f32;

      let _ = al_source.queue_buffer(al_buffer);

      loop {
        match req_rx.recv() {
          Ok(req) => dispatch_request(&mut al_source, l, req, &mut resp_sx),
          Err(_) => break
        }
      }

      info!("leaving the audio thread");
    });

    // get the length
    let _ = req_sx.send(Request::PlaybackLength);

    let len = match resp_rx.recv() {
      Ok(Response::PlaybackLength(len)) => len,
      _ => unimplemented!()
    };

    Device {
      len: len,
      req_sx: req_sx,
      resp_rx: resp_rx
    }
  }

  pub fn toggle(&self) {
    let _ = self.req_sx.send(Request::Toggle);
  }

  pub fn playback_len(&self) -> f32 {
    self.len
  }

  pub fn playback_cursor(&self) -> f32 {
    let _ = self.req_sx.send(Request::PlaybackCursor);

    match self.resp_rx.recv() {
      Ok(Response::PlaybackCursor(c)) => c,
      _ => unimplemented!()
    }
  }

  pub fn set_playback_cursor(&self, t: f32) {
    let _ = self.req_sx.send(Request::SetCursor(t));
  }
}

fn dispatch_request(source: &mut alto::StreamingSource, len: f32, req: Request, resp_sx: &mut SyncSender<Response>) {
  match req {
    Request::Toggle => {
      toggle_source(source);
    },

    Request::PlaybackLength => {
      let _ = resp_sx.send(Response::PlaybackLength(len));
    },

    Request::PlaybackCursor => {
      let _ = resp_sx.send(Response::PlaybackCursor(playback_cursor_source(source, len)));
    },

    Request::SetCursor(t) => {
      set_playback_cursor_source(source, t, len);
    }
  }
}

fn toggle_source(source: &mut alto::StreamingSource) {
  if source.state().unwrap() == alto::SourceState::Playing {
    // pause the OpenAL source
    let _ = source.pause();
  } else {
    // unpause the OpenAL source
    let _ = source.play();
  }
}

fn playback_cursor_source(source: &mut alto::StreamingSource, len: f32) -> f32 {
  let cursor = source.sec_offset().unwrap();

  // loop the device if we hit the end of the demo
  if cursor > len {
    let _ = source.rewind();
    0.
  } else {
    cursor
  }
}

pub fn set_playback_cursor_source(source: &mut alto::StreamingSource, t: f32, len: f32) {
  assert!(t >= 0. && t <= 1.);
  let _ = source.set_sec_offset(t * len);
}
<|endoftext|>


<commit_before>use rand::Rng;
use domination::{Dominate, Domination};
use multi_objective::MultiObjective;
use population::{UnratedPopulation, RatedPopulation, SelectedPopulation};
use time;

pub struct DriverConfig {
    pub mu: usize,
    pub lambda: usize,
    pub k: usize,
    pub ngen: usize,
    pub num_objectives: usize,
    pub parallel_weight: f64,
}

pub trait Driver: Sync
{
    type IND: Clone + Sync;
    type FIT: Dominate + MultiObjective + Clone + Send;

    fn random_individual<R>(&self, rng: &mut R) -> Self::IND where R: Rng;
    fn random_population<R>(&self, rng: &mut R, n: usize) -> UnratedPopulation<Self::IND> where R: Rng {
        (0..n).map(|_| self.random_individual(rng)).collect()
    }
    fn fitness(&self, ind: &Self::IND) -> Self::FIT;
    fn mate<R>(&self, rng: &mut R, parent1: &Self::IND, parent2: &Self::IND) -> Self::IND where R: Rng;
    fn is_solution(&self, _ind: &Self::IND, _fit: &Self::FIT) -> bool {
        false
    }

    /// This can be used to update certain objectives in relation to the whole population.
    fn population_metric(&self, _population: &mut RatedPopulation<Self::IND, Self::FIT>) {
    }

    fn run<R, D, L>(&self,
                    rng: &mut R,
                    config: &DriverConfig,
                    domination: &mut D,
                    logger: &L)
                    -> SelectedPopulation<Self::IND, Self::FIT>
        where R: Rng,
              D: Domination<Self::FIT>,
              L: Fn(usize, u64, usize, &SelectedPopulation<Self::IND, Self::FIT>)
    {
        // this is generation 0. it's empty
        let mut time_last = time::precise_time_ns();
        let mut parents = SelectedPopulation::<Self::IND, Self::FIT>::new();
        let mut offspring = self.random_population(rng, config.mu);
        let mut gen: usize = 0;

        loop {
            let rated_offspring = offspring.rate_in_parallel(&|ind| self.fitness(ind), config.parallel_weight);
            let mut next_generation = parents.merge(rated_offspring);
            // apply a population metric on the whole population
            self.population_metric(&mut next_generation);
            parents = next_generation.select(config.mu, config.num_objectives, domination);

            let mut found_solutions = 0;
            parents.all(&mut |ind, fit| {
                if self.is_solution(ind, fit) {
                    found_solutions += 1;
                }
            });

            let now = time::precise_time_ns();
            let duration = now - time_last;
            time_last = now;

            logger(gen, duration, found_solutions, &parents);

            if found_solutions > 0 {
                break;
            }

            gen += 1;
            if gen > config.ngen {
                break;
            }

            offspring = parents.reproduce(rng,
                                          config.lambda,
                                          config.k,
                                          &|rng, p1, p2| self.mate(rng, p1, p2));
        }

        return parents;
    }
}
<commit_msg>Rename random_population() to initial_population()<commit_after>use rand::Rng;
use domination::{Dominate, Domination};
use multi_objective::MultiObjective;
use population::{UnratedPopulation, RatedPopulation, SelectedPopulation};
use time;

pub struct DriverConfig {
    pub mu: usize,
    pub lambda: usize,
    pub k: usize,
    pub ngen: usize,
    pub num_objectives: usize,
    pub parallel_weight: f64,
}

pub trait Driver: Sync
{
    type IND: Clone + Sync;
    type FIT: Dominate + MultiObjective + Clone + Send;

    fn random_individual<R>(&self, rng: &mut R) -> Self::IND where R: Rng;
    fn initial_population<R>(&self, rng: &mut R, n: usize) -> UnratedPopulation<Self::IND> where R: Rng {
        (0..n).map(|_| self.random_individual(rng)).collect()
    }
    fn fitness(&self, ind: &Self::IND) -> Self::FIT;
    fn mate<R>(&self, rng: &mut R, parent1: &Self::IND, parent2: &Self::IND) -> Self::IND where R: Rng;
    fn is_solution(&self, _ind: &Self::IND, _fit: &Self::FIT) -> bool {
        false
    }

    /// This can be used to update certain objectives in relation to the whole population.
    fn population_metric(&self, _population: &mut RatedPopulation<Self::IND, Self::FIT>) {
    }

    fn run<R, D, L>(&self,
                    rng: &mut R,
                    config: &DriverConfig,
                    domination: &mut D,
                    logger: &L)
                    -> SelectedPopulation<Self::IND, Self::FIT>
        where R: Rng,
              D: Domination<Self::FIT>,
              L: Fn(usize, u64, usize, &SelectedPopulation<Self::IND, Self::FIT>)
    {
        // this is generation 0. it's empty
        let mut time_last = time::precise_time_ns();
        let mut parents = SelectedPopulation::<Self::IND, Self::FIT>::new();
        let mut offspring = self.initial_population(rng, config.mu);
        assert!(offspring.len() == config.mu);
        let mut gen: usize = 0;

        loop {
            let rated_offspring = offspring.rate_in_parallel(&|ind| self.fitness(ind), config.parallel_weight);
            let mut next_generation = parents.merge(rated_offspring);
            // apply a population metric on the whole population
            self.population_metric(&mut next_generation);
            parents = next_generation.select(config.mu, config.num_objectives, domination);

            let mut found_solutions = 0;
            parents.all(&mut |ind, fit| {
                if self.is_solution(ind, fit) {
                    found_solutions += 1;
                }
            });

            let now = time::precise_time_ns();
            let duration = now - time_last;
            time_last = now;

            logger(gen, duration, found_solutions, &parents);

            if found_solutions > 0 {
                break;
            }

            gen += 1;
            if gen > config.ngen {
                break;
            }

            offspring = parents.reproduce(rng,
                                          config.lambda,
                                          config.k,
                                          &|rng, p1, p2| self.mate(rng, p1, p2));
        }

        return parents;
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::collections::HashMap;
use std::fmt;

#[derive(Debug)]
enum ParameterMode {
  Position,
  Immediate,
  Relative
}

#[derive(Debug)]
enum OperationType {
  Add,
  Multiply,
  Input,
  Output,
  JumpIfTrue,
  JumpIfFalse,
  LessThan,
  Equals,
  SetRelativeBase,
  Halt
}

#[derive(Debug)]
struct Instruction {
  operation: OperationType,
  inputs: Vec<(ParameterMode, i64)>
}

#[derive(Debug, Copy, Clone)]
enum ProgramResult {
  Output(i64),
  WaitForInput,
  Halt,
}

#[derive(Debug, PartialEq, Copy, Clone)]
enum Tile {
  Empty,
  Wall,
  Block,
  HorizontalPaddle,
  Ball
}

impl fmt::Display for Tile {
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    write!(f, "{}", match self {
      Tile::Empty => "  ",
      Tile::Wall => "##",
      Tile::Block => "[]",
      Tile::HorizontalPaddle => "==",
      Tile::Ball => "()",
    })
  }
}

type TileGrid = HashMap<(i64, i64), Tile>;

fn get_input() -> std::io::Result<String> {
  let mut file = File::open("13.txt")?;
  let mut contents = String::new();
  file.read_to_string(&mut contents)?;

  Ok(contents)
}

fn parse_instruction(numbers: &[i64]) -> Instruction {
  let instruction_code = numbers[0];
  let op_code = instruction_code % 100;

  let (operation, inputs_count) = match op_code {
    1 => (OperationType::Add, 3),
    2 => (OperationType::Multiply, 3),
    3 => (OperationType::Input, 1),
    4 => (OperationType::Output, 1),
    5 => (OperationType::JumpIfTrue, 2),
    6 => (OperationType::JumpIfFalse, 2),
    7 => (OperationType::LessThan, 3),
    8 => (OperationType::Equals, 3),
    9 => (OperationType::SetRelativeBase, 1),
    99 => (OperationType::Halt, 0),
    _ => panic!()
  };

  let get_parameter_mode = |i| {
    match (instruction_code - op_code) / 10i64.pow(2 + i as u32) % 10 {
      0 => ParameterMode::Position,
      1 => ParameterMode::Immediate,
      2 => ParameterMode::Relative,
      _ => panic!()
    }
  };

  Instruction {
    operation,
    inputs: (0..inputs_count)
      .map(|i| (get_parameter_mode(i), numbers[i + 1]))
      .collect()
  }
}

fn run_program(state: (&mut Vec<i64>, &mut usize, &mut usize), input: Option<i64>) -> ProgramResult {
  let (program, pointer, relative_base) = state;
  let mut input = input;

  fn extend_memory(program: &mut Vec<i64>, index: usize) {
    while index >= program.len() {
      program.push(0);
    }
  }

  fn get_instruction_input_index(
    program: &mut Vec<i64>,
    instruction: &Instruction,
    relative_base: usize,
    index: usize
  ) -> usize {
    match instruction.inputs[index] {
      (ParameterMode::Relative, d) => {
        let j = (relative_base as i64 + d) as usize;
        extend_memory(program, j);
        j
      },
      (_, j) => {
        extend_memory(program, j as usize);
        j as usize
      }
    }
  }

  fn get_instruction_input(
    program: &mut Vec<i64>,
    instruction: &Instruction,
    relative_base: usize,
    index: usize
  ) -> i64 {
    match instruction.inputs[index] {
      (ParameterMode::Immediate, value) => value,
      _ => {
        let j = get_instruction_input_index(program, instruction, relative_base, index);
        program[j]
      }
    }
  }

  while *pointer < program.len() {
    let init_pointer = *pointer;
    let instruction = parse_instruction(&program[*pointer..]);

    let (target_value, target_index) = {
      let mut get_input = |i| {
        get_instruction_input(program, &instruction, *relative_base, i)
      };

      let (target_value, output_index) = match instruction.operation {
        OperationType::Add => (Some(get_input(0) + get_input(1)), Some(2)),
        OperationType::Multiply => (Some(get_input(0) * get_input(1)), Some(2)),
        OperationType::Input => match input {
          Some(x) => {
            input = None;
            (Some(x), Some(0))
          },
          _ => return ProgramResult::WaitForInput
        },
        OperationType::Output => (Some(get_input(0)), None),
        OperationType::LessThan => (Some((get_input(0) < get_input(1)) as i64), Some(2)),
        OperationType::Equals => (Some((get_input(0) == get_input(1)) as i64), Some(2)),
        OperationType::JumpIfTrue => {
          if get_input(0) != 0 {
            *pointer = get_input(1) as usize;
          }

          (None, None)
        },
        OperationType::JumpIfFalse => {
          if get_input(0) == 0 {
            *pointer = get_input(1) as usize;
          }

          (None, None)
        },
        OperationType::SetRelativeBase => {
          *relative_base = (*relative_base as i64 + get_input(0)) as usize;
          (None, None)
        }
        OperationType::Halt => break
      };

      (
        target_value,
        output_index.map(|i| {
          get_instruction_input_index(program, &instruction, *relative_base, i)
        })
      )
    };

    if *pointer == init_pointer {
      *pointer += instruction.inputs.len() + 1;
    }

    if let Some(target_value) = target_value {
      if let Some(target_index) = target_index {
        extend_memory(program, target_index);
        program[target_index] = target_value;
      } else {
        return ProgramResult::Output(target_value);
      }
    }
  }

  ProgramResult::Halt
}

fn output_screen(state: (&mut Vec<i64>, &mut usize, &mut usize), input: Option<i64>) -> (TileGrid, Option<i64>, bool) {
  let mut result = TileGrid::new();
  let mut score = None;
  let mut input_iter = input.into_iter();
  let mut halted = false;

  loop {
    let mut get = |input| run_program((state.0, state.1, state.2), input);

    match (get(input_iter.next()), get(None), get(None)) {
      (ProgramResult::Output(x), ProgramResult::Output(y), ProgramResult::Output(value)) => {
        if (x, y) == (-1, 0) {
          score = Some(value);
        } else {
          result.insert((x, y), match value {
            0 => Tile::Empty,
            1 => Tile::Wall,
            2 => Tile::Block,
            3 => Tile::HorizontalPaddle,
            4 => Tile::Ball,
            _ => panic!()
          });
        }
      },
      (ProgramResult::WaitForInput, _, _) => break,
      (ProgramResult::Halt, _, _) => {
        halted = true;
        break;
      },
      _ => panic!()
    };
  }

  (result, score, halted)
}

fn render_screen(screen: &TileGrid) -> String {
  let mut result = String::new();
  let bounds = screen.keys().cloned()
    .fold((None, None, None, None), |(min_x, max_x, min_y, max_y), (x, y)| {
      (
        [min_x, Some(x)].into_iter().filter_map(|&x| x).min(),
        [max_x, Some(x)].into_iter().filter_map(|&x| x).max(),
        [min_y, Some(y)].into_iter().filter_map(|&y| y).min(),
        [max_y, Some(y)].into_iter().filter_map(|&y| y).max()
      )
    });

  if let (Some(min_x), Some(max_x), Some(min_y), Some(max_y)) = bounds {
    for y in min_y..=max_y {
      for x in min_x..=max_x {
        let tile = screen.get(&(x, y)).cloned().unwrap_or(Tile::Empty);

        result.push_str(&format!("{}", tile));
      }

      result.push('\n');
    }
  }

  result
}

fn play_game(state: (&mut Vec<i64>, &mut usize, &mut usize)) -> i64 {
  fn get_tile_position(screen: &TileGrid, tile: Tile) -> (i64, i64) {
    screen.iter()
    .find(|&(_, &t)| t == tile)
    .map(|(&position, _)| position)
    .unwrap()
  }

  let (mut screen, mut score, _) = output_screen((state.0, state.1, state.2), None);
  let mut joystick = 0;

  loop {
    let (screen_update, score_update, halted) = output_screen((state.0, state.1, state.2), Some(joystick));

    for (&(x, y), &tile) in screen_update.iter() {
      screen.insert((x, y), tile);
    }

    if let Some(_) = score_update {
      score = score_update;
    }

    let paddle_position = get_tile_position(&screen, Tile::HorizontalPaddle);
    let ball_position = get_tile_position(&screen, Tile::Ball);

    if ball_position.0 == paddle_position.0 {
      joystick = 0;
    } else if ball_position.0 < paddle_position.0 {
      joystick = -1;
    } else {
      joystick = 1;
    }

    if halted {
      break;
    }
  }

  score.unwrap_or(0)
}

fn main() {
  let input = get_input().unwrap();
  let numbers = input.split(',')
    .filter_map(|x| x.trim().parse::<i64>().ok())
    .collect::<Vec<_>>();

  let (screen, _, _) = output_screen((&mut numbers.clone(), &mut 0, &mut 0), None);
  let block_tile_count = screen.iter()
    .filter(|&(_, &tile)| match tile {
      Tile::Block => true,
      _ => false
    })
    .count();

  println!("Part 1: {}", block_tile_count);

  let mut program = numbers.clone();
  program[0] = 2;

  let score = play_game((&mut program, &mut 0, &mut 0));

  println!("Part 2: {}", score);
}
<commit_msg>Add option to print game state<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::collections::HashMap;
use std::{fmt, env, thread, time};

#[derive(Debug)]
enum ParameterMode {
  Position,
  Immediate,
  Relative
}

#[derive(Debug)]
enum OperationType {
  Add,
  Multiply,
  Input,
  Output,
  JumpIfTrue,
  JumpIfFalse,
  LessThan,
  Equals,
  SetRelativeBase,
  Halt
}

#[derive(Debug)]
struct Instruction {
  operation: OperationType,
  inputs: Vec<(ParameterMode, i64)>
}

#[derive(Debug, Copy, Clone)]
enum ProgramResult {
  Output(i64),
  WaitForInput,
  Halt,
}

#[derive(Debug, PartialEq, Copy, Clone)]
enum Tile {
  Empty,
  Wall,
  Block,
  HorizontalPaddle,
  Ball
}

impl fmt::Display for Tile {
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    write!(f, "{}", match self {
      Tile::Empty => "  ",
      Tile::Wall => "##",
      Tile::Block => "[]",
      Tile::HorizontalPaddle => "==",
      Tile::Ball => "()",
    })
  }
}

type TileGrid = HashMap<(i64, i64), Tile>;

fn get_input() -> std::io::Result<String> {
  let mut file = File::open("13.txt")?;
  let mut contents = String::new();
  file.read_to_string(&mut contents)?;

  Ok(contents)
}

fn parse_instruction(numbers: &[i64]) -> Instruction {
  let instruction_code = numbers[0];
  let op_code = instruction_code % 100;

  let (operation, inputs_count) = match op_code {
    1 => (OperationType::Add, 3),
    2 => (OperationType::Multiply, 3),
    3 => (OperationType::Input, 1),
    4 => (OperationType::Output, 1),
    5 => (OperationType::JumpIfTrue, 2),
    6 => (OperationType::JumpIfFalse, 2),
    7 => (OperationType::LessThan, 3),
    8 => (OperationType::Equals, 3),
    9 => (OperationType::SetRelativeBase, 1),
    99 => (OperationType::Halt, 0),
    _ => panic!()
  };

  let get_parameter_mode = |i| {
    match (instruction_code - op_code) / 10i64.pow(2 + i as u32) % 10 {
      0 => ParameterMode::Position,
      1 => ParameterMode::Immediate,
      2 => ParameterMode::Relative,
      _ => panic!()
    }
  };

  Instruction {
    operation,
    inputs: (0..inputs_count)
      .map(|i| (get_parameter_mode(i), numbers[i + 1]))
      .collect()
  }
}

fn run_program(state: (&mut Vec<i64>, &mut usize, &mut usize), input: Option<i64>) -> ProgramResult {
  let (program, pointer, relative_base) = state;
  let mut input = input;

  fn extend_memory(program: &mut Vec<i64>, index: usize) {
    while index >= program.len() {
      program.push(0);
    }
  }

  fn get_instruction_input_index(
    program: &mut Vec<i64>,
    instruction: &Instruction,
    relative_base: usize,
    index: usize
  ) -> usize {
    match instruction.inputs[index] {
      (ParameterMode::Relative, d) => {
        let j = (relative_base as i64 + d) as usize;
        extend_memory(program, j);
        j
      },
      (_, j) => {
        extend_memory(program, j as usize);
        j as usize
      }
    }
  }

  fn get_instruction_input(
    program: &mut Vec<i64>,
    instruction: &Instruction,
    relative_base: usize,
    index: usize
  ) -> i64 {
    match instruction.inputs[index] {
      (ParameterMode::Immediate, value) => value,
      _ => {
        let j = get_instruction_input_index(program, instruction, relative_base, index);
        program[j]
      }
    }
  }

  while *pointer < program.len() {
    let init_pointer = *pointer;
    let instruction = parse_instruction(&program[*pointer..]);

    let (target_value, target_index) = {
      let mut get_input = |i| {
        get_instruction_input(program, &instruction, *relative_base, i)
      };

      let (target_value, output_index) = match instruction.operation {
        OperationType::Add => (Some(get_input(0) + get_input(1)), Some(2)),
        OperationType::Multiply => (Some(get_input(0) * get_input(1)), Some(2)),
        OperationType::Input => match input {
          Some(x) => {
            input = None;
            (Some(x), Some(0))
          },
          _ => return ProgramResult::WaitForInput
        },
        OperationType::Output => (Some(get_input(0)), None),
        OperationType::LessThan => (Some((get_input(0) < get_input(1)) as i64), Some(2)),
        OperationType::Equals => (Some((get_input(0) == get_input(1)) as i64), Some(2)),
        OperationType::JumpIfTrue => {
          if get_input(0) != 0 {
            *pointer = get_input(1) as usize;
          }

          (None, None)
        },
        OperationType::JumpIfFalse => {
          if get_input(0) == 0 {
            *pointer = get_input(1) as usize;
          }

          (None, None)
        },
        OperationType::SetRelativeBase => {
          *relative_base = (*relative_base as i64 + get_input(0)) as usize;
          (None, None)
        }
        OperationType::Halt => break
      };

      (
        target_value,
        output_index.map(|i| {
          get_instruction_input_index(program, &instruction, *relative_base, i)
        })
      )
    };

    if *pointer == init_pointer {
      *pointer += instruction.inputs.len() + 1;
    }

    if let Some(target_value) = target_value {
      if let Some(target_index) = target_index {
        extend_memory(program, target_index);
        program[target_index] = target_value;
      } else {
        return ProgramResult::Output(target_value);
      }
    }
  }

  ProgramResult::Halt
}

fn output_screen(state: (&mut Vec<i64>, &mut usize, &mut usize), input: Option<i64>) -> (TileGrid, Option<i64>, bool) {
  let mut result = TileGrid::new();
  let mut score = None;
  let mut input_iter = input.into_iter();
  let mut halted = false;

  loop {
    let mut get = |input| run_program((state.0, state.1, state.2), input);

    match (get(input_iter.next()), get(None), get(None)) {
      (ProgramResult::Output(x), ProgramResult::Output(y), ProgramResult::Output(value)) => {
        if (x, y) == (-1, 0) {
          score = Some(value);
        } else {
          result.insert((x, y), match value {
            0 => Tile::Empty,
            1 => Tile::Wall,
            2 => Tile::Block,
            3 => Tile::HorizontalPaddle,
            4 => Tile::Ball,
            _ => panic!()
          });
        }
      },
      (ProgramResult::WaitForInput, _, _) => break,
      (ProgramResult::Halt, _, _) => {
        halted = true;
        break;
      },
      _ => panic!()
    };
  }

  (result, score, halted)
}

fn render_screen(screen: &TileGrid) -> String {
  let mut result = String::new();
  let bounds = screen.keys().cloned()
    .fold((None, None, None, None), |(min_x, max_x, min_y, max_y), (x, y)| {
      (
        [min_x, Some(x)].into_iter().filter_map(|&x| x).min(),
        [max_x, Some(x)].into_iter().filter_map(|&x| x).max(),
        [min_y, Some(y)].into_iter().filter_map(|&y| y).min(),
        [max_y, Some(y)].into_iter().filter_map(|&y| y).max()
      )
    });

  if let (Some(min_x), Some(max_x), Some(min_y), Some(max_y)) = bounds {
    for y in min_y..=max_y {
      for x in min_x..=max_x {
        let tile = screen.get(&(x, y)).cloned().unwrap_or(Tile::Empty);

        result.push_str(&format!("{}", tile));
      }

      result.push('\n');
    }
  }

  result
}

fn play_game(state: (&mut Vec<i64>, &mut usize, &mut usize), print: bool) -> i64 {
  fn get_tile_position(screen: &TileGrid, tile: Tile) -> (i64, i64) {
    screen.iter()
    .find(|&(_, &t)| t == tile)
    .map(|(&position, _)| position)
    .unwrap()
  }

  let (mut screen, mut score, _) = output_screen((state.0, state.1, state.2), None);
  let mut joystick = 0;

  loop {
    let (screen_update, score_update, halted) = output_screen((state.0, state.1, state.2), Some(joystick));

    for (&(x, y), &tile) in screen_update.iter() {
      screen.insert((x, y), tile);
    }

    if let Some(_) = score_update {
      score = score_update;
    }

    let paddle_position = get_tile_position(&screen, Tile::HorizontalPaddle);
    let ball_position = get_tile_position(&screen, Tile::Ball);

    if ball_position.0 == paddle_position.0 {
      joystick = 0;
    } else if ball_position.0 < paddle_position.0 {
      joystick = -1;
    } else {
      joystick = 1;
    }

    if print {
      println!("// Score: {}\n{}\n", score.unwrap_or(0), render_screen(&screen));
      thread::sleep(time::Duration::from_millis(20));
    }

    if halted {
      break;
    }
  }

  score.unwrap_or(0)
}

fn main() {
  let input = get_input().unwrap();
  let numbers = input.split(',')
    .filter_map(|x| x.trim().parse::<i64>().ok())
    .collect::<Vec<_>>();

  let (screen, _, _) = output_screen((&mut numbers.clone(), &mut 0, &mut 0), None);
  let block_tile_count = screen.iter()
    .filter(|&(_, &tile)| match tile {
      Tile::Block => true,
      _ => false
    })
    .count();

  println!("Part 1: {}", block_tile_count);

  let mut program = numbers.clone();
  program[0] = 2;

  let print_game = env::args().any(|s| s == "--print");
  let score = play_game((&mut program, &mut 0, &mut 0), print_game);

  println!("Part 2: {}", score);
}
<|endoftext|>


<commit_before>//! Implementation of support for the Enttec USB DMX Pro dongle.

use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fs;
use std::io::Write;
use std::time::Duration;
use std::{cmp::min, fmt};

use crate::{PortListing, PortOpener};

use super::{DmxPort, Error};
use serial::prelude::*;
use serial::{open, SystemPort};

// Some constants used for enttec message framing.
const START_VAL: u8 = 0x7E;
const END_VAL: u8 = 0xE7;

// Universe size constraints.
const MIN_UNIVERSE_SIZE: usize = 24;
const MAX_UNIVERSE_SIZE: usize = 512;

// Port action flags.
const SET_PARAMETERS: u8 = 4;
//const RECEIVE_DMX_PACKET: u8 = 5;
const SEND_DMX_PACKET: u8 = 6;

/// Format a byte buffer as an enttec message into the provided output buffer.
/// Maximum valid size for payload is 600; no check is made here that the payload is within this range.
fn make_packet(message_type: u8, payload: &[u8], output: &mut Vec<u8>) {
    // Enttec messages are the size of the payload plus 5 bytes for type, length, and framing.
    let payload_size = payload.len();
    output.clear();
    output.reserve(payload_size + 5);
    let (len_lsb, len_msb) = (payload_size as u8, (payload_size >> 8) as u8);
    output.push(START_VAL);
    output.push(message_type);
    output.push(len_lsb);
    output.push(len_msb);
    output.extend_from_slice(payload);
    output.push(END_VAL);
}

#[derive(Debug)]
pub struct EnttecParams {
    /// DMX output break time in 10.67 microsecond units. Valid range is 9 to 127.
    break_time: u8,
    /// DMX output Mark After Break time in 10.67 microsecond units. Valid range is 1 to 127.
    mark_after_break_time: u8,
    /// DMX output rate in packets per second. Valid range is 1 to 40, or 0 for fastest rate
    /// possible (this will make the most difference when the output universe size is smallest).
    output_rate: u8,
}

impl Default for EnttecParams {
    /// Default parameters for the enttec port.
    /// In summary: minimum break and mark times, fastest fixed framerate.
    fn default() -> Self {
        EnttecParams {
            break_time: 9,
            mark_after_break_time: 1,
            output_rate: 40,
        }
    }
}

impl EnttecParams {
    fn as_packet(&self, output: &mut Vec<u8>) {
        let payload = [
            self.break_time,
            self.mark_after_break_time,
            self.output_rate,
        ];
        make_packet(SET_PARAMETERS, &payload, output)
    }
}

pub struct EnttecDmxPort {
    params: EnttecParams,
    port: Option<SystemPort>,
    port_name: String,
    output_buffer: Vec<u8>,
}

impl EnttecDmxPort {
    /// Create an enttec port with the specified port name.
    /// The port is not opened yet.
    pub fn new<N: Into<String>>(port_name: N) -> Self {
        let port_name = port_name.into();

        let params = EnttecParams::default();

        Self {
            params: params,
            port: None,
            port_name: port_name,
            output_buffer: Vec::new(),
        }
    }

    /// Create an enttec port with the specified port name, and open it.
    pub fn opened<N: Into<String>>(port_name: N) -> Result<Self, Error> {
        let mut port = Self::new(port_name);
        port.open()?;
        Ok(port)
    }

    /// Write a packet to the port.
    /// If the port is not open, return an error.

    /// Write the current parameters out to the port.
    fn write_params(&mut self) -> Result<(), Error> {
        self.params.as_packet(&mut self.output_buffer);
        self.write_output_buffer()
    }

    fn write_output_buffer(&mut self) -> Result<(), Error> {
        match &mut self.port {
            Some(p) => p.write_all(&self.output_buffer)?,
            None => return Err(Error::PortClosed),
        }
        Ok(())
    }
}

#[typetag::serde]
impl DmxPort for EnttecDmxPort {
    /// Return the available enttec ports connected to this system.
    /// TODO: provide a mechanism to specialize this implementation depending on platform.
    fn available_ports() -> PortListing {
        match fs::read_dir("/dev/") {
            Err(_) => Vec::new(),
            Ok(dirs) => dirs
                .filter_map(|x| x.ok())
                .filter_map(|p| {
                    p.path().to_str().and_then(|p| {
                        if p.starts_with(ENTTEC_PATH_PREFIX) {
                            let port_name = p[ENTTEC_PATH_PREFIX.len()..].to_string();
                            let open_name = port_name.clone();
                            let opener: Box<PortOpener> = Box::new(move || {
                                EnttecDmxPort::opened(open_name.clone())
                                    .map(|p| Box::new(p) as Box<dyn DmxPort>)
                            });
                            Some((port_name, opener))
                        } else {
                            None
                        }
                    })
                })
                .collect(),
        }
    }

    /// Open the port.
    fn open(&mut self) -> Result<(), Error> {
        if self.port.is_some() {
            return Ok(());
        }

        let port_path = format!("{}{}", ENTTEC_PATH_PREFIX, self.port_name);
        let mut port = open(&port_path)?;

        // use a short 1 ms timeout to avoid blocking if, say, the port disappears
        port.set_timeout(Duration::from_millis(1))?;

        // send the default parameters to the port
        self.write_params()?;

        self.port = Some(port);
        Ok(())
    }

    fn close(&mut self) {
        self.port = None;
    }

    fn write(&mut self, frame: &[u8]) -> Result<(), Error> {
        let size = frame.len();
        if size < MIN_UNIVERSE_SIZE {
            let mut padded_frame = Vec::with_capacity(MIN_UNIVERSE_SIZE);
            padded_frame.extend_from_slice(frame);
            padded_frame.resize(MIN_UNIVERSE_SIZE, 0);
            make_packet(SEND_DMX_PACKET, &padded_frame, &mut self.output_buffer)
        } else {
            make_packet(
                SEND_DMX_PACKET,
                &frame[0..min(size, MAX_UNIVERSE_SIZE)],
                &mut self.output_buffer,
            )
        }

        self.write_output_buffer()
    }
}

impl Serialize for EnttecDmxPort {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        self.port_name.serialize(serializer)
    }
}

impl<'de> Deserialize<'de> for EnttecDmxPort {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        Ok(Self::new(String::deserialize(deserializer)?))
    }
}

const ENTTEC_PATH_PREFIX: &'static str = "/dev/tty.usbserial-";

impl fmt::Display for EnttecDmxPort {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.port_name)
    }
}
<commit_msg>Fix use-before-set bug in open method.<commit_after>//! Implementation of support for the Enttec USB DMX Pro dongle.

use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fs;
use std::io::Write;
use std::time::Duration;
use std::{cmp::min, fmt};

use crate::{PortListing, PortOpener};

use super::{DmxPort, Error};
use serial::prelude::*;
use serial::{open, SystemPort};

// Some constants used for enttec message framing.
const START_VAL: u8 = 0x7E;
const END_VAL: u8 = 0xE7;

// Universe size constraints.
const MIN_UNIVERSE_SIZE: usize = 24;
const MAX_UNIVERSE_SIZE: usize = 512;

// Port action flags.
const SET_PARAMETERS: u8 = 4;
//const RECEIVE_DMX_PACKET: u8 = 5;
const SEND_DMX_PACKET: u8 = 6;

/// Format a byte buffer as an enttec message into the provided output buffer.
/// Maximum valid size for payload is 600; no check is made here that the payload is within this range.
fn make_packet(message_type: u8, payload: &[u8], output: &mut Vec<u8>) {
    // Enttec messages are the size of the payload plus 5 bytes for type, length, and framing.
    let payload_size = payload.len();
    output.clear();
    output.reserve(payload_size + 5);
    let (len_lsb, len_msb) = (payload_size as u8, (payload_size >> 8) as u8);
    output.push(START_VAL);
    output.push(message_type);
    output.push(len_lsb);
    output.push(len_msb);
    output.extend_from_slice(payload);
    output.push(END_VAL);
}

#[derive(Debug)]
pub struct EnttecParams {
    /// DMX output break time in 10.67 microsecond units. Valid range is 9 to 127.
    break_time: u8,
    /// DMX output Mark After Break time in 10.67 microsecond units. Valid range is 1 to 127.
    mark_after_break_time: u8,
    /// DMX output rate in packets per second. Valid range is 1 to 40, or 0 for fastest rate
    /// possible (this will make the most difference when the output universe size is smallest).
    output_rate: u8,
}

impl Default for EnttecParams {
    /// Default parameters for the enttec port.
    /// In summary: minimum break and mark times, fastest fixed framerate.
    fn default() -> Self {
        EnttecParams {
            break_time: 9,
            mark_after_break_time: 1,
            output_rate: 40,
        }
    }
}

impl EnttecParams {
    fn as_packet(&self, output: &mut Vec<u8>) {
        let payload = [
            self.break_time,
            self.mark_after_break_time,
            self.output_rate,
        ];
        make_packet(SET_PARAMETERS, &payload, output)
    }
}

pub struct EnttecDmxPort {
    params: EnttecParams,
    port: Option<SystemPort>,
    port_name: String,
    output_buffer: Vec<u8>,
}

impl EnttecDmxPort {
    /// Create an enttec port with the specified port name.
    /// The port is not opened yet.
    pub fn new<N: Into<String>>(port_name: N) -> Self {
        let port_name = port_name.into();

        let params = EnttecParams::default();

        Self {
            params: params,
            port: None,
            port_name: port_name,
            output_buffer: Vec::new(),
        }
    }

    /// Create an enttec port with the specified port name, and open it.
    pub fn opened<N: Into<String>>(port_name: N) -> Result<Self, Error> {
        let mut port = Self::new(port_name);
        port.open()?;
        Ok(port)
    }

    /// Write the current parameters out to the port.
    fn write_params(&mut self) -> Result<(), Error> {
        self.params.as_packet(&mut self.output_buffer);
        self.write_output_buffer()
    }

    /// Write the current contents of the output buffer to the port.
    fn write_output_buffer(&mut self) -> Result<(), Error> {
        match &mut self.port {
            Some(p) => p.write_all(&self.output_buffer)?,
            None => return Err(Error::PortClosed),
        }
        Ok(())
    }
}

#[typetag::serde]
impl DmxPort for EnttecDmxPort {
    /// Return the available enttec ports connected to this system.
    /// TODO: provide a mechanism to specialize this implementation depending on platform.
    fn available_ports() -> PortListing {
        match fs::read_dir("/dev/") {
            Err(_) => Vec::new(),
            Ok(dirs) => dirs
                .filter_map(|x| x.ok())
                .filter_map(|p| {
                    p.path().to_str().and_then(|p| {
                        if p.starts_with(ENTTEC_PATH_PREFIX) {
                            let port_name = p[ENTTEC_PATH_PREFIX.len()..].to_string();
                            let open_name = port_name.clone();
                            let opener: Box<PortOpener> = Box::new(move || {
                                EnttecDmxPort::opened(open_name.clone())
                                    .map(|p| Box::new(p) as Box<dyn DmxPort>)
                            });
                            Some((port_name, opener))
                        } else {
                            None
                        }
                    })
                })
                .collect(),
        }
    }

    /// Open the port.
    fn open(&mut self) -> Result<(), Error> {
        if self.port.is_some() {
            return Ok(());
        }

        let port_path = format!("{}{}", ENTTEC_PATH_PREFIX, self.port_name);
        let mut port = open(&port_path)?;

        // use a short 1 ms timeout to avoid blocking if, say, the port disappears
        port.set_timeout(Duration::from_millis(1))?;

        self.port = Some(port);

        // send the default parameters to the port
        if let Err(e) = self.write_params() {
            self.port = None;
            return Err(e);
        }
        Ok(())
    }

    fn close(&mut self) {
        self.port = None;
    }

    fn write(&mut self, frame: &[u8]) -> Result<(), Error> {
        let size = frame.len();
        if size < MIN_UNIVERSE_SIZE {
            let mut padded_frame = Vec::with_capacity(MIN_UNIVERSE_SIZE);
            padded_frame.extend_from_slice(frame);
            padded_frame.resize(MIN_UNIVERSE_SIZE, 0);
            make_packet(SEND_DMX_PACKET, &padded_frame, &mut self.output_buffer)
        } else {
            make_packet(
                SEND_DMX_PACKET,
                &frame[0..min(size, MAX_UNIVERSE_SIZE)],
                &mut self.output_buffer,
            )
        }

        self.write_output_buffer()
    }
}

impl Serialize for EnttecDmxPort {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        self.port_name.serialize(serializer)
    }
}

impl<'de> Deserialize<'de> for EnttecDmxPort {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        Ok(Self::new(String::deserialize(deserializer)?))
    }
}

const ENTTEC_PATH_PREFIX: &'static str = "/dev/tty.usbserial-";

impl fmt::Display for EnttecDmxPort {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.port_name)
    }
}
<|endoftext|>


<commit_before>extern crate inkwell;

use self::inkwell::context::Context;
use self::inkwell::module::Module;
use self::inkwell::targets::{
    CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine,
};
use self::inkwell::types::IntType;
use self::inkwell::values::BasicValue;
use self::inkwell::OptimizationLevel;

#[llvm_versions(4.0..=latest)]
fn get_host_cpu_name() -> String {
    TargetMachine::get_host_cpu_name().to_string()
}
#[llvm_versions(4.0..=latest)]
fn get_host_cpu_features() -> String {
    TargetMachine::get_host_cpu_features().to_string()
}
#[llvm_versions(4.0..=latest)]
fn ptr_sized_int_type<'ctx>(
    target_machine: &TargetMachine,
    context: &'ctx Context,
) -> IntType<'ctx> {
    let target_data = target_machine.get_target_data();
    target_data.ptr_sized_int_type_in_context(&context, None)
}
#[llvm_versions(4.0..=latest)]
fn apply_target_to_module<'ctx>(target_machine: &TargetMachine, module: &Module) {
    module.set_triple(&target_machine.get_triple());
    module.set_data_layout(&target_machine.get_target_data().get_data_layout());
}

#[llvm_versions(3.6..4.0)]
fn get_host_cpu_name() -> String {
    "".to_string()
}
#[llvm_versions(3.6..4.0)]
fn get_host_cpu_features() -> String {
    "".to_string()
}
#[llvm_versions(3.6..4.0)]
fn ptr_sized_int_type<'ctx>(
    _target_machine: &TargetMachine,
    context: &'ctx Context,
) -> IntType<'ctx> {
    context.i64_type()
}
#[llvm_versions(3.6..4.0)]
fn apply_target_to_module(target_machine: &TargetMachine, module: &Module) {
    module.set_triple(&target_machine.get_triple());
}

fn get_native_target_machine() -> TargetMachine {
    Target::initialize_native(&InitializationConfig::default())
        .expect("Failed to initialize native target");
    let target_triple = TargetMachine::get_default_triple();
    let target = Target::from_triple(&target_triple).unwrap();
    target
        .create_target_machine(
            &target_triple,
            &get_host_cpu_name(),
            &get_host_cpu_features(),
            OptimizationLevel::None,
            RelocMode::Default,
            CodeModel::Default,
        )
        .unwrap()
}

#[test]
fn test_section_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let mut module = context.create_module("test_section_iterator");

    let gv_a = module.add_global(context.i8_type(), None, "a");
    gv_a.set_initializer(&context.i8_type().const_zero().as_basic_value_enum());
    gv_a.set_section("A");

    let gv_b = module.add_global(context.i16_type(), None, "b");
    gv_b.set_initializer(&context.i16_type().const_zero().as_basic_value_enum());
    gv_b.set_section("B");

    let gv_c = module.add_global(context.i32_type(), None, "c");
    gv_c.set_initializer(&context.i32_type().const_zero().as_basic_value_enum());
    gv_c.set_section("C");

    apply_target_to_module(&target_machine, &module);

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut has_section_a = false;
    let mut has_section_b = false;
    let mut has_section_c = false;
    for section in object_file.get_sections() {
        if let Some(name) = section.get_name() {
            match name.to_str().unwrap() {
                "A" => {
                    assert!(!has_section_a);
                    has_section_a = true;
                    assert_eq!(section.size(), 1);
                }
                "B" => {
                    assert!(!has_section_b);
                    has_section_b = true;
                    assert_eq!(section.size(), 2);
                }
                "C" => {
                    assert!(!has_section_c);
                    has_section_c = true;
                    assert_eq!(section.size(), 4);
                }
                _ => {}
            }
        }
    }
    assert!(has_section_a);
    assert!(has_section_b);
    assert!(has_section_c);
}

#[test]
fn test_symbol_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let mut module = context.create_module("test_symbol_iterator");
    module
        .add_global(context.i8_type(), None, "a")
        .set_initializer(&context.i8_type().const_zero().as_basic_value_enum());
    module
        .add_global(context.i16_type(), None, "b")
        .set_initializer(&context.i16_type().const_zero().as_basic_value_enum());
    module
        .add_global(context.i32_type(), None, "c")
        .set_initializer(&context.i32_type().const_zero().as_basic_value_enum());
    apply_target_to_module(&target_machine, &module);

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut has_symbol_a = false;
    let mut has_symbol_b = false;
    let mut has_symbol_c = false;
    for symbol in object_file.get_symbols() {
        if let Some(name) = symbol.get_name() {
            match name.to_str().unwrap() {
                "a" => {
                    assert!(!has_symbol_a);
                    has_symbol_a = true;
                    assert_eq!(symbol.size(), 1);
                }
                "b" => {
                    assert!(!has_symbol_b);
                    has_symbol_b = true;
                    assert_eq!(symbol.size(), 2);
                }
                "c" => {
                    assert!(!has_symbol_c);
                    has_symbol_c = true;
                    assert_eq!(symbol.size(), 4);
                }
                _ => {}
            }
        }
    }
    assert!(has_symbol_a);
    assert!(has_symbol_b);
    assert!(has_symbol_c);
}

#[test]
fn test_reloc_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let intptr_t = ptr_sized_int_type(&target_machine, &context);

    let mut module = context.create_module("test_reloc_iterator");
    let x_ptr = module
        .add_global(context.i8_type(), None, "x")
        .as_pointer_value();
    let x_plus_4 = x_ptr
        .const_to_int(intptr_t)
        .const_add(intptr_t.const_int(4, false));
    module
        .add_global(intptr_t, None, "a")
        .set_initializer(&x_plus_4);

    apply_target_to_module(&target_machine, &module);

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut found_relocation = false;
    for section in object_file.get_sections() {
        for _ in section.get_relocations() {
            found_relocation = true;
            // We don't stop the traversal here, so as to exercise the iterators.
        }
    }
    assert!(found_relocation);
}
<commit_msg>get_host_cpu_{name,features} were added in LLVM 7.<commit_after>extern crate inkwell;

use self::inkwell::context::Context;
use self::inkwell::module::Module;
use self::inkwell::targets::{
    CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine,
};
use self::inkwell::types::IntType;
use self::inkwell::values::BasicValue;
use self::inkwell::OptimizationLevel;

#[llvm_versions(7.0..=latest)]
fn get_host_cpu_name() -> String {
    TargetMachine::get_host_cpu_name().to_string()
}
#[llvm_versions(7.0..=latest)]
fn get_host_cpu_features() -> String {
    TargetMachine::get_host_cpu_features().to_string()
}
#[llvm_versions(4.0..=latest)]
fn ptr_sized_int_type<'ctx>(
    target_machine: &TargetMachine,
    context: &'ctx Context,
) -> IntType<'ctx> {
    let target_data = target_machine.get_target_data();
    target_data.ptr_sized_int_type_in_context(&context, None)
}
#[llvm_versions(4.0..=latest)]
fn apply_target_to_module<'ctx>(target_machine: &TargetMachine, module: &Module) {
    module.set_triple(&target_machine.get_triple());
    module.set_data_layout(&target_machine.get_target_data().get_data_layout());
}

#[llvm_versions(3.6..7.0)]
fn get_host_cpu_name() -> String {
    "".to_string()
}
#[llvm_versions(3.6..7.0)]
fn get_host_cpu_features() -> String {
    "".to_string()
}
#[llvm_versions(3.6..4.0)]
fn ptr_sized_int_type<'ctx>(
    _target_machine: &TargetMachine,
    context: &'ctx Context,
) -> IntType<'ctx> {
    context.i64_type()
}
#[llvm_versions(3.6..4.0)]
fn apply_target_to_module(target_machine: &TargetMachine, module: &Module) {
    module.set_triple(&target_machine.get_triple());
}

fn get_native_target_machine() -> TargetMachine {
    Target::initialize_native(&InitializationConfig::default())
        .expect("Failed to initialize native target");
    let target_triple = TargetMachine::get_default_triple();
    let target = Target::from_triple(&target_triple).unwrap();
    target
        .create_target_machine(
            &target_triple,
            &get_host_cpu_name(),
            &get_host_cpu_features(),
            OptimizationLevel::None,
            RelocMode::Default,
            CodeModel::Default,
        )
        .unwrap()
}

#[test]
fn test_section_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let mut module = context.create_module("test_section_iterator");

    let gv_a = module.add_global(context.i8_type(), None, "a");
    gv_a.set_initializer(&context.i8_type().const_zero().as_basic_value_enum());
    gv_a.set_section("A");

    let gv_b = module.add_global(context.i16_type(), None, "b");
    gv_b.set_initializer(&context.i16_type().const_zero().as_basic_value_enum());
    gv_b.set_section("B");

    let gv_c = module.add_global(context.i32_type(), None, "c");
    gv_c.set_initializer(&context.i32_type().const_zero().as_basic_value_enum());
    gv_c.set_section("C");

    apply_target_to_module(&target_machine, &module);

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut has_section_a = false;
    let mut has_section_b = false;
    let mut has_section_c = false;
    for section in object_file.get_sections() {
        if let Some(name) = section.get_name() {
            match name.to_str().unwrap() {
                "A" => {
                    assert!(!has_section_a);
                    has_section_a = true;
                    assert_eq!(section.size(), 1);
                }
                "B" => {
                    assert!(!has_section_b);
                    has_section_b = true;
                    assert_eq!(section.size(), 2);
                }
                "C" => {
                    assert!(!has_section_c);
                    has_section_c = true;
                    assert_eq!(section.size(), 4);
                }
                _ => {}
            }
        }
    }
    assert!(has_section_a);
    assert!(has_section_b);
    assert!(has_section_c);
}

#[test]
fn test_symbol_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let mut module = context.create_module("test_symbol_iterator");
    module
        .add_global(context.i8_type(), None, "a")
        .set_initializer(&context.i8_type().const_zero().as_basic_value_enum());
    module
        .add_global(context.i16_type(), None, "b")
        .set_initializer(&context.i16_type().const_zero().as_basic_value_enum());
    module
        .add_global(context.i32_type(), None, "c")
        .set_initializer(&context.i32_type().const_zero().as_basic_value_enum());
    apply_target_to_module(&target_machine, &module);

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut has_symbol_a = false;
    let mut has_symbol_b = false;
    let mut has_symbol_c = false;
    for symbol in object_file.get_symbols() {
        if let Some(name) = symbol.get_name() {
            match name.to_str().unwrap() {
                "a" => {
                    assert!(!has_symbol_a);
                    has_symbol_a = true;
                    assert_eq!(symbol.size(), 1);
                }
                "b" => {
                    assert!(!has_symbol_b);
                    has_symbol_b = true;
                    assert_eq!(symbol.size(), 2);
                }
                "c" => {
                    assert!(!has_symbol_c);
                    has_symbol_c = true;
                    assert_eq!(symbol.size(), 4);
                }
                _ => {}
            }
        }
    }
    assert!(has_symbol_a);
    assert!(has_symbol_b);
    assert!(has_symbol_c);
}

#[test]
fn test_reloc_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let intptr_t = ptr_sized_int_type(&target_machine, &context);

    let mut module = context.create_module("test_reloc_iterator");
    let x_ptr = module
        .add_global(context.i8_type(), None, "x")
        .as_pointer_value();
    let x_plus_4 = x_ptr
        .const_to_int(intptr_t)
        .const_add(intptr_t.const_int(4, false));
    module
        .add_global(intptr_t, None, "a")
        .set_initializer(&x_plus_4);

    apply_target_to_module(&target_machine, &module);

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut found_relocation = false;
    for section in object_file.get_sections() {
        for _ in section.get_relocations() {
            found_relocation = true;
            // We don't stop the traversal here, so as to exercise the iterators.
        }
    }
    assert!(found_relocation);
}
<|endoftext|>


<commit_before>//! Common filesystem errors.
//!
//! This module provides convenience functions for generating [`io::Error`]s from OS error codes.
//! Notably, these errors are the only errors returned in the [`mem`] module if using implemented
//! behavior (unimplemented behavior returns `Error::new::ErrorKind::Other`).
//!
//! [`io::Error`]: https://doc.rust-lang.org/std/io/struct.Error.html
//! [`mem`]: ../mem/index.html

use std::io::Error;

/// Used when a file or directory does not exist.
#[allow(non_snake_case)]
pub fn ENOENT() -> Error {
    Error::from_raw_os_error(2)
}

/// Used when performing an operation with a file that was not opened in a way to allow that
/// operation (read on a write only open, etc).
#[allow(non_snake_case)]
pub fn EBADF() -> Error {
    Error::from_raw_os_error(9)
}

/// Used when a user does not have requisite permissions.
#[allow(non_snake_case)]
pub fn EACCES() -> Error {
    Error::from_raw_os_error(13)
}

/// Used when a file or directory does not exist.
#[allow(non_snake_case)]
pub fn EEXIST() -> Error {
    Error::from_raw_os_error(17)
}

/// Used when attempting to perform a directory operation on a file.
#[allow(non_snake_case)]
pub fn ENOTDIR() -> Error {
    Error::from_raw_os_error(20)
}

/// Used when attempting to perform a file operation on a directory.
#[allow(non_snake_case)]
pub fn EISDIR() -> Error {
    Error::from_raw_os_error(21)
}

/// Used when performing an invalid operation (aka, a bad OpenOptions combination).
#[allow(non_snake_case)]
pub fn EINVAL() -> Error {
    Error::from_raw_os_error(22)
}

/// Used when an operation needs an empty directory and is performed on a non-empty directory.
#[allow(non_snake_case)]
pub fn ENOTEMPTY() -> Error {
    // TODO Windows is 41, other Unix / BSD distros differ from 39.
    Error::from_raw_os_error(39)
}
<commit_msg>errors: use backticks in doc<commit_after>//! Common filesystem errors.
//!
//! This module provides convenience functions for generating [`io::Error`]s from OS error codes.
//! Notably, these errors are the only errors returned in the [`mem`] module if using implemented
//! behavior (unimplemented behavior returns `Error::new::ErrorKind::Other`).
//!
//! [`io::Error`]: https://doc.rust-lang.org/std/io/struct.Error.html
//! [`mem`]: ../mem/index.html

use std::io::Error;

/// Used when a file or directory does not exist.
#[allow(non_snake_case)]
pub fn ENOENT() -> Error {
    Error::from_raw_os_error(2)
}

/// Used when performing an operation with a file that was not opened in a way to allow that
/// operation (read on a write only open, etc).
#[allow(non_snake_case)]
pub fn EBADF() -> Error {
    Error::from_raw_os_error(9)
}

/// Used when a user does not have requisite permissions.
#[allow(non_snake_case)]
pub fn EACCES() -> Error {
    Error::from_raw_os_error(13)
}

/// Used when a file or directory does not exist.
#[allow(non_snake_case)]
pub fn EEXIST() -> Error {
    Error::from_raw_os_error(17)
}

/// Used when attempting to perform a directory operation on a file.
#[allow(non_snake_case)]
pub fn ENOTDIR() -> Error {
    Error::from_raw_os_error(20)
}

/// Used when attempting to perform a file operation on a directory.
#[allow(non_snake_case)]
pub fn EISDIR() -> Error {
    Error::from_raw_os_error(21)
}

/// Used when performing an invalid operation (aka, a bad `OpenOptions` combination).
#[allow(non_snake_case)]
pub fn EINVAL() -> Error {
    Error::from_raw_os_error(22)
}

/// Used when an operation needs an empty directory and is performed on a non-empty directory.
#[allow(non_snake_case)]
pub fn ENOTEMPTY() -> Error {
    // TODO Windows is 41, other Unix / BSD distros differ from 39.
    Error::from_raw_os_error(39)
}
<|endoftext|>


<commit_before>use std::io::Error as IoError;
use reqwest::Error as HttpError;
use reqwest::StatusCode;
use serde_json::error::Error as SerdeError;
use super::Errors;

/// an enumeration over potential errors
/// that may happen when sending a request to jira
#[derive(Debug)]
pub enum Error {
    /// error associated with http request
    Http(HttpError),
    /// error associated IO
    IO(IoError),
    /// error associated with parsing or serializing
    Serde(SerdeError),
    /// client request errors
    Fault { code: StatusCode, errors: Errors },
    /// invalid credentials
    Unauthorized,
}

impl From<SerdeError> for Error {
    fn from(error: SerdeError) -> Error {
        Error::Serde(error)
    }
}

impl From<HttpError> for Error {
    fn from(error: HttpError) -> Error {
        Error::Http(error)
    }
}

impl From<IoError> for Error {
    fn from(error: IoError) -> Error {
        Error::IO(error)
    }
}
<commit_msg>Implement std::error::Error for goji::Error<commit_after>use std::io::Error as IoError;
use reqwest::Error as HttpError;
use reqwest::StatusCode;
use serde_json::error::Error as SerdeError;
use super::Errors;

/// an enumeration over potential errors
/// that may happen when sending a request to jira
#[derive(Debug)]
pub enum Error {
    /// error associated with http request
    Http(HttpError),
    /// error associated IO
    IO(IoError),
    /// error associated with parsing or serializing
    Serde(SerdeError),
    /// client request errors
    Fault { code: StatusCode, errors: Errors },
    /// invalid credentials
    Unauthorized,
}

impl From<SerdeError> for Error {
    fn from(error: SerdeError) -> Error {
        Error::Serde(error)
    }
}

impl From<HttpError> for Error {
    fn from(error: HttpError) -> Error {
        Error::Http(error)
    }
}

impl From<IoError> for Error {
    fn from(error: IoError) -> Error {
        Error::IO(error)
    }
}

impl ::std::fmt::Display for Error {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        use Error::*;
        match self {
            &Http(ref e) => writeln!(f, "Http Error: {}", e),
            &IO(ref e) => writeln!(f, "IO Error: {}", e),
            &Serde(ref e) => writeln!(f, "Serialization Error: {}", e),
            &Fault { ref code, ref errors } => writeln!(f, "Jira Client Error ({}):\n{:#?}", code, errors),
            &Unauthorized => writeln!(f, "Could not connect to Jira: Unauthorized!"),
        }
    }
}

impl ::std::error::Error for Error {
    fn description(&self) -> &str {
        use Error::*;
        match self {
            &Http(ref e) => e.description(),
            &IO(ref e) => e.description(),
            &Serde(ref e) => e.description(),
            &Fault { .. } => "Jira client error",
            &Unauthorized => "Unauthorized",
        }
    }

    fn cause(&self) -> Option<&::std::error::Error> {
        use Error::*;
        match self {
            &Http(ref e) => Some(e),
            &IO(ref e) => Some(e),
            &Serde(ref e) => Some(e),
            &Fault { .. } => None,
            &Unauthorized => None,
        }
    }
}
<|endoftext|>


<commit_before>use utils::json::{JsonEncodable, JsonDecodable};

#[derive(Serialize, Deserialize, Clone)]
pub struct MyDidInfo {
    pub did: Option<String>,
    pub seed: Option<String>,
    pub crypto_type: Option<String>,
    pub cid: Option<bool>
}

impl MyDidInfo {
    pub fn new(did: Option<String>, seed: Option<String>,
               crypto_type: Option<String>, cid: Option<bool>) -> MyDidInfo {
        MyDidInfo {
            did: did,
            seed: seed,
            crypto_type: crypto_type,
            cid: cid
        }
    }
}

impl JsonEncodable for MyDidInfo {}

impl<'a> JsonDecodable<'a> for MyDidInfo {}

#[derive(Serialize, Deserialize)]
pub struct MyKyesInfo {
    pub seed: Option<String>,
    pub crypto_type: Option<String>
}

impl MyKyesInfo {
    pub fn new(seed: Option<String>, crypto_type: Option<String>) -> MyKyesInfo {
        MyKyesInfo {
            seed: seed,
            crypto_type: crypto_type
        }
    }
}

impl JsonEncodable for MyKyesInfo {}

impl<'a> JsonDecodable<'a> for MyKyesInfo {}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct MyDid {
    pub did: String,
    pub crypto_type: String,
    pub pk: String,
    pub sk: String,
    pub verkey: String,
    pub signkey: String
}

impl MyDid {
    pub fn new(did: String, crypto_type: String, pk: String, sk: String, verkey: String, signkey: String) -> MyDid {
        MyDid {
            did: did,
            crypto_type: crypto_type,
            pk: pk,
            sk: sk,
            verkey: verkey,
            signkey: signkey
        }
    }
}

impl JsonEncodable for MyDid {}

impl<'a> JsonDecodable<'a> for MyDid {}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TheirDidInfo {
    pub did: String,
    pub crypto_type: Option<String>,
    pub verkey: Option<String>,
    pub endpoint: Option<String>,
}

impl TheirDidInfo {
    pub fn new(did: String, crypto_type: Option<String>, verkey: Option<String>, endpoint: Option<String>) -> TheirDidInfo {
        TheirDidInfo {
            did: did,
            crypto_type: crypto_type,
            verkey: verkey,
            endpoint: endpoint,
        }
    }
}

impl JsonEncodable for TheirDidInfo {}

impl<'a> JsonDecodable<'a> for TheirDidInfo {}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TheirDid {
    pub did: String,
    pub crypto_type: String,
    pub verkey: Option<String>,
    pub pk: Option<String>,
    pub endpoint: Option<String>,
}

impl TheirDid {
    pub fn new(did: String, crypto_type: String, verkey: Option<String>, pk: Option<String>, endpoint: Option<String>) -> TheirDid {
        TheirDid {
            did: did,
            crypto_type: crypto_type,
            verkey: verkey,
            pk: pk,
            endpoint: endpoint,
        }
    }
}

impl JsonEncodable for TheirDid {}

impl<'a> JsonDecodable<'a> for TheirDid {}

#[derive(Serialize, Deserialize)]
pub struct DidPair {
    pub my_did: String,
    pub their_did: String
}

impl DidPair {
    pub fn new(my_did: String, their_did: String) -> DidPair {
        DidPair {
            my_did: my_did,
            their_did: their_did
        }
    }
}

impl JsonEncodable for DidPair {}

impl<'a> JsonDecodable<'a> for DidPair {}<commit_msg>Deleted unused struct<commit_after>use utils::json::{JsonEncodable, JsonDecodable};

#[derive(Serialize, Deserialize, Clone)]
pub struct MyDidInfo {
    pub did: Option<String>,
    pub seed: Option<String>,
    pub crypto_type: Option<String>,
    pub cid: Option<bool>
}

impl MyDidInfo {
    pub fn new(did: Option<String>, seed: Option<String>,
               crypto_type: Option<String>, cid: Option<bool>) -> MyDidInfo {
        MyDidInfo {
            did: did,
            seed: seed,
            crypto_type: crypto_type,
            cid: cid
        }
    }
}

impl JsonEncodable for MyDidInfo {}

impl<'a> JsonDecodable<'a> for MyDidInfo {}

#[derive(Serialize, Deserialize)]
pub struct MyKyesInfo {
    pub seed: Option<String>,
    pub crypto_type: Option<String>
}

impl MyKyesInfo {
    pub fn new(seed: Option<String>, crypto_type: Option<String>) -> MyKyesInfo {
        MyKyesInfo {
            seed: seed,
            crypto_type: crypto_type
        }
    }
}

impl JsonEncodable for MyKyesInfo {}

impl<'a> JsonDecodable<'a> for MyKyesInfo {}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct MyDid {
    pub did: String,
    pub crypto_type: String,
    pub pk: String,
    pub sk: String,
    pub verkey: String,
    pub signkey: String
}

impl MyDid {
    pub fn new(did: String, crypto_type: String, pk: String, sk: String, verkey: String, signkey: String) -> MyDid {
        MyDid {
            did: did,
            crypto_type: crypto_type,
            pk: pk,
            sk: sk,
            verkey: verkey,
            signkey: signkey
        }
    }
}

impl JsonEncodable for MyDid {}

impl<'a> JsonDecodable<'a> for MyDid {}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TheirDidInfo {
    pub did: String,
    pub crypto_type: Option<String>,
    pub verkey: Option<String>,
    pub endpoint: Option<String>,
}

impl TheirDidInfo {
    pub fn new(did: String, crypto_type: Option<String>, verkey: Option<String>, endpoint: Option<String>) -> TheirDidInfo {
        TheirDidInfo {
            did: did,
            crypto_type: crypto_type,
            verkey: verkey,
            endpoint: endpoint,
        }
    }
}

impl JsonEncodable for TheirDidInfo {}

impl<'a> JsonDecodable<'a> for TheirDidInfo {}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TheirDid {
    pub did: String,
    pub crypto_type: String,
    pub verkey: Option<String>,
    pub pk: Option<String>,
    pub endpoint: Option<String>,
}

impl TheirDid {
    pub fn new(did: String, crypto_type: String, verkey: Option<String>, pk: Option<String>, endpoint: Option<String>) -> TheirDid {
        TheirDid {
            did: did,
            crypto_type: crypto_type,
            verkey: verkey,
            pk: pk,
            endpoint: endpoint,
        }
    }
}

impl JsonEncodable for TheirDid {}

impl<'a> JsonDecodable<'a> for TheirDid {}<|endoftext|>


<commit_before>//! Emscripten-specific raw type definitions
//! This is basically exactly the same as the linux definitions,
//! except using the musl-specific stat64 structure in liblibc.

#![stable(feature = "raw_ext", since = "1.1.0")]
#![rustc_deprecated(
    since = "1.8.0",
    reason = "these type aliases are no longer supported by \
              the standard library, the `libc` crate on \
              crates.io should be used instead for the correct \
              definitions"
)]
#![allow(deprecated)]

use crate::os::raw::{c_long, c_short, c_uint, c_ulong};

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type dev_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type mode_t = u32;

#[stable(feature = "pthread_t", since = "1.8.0")]
pub type pthread_t = c_ulong;

#[doc(inline)]
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blkcnt_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blksize_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type ino_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type nlink_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type off_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type time_t = c_long;

#[repr(C)]
#[derive(Clone)]
#[stable(feature = "raw_ext", since = "1.1.0")]
pub struct stat {
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_dev: u64,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub __pad1: c_short,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub __st_ino: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mode: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_nlink: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_uid: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_gid: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_rdev: u64,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub __pad2: c_uint,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_size: i64,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_blksize: i32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_blocks: i64,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_atime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_atime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mtime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mtime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ctime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ctime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ino: u64,
}
<commit_msg>Remove an invalid `#[doc(inline)]`<commit_after>//! Emscripten-specific raw type definitions
//! This is basically exactly the same as the linux definitions,
//! except using the musl-specific stat64 structure in liblibc.

#![stable(feature = "raw_ext", since = "1.1.0")]
#![rustc_deprecated(
    since = "1.8.0",
    reason = "these type aliases are no longer supported by \
              the standard library, the `libc` crate on \
              crates.io should be used instead for the correct \
              definitions"
)]
#![allow(deprecated)]

use crate::os::raw::{c_long, c_short, c_uint, c_ulong};

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type dev_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type mode_t = u32;

#[stable(feature = "pthread_t", since = "1.8.0")]
pub type pthread_t = c_ulong;

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blkcnt_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blksize_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type ino_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type nlink_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type off_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type time_t = c_long;

#[repr(C)]
#[derive(Clone)]
#[stable(feature = "raw_ext", since = "1.1.0")]
pub struct stat {
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_dev: u64,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub __pad1: c_short,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub __st_ino: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mode: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_nlink: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_uid: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_gid: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_rdev: u64,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub __pad2: c_uint,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_size: i64,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_blksize: i32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_blocks: i64,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_atime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_atime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mtime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mtime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ctime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ctime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ino: u64,
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(clippy)]

#![allow(unused)]
#![deny(clippy, clippy_pedantic)]

use std::ops::Mul;

struct T;

impl T {
    fn add(self, other: T) -> T { self } //~ERROR defining a method called `add`
    fn drop(&mut self) { } //~ERROR defining a method called `drop`

    fn sub(&self, other: T) -> &T { self } // no error, self is a ref
    fn div(self) -> T { self } // no error, different #arguments
    fn rem(self, other: T) { } // no error, wrong return type

    fn into_u32(self) -> u32 { 0 } // fine
    fn into_u16(&self) -> u16 { 0 } //~ERROR methods called `into_*` usually take self by value

    fn to_something(self) -> u32 { 0 } //~ERROR methods called `to_*` usually take self by reference
}

#[derive(Clone,Copy)]
struct U;

impl U {
    fn to_something(self) -> u32 { 0 } // ok because U is Copy
}

impl Mul<T> for T {
    type Output = T;
    fn mul(self, other: T) -> T { self } // no error, obviously
}

/// Utility macro to test linting behavior in `option_methods()`
/// The lints included in `option_methods()` should not lint if the call to map is partially
/// within a macro
macro_rules! opt_map {
    ($opt:expr, $map:expr) => {($opt).map($map)};
}

/// Checks implementation of the following lints:
/// OPTION_MAP_UNWRAP_OR
/// OPTION_MAP_UNWRAP_OR_ELSE
fn option_methods() {
    let opt = Some(1);

    // Check OPTION_MAP_UNWRAP_OR
    // single line case
    let _ = opt.map(|x| x + 1) //~  ERROR called `map(f).unwrap_or(a)`
                               //~| NOTE replace `map(|x| x + 1).unwrap_or(0)`
               .unwrap_or(0); // should lint even though this call is on a separate line
    // multi line cases
    let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or(a)`
                        x + 1
                    }
              ).unwrap_or(0);
    let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or(a)`
               .unwrap_or({
                    0
                });
    // macro case
    let _ = opt_map!(opt, |x| x + 1).unwrap_or(0); // should not lint

    // Check OPTION_MAP_UNWRAP_OR_ELSE
    // single line case
    let _ = opt.map(|x| x + 1) //~  ERROR called `map(f).unwrap_or_else(g)`
                               //~| NOTE replace `map(|x| x + 1).unwrap_or_else(|| 0)`
               .unwrap_or_else(|| 0); // should lint even though this call is on a separate line
    // multi line cases
    let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or_else(g)`
                        x + 1
                    }
              ).unwrap_or_else(|| 0);
    let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or_else(g)`
               .unwrap_or_else(||
                    0
                );
    // macro case
    let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0); // should not lint

}

/// Struct to generate false positive for Iterator-based lints
#[derive(Copy, Clone)]
struct IteratorFalsePositives {
    foo: u32,
}

impl IteratorFalsePositives {
    fn filter(self) -> IteratorFalsePositives {
        self
    }

    fn next(self) -> IteratorFalsePositives {
        self
    }

    fn find(self) -> Option<u32> {
        Some(self.foo)
    }

    fn position(self) -> Option<u32> {
        Some(self.foo)
    }

    fn rposition(self) -> Option<u32> {
        Some(self.foo)
    }
}

/// Checks implementation of FILTER_NEXT lint
fn filter_next() {
    let v = vec![3, 2, 1, 0, -1, -2, -3];

    // check single-line case
    let _ = v.iter().filter(|&x| *x < 0).next();
    //~^ ERROR called `filter(p).next()` on an Iterator.
    //~| NOTE replace `filter(|&x| *x < 0).next()`

    // check multi-line case
    let _ = v.iter().filter(|&x| { //~ERROR called `filter(p).next()` on an Iterator.
                                *x < 0
                            }
                   ).next();

    // check that we don't lint if the caller is not an Iterator
    let foo = IteratorFalsePositives { foo: 0 };
    let _ = foo.filter().next();
}

/// Checks implementation of SEARCH_IS_SOME lint
fn search_is_some() {
    let v = vec![3, 2, 1, 0, -1, -2, -3];

    // check `find().is_some()`, single-line
    let _ = v.iter().find(|&x| *x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `find(|&x| *x < 0).is_some()`

    // check `find().is_some()`, multi-line
    let _ = v.iter().find(|&x| { //~ERROR called `is_some()` after searching
                              *x < 0
                          }
                   ).is_some();

    // check `position().is_some()`, single-line
    let _ = v.iter().position(|&x| x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `position(|&x| x < 0).is_some()`

    // check `position().is_some()`, multi-line
    let _ = v.iter().position(|&x| { //~ERROR called `is_some()` after searching
                                  x < 0
                              }
                   ).is_some();

    // check `rposition().is_some()`, single-line
    let _ = v.iter().rposition(|&x| x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `rposition(|&x| x < 0).is_some()`

    // check `rposition().is_some()`, multi-line
    let _ = v.iter().rposition(|&x| { //~ERROR called `is_some()` after searching
                                   x < 0
                               }
                   ).is_some();

    // check that we don't lint if the caller is not an Iterator
    let foo = IteratorFalsePositives { foo: 0 };
    let _ = foo.find().is_some();
    let _ = foo.position().is_some();
    let _ = foo.rposition().is_some();
}

/// Checks implementation of the OR_FUN_CALL lint
fn or_fun_call() {
    fn make<T>() -> T { unimplemented!(); }

    let with_constructor = Some(vec![1]);
    with_constructor.unwrap_or(make());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_constructor.unwrap_or_else(make)

    let with_new = Some(vec![1]);
    with_new.unwrap_or(Vec::new());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_new.unwrap_or_default();

    let with_const_args = Some(vec![1]);
    with_const_args.unwrap_or(Vec::with_capacity(12));
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_const_args.unwrap_or_else(|| Vec::with_capacity(12));

    let with_err : Result<_, ()> = Ok(vec![1]);
    with_err.unwrap_or(make());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_err.unwrap_or_else(|_| make());

    let with_err_args : Result<_, ()> = Ok(vec![1]);
    with_err_args.unwrap_or(Vec::with_capacity(12));
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_err_args.unwrap_or_else(|_| Vec::with_capacity(12));

    let with_default_trait = Some(1);
    with_default_trait.unwrap_or(Default::default());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_default_trait.unwrap_or_default();

    let with_default_type = Some(1);
    with_default_type.unwrap_or(u64::default());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_default_type.unwrap_or_default();

    let with_vec = Some(vec![1]);
    with_vec.unwrap_or(vec![]);
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_vec.unwrap_or_else(|| vec![]);
}

fn main() {
    use std::io;

    let opt = Some(0);
    let _ = opt.unwrap();  //~ERROR used unwrap() on an Option

    let res: Result<i32, ()> = Ok(0);
    let _ = res.unwrap();  //~ERROR used unwrap() on a Result

    let _ = "str".to_string();  //~ERROR `"str".to_owned()` is faster

    let v = &"str";
    let string = v.to_string();  //~ERROR `(*v).to_owned()` is faster
    let _again = string.to_string();  //~ERROR `String.to_string()` is a no-op

    res.ok().expect("disaster!"); //~ERROR called `ok().expect()`
    // the following should not warn, since `expect` isn't implemented unless
    // the error type implements `Debug`
    let res2: Result<i32, MyError> = Ok(0);
    res2.ok().expect("oh noes!");
    // we currently don't warn if the error type has a type parameter
    // (but it would be nice if we did)
    let res3: Result<u32, MyErrorWithParam<u8>>= Ok(0);
    res3.ok().expect("whoof");
    let res4: Result<u32, io::Error> = Ok(0);
    res4.ok().expect("argh"); //~ERROR called `ok().expect()`
    let res5: io::Result<u32> = Ok(0);
    res5.ok().expect("oops"); //~ERROR called `ok().expect()`
    let res6: Result<u32, &str> = Ok(0);
    res6.ok().expect("meh"); //~ERROR called `ok().expect()`
}

struct MyError(()); // doesn't implement Debug

#[derive(Debug)]
struct MyErrorWithParam<T> {
    x: T
}
<commit_msg>Add a test for the OR_FUN_CALL lint<commit_after>#![feature(plugin)]
#![plugin(clippy)]

#![allow(unused)]
#![deny(clippy, clippy_pedantic)]

use std::ops::Mul;

struct T;

impl T {
    fn add(self, other: T) -> T { self } //~ERROR defining a method called `add`
    fn drop(&mut self) { } //~ERROR defining a method called `drop`

    fn sub(&self, other: T) -> &T { self } // no error, self is a ref
    fn div(self) -> T { self } // no error, different #arguments
    fn rem(self, other: T) { } // no error, wrong return type

    fn into_u32(self) -> u32 { 0 } // fine
    fn into_u16(&self) -> u16 { 0 } //~ERROR methods called `into_*` usually take self by value

    fn to_something(self) -> u32 { 0 } //~ERROR methods called `to_*` usually take self by reference
}

#[derive(Clone,Copy)]
struct U;

impl U {
    fn to_something(self) -> u32 { 0 } // ok because U is Copy
}

impl Mul<T> for T {
    type Output = T;
    fn mul(self, other: T) -> T { self } // no error, obviously
}

/// Utility macro to test linting behavior in `option_methods()`
/// The lints included in `option_methods()` should not lint if the call to map is partially
/// within a macro
macro_rules! opt_map {
    ($opt:expr, $map:expr) => {($opt).map($map)};
}

/// Checks implementation of the following lints:
/// OPTION_MAP_UNWRAP_OR
/// OPTION_MAP_UNWRAP_OR_ELSE
fn option_methods() {
    let opt = Some(1);

    // Check OPTION_MAP_UNWRAP_OR
    // single line case
    let _ = opt.map(|x| x + 1) //~  ERROR called `map(f).unwrap_or(a)`
                               //~| NOTE replace `map(|x| x + 1).unwrap_or(0)`
               .unwrap_or(0); // should lint even though this call is on a separate line
    // multi line cases
    let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or(a)`
                        x + 1
                    }
              ).unwrap_or(0);
    let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or(a)`
               .unwrap_or({
                    0
                });
    // macro case
    let _ = opt_map!(opt, |x| x + 1).unwrap_or(0); // should not lint

    // Check OPTION_MAP_UNWRAP_OR_ELSE
    // single line case
    let _ = opt.map(|x| x + 1) //~  ERROR called `map(f).unwrap_or_else(g)`
                               //~| NOTE replace `map(|x| x + 1).unwrap_or_else(|| 0)`
               .unwrap_or_else(|| 0); // should lint even though this call is on a separate line
    // multi line cases
    let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or_else(g)`
                        x + 1
                    }
              ).unwrap_or_else(|| 0);
    let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or_else(g)`
               .unwrap_or_else(||
                    0
                );
    // macro case
    let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0); // should not lint

}

/// Struct to generate false positive for Iterator-based lints
#[derive(Copy, Clone)]
struct IteratorFalsePositives {
    foo: u32,
}

impl IteratorFalsePositives {
    fn filter(self) -> IteratorFalsePositives {
        self
    }

    fn next(self) -> IteratorFalsePositives {
        self
    }

    fn find(self) -> Option<u32> {
        Some(self.foo)
    }

    fn position(self) -> Option<u32> {
        Some(self.foo)
    }

    fn rposition(self) -> Option<u32> {
        Some(self.foo)
    }
}

/// Checks implementation of FILTER_NEXT lint
fn filter_next() {
    let v = vec![3, 2, 1, 0, -1, -2, -3];

    // check single-line case
    let _ = v.iter().filter(|&x| *x < 0).next();
    //~^ ERROR called `filter(p).next()` on an Iterator.
    //~| NOTE replace `filter(|&x| *x < 0).next()`

    // check multi-line case
    let _ = v.iter().filter(|&x| { //~ERROR called `filter(p).next()` on an Iterator.
                                *x < 0
                            }
                   ).next();

    // check that we don't lint if the caller is not an Iterator
    let foo = IteratorFalsePositives { foo: 0 };
    let _ = foo.filter().next();
}

/// Checks implementation of SEARCH_IS_SOME lint
fn search_is_some() {
    let v = vec![3, 2, 1, 0, -1, -2, -3];

    // check `find().is_some()`, single-line
    let _ = v.iter().find(|&x| *x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `find(|&x| *x < 0).is_some()`

    // check `find().is_some()`, multi-line
    let _ = v.iter().find(|&x| { //~ERROR called `is_some()` after searching
                              *x < 0
                          }
                   ).is_some();

    // check `position().is_some()`, single-line
    let _ = v.iter().position(|&x| x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `position(|&x| x < 0).is_some()`

    // check `position().is_some()`, multi-line
    let _ = v.iter().position(|&x| { //~ERROR called `is_some()` after searching
                                  x < 0
                              }
                   ).is_some();

    // check `rposition().is_some()`, single-line
    let _ = v.iter().rposition(|&x| x < 0).is_some();
    //~^ ERROR called `is_some()` after searching
    //~| NOTE replace `rposition(|&x| x < 0).is_some()`

    // check `rposition().is_some()`, multi-line
    let _ = v.iter().rposition(|&x| { //~ERROR called `is_some()` after searching
                                   x < 0
                               }
                   ).is_some();

    // check that we don't lint if the caller is not an Iterator
    let foo = IteratorFalsePositives { foo: 0 };
    let _ = foo.find().is_some();
    let _ = foo.position().is_some();
    let _ = foo.rposition().is_some();
}

/// Checks implementation of the OR_FUN_CALL lint
fn or_fun_call() {
    struct Foo;

    impl Foo {
        fn new() -> Foo { Foo }
    }

    fn make<T>() -> T { unimplemented!(); }

    let with_constructor = Some(vec![1]);
    with_constructor.unwrap_or(make());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_constructor.unwrap_or_else(make)

    let with_new = Some(vec![1]);
    with_new.unwrap_or(Vec::new());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_new.unwrap_or_default();

    let with_const_args = Some(vec![1]);
    with_const_args.unwrap_or(Vec::with_capacity(12));
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_const_args.unwrap_or_else(|| Vec::with_capacity(12));

    let with_err : Result<_, ()> = Ok(vec![1]);
    with_err.unwrap_or(make());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_err.unwrap_or_else(|_| make());

    let with_err_args : Result<_, ()> = Ok(vec![1]);
    with_err_args.unwrap_or(Vec::with_capacity(12));
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_err_args.unwrap_or_else(|_| Vec::with_capacity(12));

    let with_default_trait = Some(1);
    with_default_trait.unwrap_or(Default::default());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_default_trait.unwrap_or_default();

    let with_default_type = Some(1);
    with_default_type.unwrap_or(u64::default());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_default_type.unwrap_or_default();

    let with_vec = Some(vec![1]);
    with_vec.unwrap_or(vec![]);
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION with_vec.unwrap_or_else(|| vec![]);

    let without_default = Some(Foo);
    without_default.unwrap_or(Foo::new());
    //~^ERROR use of `unwrap_or`
    //~|HELP try this
    //~|SUGGESTION without_default.unwrap_or_else(Foo::new);
}

fn main() {
    use std::io;

    let opt = Some(0);
    let _ = opt.unwrap();  //~ERROR used unwrap() on an Option

    let res: Result<i32, ()> = Ok(0);
    let _ = res.unwrap();  //~ERROR used unwrap() on a Result

    let _ = "str".to_string();  //~ERROR `"str".to_owned()` is faster

    let v = &"str";
    let string = v.to_string();  //~ERROR `(*v).to_owned()` is faster
    let _again = string.to_string();  //~ERROR `String.to_string()` is a no-op

    res.ok().expect("disaster!"); //~ERROR called `ok().expect()`
    // the following should not warn, since `expect` isn't implemented unless
    // the error type implements `Debug`
    let res2: Result<i32, MyError> = Ok(0);
    res2.ok().expect("oh noes!");
    // we currently don't warn if the error type has a type parameter
    // (but it would be nice if we did)
    let res3: Result<u32, MyErrorWithParam<u8>>= Ok(0);
    res3.ok().expect("whoof");
    let res4: Result<u32, io::Error> = Ok(0);
    res4.ok().expect("argh"); //~ERROR called `ok().expect()`
    let res5: io::Result<u32> = Ok(0);
    res5.ok().expect("oops"); //~ERROR called `ok().expect()`
    let res6: Result<u32, &str> = Ok(0);
    res6.ok().expect("meh"); //~ERROR called `ok().expect()`
}

struct MyError(()); // doesn't implement Debug

#[derive(Debug)]
struct MyErrorWithParam<T> {
    x: T
}
<|endoftext|>