<commit_before>use std::*;
use std::iter::*;
use std::sync::atomic::*;
use rand::{Rng, XorShiftRng};
use types::*;
use config::*;
use player::*;
use field::*;

#[unsafe_no_drop_flag]
struct UctNode {
  wins: AtomicUsize,
  draws: AtomicUsize,
  visits: AtomicUsize,
  pos: Pos,
  child: AtomicPtr<UctNode>,
  sibling: Option<Box<UctNode>>
}

unsafe impl Send for UctNode { }

impl Drop for UctNode {
  fn drop(&mut self) {
    self.clear_child();
  }
}

impl UctNode {
  pub fn new(pos: Pos) -> UctNode {
    UctNode {
      wins: AtomicUsize::new(0),
      draws: AtomicUsize::new(0),
      visits: AtomicUsize::new(0),
      pos: pos,
      child: AtomicPtr::new(ptr::null_mut()),
      sibling: None
    }
  }

  pub fn get_pos(&self) -> Pos {
    self.pos
  }

  pub fn set_pos(&mut self, pos: Pos) {
    self.pos = pos;
  }

  pub fn get_sibling(&mut self) -> Option<Box<UctNode>> {
    mem::replace(&mut self.sibling, None)
  }

  pub fn get_sibling_ref<'a>(&'a self) -> Option<&'a UctNode> {
    self.sibling.as_ref().map(|b| &**b)
  }

  pub fn get_sibling_mut<'a>(&'a mut self) -> Option<&'a mut UctNode> {
    self.sibling.as_mut().map(|b| &mut **b)
  }

  pub fn clear_sibling(&mut self) {
    self.sibling = None;
  }

  pub fn set_sibling(&mut self, sibling: Box<UctNode>) {
    self.sibling = Some(sibling);
  }

  pub fn set_sibling_option(&mut self, sibling: Option<Box<UctNode>>) {
    self.sibling = sibling;
  }

  pub fn get_child(&self) -> Option<Box<UctNode>> {
    let ptr = self.child.swap(ptr::null_mut(), Ordering::Relaxed);
    if !ptr.is_null() {
      Some(unsafe { mem::transmute(ptr) })
    } else {
      None
    }
  }

  pub fn get_child_ref<'a>(&'a self) -> Option<&'a UctNode> {
    let ptr = self.child.load(Ordering::Relaxed);
    if !ptr.is_null() {
      Some(unsafe { &*ptr })
    } else {
      None
    }
  }

  pub fn get_child_mut<'a>(&'a mut self) -> Option<&'a mut UctNode> {
    let ptr = self.child.load(Ordering::Relaxed);
    if !ptr.is_null() {
      Some(unsafe { &mut *ptr })
    } else {
      None
    }
  }

  pub fn clear_child(&self) {
    let ptr = self.child.swap(ptr::null_mut(), Ordering::Relaxed);
    if !ptr.is_null() {
      drop::<Box<UctNode>>(unsafe { mem::transmute(ptr) });
    }
  }

  pub fn set_child(&self, child: Box<UctNode>) {
    let ptr = self.child.swap(unsafe { mem::transmute(child) }, Ordering::Relaxed);
    if !ptr.is_null() {
      drop::<Box<UctNode>>(unsafe { mem::transmute(ptr) });
    }
  }

  pub fn set_child_if_empty(&self, child: Box<UctNode>) {
    let child_ptr = unsafe { mem::transmute(child) };
    let ptr = self.child.compare_and_swap(ptr::null_mut(), child_ptr, Ordering::Relaxed);
    if !ptr.is_null() {
      drop::<Box<UctNode>>(unsafe { mem::transmute(child_ptr) });
    }
  }

  pub fn get_visits(&self) -> usize {
    self.visits.load(Ordering::Relaxed)
  }

  pub fn get_wins(&self) -> usize {
    self.wins.load(Ordering::Relaxed)
  }

  pub fn get_draws(&self) -> usize {
    self.draws.load(Ordering::Relaxed)
  }

  pub fn add_win(&self) {
    self.visits.fetch_add(1, Ordering::Relaxed);
    self.wins.fetch_add(1, Ordering::Relaxed);
  }

  pub fn add_draw(&self) {
    self.visits.fetch_add(1, Ordering::Relaxed);
    self.draws.fetch_add(1, Ordering::Relaxed);
  }

  pub fn add_loose(&self) {
    self.visits.fetch_add(1, Ordering::Relaxed);
  }

  pub fn clear_stats(&self) {
    self.wins.store(0, Ordering::Relaxed);
    self.draws.store(0, Ordering::Relaxed);
    self.visits.store(0, Ordering::Relaxed);
  }
}

pub struct UctRoot {
  node: Option<Box<UctNode>>,
  moves: Vec<Pos>,
  moves_field: Vec<Pos>,
  player: Player,
  moves_count: usize,
  hash: u64
}

impl UctRoot {
  fn clear(&mut self) {
    self.node = None;
    self.moves.clear();
    for i in self.moves_field.iter_mut() {
      *i = 0;
    }
    self.player = Player::Red;
    self.moves_count = 0;
    self.hash = 0;
  }

  fn init(&mut self, field: &Field, player: Player) {
    self.node = Some(Box::new(UctNode::new(0)));
    self.player = player;
    let width = field.width();
    for &start_pos in field.points_seq() {
      wave(width, start_pos, |pos| {
        if self.moves_field[pos] != start_pos && field.is_putting_allowed(pos) && manhattan(width, start_pos, pos) <= UCT_RADIUS {
          if self.moves_field[pos] == 0 {
            self.moves.push(pos);
          }
          self.moves_field[pos] = start_pos;
          true
        } else {
          false
        }
      });
    }
  }

  fn expand_node(node: &mut UctNode, moves: &Vec<Pos>) {
    if node.get_child_ref().is_none() {
      if node.get_visits() == usize::max_value() {
        node.clear_stats();
      }
    } else {
      let mut next = node.get_child_mut();
      while next.as_ref().unwrap().get_sibling_ref().is_some() {
        UctRoot::expand_node(*next.as_mut().unwrap(), moves);
        next = next.unwrap().get_sibling_mut();
      }
      UctRoot::expand_node(*next.as_mut().unwrap(), moves);
      for &pos in moves {
        next.as_mut().unwrap().set_sibling(Box::new(UctNode::new(pos)));
        next = next.unwrap().get_sibling_mut();
      }
    }
  }

  fn update(&mut self, field: &Field, player: Player) {
    if self.node.is_some() && field.hash_at(self.moves_count) != Some(self.hash) {
      self.clear();
    }
    if self.node.is_none() {
      self.init(field, player);
    } else {
      let points_seq = field.points_seq();
      let moves_count = field.moves_count();
      loop {
        if self.moves_count == moves_count {
          break;
        }
        let next_pos = points_seq[self.moves_count];
        if !field.is_players_point(next_pos, self.player) {
          self.clear();
          self.init(field, player);
          break;
        }
        let mut next = self.node.as_ref().unwrap().get_child();
        while next.is_some() && next.as_ref().unwrap().pos != next_pos {
          next = next.unwrap().get_sibling();
        }
        match next.as_mut() {
          Some(node) => {
            node.clear_sibling();
          },
          None => {
            self.clear();
            self.init(field, player);
            break;
          }
        }
        self.node = next;
        let moves_field = &mut self.moves_field;
        self.moves.retain(|&pos| {
          if field.is_putting_allowed(pos) {
            true
          } else {
            moves_field[pos] = 0;
            false
          }
        });
        let mut added_moves = Vec::new();
        let width = field.width();
        wave(width, next_pos, |pos| {
          if moves_field[pos] != next_pos && field.is_putting_allowed(pos) && manhattan(width, next_pos, pos) <= UCT_RADIUS {
            if moves_field[pos] == 0 {
              added_moves.push(pos);
            }
            moves_field[pos] = next_pos;
            true
          } else {
            false
          }
        });
        UctRoot::expand_node(self.node.as_mut().unwrap(), &added_moves);
        self.moves_count += 1;
        self.player = self.player.next();
      }
    }
  }

  pub fn new(length: Pos) -> UctRoot {
    UctRoot {
      node: None,
      moves: Vec::with_capacity(length),
      moves_field: repeat(0).take(length).collect(),
      player: Player::Red,
      moves_count: 0,
      hash: 0
    }
  }

  fn play_random_game<T: Rng>(field: &mut Field, mut player: Player, rng: &mut T, possible_moves: &mut Vec<Pos>) -> Option<Player> {
    rng.shuffle(possible_moves);
    let mut putted: CoordProd = 0;
    for &pos in possible_moves.iter() {
      if field.is_putting_allowed(pos) && !field.is_empty_base(pos) {
        field.put_point(pos, player);
        player = player.next();
        putted += 1;
      }
    }
    let red_score = field.score(Player::Red);
    let result = if red_score > 0 {
      Some(Player::Red)
    } else if red_score < 0 {
      Some(Player::Black)
    } else {
      None
    };
    for _ in 0 .. putted {
      field.undo();
    }
    result
  }

  fn ucb(parent: &UctNode, node: &UctNode) -> f32 {
    let wins = node.get_wins() as f32;
    let draws = node.get_draws() as f32;
    let visits = node.get_visits() as f32;
    let parent_visits = parent.get_visits() as f32;
    let win_rate = (wins + draws * UCT_DRAW_WEIGHT) / visits;
    let uct = match UCB_TYPE {
      UcbType::Ucb1 => UCTK * f32::sqrt(2.0 * f32::ln(parent_visits) / visits),
      UcbType::Ucb1Tuned => {
        let v = (wins + draws * UCT_DRAW_WEIGHT * UCT_DRAW_WEIGHT) / visits - win_rate * win_rate + f32::sqrt(2.0 * f32::ln(parent_visits) / visits);
        UCTK * f32::sqrt(v.min(0.25) * f32::ln(parent_visits) / visits)
      }
    };
    win_rate + uct
  }

  fn create_children(field: &Field, possible_moves: &Vec<Pos>, node: &UctNode) {
    let mut children = None;
    for &pos in possible_moves {
      if field.is_putting_allowed(pos) {
        let mut cur_child = Box::new(UctNode::new(pos));
        cur_child.set_sibling_option(children);
        children = Some(cur_child);
      }
    }
    for child in children {
      node.set_child_if_empty(child)
    }
  }

