<commit_before>use semver::Version;

lazy_static! {
    static ref FIRST_MACOS_VERSION: Version = version!(3, 5, 4);
    static ref LAST_MACOS_VERSION: Version = version!(3, 6, 0);
}

fn name_uses_macos(version: &Version) -> bool {
    version >= &FIRST_MACOS_VERSION && version < &LAST_MACOS_VERSION
}

#[derive(Debug)]
pub struct Url {
    base: String,
    filename: String,
    dirname: String,
}

impl Url {
    pub fn filename(&self) -> String {
        self.filename.clone()
    }

    pub fn dirname(&self) -> String {
        self.dirname.clone()
    }
}

impl From<Url> for String {
    fn from(url: Url) -> Self {
        format!("{}/{}", url.base, url.filename)
    }
}

#[derive(Debug)]
pub struct UrlBuilder<'a> {
    os: &'a str,
    distro: Vec<String>,
    extension: &'a str,
    version: &'a Version,
}

const SCHEME: &str = "https";
const DOMAIN: &str = "fastdl.mongodb.org";

impl<'a> UrlBuilder<'a> {
    pub fn new(os: &'a str, extension: &'a str, version: &'a Version) -> UrlBuilder<'a> {
        Self {
            os,
            distro: Vec::new(),
            extension,
            version,
        }
    }

    pub fn add_distro_path_item(&mut self, item: String) {
        self.distro.push(item)
    }

    pub fn build(self) -> Url {
        let base = format!("{}://{}/{}", SCHEME, DOMAIN, self.os);

        let mut filename = String::new();
        let mut dirname = String::new();

        for (i, mut item) in self.distro.into_iter().enumerate() {
            if i != 0 {
                filename.push('-');
            }

            filename.push_str(&item);

            if item == "ssl" {
                continue;
            }

            if item == "osx" && name_uses_macos(self.version) {
                item = "macOS".to_string();
            }

            if i != 0 {
                dirname.push('-');
            }

            dirname.push_str(&item);
        }

        filename.push('.');
        filename.push_str(self.extension);

        Url {
            base,
            filename,
            dirname,
        }
    }
}
<commit_msg>fix url generation for newer macos builds<commit_after>use semver::Version;

lazy_static! {
    static ref FIRST_MACOS_VERSION: Version = version!(3, 5, 4);
    static ref LAST_MACOS_VERSION: Version = version!(3, 6, 0);
    static ref NEW_MACOS_VERSION: Version = version!(4, 1, 1);
}

fn name_uses_macos(version: &Version) -> bool {
    version >= &FIRST_MACOS_VERSION && version < &LAST_MACOS_VERSION
}

fn url_uses_macos(version: &Version) -> bool {
    version >= &NEW_MACOS_VERSION
}

#[derive(Debug)]
pub struct Url {
    base: String,
    filename: String,
    dirname: String,
}

impl Url {
    pub fn filename(&self) -> String {
        self.filename.clone()
    }

    pub fn dirname(&self) -> String {
        self.dirname.clone()
    }
}

impl From<Url> for String {
    fn from(url: Url) -> Self {
        format!("{}/{}", url.base, url.filename)
    }
}

#[derive(Debug)]
pub struct UrlBuilder<'a> {
    os: &'a str,
    distro: Vec<String>,
    extension: &'a str,
    version: &'a Version,
}

const SCHEME: &str = "https";
const DOMAIN: &str = "fastdl.mongodb.org";