  fn uct_select<'a, T: Rng>(node: &'a UctNode, rng: &mut T) -> Option<&'a UctNode> {
    let mut best_uct = 0f32;
    let mut result = None;
    let mut next = node.get_child_ref();
    loop {
      match next {
        Some(next_node) => {
          let visits = next_node.get_visits();
          let wins = next_node.get_wins();
          let uct_value = if visits == usize::max_value() {
            if wins == usize::max_value() {
              100000.0
            } else {
              -1.0
            }
          } else if visits > 0 {
            UctRoot::ucb(node, next_node)
          } else {
            10000.0 + (rng.gen::<u16>() % 1000) as f32
          };
          if uct_value > best_uct {
            best_uct = uct_value;
            result = Some(next_node);
          }
          next = next_node.get_sibling_ref();
        },
        None => break
      }
    }
    result
  }

  fn play_simulation_rec<T: Rng>(field: &mut Field, node: &UctNode, possible_moves: &mut Vec<Pos>, rng: &mut T, depth: Depth) {

  }

  fn play_simulation<T: Rng>(field: &mut Field, rng: &mut T) {

  }

  fn best_move_generic<T: Rng>(&mut self, field: &Field, player: Player, rng: &mut T, should_stop: &AtomicBool) -> Option<Pos> {
    self.update(field, player);
    let mut guards = Vec::with_capacity(4);
    for _ in 0 .. 4 {
      let xor_shift_rng = rng.gen::<XorShiftRng>();
      guards.push(thread::scoped(|| {
        let mut local_field = field.clone();
        let mut local_rng = xor_shift_rng;
        while !should_stop.load(Ordering::Relaxed) {
          UctRoot::play_simulation(&mut local_field, &mut local_rng);
        }
      }));
    }
    drop(guards);
    let mut best_uct = 0f32;
    let mut result = None;
    for root in self.node.as_ref() {
      let mut next = root.get_child_ref();
      loop {
        match next {
          Some(next_node) => {
            let uct_value = UctRoot::ucb(root, next_node);
            if uct_value > best_uct {
              best_uct = uct_value;
              result = Some(next_node.get_pos());
            }
            next = next_node.get_sibling_ref();
          },
          None => break
        }
      }
    }
    result
  }

  pub fn best_move<T: Rng>(&mut self, field: &Field, player: Player, rng: &mut T, time: Time) -> Option<Pos> {
    let should_stop = AtomicBool::new(false);
    let guard = thread::scoped(|| {
      thread::sleep_ms(time);
      should_stop.store(true, Ordering::Relaxed);
    });
    let result = self.best_move_generic(field, player, rng, &should_stop);
    drop(guard);
    result
  }

  //pub fn estimates
}
<commit_msg>Small refactoring.<commit_after>use std::*;
use std::iter::*;
use std::sync::atomic::*;
use rand::{Rng, XorShiftRng};
use types::*;
use config::*;
use player::*;
use field::*;

#[unsafe_no_drop_flag]
struct UctNode {
  wins: AtomicUsize,
  draws: AtomicUsize,
  visits: AtomicUsize,
  pos: Pos,
  child: AtomicPtr<UctNode>,
  sibling: Option<Box<UctNode>>
}

unsafe impl Send for UctNode { }

impl Drop for UctNode {
  fn drop(&mut self) {
    self.clear_child();
  }
}

impl UctNode {
  pub fn new(pos: Pos) -> UctNode {
    UctNode {
      wins: AtomicUsize::new(0),
      draws: AtomicUsize::new(0),
      visits: AtomicUsize::new(0),
      pos: pos,
      child: AtomicPtr::new(ptr::null_mut()),
      sibling: None
    }
  }

  pub fn get_pos(&self) -> Pos {
    self.pos
  }

  pub fn set_pos(&mut self, pos: Pos) {
    self.pos = pos;
  }

  pub fn get_sibling(&mut self) -> Option<Box<UctNode>> {
    mem::replace(&mut self.sibling, None)
  }

  pub fn get_sibling_ref<'a>(&'a self) -> Option<&'a UctNode> {
    self.sibling.as_ref().map(|b| &**b)
  }

  pub fn get_sibling_mut<'a>(&'a mut self) -> Option<&'a mut UctNode> {
    self.sibling.as_mut().map(|b| &mut **b)
  }

  pub fn clear_sibling(&mut self) {
    self.sibling = None;
  }

  pub fn set_sibling(&mut self, sibling: Box<UctNode>) {
    self.sibling = Some(sibling);
  }

  pub fn set_sibling_option(&mut self, sibling: Option<Box<UctNode>>) {
    self.sibling = sibling;
  }

  pub fn get_child(&self) -> Option<Box<UctNode>> {
    let ptr = self.child.swap(ptr::null_mut(), Ordering::Relaxed);
    if !ptr.is_null() {
      Some(unsafe { mem::transmute(ptr) })
    } else {
      None
    }
  }

  pub fn get_child_ref<'a>(&'a self) -> Option<&'a UctNode> {
    let ptr = self.child.load(Ordering::Relaxed);
    if !ptr.is_null() {
      Some(unsafe { &*ptr })
    } else {
      None
    }
  }

  pub fn get_child_mut<'a>(&'a mut self) -> Option<&'a mut UctNode> {
    let ptr = self.child.load(Ordering::Relaxed);
    if !ptr.is_null() {
      Some(unsafe { &mut *ptr })
    } else {
      None
    }
  }

  pub fn clear_child(&self) {
    let ptr = self.child.swap(ptr::null_mut(), Ordering::Relaxed);
    if !ptr.is_null() {
      drop::<Box<UctNode>>(unsafe { mem::transmute(ptr) });
    }
  }

  pub fn set_child(&self, child: Box<UctNode>) {
    let ptr = self.child.swap(unsafe { mem::transmute(child) }, Ordering::Relaxed);
    if !ptr.is_null() {
      drop::<Box<UctNode>>(unsafe { mem::transmute(ptr) });
    }
  }

  pub fn set_child_if_empty(&self, child: Box<UctNode>) {
    let child_ptr = unsafe { mem::transmute(child) };
    let ptr = self.child.compare_and_swap(ptr::null_mut(), child_ptr, Ordering::Relaxed);
    if !ptr.is_null() {
      drop::<Box<UctNode>>(unsafe { mem::transmute(child_ptr) });
    }
  }

  pub fn get_visits(&self) -> usize {
    self.visits.load(Ordering::Relaxed)
  }

  pub fn get_wins(&self) -> usize {
    self.wins.load(Ordering::Relaxed)
  }

  pub fn get_draws(&self) -> usize {
    self.draws.load(Ordering::Relaxed)
  }

  pub fn add_win(&self) {
    self.visits.fetch_add(1, Ordering::Relaxed);
    self.wins.fetch_add(1, Ordering::Relaxed);
  }

  pub fn add_draw(&self) {
    self.visits.fetch_add(1, Ordering::Relaxed);
    self.draws.fetch_add(1, Ordering::Relaxed);
  }

  pub fn add_loose(&self) {
    self.visits.fetch_add(1, Ordering::Relaxed);
  }

  pub fn clear_stats(&self) {
    self.wins.store(0, Ordering::Relaxed);
    self.draws.store(0, Ordering::Relaxed);
    self.visits.store(0, Ordering::Relaxed);
  }
}

pub struct UctRoot {
  node: Option<Box<UctNode>>,
  moves: Vec<Pos>,
  moves_field: Vec<Pos>,
  player: Player,
  moves_count: usize,
  hash: u64
}

impl UctRoot {
  fn clear(&mut self) {
    self.node = None;
    self.moves.clear();
    for i in self.moves_field.iter_mut() {
      *i = 0;
    }
    self.player = Player::Red;
    self.moves_count = 0;
    self.hash = 0;
  }

  fn init(&mut self, field: &Field, player: Player) {
    self.node = Some(Box::new(UctNode::new(0)));
    self.player = player;
    let width = field.width();
    for &start_pos in field.points_seq() {
      wave(width, start_pos, |pos| {
        if self.moves_field[pos] != start_pos && field.is_putting_allowed(pos) && manhattan(width, start_pos, pos) <= UCT_RADIUS {
          if self.moves_field[pos] == 0 {
            self.moves.push(pos);
          }
          self.moves_field[pos] = start_pos;
          true
        } else {
          false
        }
      });
    }
  }

  fn expand_node(node: &mut UctNode, moves: &Vec<Pos>) {
    if node.get_child_ref().is_none() {
      if node.get_visits() == usize::max_value() {
        node.clear_stats();
      }
    } else {
      let mut next = node.get_child_mut();
      while next.as_ref().unwrap().get_sibling_ref().is_some() {
        UctRoot::expand_node(*next.as_mut().unwrap(), moves);
        next = next.unwrap().get_sibling_mut();
      }
      UctRoot::expand_node(*next.as_mut().unwrap(), moves);
      for &pos in moves {
        next.as_mut().unwrap().set_sibling(Box::new(UctNode::new(pos)));
        next = next.unwrap().get_sibling_mut();
      }
    }
  }

  fn update(&mut self, field: &Field, player: Player) {
    if self.node.is_some() && field.hash_at(self.moves_count) != Some(self.hash) {
      self.clear();
    }
    if self.node.is_none() {
      self.init(field, player);
    } else {
      let points_seq = field.points_seq();
      let moves_count = field.moves_count();
      loop {
        if self.moves_count == moves_count {
          break;
        }
        let next_pos = points_seq[self.moves_count];
        if !field.is_players_point(next_pos, self.player) {
          self.clear();
          self.init(field, player);
          break;
        }
        let mut next = self.node.as_ref().unwrap().get_child();
        while next.is_some() && next.as_ref().unwrap().pos != next_pos {
          next = next.unwrap().get_sibling();
        }
        match next.as_mut() {
          Some(node) => {
            node.clear_sibling();
          },
          None => {
            self.clear();
            self.init(field, player);
            break;
          }
        }
        self.node = next;
        let moves_field = &mut self.moves_field;
        self.moves.retain(|&pos| {
          if field.is_putting_allowed(pos) {
            true
          } else {
            moves_field[pos] = 0;
            false
          }
        });
        let mut added_moves = Vec::new();
        let width = field.width();
        wave(width, next_pos, |pos| {
          if moves_field[pos] != next_pos && field.is_putting_allowed(pos) && manhattan(width, next_pos, pos) <= UCT_RADIUS {
            if moves_field[pos] == 0 {
              added_moves.push(pos);
            }
            moves_field[pos] = next_pos;
            true
          } else {
            false
          }
        });
        UctRoot::expand_node(self.node.as_mut().unwrap(), &added_moves);
        self.moves_count += 1;
        self.player = self.player.next();
      }
    }
  }

  pub fn new(length: Pos) -> UctRoot {
    UctRoot {
      node: None,
      moves: Vec::with_capacity(length),
      moves_field: repeat(0).take(length).collect(),
      player: Player::Red,
      moves_count: 0,
      hash: 0
    }
  }

  fn play_random_game<T: Rng>(field: &mut Field, mut player: Player, rng: &mut T, possible_moves: &mut Vec<Pos>) -> Option<Player> {
    rng.shuffle(possible_moves);
    let mut putted: CoordProd = 0;
    for &pos in possible_moves.iter() {
      if field.is_putting_allowed(pos) && !field.is_empty_base(pos) {
        field.put_point(pos, player);
        player = player.next();
        putted += 1;
      }
    }
    let red_score = field.score(Player::Red);
    let result = if red_score > 0 {
      Some(Player::Red)
    } else if red_score < 0 {
      Some(Player::Black)
    } else {
      None
    };
    for _ in 0 .. putted {
      field.undo();
    }
    result
  }

  fn ucb(parent: &UctNode, node: &UctNode) -> f32 {
    let wins = node.get_wins() as f32;
    let draws = node.get_draws() as f32;
    let visits = node.get_visits() as f32;
    let parent_visits = parent.get_visits() as f32;
    let win_rate = (wins + draws * UCT_DRAW_WEIGHT) / visits;
    let uct = match UCB_TYPE {
      UcbType::Ucb1 => UCTK * f32::sqrt(2.0 * f32::ln(parent_visits) / visits),
      UcbType::Ucb1Tuned => {
        let v = (wins + draws * UCT_DRAW_WEIGHT * UCT_DRAW_WEIGHT) / visits - win_rate * win_rate + f32::sqrt(2.0 * f32::ln(parent_visits) / visits);
        UCTK * f32::sqrt(v.min(0.25) * f32::ln(parent_visits) / visits)
      }
    };
    win_rate + uct
  }

  fn create_children(field: &Field, possible_moves: &Vec<Pos>, node: &UctNode) {
    let mut children = None;
    for &pos in possible_moves {
      if field.is_putting_allowed(pos) {
        let mut cur_child = Box::new(UctNode::new(pos));
        cur_child.set_sibling_option(children);
        children = Some(cur_child);
      }
    }
    for child in children {
      node.set_child_if_empty(child)
    }
  }

  fn uct_select<'a, T: Rng>(node: &'a UctNode, rng: &mut T) -> Option<&'a UctNode> {
    let mut best_uct = 0f32;
    let mut result = None;
    let mut next = node.get_child_ref();
    while let Some(next_node) = next {
      let visits = next_node.get_visits();
      let wins = next_node.get_wins();
      let uct_value = if visits == usize::max_value() {
        if wins == usize::max_value() {
          100000.0
        } else {
          -1.0
        }
      } else if visits > 0 {
        UctRoot::ucb(node, next_node)
      } else {
        10000.0 + (rng.gen::<u16>() % 1000) as f32
      };
      if uct_value > best_uct {
        best_uct = uct_value;
        result = Some(next_node);
      }
      next = next_node.get_sibling_ref();
    }
    result
  }

  fn play_simulation_rec<T: Rng>(field: &mut Field, node: &UctNode, possible_moves: &mut Vec<Pos>, rng: &mut T, depth: Depth) {

  }

  fn play_simulation<T: Rng>(field: &mut Field, rng: &mut T) {

  }

  fn best_move_generic<T: Rng>(&mut self, field: &Field, player: Player, rng: &mut T, should_stop: &AtomicBool) -> Option<Pos> {
    self.update(field, player);
    let mut guards = Vec::with_capacity(4);
    for _ in 0 .. 4 {
      let xor_shift_rng = rng.gen::<XorShiftRng>();
      guards.push(thread::scoped(|| {
        let mut local_field = field.clone();
        let mut local_rng = xor_shift_rng;
        while !should_stop.load(Ordering::Relaxed) {
          UctRoot::play_simulation(&mut local_field, &mut local_rng);
        }
      }));
    }
    drop(guards);
    let mut best_uct = 0f32;
    let mut result = None;
    for root in self.node.as_ref() {
      let mut next = root.get_child_ref();
      while let Some(next_node) = next {
        let uct_value = UctRoot::ucb(root, next_node);
        if uct_value > best_uct {
          best_uct = uct_value;
          result = Some(next_node.get_pos());
        }
        next = next_node.get_sibling_ref();
      }
    }
    result
  }

  pub fn best_move<T: Rng>(&mut self, field: &Field, player: Player, rng: &mut T, time: Time) -> Option<Pos> {
    let should_stop = AtomicBool::new(false);
    let guard = thread::scoped(|| {
      thread::sleep_ms(time);
      should_stop.store(true, Ordering::Relaxed);
    });
    let result = self.best_move_generic(field, player, rng, &should_stop);
    drop(guard);
    result
  }

  //pub fn estimates
}
<|endoftext|>


<commit_before>use std::collections::{HashMap, HashSet};

type FreeVariable = u64;
type VariableName<'a> = &'a str;

/// AST node expression
#[derive(Copy, Clone, Debug, PartialEq)]
enum Expression<'a> {
    Number(f64),
    Boolean(bool),

    /// simple variable
    Variable(VariableName<'a>),

    /// fn (x, y, z) -> expr
    Lambda(&'a [VariableName<'a>], &'a Expression<'a>),

    /// let x = expr in expr
    Let(VariableName<'a>, &'a Expression<'a>, &'a Expression<'a>),

    /// some_fn (x, y, z)
    FnCall(&'a Expression<'a>, &'a [ &'a Expression<'a>])
}

#[derive(Clone, Debug, PartialEq)]
enum Type {
    Number,
    Boolean,
    Free(FreeVariable),
    // FIXME: can I avoid having this be boxed and vec'd?
    Lambda(Vec<Type>, Box<Type>),
}

#[derive(Clone, Debug)]
struct TypeEnv<'a> {
    bindings: HashMap<VariableName<'a>, Type>,
    // FIXME: This isn't the correct naming. Perhaps generic?
    instances: HashSet<FreeVariable>
}

impl <'a> TypeEnv <'a> {
    fn new() -> TypeEnv<'a> {
        TypeEnv {
            bindings: HashMap::new(),
            instances: HashSet::new()
        }
    }

    fn instantiate(&mut self, var: FreeVariable) {
        self.instances.insert(var);
    }

    /// Bind previously unbound type variables to a specified type.
    fn bind_type(&mut self, var: FreeVariable, ty: Type) -> Type {
        println!("binding free({}) = {:?}", var, ty);

        for val in self.bindings.values_mut() {
            if *val == Type::Free(var) {
                *val = ty.clone();
            }
        }

        ty
    }

}

#[derive(Clone, Copy)]
struct VariableGen { current: FreeVariable }
impl VariableGen {
    fn next(&mut self) -> FreeVariable { self.current += 1; self.current }
}

type UnificationError = &'static str;
type TypeError = &'static str;

/// modifies the environment to unify the given types (or returns false if not possible)
fn unify<'a>(a: Type, b: Type, env: &mut TypeEnv<'a>, inst: &mut VariableGen) -> Result<Type, UnificationError> {
    let res = match (a.clone(), b.clone()) {
        // Easy. Literals match with themselves
        (Type::Number, Type::Number) => Ok(Type::Number),
        (Type::Boolean, Type::Boolean) => Ok(Type::Boolean),

        // FIXME: is this correct?
        (Type::Free(a), Type::Free(b)) => {
            let t1 = env.bind_type(b, Type::Free(inst.next()));

            Ok(env.bind_type(a, t1))
        }

        (Type::Free(n), ty) | (ty, Type::Free(n)) =>
            Ok(env.bind_type(n, ty)),

        (Type::Lambda(args1, body1), Type::Lambda(args2, body2)) => {
            if args1.len() != args2.len() {
                return Err("lambdas take differing numbers of arguments")
            }

            let mut unified_args = Vec::with_capacity(args1.len());

            for iter in args1.into_iter().zip(args2.into_iter()) {
                match unify(iter.0, iter.1, env, inst) {
                    Ok(ty) => unified_args.push(ty),
                    err => return err
                }
            }

            match unify(*body1, *body2, env, inst) {
                Ok(body_ty) => Ok(Type::Lambda(unified_args, Box::new(body_ty))),
                err => err
            }
        }

        _ => Err("could not unify types")
    };

    println!("unify: {:?} <-> {:?} == {:?}", &a, &b, res);

    res
}