impl<'a> UrlBuilder<'a> {
    pub fn new(os: &'a str, extension: &'a str, version: &'a Version) -> UrlBuilder<'a> {
        Self {
            os,
            distro: Vec::new(),
            extension,
            version,
        }
    }

    pub fn add_distro_path_item(&mut self, item: String) {
        self.distro.push(item)
    }

    pub fn build(mut self) -> Url {
        let base = format!("{}://{}/{}", SCHEME, DOMAIN, self.os);

        let mut filename = String::new();
        let mut dirname = String::new();

        if url_uses_macos(self.version) && &self.distro[1..=2] == &["osx", "ssl"] {
            // This is inefficient, but there are only a handful of elements, so we don't care.
            let mut replacement = vec!["mongodb".to_string(), "macos".to_string()];
            replacement.extend(self.distro.split_off(3));

            self.distro = replacement;
        }

        for (i, mut item) in self.distro.into_iter().enumerate() {
            if i != 0 {
                filename.push('-');
            }

            filename.push_str(&item);

            if item == "ssl" {
                continue;
            }

            if item == "osx" && name_uses_macos(self.version) {
                item = "macOS".to_string();
            }

            if i != 0 {
                dirname.push('-');
            }

            dirname.push_str(&item);
        }

        filename.push('.');
        filename.push_str(self.extension);

        Url {
            base,
            filename,
            dirname,
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::marker::PhantomData;
use std::ops::RangeFrom;
use {Command, Error, Record};

#[derive(Debug)]
struct Branch<R> {
    parent: usize,
    cursor: usize,
    commands: Box<[Box<dyn Command<R> + 'static>]>,
}

/// A history of commands.
#[derive(Debug)]
pub struct History<R> {
    id: usize,
    next: RangeFrom<usize>,
    record: Record<R>,
    branches: HashMap<usize, Branch<R>>,
}

impl<R> History<R> {
    /// Returns a new history.
    #[inline]
    pub fn new(receiver: impl Into<R>) -> History<R> {
        History {
            id: 0,
            next: 1..,
            record: Record::new(receiver),
            branches: HashMap::new(),
        }
    }

    /// Pushes the command to the top of the history and executes its [`apply`] method.
    /// The command is merged with the previous top command if they have the same [`id`].
    ///
    /// # Errors
    /// If an error occur when executing [`apply`] the error is returned together with the command.
    ///
    /// [`apply`]: trait.Command.html#tymethod.apply
    /// [`id`]: trait.Command.html#method.id
    #[inline]
    pub fn apply(&mut self, cmd: impl Command<R> + 'static) -> Result<Option<usize>, Error<R>>
    where
        R: 'static,
    {
        let commands = self.record.apply(cmd)?;
        let commands: Vec<_> = commands.collect();
        if !commands.is_empty() {
            let id = self.next.next().unwrap();
            self.branches.insert(
                id,
                Branch {
                    parent: self.id,
                    cursor: self.record.cursor(),
                    commands: commands.into_boxed_slice(),
                },
            );
            Ok(Some(id))
        } else {
            Ok(None)
        }
    }

    /// Calls the [`undo`] method for the active command and sets the previous one as the new active one.
    ///
    /// # Errors
    /// If an error occur when executing [`undo`] the error is returned together with the command.
    ///
    /// [`undo`]: trait.Command.html#tymethod.undo
    #[inline]
    #[must_use]
    pub fn undo(&mut self) -> Option<Result<(), Error<R>>> {
        self.record.undo()
    }

    /// Calls the [`redo`] method for the active command and sets the next one as the
    /// new active one.
    ///
    /// # Errors
    /// If an error occur when executing [`redo`] the error is returned together with the command.
    ///
    /// [`redo`]: trait.Command.html#method.redo
    #[inline]
    #[must_use]
    pub fn redo(&mut self) -> Option<Result<(), Error<R>>> {
        self.record.redo()
    }

    /// Jumps to the command in `branch` at `cursor`.
    #[inline]
    #[must_use]
    pub fn jump_to(&mut self, branch: usize, cursor: usize) -> Option<Result<(), Error<R>>> {
        if self.id == branch {
            return self.record.set_cursor(cursor);
        }

        let mut dst = self.branches.get(&branch)?;
        let mut path = vec![dst];
        while dst.parent != self.id {
            dst = &self.branches[&dst.parent];
            path.push(dst);
        }

        while let Some(last) = path.pop() {
            let _ = last.parent;
            let _ = last.cursor;
        }

        unimplemented!()
    }
}

impl<R> From<R> for History<R> {
    #[inline]
    fn from(receiver: R) -> Self {
        History::new(receiver)
    }
}

/// Builder for a history.
#[derive(Debug)]
pub struct HistoryBuilder<R> {
    receiver: PhantomData<R>,
}
<commit_msg>Find full path from start to dest<commit_after>use std::collections::HashMap;
use std::marker::PhantomData;
use std::ops::RangeFrom;
use {Command, Error, Record};

const ORIGIN: usize = 0;

#[derive(Debug)]
struct Branch<R> {
    parent: usize,
    cursor: usize,
    commands: Box<[Box<dyn Command<R> + 'static>]>,
}

/// A history of commands.
#[derive(Debug)]
pub struct History<R> {
    id: usize,
    parent: usize,
    next: RangeFrom<usize>,
    record: Record<R>,
    branches: HashMap<usize, Branch<R>>,
}

impl<R> History<R> {
    /// Returns a new history.
    #[inline]
    pub fn new(receiver: impl Into<R>) -> History<R> {
        History {
            id: ORIGIN,
            parent: ORIGIN,
            next: 1..,
            record: Record::new(receiver),
            branches: HashMap::new(),
        }
    }

    /// Pushes the command to the top of the history and executes its [`apply`] method.
    /// The command is merged with the previous top command if they have the same [`id`].
    ///
    /// # Errors
    /// If an error occur when executing [`apply`] the error is returned together with the command.
    ///
    /// [`apply`]: trait.Command.html#tymethod.apply
    /// [`id`]: trait.Command.html#method.id
    #[inline]
    pub fn apply(&mut self, cmd: impl Command<R> + 'static) -> Result<Option<usize>, Error<R>>
    where
        R: 'static,
    {
        let commands = self.record.apply(cmd)?;
        let commands: Vec<_> = commands.collect();
        if !commands.is_empty() {
            let id = self.next.next().unwrap();
            self.branches.insert(
                id,
                Branch {
                    parent: self.id,
                    cursor: self.record.cursor(),
                    commands: commands.into_boxed_slice(),
                },
            );
            Ok(Some(id))
        } else {
            Ok(None)
        }
    }

    /// Calls the [`undo`] method for the active command and sets the previous one as the new active one.
    ///
    /// # Errors
    /// If an error occur when executing [`undo`] the error is returned together with the command.
    ///
    /// [`undo`]: trait.Command.html#tymethod.undo
    #[inline]
    #[must_use]
    pub fn undo(&mut self) -> Option<Result<(), Error<R>>> {
        self.record.undo()
    }

    /// Calls the [`redo`] method for the active command and sets the next one as the
    /// new active one.
    ///
    /// # Errors
    /// If an error occur when executing [`redo`] the error is returned together with the command.
    ///
    /// [`redo`]: trait.Command.html#method.redo
    #[inline]
    #[must_use]
    pub fn redo(&mut self) -> Option<Result<(), Error<R>>> {
        self.record.redo()
    }

    /// Jumps to the command in `branch` at `cursor`.
    #[inline]
    #[must_use]
    pub fn jump_to(&mut self, branch: usize, cursor: usize) -> Option<Result<(), Error<R>>> {
        if self.id == branch {
            return self.record.set_cursor(cursor);
        }

        let mut dest = self.branches.get(&branch)?;
        let mut path = vec![dest];
        while dest.parent != ORIGIN {
            dest = &self.branches[&dest.parent];
            path.push(dest);
        }

        if self.id != ORIGIN {
            let mut start = &self.branches[&self.parent];
            let mut tmp = vec![start];
            while start.parent != ORIGIN {
                start = &self.branches[&start.parent];
                tmp.push(start);
            }
            tmp.reverse();
            path.append(&mut tmp);
        }

        while let Some(_) = path.pop() {
            // Walk the path from `start` to `dest`.
        }

        unimplemented!()
    }
}

impl<R> From<R> for History<R> {
    #[inline]
    fn from(receiver: R) -> Self {
        History::new(receiver)
    }
}

/// Builder for a history.
#[derive(Debug)]
pub struct HistoryBuilder<R> {
    receiver: PhantomData<R>,
}
<|endoftext|>


<commit_before>use Graph;

use std::ops::Add;
use std::cmp::{PartialOrd, Ordering};
use std::iter::IteratorExt;
use std::hash::Hash;

use std::collections::hash_map::{HashMap, Hasher, Entry};
use std::collections::BinaryHeap;

use num;
use num::traits::Zero;

pub type Heuristic<N, W> = fn(from: &N, to: &N) -> W;

pub fn a_star<G: Graph>(graph: &G, start: G::Node, end: G::Node,
    heuristic: Heuristic<G::Node, G::Weight>) -> Option<Vec<G::Node>>
    where G::Node: Hash<Hasher> + Eq + Clone,
          G::Neighbours: Iterator<Item=G::Node>,
          G::Weight: Clone + Ord + PartialOrd + Add<Output=G::Weight> + Zero
{
    let mut dist_map: HashMap<_, PathNode<_, G::Weight>> = HashMap::new();

    let mut frontier = BinaryHeap::new();
    frontier.push(PathNode::new(start.clone(), None));

    while let Some(mut active_val) = frontier.pop() {
        // Check if a complete path has been found
        if active_val.node == end {
            // Follow the path back from the end node to the start node
            let mut path = vec![];
            loop {
                path.push(active_val.node.clone());
                active_val = match active_val.parent.clone() {
                    Some(v) => dist_map[v].clone(),
                    None => return Some(path),
                }
            }
        }

        // Insert the current value if it is better than any previous value inserted
        match dist_map.entry(active_val.node.clone()) {
            Entry::Occupied(mut e) => {
                if active_val.f_cost() < e.get().f_cost() { e.insert(active_val.clone()); }
                else { continue }
            },
            Entry::Vacant(e) => { e.insert(active_val.clone()); },
        }

        // Visit all the neighbours of the current node that have not already been added to the
        // distance map
        for node in graph.neighbours(&active_val.node).filter(|n| !dist_map.contains_key(n)) {
            // Get the cost of moving from the current node to the next node
            let move_cost = match graph.weight(&active_val.node, &node) {
                Some(c) => c,
                None => break,
            };

            let mut next_val = PathNode::new(node, Some(active_val.node.clone()));
            next_val.g_cost = active_val.g_cost.clone() + move_cost;
            next_val.h_cost = heuristic(&next_val.node, &end);
            frontier.push(next_val);
        }
    }

    // No path to the end node could be found
    None
}

#[derive(Clone)]
struct PathNode<N, C> {
    node: N,
    parent: Option<N>,
    h_cost: C,
    g_cost: C,
}

impl<N, C: Zero + Add> PathNode<N, C> {
    pub fn new(node: N, parent: Option<N>) -> PathNode<N, C> {
        PathNode {
            node: node,
            h_cost: num::zero(),
            g_cost: num::zero(),
            parent: parent,
        }
    }
}

impl<N, C> PathNode<N, C> where C: Add<Output=C> + Clone {
    pub fn f_cost(&self) -> C {
        self.h_cost.clone() + self.g_cost.clone()
    }
}

impl<N, C> PartialEq for PathNode<N, C> where C: PartialEq + Add<Output=C> + Clone {
    fn eq(&self, other: &PathNode<N, C>) -> bool {
        self.f_cost() == other.f_cost()
    }
}
impl<N, C> Eq for PathNode<N, C> where C: PartialEq + Add<Output=C> + Clone {}

impl<N, C> PartialOrd for PathNode<N, C> where C: PartialOrd + Add<Output=C> + Clone {
    fn partial_cmp(&self, other: &PathNode<N, C>) -> Option<Ordering> {
        // Reverse the ordering so that it makes a min queue
        other.f_cost().partial_cmp(&self.f_cost())
    }
}
impl<N, C> Ord for PathNode<N, C> where C: Ord + Add<Output=C> + Clone {
    fn cmp(&self, other: &PathNode<N, C>) -> Ordering {
        // Reverse the ordering so that it makes a min queue
        other.f_cost().cmp(&self.f_cost())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::iter;
    use std::num::SignedInt;
    use Graph;

    struct Grid {
        width: u32,
        height: u32,
        data: Vec<bool>,
    }

    impl Grid {
        fn new(width: u32, height: u32) -> Grid {
            Grid {
                width: width,
                height: height,
                data: iter::repeat(false).take((width as usize * height as usize)).collect(),
            }
        }

        fn get(&self, index: &(u32, u32)) -> bool {
            let &(x, y) = index;
            if x >= self.width || y >= self.height {
                true
            }
            else {
                self.data[y as usize * self.width as usize + x as usize]
            }
        }

        fn set(&mut self, index: &(u32, u32), value: bool) {
            let &(x, y) = index;
            if x >= self.width || y >= self.height {
                panic!("Index out of bounds");
            }

            let index = y as usize * self.width as usize + x as usize;
            self.data[index] = value;
        }

    }

    struct Adjacent {
        pos: (u32, u32),
        i: usize,
        width: u32,
        height: u32,
    }

    impl Iterator for Adjacent {
        type Item = (u32, u32);

        fn next(&mut self) -> Option<(u32, u32)> {
            static POSSIBLE_MOVES: [(i32, i32); 4] = [(-1, 0), (0, -1), (1, 0), (0, 1)];
            let (x, y) = self.pos;
            loop {
                if self.i > 3 {
                    return None;
                }
                let (dx, dy) = POSSIBLE_MOVES[self.i];
                let (x, y) = (x as i32 + dx, y as i32 + dy);
                self.i += 1;
                if x >= 0 && y >= 0 && (x as u32) < self.width && (y as u32) < self.height {
                    return Some((x as u32, y as u32))
                }
            }
        }
    }

    impl Graph for Grid {
        type Node = (u32, u32);
        type Weight = usize;
        type Neighbours = Adjacent;

        fn weight(&self, _: &(u32, u32), to: &(u32, u32)) -> Option<usize> {
            if self.get(to) { None } else { Some(10) }
        }

        fn neighbours(&self, node: &(u32, u32)) -> Adjacent {
            Adjacent {
                pos: *node,
                i: 0,
                width: self.width,
                height: self.height
            }
        }
    }

    fn grid_heuristic(from: &(u32, u32), to: &(u32, u32)) -> usize {
        ((from.0 as i32 - to.0 as i32).abs() + (from.1 as i32 - to.0 as i32).abs()) as usize * 10
    }

    #[test]
    fn test_pathfinding_basic() {
        let grid = Grid::new(5, 5);
        let path = a_star(&grid, (0, 0), (4, 0), grid_heuristic);
        assert!(path.is_some());
        assert_eq!(path.unwrap(), vec![(4, 0), (3, 0), (2, 0), (1, 0), (0, 0)]);
    }

    #[test]
    fn test_pathfinding_off_screen() {
        let grid = Grid::new(5, 5);
        let path = a_star(&grid, (0, 0), (5, 0), grid_heuristic);
        assert!(path.is_none());
    }

    #[test]
    fn test_pathfinding_possible() {
        let mut grid = Grid::new(400, 200);
        for y in (0..100) {
            grid.set(&(7, y), true);
        }

        let path = a_star(&grid, (2, 2), (300, 50), grid_heuristic);
        assert!(path.is_some());

        let path = path.unwrap();
        assert_eq!(path[0], (300, 50));
        assert_eq!(path.last().unwrap(), &(2, 2));

        for (&(x1, y1), &(x2, y2)) in path.iter().zip(path.iter().skip(1)) {
            assert!(grid.get(&(x1, y1)) == false);
            assert!(((x2 as i32 - x1 as i32) + (y2 as i32 - y1 as i32)).abs() == 1);
        }
    }

    #[test]
    fn test_pathfinding_impossible() {
        let mut grid = Grid::new(5, 5);
        grid.set(&(3, 0), true);
        grid.set(&(4, 1), true);
        let path = a_star(&grid, (0, 0), (4, 0), grid_heuristic);
        assert!(path.is_none());
    }
}
<commit_msg>Rename type parameters for better consistancy.<commit_after>use Graph;

use std::ops::Add;
use std::cmp::{PartialOrd, Ordering};
use std::iter::IteratorExt;
use std::hash::Hash;

use std::collections::hash_map::{HashMap, Hasher, Entry};
use std::collections::BinaryHeap;

use num;
use num::traits::Zero;

pub type Heuristic<N, W> = fn(from: &N, to: &N) -> W;

pub fn a_star<G: Graph>(graph: &G, start: G::Node, end: G::Node,
    heuristic: Heuristic<G::Node, G::Weight>) -> Option<Vec<G::Node>>
    where G::Node: Hash<Hasher> + Eq + Clone,
          G::Neighbours: Iterator<Item=G::Node>,
          G::Weight: Clone + Ord + PartialOrd + Add<Output=G::Weight> + Zero
{
    let mut dist_map: HashMap<_, PathNode<_, G::Weight>> = HashMap::new();

    let mut frontier = BinaryHeap::new();
    frontier.push(PathNode::new(start.clone(), None));

    while let Some(mut active_val) = frontier.pop() {
        // Check if a complete path has been found
        if active_val.node == end {
            // Follow the path back from the end node to the start node
            let mut path = vec![];
            loop {
                path.push(active_val.node.clone());
                active_val = match active_val.parent.clone() {
                    Some(v) => dist_map[v].clone(),
                    None => return Some(path),
                }
            }
        }

        // Insert the current value if it is better than any previous value inserted
        match dist_map.entry(active_val.node.clone()) {
            Entry::Occupied(mut e) => {
                if active_val.f_cost() < e.get().f_cost() { e.insert(active_val.clone()); }
                else { continue }
            },
            Entry::Vacant(e) => { e.insert(active_val.clone()); },
        }

        // Visit all the neighbours of the current node that have not already been added to the
        // distance map
        for node in graph.neighbours(&active_val.node).filter(|n| !dist_map.contains_key(n)) {
            // Get the cost of moving from the current node to the next node
            let move_cost = match graph.weight(&active_val.node, &node) {
                Some(c) => c,
                None => break,
            };

            let mut next_val = PathNode::new(node, Some(active_val.node.clone()));
            next_val.g_cost = active_val.g_cost.clone() + move_cost;
            next_val.h_cost = heuristic(&next_val.node, &end);
            frontier.push(next_val);
        }
    }

    // No path to the end node could be found
    None
}

#[derive(Clone)]
struct PathNode<N, W> {
    node: N,
    parent: Option<N>,
    h_cost: W,
    g_cost: W,
}

impl<N, W: Zero + Add> PathNode<N, W> {
    pub fn new(node: N, parent: Option<N>) -> PathNode<N, W> {
        PathNode {
            node: node,
            h_cost: num::zero(),
            g_cost: num::zero(),
            parent: parent,
        }
    }
}

impl<N, W> PathNode<N, W> where W: Add<Output=W> + Clone {
    pub fn f_cost(&self) -> W {
        self.h_cost.clone() + self.g_cost.clone()
    }
}

impl<N, W> PartialEq for PathNode<N, W> where W: PartialEq + Add<Output=W> + Clone {
    fn eq(&self, other: &PathNode<N, W>) -> bool {
        self.f_cost() == other.f_cost()
    }
}
impl<N, W> Eq for PathNode<N, W> where W: PartialEq + Add<Output=W> + Clone {}

impl<N, W> PartialOrd for PathNode<N, W> where W: PartialOrd + Add<Output=W> + Clone {
    fn partial_cmp(&self, other: &PathNode<N, W>) -> Option<Ordering> {
        // Reverse the ordering so that it makes a min queue
        other.f_cost().partial_cmp(&self.f_cost())
    }
}
impl<N, W> Ord for PathNode<N, W> where W: Ord + Add<Output=W> + Clone {
    fn cmp(&self, other: &PathNode<N, W>) -> Ordering {
        // Reverse the ordering so that it makes a min queue
        other.f_cost().cmp(&self.f_cost())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::iter;
    use std::num::SignedInt;
    use Graph;

    struct Grid {
        width: u32,
        height: u32,
        data: Vec<bool>,
    }

    impl Grid {
        fn new(width: u32, height: u32) -> Grid {
            Grid {
                width: width,
                height: height,
                data: iter::repeat(false).take((width as usize * height as usize)).collect(),
            }
        }

        fn get(&self, index: &(u32, u32)) -> bool {
            let &(x, y) = index;
            if x >= self.width || y >= self.height {
                true
            }
            else {
                self.data[y as usize * self.width as usize + x as usize]
            }
        }

        fn set(&mut self, index: &(u32, u32), value: bool) {
            let &(x, y) = index;
            if x >= self.width || y >= self.height {
                panic!("Index out of bounds");
            }

            let index = y as usize * self.width as usize + x as usize;
            self.data[index] = value;
        }

    }

    struct Adjacent {
        pos: (u32, u32),
        i: usize,
        width: u32,
        height: u32,
    }

    impl Iterator for Adjacent {
        type Item = (u32, u32);

        fn next(&mut self) -> Option<(u32, u32)> {
            static POSSIBLE_MOVES: [(i32, i32); 4] = [(-1, 0), (0, -1), (1, 0), (0, 1)];
            let (x, y) = self.pos;
            loop {
                if self.i > 3 {
                    return None;
                }
                let (dx, dy) = POSSIBLE_MOVES[self.i];
                let (x, y) = (x as i32 + dx, y as i32 + dy);
                self.i += 1;
                if x >= 0 && y >= 0 && (x as u32) < self.width && (y as u32) < self.height {
                    return Some((x as u32, y as u32))
                }
            }
        }
    }

    impl Graph for Grid {
        type Node = (u32, u32);
        type Weight = usize;
        type Neighbours = Adjacent;

        fn weight(&self, _: &(u32, u32), to: &(u32, u32)) -> Option<usize> {
            if self.get(to) { None } else { Some(10) }
        }

        fn neighbours(&self, node: &(u32, u32)) -> Adjacent {
            Adjacent {
                pos: *node,
                i: 0,
                width: self.width,
                height: self.height
            }
        }
    }

    fn grid_heuristic(from: &(u32, u32), to: &(u32, u32)) -> usize {
        ((from.0 as i32 - to.0 as i32).abs() + (from.1 as i32 - to.0 as i32).abs()) as usize * 10
    }

    #[test]
    fn test_pathfinding_basic() {
        let grid = Grid::new(5, 5);
        let path = a_star(&grid, (0, 0), (4, 0), grid_heuristic);
        assert!(path.is_some());
        assert_eq!(path.unwrap(), vec![(4, 0), (3, 0), (2, 0), (1, 0), (0, 0)]);
    }

    #[test]
    fn test_pathfinding_off_screen() {
        let grid = Grid::new(5, 5);
        let path = a_star(&grid, (0, 0), (5, 0), grid_heuristic);
        assert!(path.is_none());
    }

    #[test]
    fn test_pathfinding_possible() {
        let mut grid = Grid::new(400, 200);
        for y in (0..100) {
            grid.set(&(7, y), true);
        }

        let path = a_star(&grid, (2, 2), (300, 50), grid_heuristic);
        assert!(path.is_some());

        let path = path.unwrap();
        assert_eq!(path[0], (300, 50));
        assert_eq!(path.last().unwrap(), &(2, 2));

        for (&(x1, y1), &(x2, y2)) in path.iter().zip(path.iter().skip(1)) {
            assert!(grid.get(&(x1, y1)) == false);
            assert!(((x2 as i32 - x1 as i32) + (y2 as i32 - y1 as i32)).abs() == 1);
        }
    }

    #[test]
    fn test_pathfinding_impossible() {
        let mut grid = Grid::new(5, 5);
        grid.set(&(3, 0), true);
        grid.set(&(4, 1), true);
        let path = a_star(&grid, (0, 0), (4, 0), grid_heuristic);
        assert!(path.is_none());
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! A windowing implementation using GLUT.

use windowing::{ApplicationMethods, WindowEvent, WindowMethods};
use windowing::{IdleWindowEvent, ResizeWindowEvent, LoadUrlWindowEvent, MouseWindowEventClass};
use windowing::{ScrollWindowEvent, ZoomWindowEvent, NavigationWindowEvent, FinishedWindowEvent};
use windowing::{QuitWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent, MouseWindowMouseUpEvent};
use windowing::{Forward, Back};

use alert::{Alert, AlertMethods};
use std::libc::c_int;
use geom::point::Point2D;
use geom::size::Size2D;
use servo_msg::compositor_msg::{IdleRenderState, RenderState, RenderingRenderState};
use servo_msg::compositor_msg::{FinishedLoading, Blank, Loading, PerformingLayout, ReadyState};

use glut::glut::{ACTIVE_CTRL, ACTIVE_SHIFT, DOUBLE, HAVE_PRECISE_MOUSE_WHEEL, WindowHeight};
use glut::glut::WindowWidth;
use glut::glut;

static THROBBER: [char, ..8] = [ '⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷' ];

/// A structure responsible for setting up and tearing down the entire windowing system.
pub struct Application;

impl ApplicationMethods for Application {
    fn new() -> Application {
        glut::init();
        glut::init_display_mode(DOUBLE);
        Application
    }
}

impl Drop for Application {
    fn drop(&self) {
    }
}

/// The type of a window.
pub struct Window {
    glut_window: glut::Window,

    event_queue: @mut ~[WindowEvent],

    drag_origin: Point2D<c_int>,

    mouse_down_button: @mut c_int,
    mouse_down_point: @mut Point2D<c_int>,

    ready_state: ReadyState,
    render_state: RenderState,
    throbber_frame: u8,
}

impl WindowMethods<Application> for Window {
    /// Creates a new window.
    fn new(_: &Application) -> @mut Window {
        // Create the GLUT window.
        glut::init_window_size(800, 600);
        let glut_window = glut::create_window(~"Servo");

        // Create our window object.
        let window = @mut Window {
            glut_window: glut_window,

            event_queue: @mut ~[],

            drag_origin: Point2D(0 as c_int, 0),

            mouse_down_button: @mut 0,
            mouse_down_point: @mut Point2D(0 as c_int, 0),

            ready_state: Blank,
            render_state: IdleRenderState,
            throbber_frame: 0,
        };

        let event_queue = window.event_queue;

        // Register event handlers.
        do glut::reshape_func(window.glut_window) |width, height| {
            event_queue.push(ResizeWindowEvent(width as uint, height as uint))
        }
        do glut::keyboard_func |key, _, _| {
            window.handle_key(key)
        }
        do glut::mouse_func |button, state, x, y| {
            if button < 3 {
                window.handle_mouse(button, state, x, y);
            }
            else {
                match button {
                    3 => {
                        event_queue.push(ScrollWindowEvent(Point2D(0.0, 5.0 as f32), Point2D(0.0 as i32, 5.0 as i32)));
                    },
                    4 => {
                        event_queue.push(ScrollWindowEvent(Point2D(0.0, -5.0 as f32), Point2D(0.0 as i32, -5.0 as i32)));
                    },
                    _ => {}
                }
            }
        }

        window
    }

    /// Returns the size of the window.
    fn size(&self) -> Size2D<f32> {
        Size2D(glut::get(WindowWidth) as f32, glut::get(WindowHeight) as f32)
    }

    /// Presents the window to the screen (perhaps by page flipping).
    fn present(&mut self) {
        glut::swap_buffers();
    }

    fn recv(@mut self) -> WindowEvent {
        if !self.event_queue.is_empty() {
            return self.event_queue.shift()
        }
        glut::check_loop();
        if !self.event_queue.is_empty() {
            self.event_queue.shift()
        } else {
            IdleWindowEvent
        }
    }

    /// Sets the ready state.
    fn set_ready_state(@mut self, ready_state: ReadyState) {
        self.ready_state = ready_state;
        //FIXME: set_window_title causes crash with Android version of freeGLUT. Temporarily blocked.
        //self.update_window_title()
    }

    /// Sets the render state.
    fn set_render_state(@mut self, render_state: RenderState) {
        if self.ready_state == FinishedLoading &&
            self.render_state == RenderingRenderState &&
            render_state == IdleRenderState {
            // page loaded
            self.event_queue.push(FinishedWindowEvent);
        }

        self.render_state = render_state;
        //FIXME: set_window_title causes crash with Android version of freeGLUT. Temporarily blocked.
        //self.update_window_title()
    }

    fn hidpi_factor(@mut self) -> f32 {
        //FIXME: Do nothing in GLUT now.
    0f32
    }
}

impl Window {
    /// Helper function to set the window title in accordance with the ready state.
    fn update_window_title(&self) {
        let throbber = THROBBER[self.throbber_frame];
        match self.ready_state {
            Blank => {
                glut::set_window_title(self.glut_window, "Blank")
            }
            Loading => {
                glut::set_window_title(self.glut_window, format!("{:c} Loading . Servo", throbber))
            }
            PerformingLayout => {
                glut::set_window_title(self.glut_window, format!("{:c} Performing Layout . Servo", throbber))
            }
            FinishedLoading => {
                match self.render_state {
                    RenderingRenderState => {
                        glut::set_window_title(self.glut_window, format!("{:c} Rendering . Servo", throbber))
                    }
                    IdleRenderState => glut::set_window_title(self.glut_window, "Servo"),
                }
            }
        }
    }

    /// Helper function to handle keyboard events.
    fn handle_key(&self, key: u8) {
        debug!("got key: {}", key);
        let modifiers = glut::get_modifiers();
        match key {
            42 => self.load_url(),
            43 => self.event_queue.push(ZoomWindowEvent(1.1)),
            45 => self.event_queue.push(ZoomWindowEvent(0.909090909)),
            56 => self.event_queue.push(ScrollWindowEvent(Point2D(0.0, 5.0 as f32), Point2D(0.0 as i32, 5.0 as i32))),
            50 => self.event_queue.push(ScrollWindowEvent(Point2D(0.0, -5.0 as f32), Point2D(0.0 as i32, -5.0 as i32))),
            127 => {
                if (modifiers & ACTIVE_SHIFT) != 0 {
                    self.event_queue.push(NavigationWindowEvent(Forward));
                }
                else {
                    self.event_queue.push(NavigationWindowEvent(Back));
                }
            }
            _ => {}
        }
    }

    /// Helper function to handle a click
    fn handle_mouse(&self, button: c_int, state: c_int, x: c_int, y: c_int) {
        // FIXME(tkuehn): max pixel dist should be based on pixel density
        let max_pixel_dist = 10f64;
        let event = match state {
            glut::MOUSE_DOWN => {
                *self.mouse_down_point = Point2D(x, y);
                *self.mouse_down_button = button;
                MouseWindowMouseDownEvent(button as uint, Point2D(x as f32, y as f32))
            }
            glut::MOUSE_UP => {
                if *self.mouse_down_button == button {
                    let pixel_dist = *self.mouse_down_point - Point2D(x, y);
                    let pixel_dist = ((pixel_dist.x * pixel_dist.x +
                                       pixel_dist.y * pixel_dist.y) as float).sqrt();
                    if pixel_dist < max_pixel_dist {
                        let click_event = MouseWindowClickEvent(button as uint,
                                                           Point2D(x as f32, y as f32));
                        self.event_queue.push(MouseWindowEventClass(click_event));
                    }
                }
                MouseWindowMouseUpEvent(button as uint, Point2D(x as f32, y as f32))
            }
            _ => fail!("I cannot recognize the type of mouse action that occured. :-(")
        };
        self.event_queue.push(MouseWindowEventClass(event));
    }

    /// Helper function to pop up an alert box prompting the user to load a URL.
    fn load_url(&self) {
        let mut alert: Alert = AlertMethods::new("Navigate to:");
        alert.add_prompt();
        alert.run();
        let value = alert.prompt_value();
        if "" == value {    // To avoid crashing on Linux.
            self.event_queue.push(LoadUrlWindowEvent(~"http://purple.com/"))
        } else {
            self.event_queue.push(LoadUrlWindowEvent(value))
        }
    }
}

<commit_msg>update glut_windowing for language change<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! A windowing implementation using GLUT.

use windowing::{ApplicationMethods, WindowEvent, WindowMethods};
use windowing::{IdleWindowEvent, ResizeWindowEvent, LoadUrlWindowEvent, MouseWindowEventClass};
use windowing::{ScrollWindowEvent, ZoomWindowEvent, NavigationWindowEvent, FinishedWindowEvent};
use windowing::{QuitWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent, MouseWindowMouseUpEvent};
use windowing::{Forward, Back};

use alert::{Alert, AlertMethods};
use std::libc::c_int;
use std::local_data;
use geom::point::Point2D;
use geom::size::Size2D;
use servo_msg::compositor_msg::{IdleRenderState, RenderState, RenderingRenderState};
use servo_msg::compositor_msg::{FinishedLoading, Blank, Loading, PerformingLayout, ReadyState};

use glut::glut::{ACTIVE_CTRL, ACTIVE_SHIFT, DOUBLE, HAVE_PRECISE_MOUSE_WHEEL, WindowHeight};
use glut::glut::WindowWidth;
use glut::glut;

static THROBBER: [char, ..8] = [ '⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷' ];

/// A structure responsible for setting up and tearing down the entire windowing system.
pub struct Application;

impl ApplicationMethods for Application {
    fn new() -> Application {
        glut::init();
        glut::init_display_mode(DOUBLE);
        Application
    }
}

impl Drop for Application {
    fn drop(&mut self) {
    }
}

/// The type of a window.
pub struct Window {
    glut_window: glut::Window,

    event_queue: @mut ~[WindowEvent],

    drag_origin: Point2D<c_int>,

    mouse_down_button: @mut c_int,
    mouse_down_point: @mut Point2D<c_int>,

    ready_state: ReadyState,
    render_state: RenderState,
    throbber_frame: u8,
}

impl WindowMethods<Application> for Window {
    /// Creates a new window.
    fn new(_: &Application) -> @mut Window {
        // Create the GLUT window.
        glut::init_window_size(800, 600);
        let glut_window = glut::create_window(~"Servo");

        // Create our window object.
        let window = @mut Window {
            glut_window: glut_window,

            event_queue: @mut ~[],

            drag_origin: Point2D(0 as c_int, 0),

            mouse_down_button: @mut 0,
            mouse_down_point: @mut Point2D(0 as c_int, 0),

            ready_state: Blank,
            render_state: IdleRenderState,
            throbber_frame: 0,
        };

        install_local_window(window);

        // Register event handlers.

        //Added dummy display callback to freeglut. According to freeglut ref, we should register some kind of display callback after freeglut 3.0.
        do glut::display_func || {
            debug!("GLUT display func registered");
        }
        do glut::reshape_func(window.glut_window) |width, height| {
            local_window().event_queue.push(ResizeWindowEvent(width as uint, height as uint))
        }
        do glut::keyboard_func |key, _, _| {
            local_window().handle_key(key)
        }
        do glut::mouse_func |button, state, x, y| {
            if button < 3 {
                local_window().handle_mouse(button, state, x, y);
            }
            else {
                match button {
                    3 => {
                        local_window().event_queue.push(ScrollWindowEvent(Point2D(0.0, 5.0 as f32), Point2D(0.0 as i32, 5.0 as i32)));
                    },
                    4 => {
                        local_window().event_queue.push(ScrollWindowEvent(Point2D(0.0, -5.0 as f32), Point2D(0.0 as i32, -5.0 as i32)));
                    },
                    _ => {}
                }
            }
        }

        window
    }

    /// Returns the size of the window.
    fn size(&self) -> Size2D<f32> {
        Size2D(glut::get(WindowWidth) as f32, glut::get(WindowHeight) as f32)
    }

    /// Presents the window to the screen (perhaps by page flipping).
    fn present(&mut self) {
        glut::swap_buffers();
    }

    fn recv(@mut self) -> WindowEvent {
        if !self.event_queue.is_empty() {
            return self.event_queue.shift()
        }
        glut::check_loop();
        if !self.event_queue.is_empty() {
            self.event_queue.shift()
        } else {
            IdleWindowEvent
        }
    }

    /// Sets the ready state.
    fn set_ready_state(@mut self, ready_state: ReadyState) {
        self.ready_state = ready_state;
        //FIXME: set_window_title causes crash with Android version of freeGLUT. Temporarily blocked.
        //self.update_window_title()
    }

    /// Sets the render state.
    fn set_render_state(@mut self, render_state: RenderState) {
        if self.ready_state == FinishedLoading &&
            self.render_state == RenderingRenderState &&
            render_state == IdleRenderState {
            // page loaded
            self.event_queue.push(FinishedWindowEvent);
        }

        self.render_state = render_state;
        //FIXME: set_window_title causes crash with Android version of freeGLUT. Temporarily blocked.
        //self.update_window_title()
    }

    fn hidpi_factor(@mut self) -> f32 {
        //FIXME: Do nothing in GLUT now.
    0f32
    }
}

impl Window {
    /// Helper function to set the window title in accordance with the ready state.
    fn update_window_title(&self) {
        let throbber = THROBBER[self.throbber_frame];
        match self.ready_state {
            Blank => {
                glut::set_window_title(self.glut_window, "Blank")
            }
            Loading => {
                glut::set_window_title(self.glut_window, format!("{:c} Loading . Servo", throbber))
            }
            PerformingLayout => {
                glut::set_window_title(self.glut_window, format!("{:c} Performing Layout . Servo", throbber))
            }
            FinishedLoading => {
                match self.render_state {
                    RenderingRenderState => {
                        glut::set_window_title(self.glut_window, format!("{:c} Rendering . Servo", throbber))
                    }
                    IdleRenderState => glut::set_window_title(self.glut_window, "Servo"),
                }
            }
        }
    }

    /// Helper function to handle keyboard events.
    fn handle_key(&self, key: u8) {
        debug!("got key: {}", key);
        let modifiers = glut::get_modifiers();
        match key {
            42 => self.load_url(),
            43 => self.event_queue.push(ZoomWindowEvent(1.1)),
            45 => self.event_queue.push(ZoomWindowEvent(0.909090909)),
            56 => self.event_queue.push(ScrollWindowEvent(Point2D(0.0, 5.0 as f32), Point2D(0.0 as i32, 5.0 as i32))),
            50 => self.event_queue.push(ScrollWindowEvent(Point2D(0.0, -5.0 as f32), Point2D(0.0 as i32, -5.0 as i32))),
            127 => {
                if (modifiers & ACTIVE_SHIFT) != 0 {
                    self.event_queue.push(NavigationWindowEvent(Forward));
                }
                else {
                    self.event_queue.push(NavigationWindowEvent(Back));
                }
            }
            _ => {}
        }
    }

    /// Helper function to handle a click
    fn handle_mouse(&self, button: c_int, state: c_int, x: c_int, y: c_int) {
        // FIXME(tkuehn): max pixel dist should be based on pixel density
        let max_pixel_dist = 10f32;
        let event = match state {
            glut::MOUSE_DOWN => {
                *self.mouse_down_point = Point2D(x, y);
                *self.mouse_down_button = button;
                MouseWindowMouseDownEvent(button as uint, Point2D(x as f32, y as f32))
            }
            glut::MOUSE_UP => {
                if *self.mouse_down_button == button {
                    let pixel_dist = *self.mouse_down_point - Point2D(x, y);
                    let pixel_dist = ((pixel_dist.x * pixel_dist.x +
                                       pixel_dist.y * pixel_dist.y) as f32).sqrt();
                    if pixel_dist < max_pixel_dist {
                        let click_event = MouseWindowClickEvent(button as uint,
                                                           Point2D(x as f32, y as f32));
                        self.event_queue.push(MouseWindowEventClass(click_event));
                    }
                }
                MouseWindowMouseUpEvent(button as uint, Point2D(x as f32, y as f32))
            }
            _ => fail!("I cannot recognize the type of mouse action that occured. :-(")
        };
        self.event_queue.push(MouseWindowEventClass(event));
    }

    /// Helper function to pop up an alert box prompting the user to load a URL.
    fn load_url(&self) {
        let mut alert: Alert = AlertMethods::new("Navigate to:");
        alert.add_prompt();
        alert.run();
        let value = alert.prompt_value();
        if "" == value {    // To avoid crashing on Linux.
            self.event_queue.push(LoadUrlWindowEvent(~"http://purple.com/"))
        } else {
            self.event_queue.push(LoadUrlWindowEvent(value))
        }
    }
}

static TLS_KEY: local_data::Key<@mut Window> = &local_data::Key;

fn install_local_window(window: @mut Window) {
    local_data::set(TLS_KEY, window);
}

fn drop_local_window() {
    local_data::pop(TLS_KEY);
}

fn local_window() -> @mut Window {
    local_data::get(TLS_KEY, |v| *v.unwrap())
}
<|endoftext|>


<commit_before>//! Tests for the Unix impl of `mio_serial::unix::Serial`
#![cfg(unix)]

extern crate mio_serial;
extern crate serialport;

use std::convert::TryFrom;
use std::io::{Read, Write};
use std::os::unix::prelude::*;
use std::path::Path;
use std::str;

use mio_serial::SerialStream;

fn get_available_serialport_name() -> Option<String> {
    match mio_serial::available_ports() {
        Err(_) => None,
        Ok(ports) => ports.into_iter().map(|s| s.port_name).nth(0),
    }
}

#[test]
fn test_from_serial() {
    if let Some(tty_path) = get_available_serialport_name() {
        let port = mio_serial::new(tty_path.clone(), 9600)
            .open_native()
            .expect(&format!("Unable to open serial port: {}", tty_path));
        let stream = mio_serial::SerialStream::try_from(port).expect("Unable to wrap TTYPort.");

        assert!(stream.as_raw_fd() > 0, "Illegal file descriptor.");
    }
}

#[test]
fn test_serial_pair() {
    let (mut master, mut slave) = SerialStream::pair().expect("Unable to create ptty pair");

    // Test file descriptors.
    assert!(
        master.as_raw_fd() > 0,
        "Invalid file descriptor on master ptty"
    );
    assert!(
        slave.as_raw_fd() > 0,
        "Invalid file descriptor on slave ptty"
    );
    assert_ne!(
        master.as_raw_fd(),
        slave.as_raw_fd(),
        "master and slave ptty's share the same file descriptor."
    );

    let msg = "Test Message";
    let mut buf = [0u8; 128];

    // Write the string on the master
    assert_eq!(
        master.write(msg.as_bytes()).unwrap(),
        msg.len(),
        "Unable to write message on master."
    );

    // Read it on the slave
    let nbytes = slave.read(&mut buf).expect("Unable to read bytes.");
    assert_eq!(
        nbytes,
        msg.len(),
        "Read message length differs from sent message."
    );

    assert_eq!(
        str::from_utf8(&buf[..nbytes]).unwrap(),
        msg,
        "Received message does not match sent"
    );
}
<commit_msg>ignore test_from_serial - fails in OSX appveyor environment<commit_after>//! Tests for the Unix impl of `mio_serial::unix::Serial`
#![cfg(unix)]

extern crate mio_serial;
extern crate serialport;

use std::convert::TryFrom;
use std::io::{Read, Write};
use std::os::unix::prelude::*;
use std::path::Path;
use std::str;

use mio_serial::SerialStream;

fn get_available_serialport_name() -> Option<String> {
    match mio_serial::available_ports() {
        Err(_) => None,
        Ok(ports) => ports.into_iter().map(|s| s.port_name).nth(0),
    }
}

// This test fails OSX CI on appveyor
#[test]
#[ignore]
fn test_from_serial() {
    if let Some(tty_path) = get_available_serialport_name() {
        let port = mio_serial::new(tty_path.clone(), 9600)
            .open_native()
            .expect(&format!("Unable to open serial port: {}", tty_path));
        let stream = mio_serial::SerialStream::try_from(port).expect("Unable to wrap TTYPort.");

        assert!(stream.as_raw_fd() > 0, "Illegal file descriptor.");
    }
}

#[test]
fn test_serial_pair() {
    let (mut master, mut slave) = SerialStream::pair().expect("Unable to create ptty pair");

    // Test file descriptors.
    assert!(
        master.as_raw_fd() > 0,
        "Invalid file descriptor on master ptty"
    );
    assert!(
        slave.as_raw_fd() > 0,
        "Invalid file descriptor on slave ptty"
    );
    assert_ne!(
        master.as_raw_fd(),
        slave.as_raw_fd(),
        "master and slave ptty's share the same file descriptor."
    );

    let msg = "Test Message";
    let mut buf = [0u8; 128];

    // Write the string on the master
    assert_eq!(
        master.write(msg.as_bytes()).unwrap(),
        msg.len(),
        "Unable to write message on master."
    );

    // Read it on the slave
    let nbytes = slave.read(&mut buf).expect("Unable to read bytes.");
    assert_eq!(
        nbytes,
        msg.len(),
        "Read message length differs from sent message."
    );

    assert_eq!(
        str::from_utf8(&buf[..nbytes]).unwrap(),
        msg,
        "Received message does not match sent"
    );
}
<|endoftext|>


<commit_before>use serialize::json::Json;
use std::collections::HashMap;
use std::f32;
use std::f64;
use std::fmt;
use std::num::Float;
use std::io::net::ip::IpAddr;

use postgres::{Connection, SslMode};
use postgres::types::{ToSql, FromSql};

#[cfg(feature = "uuid")]
mod uuid;
mod time;

fn test_type<T: PartialEq+FromSql+ToSql, S: fmt::String>(sql_type: &str, checks: &[(T, S)]) {
    let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &SslMode::None));
    for &(ref val, ref repr) in checks.iter() {
        let stmt = or_panic!(conn.prepare(&*format!("SELECT {}::{}", *repr, sql_type)));
        let result = or_panic!(stmt.query(&[])).next().unwrap().get(0us);
        assert!(val == &result);

        let stmt = or_panic!(conn.prepare(&*format!("SELECT $1::{}", sql_type)));
        let result = or_panic!(stmt.query(&[val])).next().unwrap().get(0us);
        assert!(val == &result);
    }
}

#[test]
fn test_bool_params() {
    test_type("BOOL", &[(Some(true), "'t'"), (Some(false), "'f'"),
                       (None, "NULL")]);
}

#[test]
fn test_i8_params() {
    test_type("\"char\"", &[(Some('a' as i8), "'a'"), (None, "NULL")]);
}

#[test]
fn test_name_params() {
    test_type("NAME", &[(Some("hello world".to_string()), "'hello world'"),
                       (Some("イロハニホヘト チリヌルヲ".to_string()), "'イロハニホヘト チリヌルヲ'"),
                       (None, "NULL")]);
}

#[test]
fn test_i16_params() {
    test_type("SMALLINT", &[(Some(15001i16), "15001"),
                           (Some(-15001i16), "-15001"), (None, "NULL")]);
}

#[test]
fn test_i32_params() {
    test_type("INT", &[(Some(2147483548i32), "2147483548"),
                      (Some(-2147483548i32), "-2147483548"), (None, "NULL")]);
}

#[test]
fn test_oid_params() {
    test_type("OID", &[(Some(2147483548u32), "2147483548"),
                       (Some(4000000000), "4000000000"), (None, "NULL")]);
}

#[test]
fn test_i64_params() {
    test_type("BIGINT", &[(Some(9223372036854775708i64), "9223372036854775708"),
                         (Some(-9223372036854775708i64), "-9223372036854775708"),
                         (None, "NULL")]);
}

#[test]
fn test_f32_params() {
    test_type("REAL", &[(Some(f32::INFINITY), "'infinity'"),
                       (Some(f32::NEG_INFINITY), "'-infinity'"),
                       (Some(1000.55), "1000.55"), (None, "NULL")]);
}

#[test]
fn test_f64_params() {
    test_type("DOUBLE PRECISION", &[(Some(f64::INFINITY), "'infinity'"),
                                   (Some(f64::NEG_INFINITY), "'-infinity'"),
                                   (Some(10000.55), "10000.55"),
                                   (None, "NULL")]);
}

#[test]
fn test_varchar_params() {
    test_type("VARCHAR", &[(Some("hello world".to_string()), "'hello world'"),
                          (Some("イロハニホヘト チリヌルヲ".to_string()), "'イロハニホヘト チリヌルヲ'"),
                          (None, "NULL")]);
}

#[test]
fn test_text_params() {
    test_type("TEXT", &[(Some("hello world".to_string()), "'hello world'"),
                       (Some("イロハニホヘト チリヌルヲ".to_string()), "'イロハニホヘト チリヌルヲ'"),
                       (None, "NULL")]);
}

#[test]
fn test_bpchar_params() {
    let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &SslMode::None));
    or_panic!(conn.execute("CREATE TEMPORARY TABLE foo (
                            id SERIAL PRIMARY KEY,
                            b CHAR(5)
                           )", &[]));
    or_panic!(conn.execute("INSERT INTO foo (b) VALUES ($1), ($2), ($3)",
                           &[&Some("12345"), &Some("123"), &None::<&'static str>]));
    let stmt = or_panic!(conn.prepare("SELECT b FROM foo ORDER BY id"));
    let res = or_panic!(stmt.query(&[]));

    assert_eq!(vec!(Some("12345".to_string()), Some("123  ".to_string()), None),
               res.map(|row| row.get(0us)).collect::<Vec<_>>());
}

#[test]
fn test_citext_params() {
    let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &SslMode::None));
    or_panic!(conn.execute("CREATE TEMPORARY TABLE foo (
                            id SERIAL PRIMARY KEY,
                            b CITEXT
                           )", &[]));
    or_panic!(conn.execute("INSERT INTO foo (b) VALUES ($1), ($2), ($3)",
                           &[&Some("foobar"), &Some("FooBar"), &None::<&'static str>]));
    let stmt = or_panic!(conn.prepare("SELECT id FROM foo WHERE b = 'FOOBAR' ORDER BY id"));
    let res = or_panic!(stmt.query(&[]));

    assert_eq!(vec!(Some(1i32), Some(2i32)), res.map(|row| row.get(0us)).collect::<Vec<_>>());
}

#[test]
fn test_bytea_params() {
    test_type("BYTEA", &[(Some(vec!(0u8, 1, 2, 3, 254, 255)), "'\\x00010203feff'"),
                        (None, "NULL")]);
}

#[test]
fn test_json_params() {
    test_type("JSON", &[(Some(Json::from_str("[10, 11, 12]").unwrap()),
                        "'[10, 11, 12]'"),
                       (Some(Json::from_str("{\"f\": \"asd\"}").unwrap()),
                        "'{\"f\": \"asd\"}'"),
                       (None, "NULL")])
}

#[test]
fn test_jsonb_params() {
    test_type("JSONB", &[(Some(Json::from_str("[10, 11, 12]").unwrap()),
                          "'[10, 11, 12]'"),
                         (Some(Json::from_str("{\"f\": \"asd\"}").unwrap()),
                          "'{\"f\": \"asd\"}'"),
                         (None, "NULL")])
}

#[test]
fn test_inet_params() {
    test_type("INET", &[(Some("127.0.0.1".parse::<IpAddr>().unwrap()),
                         "'127.0.0.1'"),
                        (Some("2001:0db8:85a3:0000:0000:8a2e:0370:7334".parse::<IpAddr>().unwrap()),
                         "'2001:0db8:85a3:0000:0000:8a2e:0370:7334'"),
                        (None, "NULL")])
}

#[test]
fn test_cidr_params() {
    test_type("CIDR", &[(Some("127.0.0.1".parse::<IpAddr>().unwrap()),
                         "'127.0.0.1'"),
                        (Some("2001:0db8:85a3:0000:0000:8a2e:0370:7334".parse::<IpAddr>().unwrap()),
                         "'2001:0db8:85a3:0000:0000:8a2e:0370:7334'"),
                        (None, "NULL")])
}

#[test]
fn test_hstore_params() {
    macro_rules! make_map {
        ($($k:expr => $v:expr),+) => ({
            let mut map = HashMap::new();
            $(map.insert($k, $v);)+
            map
        })
    }
    test_type("hstore",
              &[(Some(make_map!("a".to_string() => Some("1".to_string()))), "'a=>1'"),
               (Some(make_map!("hello".to_string() => Some("world!".to_string()),
                               "hola".to_string() => Some("mundo!".to_string()),
                               "what".to_string() => None)),
                "'hello=>world!,hola=>mundo!,what=>NULL'"),
                (None, "NULL")]);
}

fn test_nan_param<T: Float+ToSql+FromSql>(sql_type: &str) {
    let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &SslMode::None));
    let stmt = or_panic!(conn.prepare(&*format!("SELECT 'NaN'::{}", sql_type)));
    let mut result = or_panic!(stmt.query(&[]));
    let val: T = result.next().unwrap().get(0us);
    assert!(val.is_nan());

    let nan: T = Float::nan();
    let stmt = or_panic!(conn.prepare(&*format!("SELECT $1::{}", sql_type)));
    let mut result = or_panic!(stmt.query(&[&nan]));
    let val: T = result.next().unwrap().get(0us);
    assert!(val.is_nan())
}

#[test]
fn test_f32_nan_param() {
    test_nan_param::<f32>("REAL");
}

#[test]
fn test_f64_nan_param() {
    test_nan_param::<f64>("DOUBLE PRECISION");
}

#[test]
fn test_pg_database_datname() {
    let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &SslMode::None));
    let stmt = or_panic!(conn.prepare("SELECT datname FROM pg_database"));
    let mut result = or_panic!(stmt.query(&[]));

    let next = result.next().unwrap();
    or_panic!(next.get_opt::<usize, String>(0));
    or_panic!(next.get_opt::<&str, String>("datname"));
}
<commit_msg>Skip jsonb test on Travis<commit_after>use serialize::json::Json;
use std::collections::HashMap;
use std::f32;
use std::f64;
use std::fmt;
use std::num::Float;
use std::io::net::ip::IpAddr;

use postgres::{Connection, SslMode};
use postgres::types::{ToSql, FromSql};

#[cfg(feature = "uuid")]
mod uuid;
mod time;

fn test_type<T: PartialEq+FromSql+ToSql, S: fmt::String>(sql_type: &str, checks: &[(T, S)]) {
    let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &SslMode::None));
    for &(ref val, ref repr) in checks.iter() {
        let stmt = or_panic!(conn.prepare(&*format!("SELECT {}::{}", *repr, sql_type)));
        let result = or_panic!(stmt.query(&[])).next().unwrap().get(0us);
        assert!(val == &result);

        let stmt = or_panic!(conn.prepare(&*format!("SELECT $1::{}", sql_type)));
        let result = or_panic!(stmt.query(&[val])).next().unwrap().get(0us);
        assert!(val == &result);
    }
}

#[test]
fn test_bool_params() {
    test_type("BOOL", &[(Some(true), "'t'"), (Some(false), "'f'"),
                       (None, "NULL")]);
}

#[test]
fn test_i8_params() {
    test_type("\"char\"", &[(Some('a' as i8), "'a'"), (None, "NULL")]);
}

#[test]
fn test_name_params() {
    test_type("NAME", &[(Some("hello world".to_string()), "'hello world'"),
                       (Some("イロハニホヘト チリヌルヲ".to_string()), "'イロハニホヘト チリヌルヲ'"),
                       (None, "NULL")]);
}

#[test]
fn test_i16_params() {
    test_type("SMALLINT", &[(Some(15001i16), "15001"),
                           (Some(-15001i16), "-15001"), (None, "NULL")]);
}

#[test]
fn test_i32_params() {
    test_type("INT", &[(Some(2147483548i32), "2147483548"),
                      (Some(-2147483548i32), "-2147483548"), (None, "NULL")]);
}

#[test]
fn test_oid_params() {
    test_type("OID", &[(Some(2147483548u32), "2147483548"),
                       (Some(4000000000), "4000000000"), (None, "NULL")]);
}

#[test]
fn test_i64_params() {
    test_type("BIGINT", &[(Some(9223372036854775708i64), "9223372036854775708"),
                         (Some(-9223372036854775708i64), "-9223372036854775708"),
                         (None, "NULL")]);
}

#[test]
fn test_f32_params() {
    test_type("REAL", &[(Some(f32::INFINITY), "'infinity'"),
                       (Some(f32::NEG_INFINITY), "'-infinity'"),
                       (Some(1000.55), "1000.55"), (None, "NULL")]);
}

#[test]
fn test_f64_params() {
    test_type("DOUBLE PRECISION", &[(Some(f64::INFINITY), "'infinity'"),
                                   (Some(f64::NEG_INFINITY), "'-infinity'"),
                                   (Some(10000.55), "10000.55"),
                                   (None, "NULL")]);
}

#[test]
fn test_varchar_params() {
    test_type("VARCHAR", &[(Some("hello world".to_string()), "'hello world'"),
                          (Some("イロハニホヘト チリヌルヲ".to_string()), "'イロハニホヘト チリヌルヲ'"),
                          (None, "NULL")]);
}

#[test]
fn test_text_params() {
    test_type("TEXT", &[(Some("hello world".to_string()), "'hello world'"),
                       (Some("イロハニホヘト チリヌルヲ".to_string()), "'イロハニホヘト チリヌルヲ'"),
                       (None, "NULL")]);
}

#[test]
fn test_bpchar_params() {
    let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &SslMode::None));
    or_panic!(conn.execute("CREATE TEMPORARY TABLE foo (
                            id SERIAL PRIMARY KEY,
                            b CHAR(5)
                           )", &[]));
    or_panic!(conn.execute("INSERT INTO foo (b) VALUES ($1), ($2), ($3)",
                           &[&Some("12345"), &Some("123"), &None::<&'static str>]));
    let stmt = or_panic!(conn.prepare("SELECT b FROM foo ORDER BY id"));
    let res = or_panic!(stmt.query(&[]));

    assert_eq!(vec!(Some("12345".to_string()), Some("123  ".to_string()), None),
               res.map(|row| row.get(0us)).collect::<Vec<_>>());
}

#[test]
fn test_citext_params() {
    let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &SslMode::None));
    or_panic!(conn.execute("CREATE TEMPORARY TABLE foo (
                            id SERIAL PRIMARY KEY,
                            b CITEXT
                           )", &[]));
    or_panic!(conn.execute("INSERT INTO foo (b) VALUES ($1), ($2), ($3)",
                           &[&Some("foobar"), &Some("FooBar"), &None::<&'static str>]));
    let stmt = or_panic!(conn.prepare("SELECT id FROM foo WHERE b = 'FOOBAR' ORDER BY id"));
    let res = or_panic!(stmt.query(&[]));

    assert_eq!(vec!(Some(1i32), Some(2i32)), res.map(|row| row.get(0us)).collect::<Vec<_>>());
}

#[test]
fn test_bytea_params() {
    test_type("BYTEA", &[(Some(vec!(0u8, 1, 2, 3, 254, 255)), "'\\x00010203feff'"),
                        (None, "NULL")]);
}

#[test]
fn test_json_params() {
    test_type("JSON", &[(Some(Json::from_str("[10, 11, 12]").unwrap()),
                        "'[10, 11, 12]'"),
                       (Some(Json::from_str("{\"f\": \"asd\"}").unwrap()),
                        "'{\"f\": \"asd\"}'"),
                       (None, "NULL")])
}

#[test]
fn test_jsonb_params() {
    if option_env!("TRAVIS").is_some() { return } // Travis doesn't have Postgres 9.4 yet
    test_type("JSONB", &[(Some(Json::from_str("[10, 11, 12]").unwrap()),
                          "'[10, 11, 12]'"),
                         (Some(Json::from_str("{\"f\": \"asd\"}").unwrap()),
                          "'{\"f\": \"asd\"}'"),
                         (None, "NULL")])
}

#[test]
fn test_inet_params() {
    test_type("INET", &[(Some("127.0.0.1".parse::<IpAddr>().unwrap()),
                         "'127.0.0.1'"),
                        (Some("2001:0db8:85a3:0000:0000:8a2e:0370:7334".parse::<IpAddr>().unwrap()),
                         "'2001:0db8:85a3:0000:0000:8a2e:0370:7334'"),
                        (None, "NULL")])
}

#[test]
fn test_cidr_params() {
    test_type("CIDR", &[(Some("127.0.0.1".parse::<IpAddr>().unwrap()),
                         "'127.0.0.1'"),
                        (Some("2001:0db8:85a3:0000:0000:8a2e:0370:7334".parse::<IpAddr>().unwrap()),
                         "'2001:0db8:85a3:0000:0000:8a2e:0370:7334'"),
                        (None, "NULL")])
}

#[test]
fn test_hstore_params() {
    macro_rules! make_map {
        ($($k:expr => $v:expr),+) => ({
            let mut map = HashMap::new();
            $(map.insert($k, $v);)+
            map
        })
    }
    test_type("hstore",
              &[(Some(make_map!("a".to_string() => Some("1".to_string()))), "'a=>1'"),
               (Some(make_map!("hello".to_string() => Some("world!".to_string()),
                               "hola".to_string() => Some("mundo!".to_string()),
                               "what".to_string() => None)),
                "'hello=>world!,hola=>mundo!,what=>NULL'"),
                (None, "NULL")]);
}

fn test_nan_param<T: Float+ToSql+FromSql>(sql_type: &str) {
    let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &SslMode::None));
    let stmt = or_panic!(conn.prepare(&*format!("SELECT 'NaN'::{}", sql_type)));
    let mut result = or_panic!(stmt.query(&[]));
    let val: T = result.next().unwrap().get(0us);
    assert!(val.is_nan());

    let nan: T = Float::nan();
    let stmt = or_panic!(conn.prepare(&*format!("SELECT $1::{}", sql_type)));
    let mut result = or_panic!(stmt.query(&[&nan]));
    let val: T = result.next().unwrap().get(0us);
    assert!(val.is_nan())
}

#[test]
fn test_f32_nan_param() {
    test_nan_param::<f32>("REAL");
}

#[test]
fn test_f64_nan_param() {
    test_nan_param::<f64>("DOUBLE PRECISION");
}

#[test]
fn test_pg_database_datname() {
    let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &SslMode::None));
    let stmt = or_panic!(conn.prepare("SELECT datname FROM pg_database"));
    let mut result = or_panic!(stmt.query(&[]));

    let next = result.next().unwrap();
    or_panic!(next.get_opt::<usize, String>(0));
    or_panic!(next.get_opt::<&str, String>("datname"));
}
<|endoftext|>


<commit_before>fn main() {
    let boxed = Box::new(5);
    println!("boxed = {}", boxed);
}
<commit_msg>Example of using cons<commit_after>use List::{Cons, Nil};

fn main() {
    let boxed = Box::new(5);
    println!("boxed = {}", boxed);

    let list = Cons(1, Box::new(Cons(2, Box::new(Nil))));
}

enum List {
    Cons(i32, Box<List>),
    Nil
}
<|endoftext|>


<commit_before>use llvm_sys::prelude::*;
use llvm_sys::core as llvm;

use super::*;

// LLVM Wrappers

pub struct Context {
    pub ptr: LLVMContextRef
}

impl Context {
    pub fn new() -> Self {
        let context = unsafe {
            llvm::LLVMContextCreate()
        };
        Context { ptr: context }
    }

    pub fn create_builder(&self) -> Builder {
        let builder = unsafe {
            llvm::LLVMCreateBuilderInContext(self.ptr)
        };
        Builder { ptr: builder }
    }

    pub fn module_create_with_name(&self, name: &str) -> Module {
        let c_name = CString::new(name).unwrap();
        let module = unsafe {
            llvm::LLVMModuleCreateWithNameInContext(c_name.as_ptr(), self.ptr)
        };
        Module { ptr: module }
    }

    pub fn void_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMVoidTypeInContext(self.ptr)
        }
    }

    pub fn int64_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMInt64TypeInContext(self.ptr)
        }
    }

    pub fn int32_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMInt32TypeInContext(self.ptr)
        }
    }

    pub fn int16_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMInt16TypeInContext(self.ptr)
        }
    }