/// Run algorithm W on expr with given type env, yielding the resolved
/// type of the expression, or the type error encountered.
fn w<'a>(expr: &Expression<'a>, env: &mut TypeEnv<'a>, inst: &mut VariableGen) -> Type {
    match *expr {
        // simplest case: literals have immediately defined types.
        Expression::Number(_) => Type::Number,
        Expression::Boolean(_) => Type::Boolean,

        // variables we need to look up inside our type environment
        Expression::Variable(name) => match env.bindings.get(name) {
            Some(typ) => typ.clone(),
            None => panic!("undefined variable, {}", name)
        },

        Expression::Lambda(args, body) => {
            // Any parameters or variables defined inside the lambda are scoped
            // only to the lambda.
            let mut child_env = env.clone();

            let args_ty = args
                .into_iter()
                .map(|arg| {
                    let ty = inst.next();
                    child_env.bindings.insert(arg, Type::Free(ty));
                    child_env.instantiate(ty);
                    Type::Free(ty)
                })
                .collect::<Vec<Type>>();

            let body_ty = w(body, &mut child_env, inst);

            Type::Lambda(args_ty, Box::new(body_ty))
        },

        // TODO: need an occurs check here.
        Expression::Let(name, expr, body) => {
            let expr_ty = w(expr, env, inst);
            let mut child_env = env.clone();

            child_env.bindings.insert(name, expr_ty);

            w(body, &mut child_env, inst)
        },

        // 1. ensure that the callable in this function call is truly callable.
        // 2. ensure that the number and type of args match
        // 3. return type of body of lambda
        Expression::FnCall(callable, args) => {
            let mut child_env = env.clone();

            let type_args = args
                .iter()
                .map(|arg| {
                    w(arg, &mut child_env, inst)
                })
                .collect::<Vec<Type>>();

            // Try to unify the lambda we are calling with the way we are calling it.
            unify(w(callable, &mut child_env, inst),
                  Type::Lambda(type_args, Box::new(Type::Free(inst.next()))),
                  &mut child_env, inst)
                .map(move |ty|{
                    match ty {
                        Type::Lambda(_, return_type) => {
                            *return_type
                        },
                        _ => panic!("BUG: expected unify to return lambda, not {:?}", ty)
                    }
                })
                .or(Err("could not unify lambda types"))
                // FIXME: this should eventually return a result anyway.
                .unwrap()
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    fn infer(exp: Expression) -> Type {
        let mut inst = VariableGen { current: 0 };
        let mut env = TypeEnv::new();

        w(&exp, &mut env, &mut inst)
    }

    fn unify_(t1: Type, t2: Type) -> Result<Type, UnificationError> {
        let mut inst = VariableGen { current: 0 };
        let mut env = TypeEnv::new();

        unify(t1, t2, &mut env, &mut inst)
    }

    #[test]
    #[should_panic]
    fn undefined_variable() {
        let var = Expression::Variable("x");

        // FIXME: until we return a result type this will panic.
        infer(var);
    }

    #[test]
    fn literal_inference() {
        let num = Expression::Number(123.0);
        let boolean = Expression::Boolean(true);

        assert_eq!(infer(num), Type::Number);
        assert_eq!(infer(boolean), Type::Boolean);
    }

    #[test]
    fn lambda_expression_inference() {
        let args = ["x"];
        let num = Expression::Number(123.0);

        // \x -> 123.0
        let lambda = Expression::Lambda(&args, &num);

        assert_eq!(infer(lambda), Type::Lambda(vec![Type::Free(1)], Box::new(Type::Number)));

        // \x -> \y -> 123.0
        let lambdalambda = Expression::Lambda(&args, &lambda);
        assert_eq!(infer(lambdalambda),
                   Type::Lambda(vec![Type::Free(1)], Box::new(
                       Type::Lambda(vec![Type::Free(2)], Box::new(Type::Number)))));
    }

    #[test]
    fn let_inference() {
        let boolean = Expression::Boolean(false);
        let var_x = Expression::Variable("x");
        let var_y = Expression::Variable("y");

        // let x = false in x
        let let_ = Expression::Let("x", &boolean, &var_x);

        assert_eq!(infer(let_), Type::Boolean);

        // let y = (let x = false in x) in y
        let nested_let = Expression::Let("y", &let_, &var_y);
        assert_eq!(infer(nested_let), Type::Boolean);
    }

    #[test]
    fn simple_lambda_call_inference() {
        let args = ["x"];
        let num = Expression::Number(123.0);
        let boolean = Expression::Boolean(false);

        // \x -> 123.0
        let lambda = Expression::Lambda(&args, &num);

        let app_args = [&boolean];
        let application = Expression::FnCall(&lambda, &app_args);

        assert_eq!(infer(application), Type::Number);
    }

    #[test]
    #[should_panic]
    fn call_non_lambda() {
        let num = Expression::Number(123.0);
        let boolean = Expression::Boolean(false);

        let app_args = [&boolean];
        let application = Expression::FnCall(&num, &app_args);

        infer(application);
    }

    #[test]
    fn lambda_returning_lambda() {
        // let
        //    x = (\a -> a)
        // in
        //    let y = (\a -> a)
        //    in
        //       x (y)
        // ===> \a -> a
        let var_a = Expression::Variable("a");
        let var_x = Expression::Variable("x");
        let var_y = Expression::Variable("y");
        let args_a = ["a"];
        let args_y = [&var_y];
        let lambda_x = Expression::Lambda(&args_a, &var_a);
        let lambda_y = Expression::Lambda(&args_a, &var_a);

        let fncall = Expression::FnCall(&var_x, &args_y);

        let let_y = Expression::Let("y", &lambda_y, &fncall);
        let let_x = Expression::Let("x", &lambda_x, &let_y);

        assert_eq!(infer(let_x), Type::Lambda(vec![Type::Free(3)], Box::new(Type::Free(3))))
    }

    #[test]
    fn test_unify() {
        assert!(unify_(Type::Number, Type::Boolean).is_err());

        assert_eq!(unify_(Type::Number, Type::Number).unwrap(), Type::Number);
        assert_eq!(unify_(Type::Free(10), Type::Number).unwrap(), Type::Number);

        assert_eq!(unify_(Type::Lambda(vec![Type::Free(10), Type::Free(20)], Box::new(Type::Number)),
                          Type::Lambda(vec![Type::Free(30), Type::Free(40)], Box::new(Type::Number))).unwrap(),
                   Type::Lambda(vec![Type::Free(1), Type::Free(2)], Box::new(Type::Number)));
    }
}

fn main() {
    println!("patience.");
}
<commit_msg>rustfmt<commit_after>use std::collections::{HashMap, HashSet};

type FreeVariable = u64;
type VariableName<'a> = &'a str;

/// AST node expression
#[derive(Copy, Clone, Debug, PartialEq)]
enum Expression<'a> {
    Number(f64),
    Boolean(bool),

    /// simple variable
    Variable(VariableName<'a>),

    /// fn (x, y, z) -> expr
    Lambda(&'a [VariableName<'a>], &'a Expression<'a>),

    /// let x = expr in expr
    Let(VariableName<'a>, &'a Expression<'a>, &'a Expression<'a>),

    /// some_fn (x, y, z)
    FnCall(&'a Expression<'a>, &'a [&'a Expression<'a>]),
}

#[derive(Clone, Debug, PartialEq)]
enum Type {
    Number,
    Boolean,
    Free(FreeVariable),
    // FIXME: can I avoid having this be boxed and vec'd?
    Lambda(Vec<Type>, Box<Type>),
}

#[derive(Clone, Debug)]
struct TypeEnv<'a> {
    bindings: HashMap<VariableName<'a>, Type>,
    // FIXME: This isn't the correct naming. Perhaps generic?
    instances: HashSet<FreeVariable>,
}

impl<'a> TypeEnv<'a> {
    fn new() -> TypeEnv<'a> {
        TypeEnv {
            bindings: HashMap::new(),
            instances: HashSet::new(),
        }
    }

    fn instantiate(&mut self, var: FreeVariable) {
        self.instances.insert(var);
    }

    /// Bind previously unbound type variables to a specified type.
    fn bind_type(&mut self, var: FreeVariable, ty: Type) -> Type {
        println!("binding free({}) = {:?}", var, ty);

        for val in self.bindings.values_mut() {
            if *val == Type::Free(var) {
                *val = ty.clone();
            }
        }

        ty
    }
}

#[derive(Clone, Copy)]
struct VariableGen {
    current: FreeVariable,
}
impl VariableGen {
    fn next(&mut self) -> FreeVariable {
        self.current += 1;
        self.current
    }
}

type UnificationError = &'static str;
type TypeError = &'static str;

/// modifies the environment to unify the given types (or returns false if not possible)
fn unify<'a>(
    a: Type,
    b: Type,
    env: &mut TypeEnv<'a>,
    inst: &mut VariableGen,
) -> Result<Type, UnificationError> {
    let res = match (a.clone(), b.clone()) {
        // Easy. Literals match with themselves
        (Type::Number, Type::Number) => Ok(Type::Number),
        (Type::Boolean, Type::Boolean) => Ok(Type::Boolean),

        // FIXME: is this correct?
        (Type::Free(a), Type::Free(b)) => {
            let t1 = env.bind_type(b, Type::Free(inst.next()));

            Ok(env.bind_type(a, t1))
        }

        (Type::Free(n), ty) |
        (ty, Type::Free(n)) => Ok(env.bind_type(n, ty)),

        (Type::Lambda(args1, body1), Type::Lambda(args2, body2)) => {
            if args1.len() != args2.len() {
                return Err("lambdas take differing numbers of arguments");
            }

            let mut unified_args = Vec::with_capacity(args1.len());

            for iter in args1.into_iter().zip(args2.into_iter()) {
                match unify(iter.0, iter.1, env, inst) {
                    Ok(ty) => unified_args.push(ty),
                    err => return err,
                }
            }

            match unify(*body1, *body2, env, inst) {
                Ok(body_ty) => Ok(Type::Lambda(unified_args, Box::new(body_ty))),
                err => err,
            }
        }

        _ => Err("could not unify types"),
    };

    println!("unify: {:?} <-> {:?} == {:?}", &a, &b, res);

    res
}

/// Run algorithm W on expr with given type env, yielding the resolved
/// type of the expression, or the type error encountered.
fn w<'a>(expr: &Expression<'a>, env: &mut TypeEnv<'a>, inst: &mut VariableGen) -> Type {
    match *expr {
        // simplest case: literals have immediately defined types.
        Expression::Number(_) => Type::Number,
        Expression::Boolean(_) => Type::Boolean,

        // variables we need to look up inside our type environment
        Expression::Variable(name) => {
            match env.bindings.get(name) {
                Some(typ) => typ.clone(),
                None => panic!("undefined variable, {}", name),
            }
        }

        Expression::Lambda(args, body) => {
            // Any parameters or variables defined inside the lambda are scoped
            // only to the lambda.
            let mut child_env = env.clone();

            let args_ty = args.into_iter()
                .map(|arg| {
                    let ty = inst.next();
                    child_env.bindings.insert(arg, Type::Free(ty));
                    child_env.instantiate(ty);
                    Type::Free(ty)
                })
                .collect::<Vec<Type>>();

            let body_ty = w(body, &mut child_env, inst);

            Type::Lambda(args_ty, Box::new(body_ty))
        }

        // TODO: need an occurs check here.
        Expression::Let(name, expr, body) => {
            let expr_ty = w(expr, env, inst);
            let mut child_env = env.clone();

            child_env.bindings.insert(name, expr_ty);

            w(body, &mut child_env, inst)
        }

        // 1. ensure that the callable in this function call is truly callable.
        // 2. ensure that the number and type of args match
        // 3. return type of body of lambda
        Expression::FnCall(callable, args) => {
            let mut child_env = env.clone();

            let type_args = args.iter()
                .map(|arg| w(arg, &mut child_env, inst))
                .collect::<Vec<Type>>();

            // Try to unify the lambda we are calling with the way we are calling it.
            unify(w(callable, &mut child_env, inst),
                  Type::Lambda(type_args, Box::new(Type::Free(inst.next()))),
                  &mut child_env, inst)
                .map(move |ty|{
                    match ty {
                        Type::Lambda(_, return_type) => {
                            *return_type
                        },
                        _ => panic!("BUG: expected unify to return lambda, not {:?}", ty)
                    }
                })
                .or(Err("could not unify lambda types"))
                // FIXME: this should eventually return a result anyway.
                .unwrap()
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    fn infer(exp: Expression) -> Type {
        let mut inst = VariableGen { current: 0 };
        let mut env = TypeEnv::new();

        w(&exp, &mut env, &mut inst)
    }

    fn unify_(t1: Type, t2: Type) -> Result<Type, UnificationError> {
        let mut inst = VariableGen { current: 0 };
        let mut env = TypeEnv::new();

        unify(t1, t2, &mut env, &mut inst)
    }

    #[test]
    #[should_panic]
    fn undefined_variable() {
        let var = Expression::Variable("x");

        // FIXME: until we return a result type this will panic.
        infer(var);
    }

    #[test]
    fn literal_inference() {
        let num = Expression::Number(123.0);
        let boolean = Expression::Boolean(true);

        assert_eq!(infer(num), Type::Number);
        assert_eq!(infer(boolean), Type::Boolean);
    }

    #[test]
    fn lambda_expression_inference() {
        let args = ["x"];
        let num = Expression::Number(123.0);

        // \x -> 123.0
        let lambda = Expression::Lambda(&args, &num);

        assert_eq!(
            infer(lambda),
            Type::Lambda(vec![Type::Free(1)], Box::new(Type::Number))
        );

        // \x -> \y -> 123.0
        let lambdalambda = Expression::Lambda(&args, &lambda);
        assert_eq!(
            infer(lambdalambda),
            Type::Lambda(
                vec![Type::Free(1)],
                Box::new(Type::Lambda(vec![Type::Free(2)], Box::new(Type::Number))),
            )
        );
    }

    #[test]
    fn let_inference() {
        let boolean = Expression::Boolean(false);
        let var_x = Expression::Variable("x");
        let var_y = Expression::Variable("y");

        // let x = false in x
        let let_ = Expression::Let("x", &boolean, &var_x);

        assert_eq!(infer(let_), Type::Boolean);

        // let y = (let x = false in x) in y
        let nested_let = Expression::Let("y", &let_, &var_y);
        assert_eq!(infer(nested_let), Type::Boolean);
    }

    #[test]
    fn simple_lambda_call_inference() {
        let args = ["x"];
        let num = Expression::Number(123.0);
        let boolean = Expression::Boolean(false);

        // \x -> 123.0
        let lambda = Expression::Lambda(&args, &num);

        let app_args = [&boolean];
        let application = Expression::FnCall(&lambda, &app_args);

        assert_eq!(infer(application), Type::Number);
    }

    #[test]
    #[should_panic]
    fn call_non_lambda() {
        let num = Expression::Number(123.0);
        let boolean = Expression::Boolean(false);

        let app_args = [&boolean];
        let application = Expression::FnCall(&num, &app_args);

        infer(application);
    }

    #[test]
    fn lambda_returning_lambda() {
        // let
        //    x = (\a -> a)
        // in
        //    let y = (\a -> a)
        //    in
        //       x (y)
        // ===> \a -> a
        let var_a = Expression::Variable("a");
        let var_x = Expression::Variable("x");
        let var_y = Expression::Variable("y");
        let args_a = ["a"];
        let args_y = [&var_y];
        let lambda_x = Expression::Lambda(&args_a, &var_a);
        let lambda_y = Expression::Lambda(&args_a, &var_a);

        let fncall = Expression::FnCall(&var_x, &args_y);

        let let_y = Expression::Let("y", &lambda_y, &fncall);
        let let_x = Expression::Let("x", &lambda_x, &let_y);

        assert_eq!(
            infer(let_x),
            Type::Lambda(vec![Type::Free(3)], Box::new(Type::Free(3)))
        )
    }

    #[test]
    fn test_unify() {
        assert!(unify_(Type::Number, Type::Boolean).is_err());

        assert_eq!(unify_(Type::Number, Type::Number).unwrap(), Type::Number);
        assert_eq!(unify_(Type::Free(10), Type::Number).unwrap(), Type::Number);

        assert_eq!(
            unify_(
                Type::Lambda(vec![Type::Free(10), Type::Free(20)], Box::new(Type::Number)),
                Type::Lambda(vec![Type::Free(30), Type::Free(40)], Box::new(Type::Number)),
            ).unwrap(),
            Type::Lambda(vec![Type::Free(1), Type::Free(2)], Box::new(Type::Number))
        );
    }
}

fn main() {
    println!("patience.");
}
<|endoftext|>


<commit_before>use std::ptr;
use std::hash::{Hash, Hasher};
use std::slice::Iter as SliceIter;
use std::iter::Zip as ZipIter;
use std::iter::Map as MapIter;
use std::iter::Enumerate;
use std::option::IntoIter as OptionIntoIter;
use std::iter::Cycle;

#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub struct Coordinates(pub usize, pub usize);

impl Coordinates {
    pub fn in_direction(&self, direction: Direction) -> Option<Coordinates> {
        match direction {
            Direction::Up if self.1 > 0 => Some(Coordinates(self.0, self.1 - 1)),
            Direction::Right if self.0 < usize::max_value() => Some(
                Coordinates(self.0 + 1, self.1),
            ),
            Direction::Down if self.1 < usize::max_value() => Some(Coordinates(self.0, self.1 + 1)),
            Direction::Left if self.0 > 0 => Some(Coordinates(self.0 - 1, self.1)),
            _ => None,
        }
    }

    pub fn direction_to(&self, to: Coordinates) -> Option<Direction> {
        if self.0 == to.0 && self.1 == to.1 {
            return None
        }

        Some(if to.1 + to.0 >= self.1 + self.0 && to.1 + self.0 > to.0 + self.1 {
            Direction::Down
        } else if to.1 + self.0 <= to.0 + self.1 && to.1 + to.0 > self.1 + self.0 {
            Direction::Right
        } else if to.1 + to.0 <= self.1 + self.0 && to.1 + self.0 < to.0 + self.1 {
            Direction::Up
        } else {
            Direction::Left
        })
    }
}

#[test]
fn in_direction_overflow() {
    assert!(Coordinates(0, 0).in_direction(Direction::Up).is_none());
    assert!(Coordinates(0, 0).in_direction(Direction::Left).is_none());
    assert!(Coordinates(0, 0).in_direction(Direction::Down).is_some());
    assert!(Coordinates(0, 0).in_direction(Direction::Right).is_some());

    assert!(Coordinates(1, 1).in_direction(Direction::Up).is_some());
    assert!(Coordinates(1, 1).in_direction(Direction::Left).is_some());
    assert!(Coordinates(1, 1).in_direction(Direction::Down).is_some());
    assert!(Coordinates(1, 1).in_direction(Direction::Right).is_some());

    assert!(
        Coordinates(usize::max_value(), usize::max_value())
            .in_direction(Direction::Up)
            .is_some()
    );
    assert!(
        Coordinates(usize::max_value(), usize::max_value())
            .in_direction(Direction::Left)
            .is_some()
    );
    assert!(
        Coordinates(usize::max_value(), usize::max_value())
            .in_direction(Direction::Down)
            .is_none()
    );
    assert!(
        Coordinates(usize::max_value(), usize::max_value())
            .in_direction(Direction::Right)
            .is_none()
    );
}

#[test]
fn test_direction_to() {
    assert_eq!(Coordinates(1, 1).direction_to(Coordinates(1, 1)), None);

    assert_eq!(Coordinates(0, 0).direction_to(Coordinates(1, 0)), Some(Direction::Right));
    assert_eq!(Coordinates(2, 0).direction_to(Coordinates(1, 0)), Some(Direction::Left));

    assert_eq!(Coordinates(0, 0).direction_to(Coordinates(0, 1)), Some(Direction::Down));
    assert_eq!(Coordinates(0, 2).direction_to(Coordinates(0, 1)), Some(Direction::Up));

    assert_eq!(Coordinates(0, 0).direction_to(Coordinates(2, 1)), Some(Direction::Right));
    assert_eq!(Coordinates(4, 0).direction_to(Coordinates(2, 1)), Some(Direction::Left));

    assert_eq!(Coordinates(0, 2).direction_to(Coordinates(2, 1)), Some(Direction::Right));
    assert_eq!(Coordinates(4, 2).direction_to(Coordinates(2, 1)), Some(Direction::Left));

    assert_eq!(Coordinates(0, 0).direction_to(Coordinates(1, 2)), Some(Direction::Down));
    assert_eq!(Coordinates(0, 4).direction_to(Coordinates(1, 2)), Some(Direction::Up));
}

#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum Direction {
    Up,
    Right,
    Down,
    Left,
}

impl Direction {
    fn clockwise() -> DirectionClockwiseIter {
        DirectionClockwiseIter { direction: Some(Direction::Up) }
    }
}

#[derive(Debug)]
pub struct DirectionClockwiseIter {
    direction: Option<Direction>,
}

impl Iterator for DirectionClockwiseIter {
    type Item = Direction;

    fn next(&mut self) -> Option<Direction> {
        let next_direction = match self.direction {
            Some(Direction::Up) => Some(Direction::Right),
            Some(Direction::Right) => Some(Direction::Down),
            Some(Direction::Down) => Some(Direction::Left),
            Some(Direction::Left) => None,
            None => None,
        };
        let ret = self.direction;
        self.direction = next_direction;
        ret
    }
}

#[derive(Debug, Clone, Copy)]
pub struct Location<'m> {
    map: &'m Map,
    pub coordinates: Coordinates,
    pub tile: &'m Tile,
}

impl<'m> PartialEq for Location<'m> {
    fn eq(&self, other: &Location<'m>) -> bool {
        ptr::eq(self.tile, other.tile)
    }
}

impl<'m> Eq for Location<'m> {}

impl<'m> Hash for Location<'m> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        state.write_usize((self.tile as *const Tile) as usize)
    }
}

impl<'m> Location<'m> {
    pub fn neighbours(&self) -> NeighboursIter<'m> {
        NeighboursIter {
            location: self.clone(),
            directions: Direction::clockwise(),
        }
    }

    pub fn in_direction(&self, direction: Direction) -> Option<Location<'m>> {
        self.coordinates.in_direction(direction).and_then(
            |coordinates| {
                self.map.location(coordinates)
            },
        )
    }

    pub fn direction_to(&self, to: Location<'m>) -> Option<Direction> {
        self.coordinates.direction_to(to.coordinates)
    }

    pub fn walkable(&self) -> bool {
        match *self.tile {
            Tile::Empty => true,
            _ => false,
        }
    }
}

pub struct NeighboursIter<'m> {
    location: Location<'m>,
    directions: DirectionClockwiseIter,
}

impl<'m> Iterator for NeighboursIter<'m> {
    type Item = (Direction, Location<'m>);

    fn next(&mut self) -> Option<(Direction, Location<'m>)> {
        while let Some(direction) = self.directions.next() {
            if let ret @ Some(_) = self.location.in_direction(direction).map(|location| {
                (direction, location)
            })
            {
                return ret;
            }
        }
        None
    }
}

#[test]
fn location_neighbours() {
    let map = Map::new(Dimension::new(8).unwrap(), Dimension::new(8).unwrap());

    assert_eq!(
        map.location(Coordinates(0, 0))
            .unwrap()
            .neighbours()
            .collect::<Vec<_>>(),
        vec![
            (Direction::Right, map.location(Coordinates(1, 0)).unwrap()),
            (Direction::Down, map.location(Coordinates(0, 1)).unwrap()),
        ]
    )
}

#[derive(PartialEq, Eq, Hash, Debug)]
pub enum Tile {
    Empty,
    Wall,
}

#[derive(Debug)]
pub struct Map {
    tiles: Vec<Vec<Tile>>, // TODO: Matix
}

pub struct Dimension(usize);

impl Dimension {
    pub fn new(dimension: usize) -> Option<Dimension> {
        if dimension > 0 {
            Some(Dimension(dimension))
        } else {
            None
        }
    }

    pub fn unwrap(self) -> usize {
        self.0
    }
}

impl Map {
    pub fn new(width: Dimension, height: Dimension) -> Map {
        let width = width.unwrap();
        let height = height.unwrap();

        Map {
            tiles: (0..height)
                .map(|_row| (0..width).map(|_col| Tile::Empty).collect())
                .collect(),
        }
    }

    pub fn width(&self) -> usize {
        self.tiles.iter().next().unwrap().len()
    }

    pub fn height(&self) -> usize {
        self.tiles.len()
    }

    pub fn get_mut_tile(&mut self, coordinates: Coordinates) -> Option<&mut Tile> {
        self.tiles.get_mut(coordinates.1).and_then(|row| {
            row.get_mut(coordinates.0)
        })
    }

    pub fn location(&self, coordinates: Coordinates) -> Option<Location> {
        self.tiles
            .get(coordinates.1)
            .and_then(|row| row.get(coordinates.0))
            .map(|tile| {
                Location {
                    map: &self,
                    coordinates: coordinates,
                    tile: tile,
                }
            })
    }

    pub fn rows(&self) -> RowIter {
        fn to_row<'m>((row_no, (tiles, map)): (usize, (&'m Vec<Tile>, &'m Map))) -> Row<'m> {
            Row {
                map: map,
                row_no: row_no,
                tiles: tiles.as_slice(),
            }
        }
        let maps = Some(self).into_iter().cycle();
        RowIter(self.tiles.iter().zip(maps).enumerate().map(to_row))
    }
}

pub struct Row<'m> {
    map: &'m Map,
    pub row_no: usize,
    pub tiles: &'m [Tile],
}

impl<'m> IntoIterator for Row<'m> {
    type Item = Location<'m>;
    type IntoIter = RowLocationsIter<'m>;

    fn into_iter(self) -> RowLocationsIter<'m> {
        let maps = Some(self.map).into_iter().cycle();
        RowLocationsIter {
            row_no: self.row_no,
            row_iter: self.tiles.iter().zip(maps).enumerate(),
        }
    }
}