    pub fn int8_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMInt8TypeInContext(self.ptr)
        }
    }

    pub fn int1_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMInt1TypeInContext(self.ptr)
        }
    }

    pub fn const_bool(&self, val: bool) -> LLVMValueRef {
        let ty = self.int1_type();
        const_int(ty, val as u64, false)
    }

    pub fn append_basic_block(&self, func: Function, name: &str) -> LLVMBasicBlockRef {
        let c_name = CString::new(name).unwrap();
        unsafe {
            llvm::LLVMAppendBasicBlockInContext(self.ptr, func.ptr, c_name.as_ptr())
        }
    }
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe {
            llvm::LLVMContextDispose(self.ptr);
        }
    }
}

<commit_msg>Context append block, take ref to function<commit_after>use llvm_sys::prelude::*;
use llvm_sys::core as llvm;

use super::*;

// LLVM Wrappers

pub struct Context {
    pub ptr: LLVMContextRef
}

impl Context {
    pub fn new() -> Self {
        let context = unsafe {
            llvm::LLVMContextCreate()
        };
        Context { ptr: context }
    }

    pub fn create_builder(&self) -> Builder {
        let builder = unsafe {
            llvm::LLVMCreateBuilderInContext(self.ptr)
        };
        Builder { ptr: builder }
    }