type ESIter<'i, T> = Enumerate<ZipIter<SliceIter<'i, T>, Cycle<OptionIntoIter<&'i Map>>>>;
type ToRowFn<'m> = fn((usize, (&'m Vec<Tile>, &'m Map))) -> Row<'m>;
pub struct RowIter<'m>(MapIter<ESIter<'m, Vec<Tile>>, ToRowFn<'m>>);

impl<'m> Iterator for RowIter<'m> {
    type Item = Row<'m>;

    fn next(&mut self) -> Option<Row<'m>> {
        self.0.next()
    }
}

pub struct RowLocationsIter<'m> {
    row_no: usize,
    row_iter: ESIter<'m, Tile>,
}

impl<'m> Iterator for RowLocationsIter<'m> {
    type Item = Location<'m>;

    fn next(&mut self) -> Option<Location<'m>> {
        self.row_iter.next().map(|(col_no, (tile, map))| {
            Location {
                map: map,
                coordinates: Coordinates(col_no, self.row_no),
                tile: tile,
            }
        })
    }
}

#[test]
fn test_direction_iter() {
    assert_eq!(
        Direction::clockwise().collect::<Vec<_>>(),
        vec![
            Direction::Up,
            Direction::Right,
            Direction::Down,
            Direction::Left,
        ]
    )
}
<commit_msg>moved map tests to tests module<commit_after>use std::ptr;
use std::hash::{Hash, Hasher};
use std::slice::Iter as SliceIter;
use std::iter::Zip as ZipIter;
use std::iter::Map as MapIter;
use std::iter::Enumerate;
use std::option::IntoIter as OptionIntoIter;
use std::iter::Cycle;

#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub struct Coordinates(pub usize, pub usize);

impl Coordinates {
    pub fn in_direction(&self, direction: Direction) -> Option<Coordinates> {
        match direction {
            Direction::Up if self.1 > 0 => Some(Coordinates(self.0, self.1 - 1)),
            Direction::Right if self.0 < usize::max_value() => {
                Some(Coordinates(self.0 + 1, self.1))
            }
            Direction::Down if self.1 < usize::max_value() => Some(Coordinates(self.0, self.1 + 1)),
            Direction::Left if self.0 > 0 => Some(Coordinates(self.0 - 1, self.1)),
            _ => None,
        }
    }

    pub fn direction_to(&self, to: Coordinates) -> Option<Direction> {
        if self.0 == to.0 && self.1 == to.1 {
            return None;
        }

        Some(
            if to.1 + to.0 >= self.1 + self.0 && to.1 + self.0 > to.0 + self.1 {
                Direction::Down
            } else if to.1 + self.0 <= to.0 + self.1 && to.1 + to.0 > self.1 + self.0 {
                Direction::Right
            } else if to.1 + to.0 <= self.1 + self.0 && to.1 + self.0 < to.0 + self.1 {
                Direction::Up
            } else {
                Direction::Left
            },
        )
    }
}

#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum Direction {
    Up,
    Right,
    Down,
    Left,
}

impl Direction {
    fn clockwise() -> DirectionClockwiseIter {
        DirectionClockwiseIter {
            direction: Some(Direction::Up),
        }
    }
}

#[derive(Debug)]
pub struct DirectionClockwiseIter {
    direction: Option<Direction>,
}

impl Iterator for DirectionClockwiseIter {
    type Item = Direction;

    fn next(&mut self) -> Option<Direction> {
        let next_direction = match self.direction {
            Some(Direction::Up) => Some(Direction::Right),
            Some(Direction::Right) => Some(Direction::Down),
            Some(Direction::Down) => Some(Direction::Left),
            Some(Direction::Left) => None,
            None => None,
        };
        let ret = self.direction;
        self.direction = next_direction;
        ret
    }
}

#[derive(Debug, Clone, Copy)]
pub struct Location<'m> {
    map: &'m Map,
    pub coordinates: Coordinates,
    pub tile: &'m Tile,
}

impl<'m> PartialEq for Location<'m> {
    fn eq(&self, other: &Location<'m>) -> bool {
        ptr::eq(self.tile, other.tile)
    }
}

impl<'m> Eq for Location<'m> {}

impl<'m> Hash for Location<'m> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        state.write_usize((self.tile as *const Tile) as usize)
    }
}

impl<'m> Location<'m> {
    pub fn neighbours(&self) -> NeighboursIter<'m> {
        NeighboursIter {
            location: self.clone(),
            directions: Direction::clockwise(),
        }
    }

    pub fn in_direction(&self, direction: Direction) -> Option<Location<'m>> {
        self.coordinates
            .in_direction(direction)
            .and_then(|coordinates| self.map.location(coordinates))
    }

    pub fn direction_to(&self, to: Location<'m>) -> Option<Direction> {
        self.coordinates.direction_to(to.coordinates)
    }

    pub fn walkable(&self) -> bool {
        match *self.tile {
            Tile::Empty => true,
            _ => false,
        }
    }
}

pub struct NeighboursIter<'m> {
    location: Location<'m>,
    directions: DirectionClockwiseIter,
}

impl<'m> Iterator for NeighboursIter<'m> {
    type Item = (Direction, Location<'m>);

    fn next(&mut self) -> Option<(Direction, Location<'m>)> {
        while let Some(direction) = self.directions.next() {
            if let ret @ Some(_) = self.location
                .in_direction(direction)
                .map(|location| (direction, location))
            {
                return ret;
            }
        }
        None
    }
}

#[derive(PartialEq, Eq, Hash, Debug)]
pub enum Tile {
    Empty,
    Wall,
}

#[derive(Debug)]
pub struct Map {
    tiles: Vec<Vec<Tile>>, // TODO: Matix
}

pub struct Dimension(usize);

impl Dimension {
    pub fn new(dimension: usize) -> Option<Dimension> {
        if dimension > 0 {
            Some(Dimension(dimension))
        } else {
            None
        }
    }

    pub fn unwrap(self) -> usize {
        self.0
    }
}

impl Map {
    pub fn new(width: Dimension, height: Dimension) -> Map {
        let width = width.unwrap();
        let height = height.unwrap();

        Map {
            tiles: (0..height)
                .map(|_row| (0..width).map(|_col| Tile::Empty).collect())
                .collect(),
        }
    }

    pub fn width(&self) -> usize {
        self.tiles.iter().next().unwrap().len()
    }

    pub fn height(&self) -> usize {
        self.tiles.len()
    }

    pub fn get_mut_tile(&mut self, coordinates: Coordinates) -> Option<&mut Tile> {
        self.tiles
            .get_mut(coordinates.1)
            .and_then(|row| row.get_mut(coordinates.0))
    }

    pub fn location(&self, coordinates: Coordinates) -> Option<Location> {
        self.tiles
            .get(coordinates.1)
            .and_then(|row| row.get(coordinates.0))
            .map(|tile| {
                Location {
                    map: &self,
                    coordinates: coordinates,
                    tile: tile,
                }
            })
    }

    pub fn rows(&self) -> RowIter {
        fn to_row<'m>((row_no, (tiles, map)): (usize, (&'m Vec<Tile>, &'m Map))) -> Row<'m> {
            Row {
                map: map,
                row_no: row_no,
                tiles: tiles.as_slice(),
            }
        }
        let maps = Some(self).into_iter().cycle();
        RowIter(self.tiles.iter().zip(maps).enumerate().map(to_row))
    }
}

pub struct Row<'m> {
    map: &'m Map,
    pub row_no: usize,
    pub tiles: &'m [Tile],
}

impl<'m> IntoIterator for Row<'m> {
    type Item = Location<'m>;
    type IntoIter = RowLocationsIter<'m>;

    fn into_iter(self) -> RowLocationsIter<'m> {
        let maps = Some(self.map).into_iter().cycle();
        RowLocationsIter {
            row_no: self.row_no,
            row_iter: self.tiles.iter().zip(maps).enumerate(),
        }
    }
}

type ESIter<'i, T> = Enumerate<ZipIter<SliceIter<'i, T>, Cycle<OptionIntoIter<&'i Map>>>>;
type ToRowFn<'m> = fn((usize, (&'m Vec<Tile>, &'m Map))) -> Row<'m>;
pub struct RowIter<'m>(MapIter<ESIter<'m, Vec<Tile>>, ToRowFn<'m>>);

impl<'m> Iterator for RowIter<'m> {
    type Item = Row<'m>;

    fn next(&mut self) -> Option<Row<'m>> {
        self.0.next()
    }
}

pub struct RowLocationsIter<'m> {
    row_no: usize,
    row_iter: ESIter<'m, Tile>,
}

impl<'m> Iterator for RowLocationsIter<'m> {
    type Item = Location<'m>;

    fn next(&mut self) -> Option<Location<'m>> {
        self.row_iter.next().map(|(col_no, (tile, map))| {
            Location {
                map: map,
                coordinates: Coordinates(col_no, self.row_no),
                tile: tile,
            }
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn in_direction_overflow() {
        assert!(Coordinates(0, 0).in_direction(Direction::Up).is_none());
        assert!(Coordinates(0, 0).in_direction(Direction::Left).is_none());
        assert!(Coordinates(0, 0).in_direction(Direction::Down).is_some());
        assert!(Coordinates(0, 0).in_direction(Direction::Right).is_some());

        assert!(Coordinates(1, 1).in_direction(Direction::Up).is_some());
        assert!(Coordinates(1, 1).in_direction(Direction::Left).is_some());
        assert!(Coordinates(1, 1).in_direction(Direction::Down).is_some());
        assert!(Coordinates(1, 1).in_direction(Direction::Right).is_some());

        assert!(
            Coordinates(usize::max_value(), usize::max_value())
                .in_direction(Direction::Up)
                .is_some()
        );
        assert!(
            Coordinates(usize::max_value(), usize::max_value())
                .in_direction(Direction::Left)
                .is_some()
        );
        assert!(
            Coordinates(usize::max_value(), usize::max_value())
                .in_direction(Direction::Down)
                .is_none()
        );
        assert!(
            Coordinates(usize::max_value(), usize::max_value())
                .in_direction(Direction::Right)
                .is_none()
        );
    }

    #[test]
    fn test_direction_to() {
        assert_eq!(Coordinates(1, 1).direction_to(Coordinates(1, 1)), None);

        assert_eq!(
            Coordinates(0, 0).direction_to(Coordinates(1, 0)),
            Some(Direction::Right)
        );
        assert_eq!(
            Coordinates(2, 0).direction_to(Coordinates(1, 0)),
            Some(Direction::Left)
        );

        assert_eq!(
            Coordinates(0, 0).direction_to(Coordinates(0, 1)),
            Some(Direction::Down)
        );
        assert_eq!(
            Coordinates(0, 2).direction_to(Coordinates(0, 1)),
            Some(Direction::Up)
        );

        assert_eq!(
            Coordinates(0, 0).direction_to(Coordinates(2, 1)),
            Some(Direction::Right)
        );
        assert_eq!(
            Coordinates(4, 0).direction_to(Coordinates(2, 1)),
            Some(Direction::Left)
        );

        assert_eq!(
            Coordinates(0, 2).direction_to(Coordinates(2, 1)),
            Some(Direction::Right)
        );
        assert_eq!(
            Coordinates(4, 2).direction_to(Coordinates(2, 1)),
            Some(Direction::Left)
        );

        assert_eq!(
            Coordinates(0, 0).direction_to(Coordinates(1, 2)),
            Some(Direction::Down)
        );
        assert_eq!(
            Coordinates(0, 4).direction_to(Coordinates(1, 2)),
            Some(Direction::Up)
        );
    }

    #[test]
    fn location_neighbours() {
        let map = Map::new(Dimension::new(8).unwrap(), Dimension::new(8).unwrap());

        assert_eq!(
            map.location(Coordinates(0, 0))
                .unwrap()
                .neighbours()
                .collect::<Vec<_>>(),
            vec![
                (Direction::Right, map.location(Coordinates(1, 0)).unwrap()),
                (Direction::Down, map.location(Coordinates(0, 1)).unwrap()),
            ]
        )
    }

    #[test]
    fn test_direction_iter() {
        assert_eq!(
            Direction::clockwise().collect::<Vec<_>>(),
            vec![
                Direction::Up,
                Direction::Right,
                Direction::Down,
                Direction::Left,
            ]
        )
    }
}
<|endoftext|>


<commit_before>extern crate find_folder;

use screen::{self, Screen, MainMenu};
use context::{Context, GameState};

use piston_window::{self, PistonWindow, WindowSettings};

type Screens = Vec<Box<screen::Screen>>;

pub struct Game {
    window: PistonWindow,
    context: Context,
    screens: Screens,
}

impl Game {
    pub fn new() -> Self {
        let window: PistonWindow = WindowSettings::new("rrthozopsi", [600, 600])
                                       .build()
                                       .unwrap();
        let mut context = Context {
            assets_path: find_folder::Search::KidsThenParents(3, 5).for_folder("assets").unwrap(),
            game_state: GameState::NotStarted,
        };
        let screens: Screens = vec![Box::new(MainMenu::new(&window, &mut context))];
        Game {
            window: window,
            screens: screens,
            context: context,
        }
    }

    pub fn run(&mut self) {
        use piston_window::Event;

        let screens = &mut self.screens;

        for window in &mut self.window {
            match window.event {
                Some(Event::Update(ref args)) => {
                    last(screens).on_update(&args);
                }
                Some(Event::Render(ref args)) => {
                    last(screens).on_draw(&args, &window);
                }
                Some(Event::Input(ref input)) => {
                    handle_input(screens, &input, &window, &mut self.context);
                    if screens.is_empty() {
                        // No screens - exit game.
                        return;
                    }
                }
                _ => {}
            }
        }
    }
}

fn last<'a>(vec: &'a mut Screens) -> &'a mut Box<screen::Screen> {
    vec.last_mut().unwrap()
}

fn handle_input(screens: &mut Screens, input: &piston_window::Input, window: &PistonWindow, context: &mut Context) {
    for action in last(screens).on_input(&input, &window, context) {
        match action {
            screen::InputResult::PushScreen(new_screen) => {
                screens.push(new_screen);
            }
            screen::InputResult::PopScreen => {
                screens.pop();
            }
            screen::InputResult::Exit => {}
        }
    }
}
<commit_msg>TODO note<commit_after>extern crate find_folder;

use screen::{self, Screen, MainMenu};
use context::{Context, GameState};

use piston_window::{self, PistonWindow, WindowSettings};

type Screens = Vec<Box<screen::Screen>>;

pub struct Game {
    window: PistonWindow,
    context: Context,
    screens: Screens,
}

impl Game {
    pub fn new() -> Self {
        let window: PistonWindow = WindowSettings::new("rrthozopsi", [600, 600])
                                       .build()
                                       .unwrap();
        let mut context = Context {
            assets_path: find_folder::Search::KidsThenParents(3, 5).for_folder("assets").unwrap(),
            game_state: GameState::NotStarted,
        };
        let screens: Screens = vec![Box::new(MainMenu::new(&window, &mut context))];
        Game {
            window: window,
            screens: screens,
            context: context,
        }
    }

    pub fn run(&mut self) {
        use piston_window::Event;

        let screens = &mut self.screens;

        for window in &mut self.window {
            match window.event {
                Some(Event::Update(ref args)) => {
                    last(screens).on_update(&args);
                }
                Some(Event::Render(ref args)) => {
                    last(screens).on_draw(&args, &window);
                }
                Some(Event::Input(ref input)) => {
                    handle_input(screens, &input, &window, &mut self.context);
                    if screens.is_empty() {
                        // No screens - exit game.
                        return;
                    }
                }
                _ => {}
            }
        }
    }
}

fn last<'a>(vec: &'a mut Screens) -> &'a mut Box<screen::Screen> {
    vec.last_mut().unwrap()
}

fn handle_input(screens: &mut Screens, input: &piston_window::Input, window: &PistonWindow, context: &mut Context) {
    for action in last(screens).on_input(&input, &window, context) {
        match action {
            screen::InputResult::PushScreen(new_screen) => {
                screens.push(new_screen);
            }
            screen::InputResult::PopScreen => {
                screens.pop();
            }
            // TODO: Handle event correctly.
            // TODO: Use screen::InputResult.
            screen::InputResult::Exit => {}
        }
    }
}
<|endoftext|>


<commit_before>use std::borrow::Cow;
use std::fmt::{Display, self};
use std::str::FromStr;
use url::Url;
use url::ParseError as UrlError;

use Error;

/// The Request-URI of a Request's StartLine.
///
/// From Section 5.3, Request Target:
/// > Once an inbound connection is obtained, the client sends an HTTP
/// > request message (Section 3) with a request-target derived from the
/// > target URI.  There are four distinct formats for the request-target,
/// > depending on both the method being requested and whether the request
/// > is to a proxy.
/// >
/// > ```notrust
/// > request-target = origin-form
/// >                / absolute-form
/// >                / authority-form
/// >                / asterisk-form
/// > ```
///
/// # Uri explanations
///
/// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
/// |-|   |-------------------------------||--------| |-------------------| |-----|
///  |                  |                       |               |              |
/// scheme          authority                 path            query         fragment
#[derive(Clone)]
pub struct Uri {
    source: Cow<'static, str>,
    scheme_end: Option<usize>,
    authority_end: Option<usize>,
    query: Option<usize>,
    fragment: Option<usize>,
}

impl Uri {
    /// Parse a string into a `Uri`.
    pub fn new(s: &str) -> Result<Uri, Error> {
        let bytes = s.as_bytes();
        if bytes.len() == 0 {
            Err(Error::Uri(UrlError::RelativeUrlWithoutBase))
        } else if bytes == b"*" {
            Ok(Uri {
                source: "*".into(),
                scheme_end: None,
                authority_end: None,
                query: None,
                fragment: None,
            })
        } else if bytes == b"/" {
            Ok(Uri::default())
        } else if bytes.starts_with(b"/") {
            Ok(Uri {
                source: s.to_owned().into(),
                scheme_end: None,
                authority_end: None,
                query: parse_query(s),
                fragment: parse_fragment(s),
            })
        } else if s.contains("://") {
            Ok(Uri {
                source: s.to_owned().into(),
                scheme_end: parse_scheme(s),
                authority_end: parse_authority(s),
                query: parse_query(s),
                fragment: parse_fragment(s),
            })
        } else {
            Ok(Uri {
                source: s.to_owned().into(),
                scheme_end: None,
                authority_end: Some(s.len()),
                query: None,
                fragment: None,
            })
        }
    }

    /// Get the path of this `Uri`.
    pub fn path(&self) -> &str {
        let index = self.authority_end.unwrap_or(self.scheme_end.unwrap_or(0));
        let query_len = self.query.unwrap_or(0);
        let fragment_len = self.fragment.unwrap_or(0);
        let end = self.source.len() - if query_len > 0 { query_len + 1 } else { 0 } -
            if fragment_len > 0 { fragment_len + 1 } else { 0 };
        if index >= end {
            ""
        } else {
            &self.source[index..end]
        }
    }

    /// Get the scheme of this `Uri`.
    pub fn scheme(&self) -> Option<&str> {
        if let Some(end) = self.scheme_end {
            Some(&self.source[..end])
        } else {
            None
        }
    }

    /// Get the authority of this `Uri`.
    pub fn authority(&self) -> Option<&str> {
        if let Some(end) = self.authority_end {
            let index = self.scheme_end.map(|i| i + 3).unwrap_or(0);
            Some(&self.source[index..end])
        } else {
            None
        }
    }

    /// Get the host of this `Uri`.
    pub fn host(&self) -> Option<&str> {
        if let Some(auth) = self.authority() {
            auth.split(":").next()
        } else {
            None
        }
    }

    /// Get the port of this `Uri.
    pub fn port(&self) -> Option<u16> {
        if let Some(auth) = self.authority() {
            let v: Vec<&str> = auth.split(":").collect();
            if v.len() == 2 {
                u16::from_str(v[1]).ok()
            } else {
                None
            }
        } else {
            None
        }
    }

    /// Get the query string of this `Uri`, starting after the `?`.
    pub fn query(&self) -> Option<&str> {
        let fragment_len = self.fragment.unwrap_or(0);
        let fragment_len = if fragment_len > 0 { fragment_len + 1 } else { 0 };
        if let Some(len) = self.query {
            Some(&self.source[self.source.len() - len - fragment_len..self.source.len() - fragment_len])
        } else {
            None
        }
    }

    #[cfg(test)]
    fn fragment(&self) -> Option<&str> {
        if let Some(len) = self.fragment {
            Some(&self.source[self.source.len() - len..])
        } else {
            None
        }
    }
}

fn parse_scheme(s: &str) -> Option<usize> {
    s.find(':')
}

fn parse_authority(s: &str) -> Option<usize> {
    let v: Vec<&str> = s.split("://").collect();
    let auth = v.last().unwrap()
        .split("/")
        .next()
        .unwrap_or(s)
        .len() + if v.len() == 2 { v[0].len() + 3 } else { 0 };

    return Some(auth);
}

fn parse_query(s: &str) -> Option<usize> {
    match s.find('?') {
        Some(i) => {
            let frag_pos = s.find('#').unwrap_or(s.len());

            return Some(frag_pos - i - 1);
        },
        None => None,
    }
}

fn parse_fragment(s: &str) -> Option<usize> {
    match s.find('#') {
        Some(i) => Some(s.len() - i - 1),
        None => None,
    }
}

impl FromStr for Uri {
    type Err = Error;

    fn from_str(s: &str) -> Result<Uri, Error> {
        Uri::new(s)
    }
}

impl From<Url> for Uri {
    fn from(url: Url) -> Uri {
        Uri::new(url.as_str()).expect("Uri::From<Url> failed")
    }
}

impl PartialEq for Uri {
    fn eq(&self, other: &Uri) -> bool {
        self.source == other.source
    }
}

impl AsRef<str> for Uri {
    fn as_ref(&self) -> &str {
        &self.source
    }
}

impl Default for Uri {
    fn default() -> Uri {
        Uri {
            source: "/".into(),
            scheme_end: None,
            authority_end: None,
            query: None,
            fragment: None,
        }
    }
}

impl fmt::Debug for Uri {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.source.as_ref(), f)
    }
}

impl Display for Uri {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.source)
    }
}

macro_rules! test_parse {
    (
        $test_name:ident,
        $str:expr,
        $($method:ident = $value:expr,)*
    ) => (
        #[test]
        fn $test_name() {
            let uri = Uri::new($str).unwrap();
            $(
            assert_eq!(uri.$method(), $value);
            )+
        }
    );
}