    pub fn module_create_with_name(&self, name: &str) -> Module {
        let c_name = CString::new(name).unwrap();
        let module = unsafe {
            llvm::LLVMModuleCreateWithNameInContext(c_name.as_ptr(), self.ptr)
        };
        Module { ptr: module }
    }

    pub fn void_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMVoidTypeInContext(self.ptr)
        }
    }

    pub fn int64_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMInt64TypeInContext(self.ptr)
        }
    }

    pub fn int32_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMInt32TypeInContext(self.ptr)
        }
    }

    pub fn int16_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMInt16TypeInContext(self.ptr)
        }
    }

    pub fn int8_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMInt8TypeInContext(self.ptr)
        }
    }

    pub fn int1_type(&self) -> LLVMTypeRef {
        unsafe {
            llvm::LLVMInt1TypeInContext(self.ptr)
        }
    }

    pub fn const_bool(&self, val: bool) -> LLVMValueRef {
        let ty = self.int1_type();
        const_int(ty, val as u64, false)
    }

    pub fn append_basic_block(&self, func: &mut Function, name: &str) -> LLVMBasicBlockRef {
        let c_name = CString::new(name).unwrap();
        unsafe {
            llvm::LLVMAppendBasicBlockInContext(self.ptr, func.ptr, c_name.as_ptr())
        }
    }
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe {
            llvm::LLVMContextDispose(self.ptr);
        }
    }
}

<|endoftext|>