test_parse! {
    test_uri_parse_origin_form,
    "/some/path/here?and=then&hello#and-bye",

    scheme = None,
    authority = None,
    path = "/some/path/here",
    query = Some("and=then&hello"),
    fragment = Some("and-bye"),
}

test_parse! {
    test_uri_parse_absolute_form,
    "http://127.0.0.1:61761/chunks",

    scheme = Some("http"),
    authority = Some("127.0.0.1:61761"),
    path = "/chunks",
    query = None,
    fragment = None,
}

test_parse! {
    test_uri_parse_absolute_form_without_path,
    "https://127.0.0.1:61761",

    scheme = Some("https"),
    authority = Some("127.0.0.1:61761"),
    path = "/",
    query = None,
    fragment = None,
}

test_parse! {
    test_uri_parse_asterisk_form,
    "*",

    scheme = None,
    authority = None,
    path = "*",
    query = None,
    fragment = None,
}

test_parse! {
    test_uri_parse_authority_form,
    "localhost:3000",

    scheme = None,
    authority = Some("localhost:3000"),
    path = "",
    query = None,
    fragment = None,
}

test_parse! {
    test_uri_parse_absolute_with_default_port_http,
    "http://127.0.0.1:80",

    scheme = Some("http"),
    authority = Some("127.0.0.1"),
    path = "/",
    query = None,
    fragment = None,
}

test_parse! {
    test_uri_parse_absolute_with_default_port_https,
    "https://127.0.0.1:443",

    scheme = Some("https"),
    authority = Some("127.0.0.1"),
    path = "/",
    query = None,
    fragment = None,
}

#[test]
fn test_uri_parse_error() {
    fn err(s: &str) {
        Uri::new(s).unwrap_err();
    }

    err("http://");
    //TODO: these should error
    //err("htt:p//host");
    //err("hyper.rs/");
    //err("hyper.rs?key=val");
}

#[test]
fn test_uri_from_url() {
    let uri = Uri::from(Url::parse("http://test.com/nazghul?test=3").unwrap());
    assert_eq!(uri.path(), "/nazghul");
    assert_eq!(uri.authority(), Some("test.com"));
    assert_eq!(uri.scheme(), Some("http"));
    assert_eq!(uri.query(), Some("test=3"));
    assert_eq!(uri.as_ref(), "http://test.com/nazghul?test=3");
}
<commit_msg>refactor(uri): Remove extra authority logic<commit_after>use std::borrow::Cow;
use std::fmt::{Display, self};
use std::str::FromStr;
use url::Url;
use url::ParseError as UrlError;

use Error;

/// The Request-URI of a Request's StartLine.
///
/// From Section 5.3, Request Target:
/// > Once an inbound connection is obtained, the client sends an HTTP
/// > request message (Section 3) with a request-target derived from the
/// > target URI.  There are four distinct formats for the request-target,
/// > depending on both the method being requested and whether the request
/// > is to a proxy.
/// >
/// > ```notrust
/// > request-target = origin-form
/// >                / absolute-form
/// >                / authority-form
/// >                / asterisk-form
/// > ```
///
/// # Uri explanations
///
/// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
/// |-|   |-------------------------------||--------| |-------------------| |-----|
///  |                  |                       |               |              |
/// scheme          authority                 path            query         fragment
#[derive(Clone)]
pub struct Uri {
    source: Cow<'static, str>,
    scheme_end: Option<usize>,
    authority_end: Option<usize>,
    query: Option<usize>,
    fragment: Option<usize>,
}

impl Uri {
    /// Parse a string into a `Uri`.
    pub fn new(s: &str) -> Result<Uri, Error> {
        let bytes = s.as_bytes();
        if bytes.len() == 0 {
            Err(Error::Uri(UrlError::RelativeUrlWithoutBase))
        } else if bytes == b"*" {
            Ok(Uri {
                source: "*".into(),
                scheme_end: None,
                authority_end: None,
                query: None,
                fragment: None,
            })
        } else if bytes == b"/" {
            Ok(Uri::default())
        } else if bytes.starts_with(b"/") {
            Ok(Uri {
                source: s.to_owned().into(),
                scheme_end: None,
                authority_end: None,
                query: parse_query(s),
                fragment: parse_fragment(s),
            })
        } else if s.contains("://") {
            Ok(Uri {
                source: s.to_owned().into(),
                scheme_end: parse_scheme(s),
                authority_end: parse_authority(s),
                query: parse_query(s),
                fragment: parse_fragment(s),
            })
        } else {
            Ok(Uri {
                source: s.to_owned().into(),
                scheme_end: None,
                authority_end: Some(s.len()),
                query: None,
                fragment: None,
            })
        }
    }

    /// Get the path of this `Uri`.
    pub fn path(&self) -> &str {
        let index = self.authority_end.unwrap_or(self.scheme_end.unwrap_or(0));
        let query_len = self.query.unwrap_or(0);
        let fragment_len = self.fragment.unwrap_or(0);
        let end = self.source.len() - if query_len > 0 { query_len + 1 } else { 0 } -
            if fragment_len > 0 { fragment_len + 1 } else { 0 };
        if index >= end {
            ""
        } else {
            &self.source[index..end]
        }
    }

    /// Get the scheme of this `Uri`.
    pub fn scheme(&self) -> Option<&str> {
        if let Some(end) = self.scheme_end {
            Some(&self.source[..end])
        } else {
            None
        }
    }

    /// Get the authority of this `Uri`.
    pub fn authority(&self) -> Option<&str> {
        if let Some(end) = self.authority_end {
            let index = self.scheme_end.map(|i| i + 3).unwrap_or(0);

            Some(&self.source[index..end])
        } else {
            None
        }
    }

    /// Get the host of this `Uri`.
    pub fn host(&self) -> Option<&str> {
        if let Some(auth) = self.authority() {
            auth.split(":").next()
        } else {
            None
        }
    }

    /// Get the port of this `Uri.
    pub fn port(&self) -> Option<u16> {
        if let Some(auth) = self.authority() {
            let v: Vec<&str> = auth.split(":").collect();
            if v.len() == 2 {
                u16::from_str(v[1]).ok()
            } else {
                None
            }
        } else {
            None
        }
    }

    /// Get the query string of this `Uri`, starting after the `?`.
    pub fn query(&self) -> Option<&str> {
        let fragment_len = self.fragment.unwrap_or(0);
        let fragment_len = if fragment_len > 0 { fragment_len + 1 } else { 0 };
        if let Some(len) = self.query {
            Some(&self.source[self.source.len() - len - fragment_len..self.source.len() - fragment_len])
        } else {
            None
        }
    }

    #[cfg(test)]
    fn fragment(&self) -> Option<&str> {
        if let Some(len) = self.fragment {
            Some(&self.source[self.source.len() - len..])
        } else {
            None
        }
    }
}

fn parse_scheme(s: &str) -> Option<usize> {
    s.find(':')
}

fn parse_authority(s: &str) -> Option<usize> {
    let v: Vec<&str> = s.split("://").collect();
    let auth = v.last().unwrap()
        .split("/")
        .next()
        .unwrap_or(s)
        .len() + if v.len() == 2 { v[0].len() + 3 } else { 0 };

    return Some(auth);
}

fn parse_query(s: &str) -> Option<usize> {
    match s.find('?') {
        Some(i) => {
            let frag_pos = s.find('#').unwrap_or(s.len());

            return Some(frag_pos - i - 1);
        },
        None => None,
    }
}

fn parse_fragment(s: &str) -> Option<usize> {
    match s.find('#') {
        Some(i) => Some(s.len() - i - 1),
        None => None,
    }
}

impl FromStr for Uri {
    type Err = Error;

    fn from_str(s: &str) -> Result<Uri, Error> {
        Uri::new(s)
    }
}

impl From<Url> for Uri {
    fn from(url: Url) -> Uri {
        Uri::new(url.as_str()).expect("Uri::From<Url> failed")
    }
}

impl PartialEq for Uri {
    fn eq(&self, other: &Uri) -> bool {
        self.source == other.source
    }
}

impl AsRef<str> for Uri {
    fn as_ref(&self) -> &str {
        &self.source
    }
}

impl Default for Uri {
    fn default() -> Uri {
        Uri {
            source: "/".into(),
            scheme_end: None,
            authority_end: None,
            query: None,
            fragment: None,
        }
    }
}

impl fmt::Debug for Uri {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.source.as_ref(), f)
    }
}

impl Display for Uri {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.source)
    }
}

macro_rules! test_parse {
    (
        $test_name:ident,
        $str:expr,
        $($method:ident = $value:expr,)*
    ) => (
        #[test]
        fn $test_name() {
            let uri = Uri::new($str).unwrap();
            $(
            assert_eq!(uri.$method(), $value);
            )+
        }
    );
}

test_parse! {
    test_uri_parse_origin_form,
    "/some/path/here?and=then&hello#and-bye",

    scheme = None,
    authority = None,
    path = "/some/path/here",
    query = Some("and=then&hello"),
    fragment = Some("and-bye"),
}

test_parse! {
    test_uri_parse_absolute_form,
    "http://127.0.0.1:61761/chunks",

    scheme = Some("http"),
    authority = Some("127.0.0.1:61761"),
    path = "/chunks",
    query = None,
    fragment = None,
}

test_parse! {
    test_uri_parse_absolute_form_without_path,
    "https://127.0.0.1:61761",

    scheme = Some("https"),
    authority = Some("127.0.0.1:61761"),
    path = "/",
    query = None,
    fragment = None,
}

test_parse! {
    test_uri_parse_asterisk_form,
    "*",

    scheme = None,
    authority = None,
    path = "*",
    query = None,
    fragment = None,
}

test_parse! {
    test_uri_parse_authority_form,
    "localhost:3000",

    scheme = None,
    authority = Some("localhost:3000"),
    path = "",
    query = None,
    fragment = None,
}

test_parse! {
    test_uri_parse_absolute_with_default_port_http,
    "http://127.0.0.1:80",

    scheme = Some("http"),
    authority = Some("127.0.0.1"),
    path = "/",
    query = None,
    fragment = None,
}

test_parse! {
    test_uri_parse_absolute_with_default_port_https,
    "https://127.0.0.1:443",

    scheme = Some("https"),
    authority = Some("127.0.0.1"),
    path = "/",
    query = None,
    fragment = None,
}

#[test]
fn test_uri_parse_error() {
    fn err(s: &str) {
        Uri::new(s).unwrap_err();
    }

    err("http://");
    //TODO: these should error
    //err("htt:p//host");
    //err("hyper.rs/");
    //err("hyper.rs?key=val");
}

#[test]
fn test_uri_from_url() {
    let uri = Uri::from(Url::parse("http://test.com/nazghul?test=3").unwrap());
    assert_eq!(uri.path(), "/nazghul");
    assert_eq!(uri.authority(), Some("test.com"));
    assert_eq!(uri.scheme(), Some("http"));
    assert_eq!(uri.query(), Some("test=3"));
    assert_eq!(uri.as_ref(), "http://test.com/nazghul?test=3");
}
<|endoftext|>