<commit_before>pub mod dynamic_arq;
pub mod specs;
pub mod sqrt_decomp;
pub mod static_arq;
pub use dynamic_arq::{ArqView, DynamicArq};
pub use specs::ArqSpec;
pub use static_arq::StaticArq;

/// A simple data structure for coordinate compression
pub struct SparseIndex {
    coords: Vec<i64>
}

impl SparseIndex {
    /// Build an index, given the full set of coordinates to compress.
    pub fn new(mut coords: Vec<i64>) -> Self {
        coords.sort_unstable();
        coords.dedup();
        Self { coords }
    }

    /// Return Ok(i) if the coordinate q appears at index i
    /// Return Err(i) if q appears between indices i-1 and i
    pub fn compress(&self, q: i64) -> Result<usize, usize> {
        self.coords.binary_search(&q)
    }
}

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

    #[test]
    fn test_coord_compress() {
        let mut coords = vec![16, 99, 45, 18];
        let index = SparseIndex::new(coords.clone());

        coords.sort_unstable();
        for (i, q) in coords.into_iter().enumerate() {
            assert_eq!(index.compress(q - 1), Err(i));
            assert_eq!(index.compress(q), Ok(i));
            assert_eq!(index.compress(q + 1), Err(i + 1));
        }
    }

    #[test]
    fn test_range_compress() {
        let queries = vec![(0, 10), (10, 19), (20, 29)];
        let coords = queries.iter().flat_map(|&(i, j)| vec![i, j + 1]).collect();
        let index = SparseIndex::new(coords);

        assert_eq!(index.coords, vec![0, 10, 11, 20, 30]);
    }

    #[test]
    fn test_rmq() {
        let mut arq = StaticArq::<AssignMin>::new(&[0; 10]);

        assert_eq!(arq.query(0, 9), 0);

        arq.update(2, 4, &-5);
        arq.update(5, 7, &-3);
        arq.update(1, 6, &1);

        assert_eq!(arq.query(0, 9), -3);
    }

    #[test]
    fn test_dynamic_rmq() {
        let mut arq = DynamicArq::<AssignMin>::new(false);
        let view = arq.build_from_slice(&[0; 10]);

        assert_eq!(arq.query(view, 0, 9), 0);

        arq.update(view, 2, 4, &-5);
        arq.update(view, 5, 7, &-3);
        arq.update(view, 1, 6, &1);

        assert_eq!(arq.query(view, 0, 9), -3);
    }

    #[test]
    fn test_persistent_rmq() {
        let mut arq = DynamicArq::<AssignMin>::new(true);
        let mut view = arq.build_from_slice(&[0; 10]);

        let at_init = view;
        view = arq.update(view, 2, 4, &-5);
        let snapshot = view;
        view = arq.update(view, 5, 7, &-3);
        view = arq.update(view, 1, 6, &1);

        assert_eq!(arq.query(at_init, 0, 9), 0);
        assert_eq!(arq.query(snapshot, 0, 9), -5);
        assert_eq!(arq.query(view, 0, 9), -3);
    }

    #[test]
    fn test_huge_rmq() {
        let quintillion = 1_000_000_000_000_000_000;
        let mut arq = DynamicArq::<AssignMin>::new(false);
        let view = arq.build_from_identity(9 * quintillion + 1);

        arq.update(view, 2 * quintillion, 4 * quintillion, &-5);
        arq.update(view, 5 * quintillion, 7 * quintillion, &-3);
        arq.update(view, 1 * quintillion, 6 * quintillion, &1);

        assert_eq!(arq.query(view, 0, 9 * quintillion), -3);
    }

    #[test]
    fn test_range_sum() {
        let mut arq = StaticArq::<AssignSum>::new(&[0; 10]);

        assert_eq!(arq.query(0, 9), 0);

        arq.update(1, 3, &10);
        arq.update(3, 5, &1);

        assert_eq!(arq.query(0, 9), 23);
        assert_eq!(arq.query(10, 4), 0);
    }

    #[test]
    fn test_dynamic_range_sum() {
        let mut arq = DynamicArq::<AssignSum>::new(false);
        let view = arq.build_from_slice(&[0; 10]);

        assert_eq!(arq.query(view, 0, 9), 0);

        arq.update(view, 1, 3, &10);
        arq.update(view, 3, 5, &1);

        assert_eq!(arq.query(view, 0, 9), 23);
        assert_eq!(arq.query(view, 10, 4), 0);
    }

    #[test]
    fn test_supply_demand() {
        let mut arq = StaticArq::<SupplyDemand>::new(&[(0, 0, 0); 10]);

        arq.update(1, 1, &(25, 100));
        arq.update(3, 3, &(100, 30));
        arq.update(9, 9, &(0, 20));

        assert_eq!(arq.query(0, 9), (125, 150, 75));
    }

    #[test]
    fn test_dynamic_supply_demand() {
        let mut arq = DynamicArq::<SupplyDemand>::new(false);
        let view = arq.build_from_identity(10);

        arq.update(view, 1, 1, &(25, 100));
        arq.update(view, 3, 3, &(100, 30));
        arq.update(view, 9, 9, &(0, 20));

        assert_eq!(arq.query(view, 0, 9), (125, 150, 75));
    }

    #[test]
    fn test_binary_search_rmq() {
        let vec = vec![2, 1, 0, -1, -2, -3, -4, -5];
        let mut arq = StaticArq::<AssignMin>::new(&vec);
        let first_neg = static_arq::first_negative(&mut arq);

        arq.update(3, 7, &0);
        let first_neg_zeros = static_arq::first_negative(&mut arq);

        assert_eq!(first_neg, Some(3));
        assert_eq!(first_neg_zeros, None);
    }

    #[test]
    fn test_dynamic_binary_search_rmq() {
        let vec = vec![2, 1, 0, -1, -2, -3, -4, -5];
        let mut arq = DynamicArq::<AssignMin>::new(false);
        let view = arq.build_from_slice(&vec);
        let first_neg = dynamic_arq::first_negative(&mut arq, view);

        arq.update(view, 3, 7, &0);
        let first_neg_zeros = dynamic_arq::first_negative(&mut arq, view);

        assert_eq!(first_neg, Some(3));
        assert_eq!(first_neg_zeros, None);
    }
}
<commit_msg>Added upper/lower_bound on slices<commit_after>pub mod dynamic_arq;
pub mod specs;
pub mod sqrt_decomp;
pub mod static_arq;
pub use dynamic_arq::{ArqView, DynamicArq};
pub use specs::ArqSpec;
pub use static_arq::StaticArq;

/// Assuming slice is sorted, returns the minimum i for which slice[i] >= key,
/// or slice.len() if no such i exists
pub fn slice_lower_bound<T: Ord>(slice: &[T], key: &T) -> usize {
    slice
        .binary_search_by(|x| x.cmp(key).then(std::cmp::Ordering::Greater))
        .unwrap_err()
}

/// Assuming slice is sorted, returns the minimum i for which slice[i] > key,
/// or slice.len() if no such i exists
pub fn slice_upper_bound<T: Ord>(slice: &[T], key: &T) -> usize {
    slice
        .binary_search_by(|x| x.cmp(key).then(std::cmp::Ordering::Less))
        .unwrap_err()
}

/// A simple data structure for coordinate compression
pub struct SparseIndex {
    coords: Vec<i64>,
}

impl SparseIndex {
    /// Build an index, given the full set of coordinates to compress.
    pub fn new(mut coords: Vec<i64>) -> Self {
        coords.sort_unstable();
        coords.dedup();
        Self { coords }
    }

    /// Return Ok(i) if the coordinate q appears at index i
    /// Return Err(i) if q appears between indices i-1 and i
    pub fn compress(&self, q: i64) -> Result<usize, usize> {
        self.coords.binary_search(&q)
    }
}

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

    #[test]
    fn test_bounds() {
        let mut vals = vec![16, 45, 45, 45, 82];

        assert_eq!(slice_upper_bound(&vals, &44), 1);
        assert_eq!(slice_lower_bound(&vals, &45), 1);
        assert_eq!(slice_upper_bound(&vals, &45), 4);
        assert_eq!(slice_lower_bound(&vals, &46), 4);

        vals.dedup();
        for (i, q) in vals.iter().enumerate() {
            assert_eq!(slice_lower_bound(&vals, q), i);
            assert_eq!(slice_upper_bound(&vals, q), i + 1);
        }
    }

    #[test]
    fn test_coord_compress() {
        let mut coords = vec![16, 99, 45, 18];
        let index = SparseIndex::new(coords.clone());

        coords.sort_unstable();
        for (i, q) in coords.into_iter().enumerate() {
            assert_eq!(index.compress(q - 1), Err(i));
            assert_eq!(index.compress(q), Ok(i));
            assert_eq!(index.compress(q + 1), Err(i + 1));
        }
    }

    #[test]
    fn test_range_compress() {
        let queries = vec![(0, 10), (10, 19), (20, 29)];
        let coords = queries.iter().flat_map(|&(i, j)| vec![i, j + 1]).collect();
        let index = SparseIndex::new(coords);

        assert_eq!(index.coords, vec![0, 10, 11, 20, 30]);
    }

    #[test]
    fn test_rmq() {
        let mut arq = StaticArq::<AssignMin>::new(&[0; 10]);

        assert_eq!(arq.query(0, 9), 0);

        arq.update(2, 4, &-5);
        arq.update(5, 7, &-3);
        arq.update(1, 6, &1);

        assert_eq!(arq.query(0, 9), -3);
    }

    #[test]
    fn test_dynamic_rmq() {
        let mut arq = DynamicArq::<AssignMin>::new(false);
        let view = arq.build_from_slice(&[0; 10]);

        assert_eq!(arq.query(view, 0, 9), 0);

        arq.update(view, 2, 4, &-5);
        arq.update(view, 5, 7, &-3);
        arq.update(view, 1, 6, &1);

        assert_eq!(arq.query(view, 0, 9), -3);
    }

    #[test]
    fn test_persistent_rmq() {
        let mut arq = DynamicArq::<AssignMin>::new(true);
        let mut view = arq.build_from_slice(&[0; 10]);

        let at_init = view;
        view = arq.update(view, 2, 4, &-5);
        let snapshot = view;
        view = arq.update(view, 5, 7, &-3);
        view = arq.update(view, 1, 6, &1);

        assert_eq!(arq.query(at_init, 0, 9), 0);
        assert_eq!(arq.query(snapshot, 0, 9), -5);
        assert_eq!(arq.query(view, 0, 9), -3);
    }

    #[test]
    fn test_huge_rmq() {
        let quintillion = 1_000_000_000_000_000_000;
        let mut arq = DynamicArq::<AssignMin>::new(false);
        let view = arq.build_from_identity(9 * quintillion + 1);

        arq.update(view, 2 * quintillion, 4 * quintillion, &-5);
        arq.update(view, 5 * quintillion, 7 * quintillion, &-3);
        arq.update(view, 1 * quintillion, 6 * quintillion, &1);

        assert_eq!(arq.query(view, 0, 9 * quintillion), -3);
    }

    #[test]
    fn test_range_sum() {
        let mut arq = StaticArq::<AssignSum>::new(&[0; 10]);

        assert_eq!(arq.query(0, 9), 0);

        arq.update(1, 3, &10);
        arq.update(3, 5, &1);

        assert_eq!(arq.query(0, 9), 23);
        assert_eq!(arq.query(10, 4), 0);
    }

    #[test]
    fn test_dynamic_range_sum() {
        let mut arq = DynamicArq::<AssignSum>::new(false);
        let view = arq.build_from_slice(&[0; 10]);

        assert_eq!(arq.query(view, 0, 9), 0);

        arq.update(view, 1, 3, &10);
        arq.update(view, 3, 5, &1);

        assert_eq!(arq.query(view, 0, 9), 23);
        assert_eq!(arq.query(view, 10, 4), 0);
    }

    #[test]
    fn test_supply_demand() {
        let mut arq = StaticArq::<SupplyDemand>::new(&[(0, 0, 0); 10]);

        arq.update(1, 1, &(25, 100));
        arq.update(3, 3, &(100, 30));
        arq.update(9, 9, &(0, 20));

        assert_eq!(arq.query(0, 9), (125, 150, 75));
    }

    #[test]
    fn test_dynamic_supply_demand() {
        let mut arq = DynamicArq::<SupplyDemand>::new(false);
        let view = arq.build_from_identity(10);

        arq.update(view, 1, 1, &(25, 100));
        arq.update(view, 3, 3, &(100, 30));
        arq.update(view, 9, 9, &(0, 20));

        assert_eq!(arq.query(view, 0, 9), (125, 150, 75));
    }

    #[test]
    fn test_binary_search_rmq() {
        let vec = vec![2, 1, 0, -1, -2, -3, -4, -5];
        let mut arq = StaticArq::<AssignMin>::new(&vec);
        let first_neg = static_arq::first_negative(&mut arq);

        arq.update(3, 7, &0);
        let first_neg_zeros = static_arq::first_negative(&mut arq);

        assert_eq!(first_neg, Some(3));
        assert_eq!(first_neg_zeros, None);
    }

    #[test]
    fn test_dynamic_binary_search_rmq() {
        let vec = vec![2, 1, 0, -1, -2, -3, -4, -5];
        let mut arq = DynamicArq::<AssignMin>::new(false);
        let view = arq.build_from_slice(&vec);
        let first_neg = dynamic_arq::first_negative(&mut arq, view);

        arq.update(view, 3, 7, &0);
        let first_neg_zeros = dynamic_arq::first_negative(&mut arq, view);

        assert_eq!(first_neg, Some(3));
        assert_eq!(first_neg_zeros, None);
    }
}
<|endoftext|>


<commit_before>//! Functions for finding and labelling connected components of image.

use image::{
    GenericImage,
    ImageBuffer,
    Luma
};

use unionfind::DisjointSetForest;

use std::cmp;
use std::collections::HashMap;

#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Connectivity { Four, Eight }

/// Returns image of the same size as the input, where each pixel
/// is labelled by the connected foreground component it belongs to,
/// or 0 if it's in the background. Input pixels are treated as belonging
/// to the background if and only if they have value 0.
pub fn connected_components<I>(image: &I, conn: Connectivity)
        -> ImageBuffer<Luma<u32>, Vec<u32>>
    where I: GenericImage<Pixel=Luma<u8>> + 'static {

    let (width, height) = image.dimensions();
    let mut out = ImageBuffer::new(width, height);

    // TODO: add macro to abandon early if either dimension is zero
    if width == 0 || height == 0 {
        return out;
    }

    let background = Luma([0u8]);
    let mut forest = DisjointSetForest::new((width * height) as usize);
    let mut adj_labels = [0u32; 4];
    let mut next_label = 1;

    for y in 0..height {
        for x in 0..width {
            out.put_pixel(x, y, Luma([0]));
        }

        for x in 0..width {

            let current = image.get_pixel(x, y);
            if current == background {
                continue;
            }

            let mut num_adj = 0;

            if x > 0 {
                // West
                let pixel = image.get_pixel(x - 1, y);
                if pixel == current {
                    let label = out.get_pixel(x - 1, y)[0];
                    adj_labels[num_adj] = label;
                    num_adj += 1;
                }
            }

            if y > 0 {
                // North
                let pixel = image.get_pixel(x, y - 1);
                if pixel == current {
                    let label = out.get_pixel(x, y - 1)[0];
                    adj_labels[num_adj] = label;
                    num_adj += 1;
                }

                if conn == Connectivity::Eight {
                    if x > 0 {
                        // North West
                        let pixel = image.get_pixel(x - 1, y - 1);
                        if pixel == current {
                            let label = out.get_pixel(x - 1, y - 1)[0];
                            adj_labels[num_adj] = label;
                            num_adj += 1;
                        }
                    }
                    if x < width - 1 {
                        // North East
                        let pixel = image.get_pixel(x + 1, y - 1);
                        if pixel == current {
                            let label = out.get_pixel(x + 1, y - 1)[0];
                            adj_labels[num_adj] = label;
                            num_adj += 1;
                        }
                    }
                }
            }

            if num_adj == 0 {
                out.put_pixel(x, y, Luma([next_label]));
                next_label += 1;
            }
            else {
                let mut min_label = u32::max_value();
                for n in 0..num_adj {
                    min_label = cmp::min(min_label, adj_labels[n]);
                }
                out.put_pixel(x, y, Luma([min_label]));
                for n in 0..num_adj {
                    forest.union(min_label as usize, adj_labels[n] as usize);
                }
            }
        }
    }

    // Make components start at 1
    let mut root_name = 1;
    let mut root_idx: HashMap<usize, usize> = HashMap::new();

    for y in 0..height {
        for x in 0..width {
            if image.get_pixel(x, y) == background {
                continue;
            }

            let label = out.get_pixel(x, y)[0];
            let root = forest.root(label as usize);

            match root_idx.get(&root).map(|x| *x) {
                Some(idx) => {
                    out.put_pixel(x, y, Luma([idx as u32]));
                }
                None => {
                    let idx = root_name;
                    root_idx.insert(root, idx);
                    out.put_pixel(x, y, Luma([idx as u32]));
                    root_name += 1;
                }
            }
        }
    }

    out
}

#[cfg(test)]
mod test {

    use super::{
        connected_components
    };
    use super::Connectivity::{
        Four,
        Eight
    };
    use image::{
        GrayImage,
        ImageBuffer,
        Luma
    };
    use test;

    #[test]
    fn test_connected_components_four() {
        let image: GrayImage = ImageBuffer::from_raw(4, 4, vec![
            1, 0, 2, 1,
            0, 1, 1, 0,
            0, 0, 0, 0,
            0, 0, 0, 1]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(4, 4, vec![
                1, 0, 2, 3,
                0, 4, 4, 0,
                0, 0, 0, 0,
                0, 0, 0, 5]).unwrap();

        let labelled = connected_components(&image, Four);
        assert_pixels_eq!(labelled, expected);
    }

    #[test]
    fn test_connected_components_eight() {
        let image: GrayImage = ImageBuffer::from_raw(4, 4, vec![
            1, 0, 2, 1,
            0, 1, 1, 0,
            0, 0, 0, 0,
            0, 0, 0, 1]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(4, 4, vec![
                1, 0, 2, 1,
                0, 1, 1, 0,
                0, 0, 0, 0,
                0, 0, 0, 3]).unwrap();

        let labelled = connected_components(&image, Eight);
        assert_pixels_eq!(labelled, expected);
    }

    // TODO: add benchmark
}
<commit_msg>Fix typos in comments<commit_after>//! Functions for finding and labelling connected components of an image.

use image::{
    GenericImage,
    ImageBuffer,
    Luma
};

use unionfind::DisjointSetForest;

use std::cmp;
use std::collections::HashMap;

#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Connectivity { Four, Eight }

/// Returns an image of the same size as the input, where each pixel
/// is labelled by the connected foreground component it belongs to,
/// or 0 if it's in the background. Input pixels are treated as belonging
/// to the background if and only if they have value 0.
pub fn connected_components<I>(image: &I, conn: Connectivity)
        -> ImageBuffer<Luma<u32>, Vec<u32>>
    where I: GenericImage<Pixel=Luma<u8>> + 'static {

    let (width, height) = image.dimensions();
    let mut out = ImageBuffer::new(width, height);

    // TODO: add macro to abandon early if either dimension is zero
    if width == 0 || height == 0 {
        return out;
    }

    let background = Luma([0u8]);
    let mut forest = DisjointSetForest::new((width * height) as usize);
    let mut adj_labels = [0u32; 4];
    let mut next_label = 1;

    for y in 0..height {
        for x in 0..width {
            out.put_pixel(x, y, Luma([0]));
        }

        for x in 0..width {

            let current = image.get_pixel(x, y);
            if current == background {
                continue;
            }

            let mut num_adj = 0;

            if x > 0 {
                // West
                let pixel = image.get_pixel(x - 1, y);
                if pixel == current {
                    let label = out.get_pixel(x - 1, y)[0];
                    adj_labels[num_adj] = label;
                    num_adj += 1;
                }
            }

            if y > 0 {
                // North
                let pixel = image.get_pixel(x, y - 1);
                if pixel == current {
                    let label = out.get_pixel(x, y - 1)[0];
                    adj_labels[num_adj] = label;
                    num_adj += 1;
                }

                if conn == Connectivity::Eight {
                    if x > 0 {
                        // North West
                        let pixel = image.get_pixel(x - 1, y - 1);
                        if pixel == current {
                            let label = out.get_pixel(x - 1, y - 1)[0];
                            adj_labels[num_adj] = label;
                            num_adj += 1;
                        }
                    }
                    if x < width - 1 {
                        // North East
                        let pixel = image.get_pixel(x + 1, y - 1);
                        if pixel == current {
                            let label = out.get_pixel(x + 1, y - 1)[0];
                            adj_labels[num_adj] = label;
                            num_adj += 1;
                        }
                    }
                }
            }

            if num_adj == 0 {
                out.put_pixel(x, y, Luma([next_label]));
                next_label += 1;
            }
            else {
                let mut min_label = u32::max_value();
                for n in 0..num_adj {
                    min_label = cmp::min(min_label, adj_labels[n]);
                }
                out.put_pixel(x, y, Luma([min_label]));
                for n in 0..num_adj {
                    forest.union(min_label as usize, adj_labels[n] as usize);
                }
            }
        }
    }

    // Make components start at 1
    let mut root_name = 1;
    let mut root_idx: HashMap<usize, usize> = HashMap::new();

    for y in 0..height {
        for x in 0..width {
            if image.get_pixel(x, y) == background {
                continue;
            }

            let label = out.get_pixel(x, y)[0];
            let root = forest.root(label as usize);

            match root_idx.get(&root).map(|x| *x) {
                Some(idx) => {
                    out.put_pixel(x, y, Luma([idx as u32]));
                }
                None => {
                    let idx = root_name;
                    root_idx.insert(root, idx);
                    out.put_pixel(x, y, Luma([idx as u32]));
                    root_name += 1;
                }
            }
        }
    }

    out
}

#[cfg(test)]
mod test {

    use super::{
        connected_components
    };
    use super::Connectivity::{
        Four,
        Eight
    };
    use image::{
        GrayImage,
        ImageBuffer,
        Luma
    };
    use test;

    #[test]
    fn test_connected_components_four() {
        let image: GrayImage = ImageBuffer::from_raw(4, 4, vec![
            1, 0, 2, 1,
            0, 1, 1, 0,
            0, 0, 0, 0,
            0, 0, 0, 1]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(4, 4, vec![
                1, 0, 2, 3,
                0, 4, 4, 0,
                0, 0, 0, 0,
                0, 0, 0, 5]).unwrap();

        let labelled = connected_components(&image, Four);
        assert_pixels_eq!(labelled, expected);
    }

    #[test]
    fn test_connected_components_eight() {
        let image: GrayImage = ImageBuffer::from_raw(4, 4, vec![
            1, 0, 2, 1,
            0, 1, 1, 0,
            0, 0, 0, 0,
            0, 0, 0, 1]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(4, 4, vec![
                1, 0, 2, 1,
                0, 1, 1, 0,
                0, 0, 0, 0,
                0, 0, 0, 3]).unwrap();

        let labelled = connected_components(&image, Eight);
        assert_pixels_eq!(labelled, expected);
    }

    // TODO: add benchmark
}
<|endoftext|>


<commit_before>// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the MIT License, <LICENSE or http://opensource.org/licenses/MIT>.
// This file may not be copied, modified, or distributed except according to those terms.

use serde;
use std::fmt;
use std::io::{self, BufReader, BufWriter, Read};
use std::collections::HashMap;
use std::mem;
use std::net::{TcpStream, ToSocketAddrs};
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{Receiver, Sender, channel};
use std::thread;

use super::{Config, Deserialize, Error, Packet, Result, Serialize};
use transport::{Dialer, Stream};
use transport::tcp::TcpDialer;

/// A client stub that connects to a server to run rpcs.
pub struct Client<Request, Reply, S: Stream>
    where Request: serde::ser::Serialize
{
    // The guard is in an option so it can be joined in the drop fn
    reader_guard: Arc<Option<thread::JoinHandle<()>>>,
    outbound: Sender<(Request, Sender<Result<Reply>>)>,
    requests: Arc<Mutex<RpcFutures<Reply>>>,
    shutdown: S,
}

impl<Request, Reply> Client<Request, Reply, TcpStream>
    where Request: serde::ser::Serialize + Send + 'static,
          Reply: serde::de::Deserialize + Send + 'static
{
    /// Create a new client that connects to `addr`. The client uses the given timeout
    /// for both reads and writes.
    pub fn new<A: ToSocketAddrs>(addr: A) -> io::Result<Self> {
        Self::with_config(TcpDialer(addr), Config::default())
    }
}

impl<Request, Reply, S: Stream> Client<Request, Reply, S>
    where Request: serde::ser::Serialize + Send + 'static,
          Reply: serde::de::Deserialize + Send + 'static
{
    /// Create a new client that connects to `addr`. The client uses the given timeout
    /// for both reads and writes.
    pub fn with_config<D>(dialer: D, config: Config) -> io::Result<Self>
        where D: Dialer<Stream=S>,
    {
        let stream = try!(dialer.dial());
        try!(stream.set_read_timeout(config.timeout));
        try!(stream.set_write_timeout(config.timeout));
        let reader_stream = try!(stream.try_clone());
        let writer_stream = try!(stream.try_clone());
        let requests = Arc::new(Mutex::new(RpcFutures::new()));
        let reader_requests = requests.clone();
        let writer_requests = requests.clone();
        let (tx, rx) = channel();
        let reader_guard = thread::spawn(move || read(reader_requests, reader_stream));
        thread::spawn(move || write(rx, writer_requests, writer_stream));
        Ok(Client {
            reader_guard: Arc::new(Some(reader_guard)),
            outbound: tx,
            requests: requests,
            shutdown: stream,
        })
    }

    /// Clones the Client so that it can be shared across threads.
    pub fn try_clone(&self) -> io::Result<Self> {
        Ok(Client {
            reader_guard: self.reader_guard.clone(),
            outbound: self.outbound.clone(),
            requests: self.requests.clone(),
            shutdown: try!(self.shutdown.try_clone()),
        })
    }

    fn rpc_internal(&self, request: Request) -> Receiver<Result<Reply>>
        where Request: serde::ser::Serialize + fmt::Debug + Send + 'static
    {
        let (tx, rx) = channel();
        self.outbound.send((request, tx)).expect(pos!());
        rx
    }

    /// Run the specified rpc method on the server this client is connected to
    pub fn rpc(&self, request: Request) -> Result<Reply>
        where Request: serde::ser::Serialize + fmt::Debug + Send + 'static
    {
        self.rpc_internal(request)
            .recv()
            .map_err(|_| self.requests.lock().expect(pos!()).get_error())
            .and_then(|reply| reply)
    }

    /// Asynchronously run the specified rpc method on the server this client is connected to
    pub fn rpc_async(&self, request: Request) -> Future<Reply>
        where Request: serde::ser::Serialize + fmt::Debug + Send + 'static
    {
        Future {
            rx: self.rpc_internal(request),
            requests: self.requests.clone(),
        }
    }
}

impl<Request, Reply, S: Stream> Drop for Client<Request, Reply, S>
    where Request: serde::ser::Serialize
{
    fn drop(&mut self) {
        debug!("Dropping Client.");
        if let Some(reader_guard) = Arc::get_mut(&mut self.reader_guard) {
            debug!("Attempting to shut down writer and reader threads.");
            if let Err(e) = self.shutdown.shutdown() {
                warn!("Client: couldn't shutdown writer and reader threads: {:?}",
                      e);
            } else {
                // We only join if we know the TcpStream was shut down. Otherwise we might never
                // finish.
                debug!("Joining writer and reader.");
                reader_guard.take()
                            .expect(pos!())
                            .join()
                            .expect(pos!());
                debug!("Successfully joined writer and reader.");
            }
        }
    }
}

/// An asynchronous RPC call
pub struct Future<T> {
    rx: Receiver<Result<T>>,
    requests: Arc<Mutex<RpcFutures<T>>>,
}

impl<T> Future<T> {
    /// Block until the result of the RPC call is available
    pub fn get(self) -> Result<T> {
        let requests = self.requests;
        self.rx
            .recv()
            .map_err(|_| requests.lock().expect(pos!()).get_error())
            .and_then(|reply| reply)
    }
}

struct RpcFutures<Reply>(Result<HashMap<u64, Sender<Result<Reply>>>>);

impl<Reply> RpcFutures<Reply> {
    fn new() -> RpcFutures<Reply> {
        RpcFutures(Ok(HashMap::new()))
    }

    fn insert_tx(&mut self, id: u64, tx: Sender<Result<Reply>>) -> Result<()> {
        match self.0 {
            Ok(ref mut requests) => {
                requests.insert(id, tx);
                Ok(())
            }
            Err(ref e) => Err(e.clone()),
        }
    }

    fn remove_tx(&mut self, id: u64) -> Result<()> {
        match self.0 {
            Ok(ref mut requests) => {
                requests.remove(&id);
                Ok(())
            }
            Err(ref e) => Err(e.clone()),
        }
    }

    fn complete_reply(&mut self, packet: Packet<Reply>) {
        if let Some(tx) = self.0.as_mut().expect(pos!()).remove(&packet.rpc_id) {
            if let Err(e) = tx.send(Ok(packet.message)) {
                info!("Reader: could not complete reply: {:?}", e);
            }
        } else {
            warn!("RpcFutures: expected sender for id {} but got None!",
                  packet.rpc_id);
        }
    }

    fn set_error(&mut self, err: Error) {
        let _ = mem::replace(&mut self.0, Err(err));
    }

    fn get_error(&self) -> Error {
        self.0.as_ref().err().expect(pos!()).clone()
    }
}

fn write<Request, Reply, S: Stream>(outbound: Receiver<(Request, Sender<Result<Reply>>)>,
                         requests: Arc<Mutex<RpcFutures<Reply>>>,
                         stream: S)
    where Request: serde::Serialize,
          Reply: serde::Deserialize
{
    let mut next_id = 0;
    let mut stream = BufWriter::new(stream);
    loop {
        let (request, tx) = match outbound.recv() {
            Err(e) => {
                debug!("Writer: all senders have exited ({:?}). Returning.", e);
                return;
            }
            Ok(request) => request,
        };
        if let Err(e) = requests.lock().expect(pos!()).insert_tx(next_id, tx.clone()) {
            report_error(&tx, e);
            // Once insert_tx returns Err, it will continue to do so. However, continue here so
            // that any other clients who sent requests will also recv the Err.
            continue;
        }
        let id = next_id;
        next_id += 1;
        let packet = Packet {
            rpc_id: id,
            message: request,
        };
        debug!("Writer: writing rpc, id={:?}", id);
        if let Err(e) = stream.serialize(&packet) {
            report_error(&tx, e.into());
            // Typically we'd want to notify the client of any Err returned by remove_tx, but in
            // this case the client already hit an Err, and doesn't need to know about this one, as
            // well.
            let _ = requests.lock().expect(pos!()).remove_tx(id);
            continue;
        }
    }

    fn report_error<Reply>(tx: &Sender<Result<Reply>>, e: Error)
        where Reply: serde::Deserialize
    {
        // Clone the err so we can log it if sending fails
        if let Err(e2) = tx.send(Err(e.clone())) {
            debug!("Error encountered while trying to send an error. Initial error: {:?}; Send \
                    error: {:?}",
                   e,
                   e2);
        }
    }

}

fn read<Reply, S: Stream>(requests: Arc<Mutex<RpcFutures<Reply>>>, stream: S)
    where Reply: serde::Deserialize
{
    let mut stream = BufReader::new(stream);
    loop {
        match stream.deserialize::<Packet<Reply>>() {
            Ok(packet) => {
                debug!("Client: received message, id={}", packet.rpc_id);
                requests.lock().expect(pos!()).complete_reply(packet);
            }
            Err(err) => {
                warn!("Client: reader thread encountered an unexpected error while parsing; \
                       returning now. Error: {:?}",
                      err);
                requests.lock().expect(pos!()).set_error(err);
                break;
            }
        }
    }
}
<commit_msg>Move generic bounds to where clause<commit_after>// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the MIT License, <LICENSE or http://opensource.org/licenses/MIT>.
// This file may not be copied, modified, or distributed except according to those terms.

use serde;
use std::fmt;
use std::io::{self, BufReader, BufWriter, Read};
use std::collections::HashMap;
use std::mem;
use std::net::{TcpStream, ToSocketAddrs};
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{Receiver, Sender, channel};
use std::thread;

use super::{Config, Deserialize, Error, Packet, Result, Serialize};
use transport::{Dialer, Stream};
use transport::tcp::TcpDialer;

/// A client stub that connects to a server to run rpcs.
pub struct Client<Request, Reply, S>
    where Request: serde::ser::Serialize,
          S: Stream,
{
    // The guard is in an option so it can be joined in the drop fn
    reader_guard: Arc<Option<thread::JoinHandle<()>>>,
    outbound: Sender<(Request, Sender<Result<Reply>>)>,
    requests: Arc<Mutex<RpcFutures<Reply>>>,
    shutdown: S,
}

impl<Request, Reply> Client<Request, Reply, TcpStream>
    where Request: serde::ser::Serialize + Send + 'static,
          Reply: serde::de::Deserialize + Send + 'static
{
    /// Create a new client that connects to `addr`. The client uses the given timeout
    /// for both reads and writes.
    pub fn new<A: ToSocketAddrs>(addr: A) -> io::Result<Self> {
        Self::with_config(TcpDialer(addr), Config::default())
    }
}

impl<Request, Reply, S> Client<Request, Reply, S>
    where Request: serde::ser::Serialize + Send + 'static,
          Reply: serde::de::Deserialize + Send + 'static,
          S: Stream,
{
    /// Create a new client that connects to `addr`. The client uses the given timeout
    /// for both reads and writes.
    pub fn with_config<D>(dialer: D, config: Config) -> io::Result<Self>
        where D: Dialer<Stream=S>,
    {
        let stream = try!(dialer.dial());
        try!(stream.set_read_timeout(config.timeout));
        try!(stream.set_write_timeout(config.timeout));
        let reader_stream = try!(stream.try_clone());
        let writer_stream = try!(stream.try_clone());
        let requests = Arc::new(Mutex::new(RpcFutures::new()));
        let reader_requests = requests.clone();
        let writer_requests = requests.clone();
        let (tx, rx) = channel();
        let reader_guard = thread::spawn(move || read(reader_requests, reader_stream));
        thread::spawn(move || write(rx, writer_requests, writer_stream));
        Ok(Client {
            reader_guard: Arc::new(Some(reader_guard)),
            outbound: tx,
            requests: requests,
            shutdown: stream,
        })
    }

    /// Clones the Client so that it can be shared across threads.
    pub fn try_clone(&self) -> io::Result<Self> {
        Ok(Client {
            reader_guard: self.reader_guard.clone(),
            outbound: self.outbound.clone(),
            requests: self.requests.clone(),
            shutdown: try!(self.shutdown.try_clone()),
        })
    }

    fn rpc_internal(&self, request: Request) -> Receiver<Result<Reply>>
        where Request: serde::ser::Serialize + fmt::Debug + Send + 'static
    {
        let (tx, rx) = channel();
        self.outbound.send((request, tx)).expect(pos!());
        rx
    }

    /// Run the specified rpc method on the server this client is connected to
    pub fn rpc(&self, request: Request) -> Result<Reply>
        where Request: serde::ser::Serialize + fmt::Debug + Send + 'static
    {
        self.rpc_internal(request)
            .recv()
            .map_err(|_| self.requests.lock().expect(pos!()).get_error())
            .and_then(|reply| reply)
    }

    /// Asynchronously run the specified rpc method on the server this client is connected to
    pub fn rpc_async(&self, request: Request) -> Future<Reply>
        where Request: serde::ser::Serialize + fmt::Debug + Send + 'static
    {
        Future {
            rx: self.rpc_internal(request),
            requests: self.requests.clone(),
        }
    }
}

impl<Request, Reply, S> Drop for Client<Request, Reply, S>
    where Request: serde::ser::Serialize,
          S: Stream,
{
    fn drop(&mut self) {
        debug!("Dropping Client.");
        if let Some(reader_guard) = Arc::get_mut(&mut self.reader_guard) {
            debug!("Attempting to shut down writer and reader threads.");
            if let Err(e) = self.shutdown.shutdown() {
                warn!("Client: couldn't shutdown writer and reader threads: {:?}",
                      e);
            } else {
                // We only join if we know the TcpStream was shut down. Otherwise we might never
                // finish.
                debug!("Joining writer and reader.");
                reader_guard.take()
                            .expect(pos!())
                            .join()
                            .expect(pos!());
                debug!("Successfully joined writer and reader.");
            }
        }
    }
}

/// An asynchronous RPC call
pub struct Future<T> {
    rx: Receiver<Result<T>>,
    requests: Arc<Mutex<RpcFutures<T>>>,
}

impl<T> Future<T> {
    /// Block until the result of the RPC call is available
    pub fn get(self) -> Result<T> {
        let requests = self.requests;
        self.rx
            .recv()
            .map_err(|_| requests.lock().expect(pos!()).get_error())
            .and_then(|reply| reply)
    }
}

struct RpcFutures<Reply>(Result<HashMap<u64, Sender<Result<Reply>>>>);

impl<Reply> RpcFutures<Reply> {
    fn new() -> RpcFutures<Reply> {
        RpcFutures(Ok(HashMap::new()))
    }

    fn insert_tx(&mut self, id: u64, tx: Sender<Result<Reply>>) -> Result<()> {
        match self.0 {
            Ok(ref mut requests) => {
                requests.insert(id, tx);
                Ok(())
            }
            Err(ref e) => Err(e.clone()),
        }
    }

    fn remove_tx(&mut self, id: u64) -> Result<()> {
        match self.0 {
            Ok(ref mut requests) => {
                requests.remove(&id);
                Ok(())
            }
            Err(ref e) => Err(e.clone()),
        }
    }

    fn complete_reply(&mut self, packet: Packet<Reply>) {
        if let Some(tx) = self.0.as_mut().expect(pos!()).remove(&packet.rpc_id) {
            if let Err(e) = tx.send(Ok(packet.message)) {
                info!("Reader: could not complete reply: {:?}", e);
            }
        } else {
            warn!("RpcFutures: expected sender for id {} but got None!",
                  packet.rpc_id);
        }
    }

    fn set_error(&mut self, err: Error) {
        let _ = mem::replace(&mut self.0, Err(err));
    }

    fn get_error(&self) -> Error {
        self.0.as_ref().err().expect(pos!()).clone()
    }
}

fn write<Request, Reply, S>(outbound: Receiver<(Request, Sender<Result<Reply>>)>,
                         requests: Arc<Mutex<RpcFutures<Reply>>>,
                         stream: S)
    where Request: serde::Serialize,
          Reply: serde::Deserialize,
          S: Stream,
{
    let mut next_id = 0;
    let mut stream = BufWriter::new(stream);
    loop {
        let (request, tx) = match outbound.recv() {
            Err(e) => {
                debug!("Writer: all senders have exited ({:?}). Returning.", e);
                return;
            }
            Ok(request) => request,
        };
        if let Err(e) = requests.lock().expect(pos!()).insert_tx(next_id, tx.clone()) {
            report_error(&tx, e);
            // Once insert_tx returns Err, it will continue to do so. However, continue here so
            // that any other clients who sent requests will also recv the Err.
            continue;
        }
        let id = next_id;
        next_id += 1;
        let packet = Packet {
            rpc_id: id,
            message: request,
        };
        debug!("Writer: writing rpc, id={:?}", id);
        if let Err(e) = stream.serialize(&packet) {
            report_error(&tx, e.into());
            // Typically we'd want to notify the client of any Err returned by remove_tx, but in
            // this case the client already hit an Err, and doesn't need to know about this one, as
            // well.
            let _ = requests.lock().expect(pos!()).remove_tx(id);
            continue;
        }
    }

    fn report_error<Reply>(tx: &Sender<Result<Reply>>, e: Error)
        where Reply: serde::Deserialize
    {
        // Clone the err so we can log it if sending fails
        if let Err(e2) = tx.send(Err(e.clone())) {
            debug!("Error encountered while trying to send an error. Initial error: {:?}; Send \
                    error: {:?}",
                   e,
                   e2);
        }
    }

}

fn read<Reply, S>(requests: Arc<Mutex<RpcFutures<Reply>>>, stream: S)
    where Reply: serde::Deserialize,
          S: Stream,
{
    let mut stream = BufReader::new(stream);
    loop {
        match stream.deserialize::<Packet<Reply>>() {
            Ok(packet) => {
                debug!("Client: received message, id={}", packet.rpc_id);
                requests.lock().expect(pos!()).complete_reply(packet);
            }
            Err(err) => {
                warn!("Client: reader thread encountered an unexpected error while parsing; \
                       returning now. Error: {:?}",
                      err);
                requests.lock().expect(pos!()).set_error(err);
                break;
            }
        }
    }
}
<|endoftext|>


<commit_before>use generate::GenerateCtx;
use arbitrary::Arbitrary;
use property::{Property, ForAllProperty};

use std::convert::{Into, From};

use rand;

#[derive(Copy, Clone)]
pub struct TestResult {
    pub status: Status,
}

#[derive(Copy, Clone)]
pub enum Status { Pass, Fail, Discard }

pub trait Testable {
    fn test<R: rand::Rng>(&self, ctx: &mut GenerateCtx<R>) -> TestResult;
}

impl <'a, T: Testable> Testable for &'a T {
    #[inline]
    fn test<R: rand::Rng>(&self, ctx: &mut GenerateCtx<R>) -> TestResult {
        (*self).test(ctx)
    }
}

pub trait IntoTestable {
    type Testable: Testable;

    fn into_testable(self) -> Self::Testable;
}

impl <T: Testable> IntoTestable for T {
    type Testable = Self;

    #[inline]
    fn into_testable(self) -> Self { self }
}

impl <T: Clone + Into<TestResult>> Testable for T {
    #[inline]
    fn test<R: rand::Rng>(&self, _: &mut GenerateCtx<R>) -> TestResult {
        self.clone().into()
    }
}

impl From<u8> for TestResult {
    #[inline]
    fn from(_: u8) -> TestResult {
        TestResult { status: Status::Pass }
    }
}

impl From<bool> for TestResult {
    #[inline]
    fn from(success: bool) -> TestResult {
        TestResult { status: if success {Status::Pass} else {Status::Fail} }
    }
}

macro_rules! fn_impls {
    ($($name:ident),*) => {
        impl <Output: Into<TestResult>, $($name: Arbitrary),*> IntoTestable for fn($($name),*) -> Output
        {
            type Testable = ForAllProperty<($($name,)*), <($($name,)*) as Arbitrary>::ArbitraryGenerator, Self>;

            #[inline]
            fn into_testable(self) -> Self::Testable {
                Property::<($($name,)*)>::new(self)
            }
        }
    }
}

macro_tuples_impl! {fn_impls}

#[derive(Copy, Clone)]
pub struct CheckResult;

pub fn qckchk<T: IntoTestable>(t: T) -> CheckResult
{
    let testable = t.into_testable();
    let mut ctx = GenerateCtx { rng: rand::thread_rng(), size: 5 };
    let _test_result = testable.test(&mut ctx);
    CheckResult
}

#[cfg(test)]
mod tests {
    use super::*;
    use generate::Constant;
    use property::Property;

    #[test]
    fn test_result_is_testable() {
        qckchk(TestResult { status: Status::Pass });
    }

    #[test]
    fn into_test_result_is_testable() {
        qckchk(6u8);
    }

    #[test]
    fn property_is_testable() {
        let simple_prop = Property::<()>::new(|| TestResult { status: Status::Pass });
        qckchk(simple_prop);
    }

    #[test]
    fn property_is_testable_by_reference() {
        let simple_prop = Property::<()>::new(|| TestResult { status: Status::Pass });
        qckchk(&simple_prop);
    }

    #[test]
    fn property_with_args_is_testable() {
        let my_prop = Property::<(usize,)>::new(|_| TestResult { status: Status::Pass });
        qckchk(&my_prop);
    }

    #[test]
    fn property_returning_non_test_result_is_testable() {
        let my_prop2 = Property::<(usize,)>::new(|_| 3u8 );
        qckchk(&my_prop2);
    }

    #[test]
    fn for_all_is_testable() {
        let for_all_prop = Property::<(usize,)>
            ::for_all((Constant(32usize),))
            .property(|_| 3u8);
        qckchk(&for_all_prop);
    }

    #[test]
    fn for_all_with_two_arguments_is_testable() {
        let my_prop3 = Property::<(usize, usize)>
            ::for_all((Constant(32usize), Constant(42usize)))
            .property(|_, _| 3u8);
        qckchk(&my_prop3);
    }

    #[test]
    fn when_property_is_testable() {
        let predicate_prop = Property::<(usize,)>
            ::when(|s| s > 5)
            .then(|_| 3u8);
        qckchk(&predicate_prop);
    }

    #[test]
    fn cast_fn_is_testable() {
        fn my_fn() -> bool { true }
        qckchk(my_fn as fn() -> bool);

        fn my_fn2(_:usize) -> bool { true }
        qckchk(my_fn2 as fn(usize) -> bool);
    }
}
<commit_msg>One more test...<commit_after>use generate::GenerateCtx;
use arbitrary::Arbitrary;
use property::{Property, ForAllProperty};

use std::convert::{Into, From};

use rand;

#[derive(Copy, Clone)]
pub struct TestResult {
    pub status: Status,
}

#[derive(Copy, Clone)]
pub enum Status { Pass, Fail, Discard }

pub trait Testable {
    fn test<R: rand::Rng>(&self, ctx: &mut GenerateCtx<R>) -> TestResult;
}

impl <'a, T: Testable> Testable for &'a T {
    #[inline]
    fn test<R: rand::Rng>(&self, ctx: &mut GenerateCtx<R>) -> TestResult {
        (*self).test(ctx)
    }
}

pub trait IntoTestable {
    type Testable: Testable;

    fn into_testable(self) -> Self::Testable;
}

impl <T: Testable> IntoTestable for T {
    type Testable = Self;

    #[inline]
    fn into_testable(self) -> Self { self }
}

impl <T: Clone + Into<TestResult>> Testable for T {
    #[inline]
    fn test<R: rand::Rng>(&self, _: &mut GenerateCtx<R>) -> TestResult {
        self.clone().into()
    }
}

impl From<u8> for TestResult {
    #[inline]
    fn from(_: u8) -> TestResult {
        TestResult { status: Status::Pass }
    }
}

impl From<bool> for TestResult {
    #[inline]
    fn from(success: bool) -> TestResult {
        TestResult { status: if success {Status::Pass} else {Status::Fail} }
    }
}

macro_rules! fn_impls {
    ($($name:ident),*) => {
        impl <Output: Into<TestResult>, $($name: Arbitrary),*> IntoTestable for fn($($name),*) -> Output
        {
            type Testable = ForAllProperty<($($name,)*), <($($name,)*) as Arbitrary>::ArbitraryGenerator, Self>;

            #[inline]
            fn into_testable(self) -> Self::Testable {
                Property::<($($name,)*)>::new(self)
            }
        }
    }
}

macro_tuples_impl! {fn_impls}

#[derive(Copy, Clone)]
pub struct CheckResult;

pub fn qckchk<T: IntoTestable>(t: T) -> CheckResult
{
    let testable = t.into_testable();
    let mut ctx = GenerateCtx { rng: rand::thread_rng(), size: 5 };
    let _test_result = testable.test(&mut ctx);
    CheckResult
}

#[cfg(test)]
mod tests {
    use super::*;
    use generate::Constant;
    use property::Property;

    #[test]
    fn test_result_is_testable() {
        qckchk(TestResult { status: Status::Pass });
    }

    #[test]
    fn into_test_result_is_testable() {
        qckchk(6u8);
    }

    #[test]
    fn property_is_testable() {
        let simple_prop = Property::<()>::new(|| TestResult { status: Status::Pass });
        qckchk(simple_prop);
    }

    #[test]
    fn property_is_testable_by_reference() {
        let simple_prop = Property::<()>::new(|| TestResult { status: Status::Pass });
        qckchk(&simple_prop);
    }

    #[test]
    fn property_with_args_is_testable() {
        let my_prop = Property::<(usize,)>::new(|_| TestResult { status: Status::Pass });
        qckchk(&my_prop);
    }

    #[test]
    fn property_returning_non_test_result_is_testable() {
        let my_prop2 = Property::<(usize,)>::new(|_| 3u8 );
        qckchk(&my_prop2);
    }

    #[test]
    fn for_all_is_testable() {
        let for_all_prop = Property::<(usize,)>
            ::for_all((Constant(32usize),))
            .property(|_| 3u8);
        qckchk(&for_all_prop);
    }

    #[test]
    fn for_all_with_two_arguments_is_testable() {
        let my_prop3 = Property::<(usize, usize)>
            ::for_all((Constant(32usize), Constant(42usize)))
            .property(|_, _| 3u8);
        qckchk(&my_prop3);
    }

    #[test]
    fn when_property_is_testable() {
        let predicate_prop = Property::<(usize,)>
            ::when(|s| s > 5)
            .then(|_| 3u8);
        qckchk(&predicate_prop);
    }

    #[test]
    fn cast_fn_is_testable() {
        fn my_fn() -> bool { true }
        qckchk(my_fn as fn() -> bool);

        fn my_fn2(_:usize) -> bool { true }
        qckchk(my_fn2 as fn(usize) -> bool);
    }

    #[test]
    fn cast_fn_is_testable2() {
        fn simple_prop() -> TestResult { TestResult { status: Status::Pass }};
        qckchk(simple_prop as fn() -> TestResult);
    }
}
<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! `x86` and `x86_64` control registers
use core::fmt;

/// `%cr0` contains flags that modify basic processor operation.
pub mod cr0;

/// `%cr4` contains flags that control protected mode execution.
pub mod cr4;

/// A struct bundling together a snapshot of the control registers state.
#[derive(Copy,Clone,Debug)]
pub struct CrState { /// `$cr0` contains flags that control the CPU's operations
                     pub cr0: cr0::Flags
                   , /// `$cr2` contains the page fault linear address
                     pub cr2: usize
                   , /// `$cr3` contains the page table root pointer
                     pub cr3: usize
                   , /// `$cr4` contains flags that control operations in
                     ///  protected mode
                     pub cr4: cr4::Flags
                   }

impl fmt::Display for CrState {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!( f, "CR0: {:#08x} CR2: {:#08x} CR3: {:#08x} CR4: {:#08x}"
                , self.cr0, self.cr2, self.cr3, self.cr4)
    }
}

/// Dump the current contents of the control registers to a `CrState`.
pub fn dump() -> CrState {
    let cr0_: usize; let cr2_: usize;
    let cr3_: usize; let cr4_: usize;
    unsafe {
        asm!(  "mov $0, cr0
                mov $1, cr2
                mov $2, cr3
                mov $3, cr4"
            :   "=r"(cr0_)
              , "=r"(cr2_)
              , "=r"(cr3_)
              , "=r"(cr4_)
            ::: "intel"
              , "volatile");
    }
    CrState { cr0: cr0::Flags::from_bits_truncate(cr0_)
            , cr2: cr2_, cr3: cr3_
            , cr4: cr4::Flags::from_bits_truncate(cr4_)
            }

}

/// Read the current value from `$cr2`.
pub fn cr2_read() -> usize {
    let result: usize;
    unsafe {
        asm!(   "mov $0, cr2"
            :   "=r"(result)
            ::: "intel" );
    }
    result
}

/// Write a value to `$cr2`.
///
/// # Unsafe Because:
/// + Control registers should generally not be modified during normal
///   operation.
pub unsafe fn cr2_write(value: usize) {
    asm!(  "mov cr2, $0"
        :: "r"(value)
        :: "intel");
}

/// Read the current value from `$cr3`.
pub fn cr3_read() -> usize {
    let result: usize;
    unsafe {
        asm!(   "mov $0, cr3"
            :   "=r"(result)
            ::: "intel" );
    }
    result
}

/// Write a value to `$cr3`.
///
/// # Unsafe Because:
/// + Control registers should generally not be modified during normal
///   operation.
pub unsafe fn cr3_write(value: usize) {
    asm!(  "mov cr3, $0"
        :: "r"(value)
        :: "intel");
}
<commit_msg>[x86_all] Gave control regs without flags the same API as others<commit_after>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! `x86` and `x86_64` control registers
use core::fmt;

/// `%cr0` contains flags that modify basic processor operation.
pub mod cr0;

/// `%cr4` contains flags that control protected mode execution.
pub mod cr4;

/// A struct bundling together a snapshot of the control registers state.
#[derive(Copy,Clone,Debug)]
pub struct CrState { /// `$cr0` contains flags that control the CPU's operations
                     pub cr0: cr0::Flags
                   , /// `$cr2` contains the page fault linear address
                     pub cr2: usize
                   , /// `$cr3` contains the page table root pointer
                     pub cr3: usize
                   , /// `$cr4` contains flags that control operations in
                     ///  protected mode
                     pub cr4: cr4::Flags
                   }

impl fmt::Display for CrState {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!( f, "CR0: {:#08x} CR2: {:#08x} CR3: {:#08x} CR4: {:#08x}"
                , self.cr0, self.cr2, self.cr3, self.cr4)
    }
}

/// Dump the current contents of the control registers to a `CrState`.
pub fn dump() -> CrState {
    let cr0_: usize; let cr2_: usize;
    let cr3_: usize; let cr4_: usize;
    unsafe {
        asm!(  "mov $0, cr0
                mov $1, cr2
                mov $2, cr3
                mov $3, cr4"
            :   "=r"(cr0_)
              , "=r"(cr2_)
              , "=r"(cr3_)
              , "=r"(cr4_)
            ::: "intel"
              , "volatile");
    }
    CrState { cr0: cr0::Flags::from_bits_truncate(cr0_)
            , cr2: cr2_, cr3: cr3_
            , cr4: cr4::Flags::from_bits_truncate(cr4_)
            }

}

pub mod cr2 {

    /// Read the current value from `$cr2`.
    pub fn read() -> usize {
        let result: usize;
        unsafe {
            asm!(   "mov $0, cr2"
                :   "=r"(result)
                ::: "intel" );
        }
        result
    }

    /// Write a value to `$cr2`.
    ///
    /// # Unsafe Because:
    /// + Control registers should generally not be modified during normal
    ///   operation.
    pub unsafe fn write(value: usize) {
        asm!(  "mov cr2, $0"
            :: "r"(value)
            :: "intel");
    }
}

pub mod cr3 {
    /// Read the current value from `$cr3`.
    pub fn read() -> usize {
        let result: usize;
        unsafe {
            asm!(   "mov $0, cr3"
                :   "=r"(result)
                ::: "intel" );
        }
        result
    }

    /// Write a value to `$cr3`.
    ///
    /// # Unsafe Because:
    /// + Control registers should generally not be modified during normal
    ///   operation.
    pub unsafe fn write(value: usize) {
        asm!(  "mov cr3, $0"
            :: "r"(value)
            :: "intel");
    }
}
<|endoftext|>


<commit_before>use error::Error;
use client::Client;
use resources::{Charge, Invoice};

#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub enum EventType {
    #[serde(rename = "invoice.created")] InvoiceCreated,
    #[serde(rename = "invoice.updated")] InvoiceUpdated,
    #[serde(rename = "charge.succeeded")] ChargeSucceeded,
}

#[derive(Debug, Deserialize)]
pub struct Event {
    #[serde(rename = "type")] pub event_type: EventType,
    pub data: EventData,
    // ...
}

#[derive(Debug, Deserialize)]
pub struct EventData {
    pub object: EventObject,
    // previous_attributes: ...
}

#[derive(Debug, Deserialize)]
#[serde(tag = "object")]
pub enum EventObject {
    #[serde(rename = "charge")] Charge(Charge),
    #[serde(rename = "invoice")] Invoice(Invoice),
}
<commit_msg>Remove unused modules from event.rs<commit_after>use resources::{Charge, Invoice};

#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub enum EventType {
    #[serde(rename = "invoice.created")] InvoiceCreated,
    #[serde(rename = "invoice.updated")] InvoiceUpdated,
    #[serde(rename = "charge.succeeded")] ChargeSucceeded,
}

#[derive(Debug, Deserialize)]
pub struct Event {
    #[serde(rename = "type")] pub event_type: EventType,
    pub data: EventData,
    // ...
}

#[derive(Debug, Deserialize)]
pub struct EventData {
    pub object: EventObject,
    // previous_attributes: ...
}

#[derive(Debug, Deserialize)]
#[serde(tag = "object")]
pub enum EventObject {
    #[serde(rename = "charge")] Charge(Charge),
    #[serde(rename = "invoice")] Invoice(Invoice),
}
<|endoftext|>


<commit_before>//! Runs completion for testing purposes.

use hir::Semantics;
use itertools::Itertools;
use ra_syntax::{AstNode, NodeOrToken, SyntaxElement};
use stdx::{format_to, trim_indent};
use test_utils::assert_eq_text;

use crate::{
    completion::{completion_item::CompletionKind, CompletionConfig},
    mock_analysis::analysis_and_position,
    CompletionItem,
};

pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
    do_completion_with_options(code, kind, &CompletionConfig::default())
}

pub(crate) fn do_completion_with_options(
    code: &str,
    kind: CompletionKind,
    options: &CompletionConfig,
) -> Vec<CompletionItem> {
    let mut kind_completions: Vec<CompletionItem> = get_all_completion_items(code, options)
        .into_iter()
        .filter(|c| c.completion_kind == kind)
        .collect();
    kind_completions.sort_by(|l, r| l.label().cmp(r.label()));
    kind_completions
}

pub(crate) fn completion_list(code: &str, kind: CompletionKind) -> String {
    completion_list_with_options(code, kind, &CompletionConfig::default())
}

pub(crate) fn completion_list_with_options(
    code: &str,
    kind: CompletionKind,
    options: &CompletionConfig,
) -> String {
    let mut kind_completions: Vec<CompletionItem> = get_all_completion_items(code, options)
        .into_iter()
        .filter(|c| c.completion_kind == kind)
        .collect();
    kind_completions.sort_by_key(|c| c.label().to_owned());
    kind_completions
        .into_iter()
        .map(|it| {
            let mut buf = format!("{} {}", it.kind().unwrap().tag(), it.label());
            if let Some(detail) = it.detail() {
                format_to!(buf, " {}", detail);
            }
            format_to!(buf, "\n");
            buf
        })
        .collect()
}

pub(crate) fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
    check_edit_with_config(what, ra_fixture_before, ra_fixture_after, &CompletionConfig::default())
}

pub(crate) fn check_edit_with_config(
    what: &str,
    ra_fixture_before: &str,
    ra_fixture_after: &str,
    config: &CompletionConfig,
) {
    let ra_fixture_after = trim_indent(ra_fixture_after);
    let (analysis, position) = analysis_and_position(ra_fixture_before);
    let completions: Vec<CompletionItem> =
        analysis.completions(config, position).unwrap().unwrap().into();
    let (completion,) = completions
        .iter()
        .filter(|it| it.lookup() == what)
        .collect_tuple()
        .unwrap_or_else(|| panic!("can't find {:?} completion in {:#?}", what, completions));
    let mut actual = analysis.file_text(position.file_id).unwrap().to_string();
    completion.text_edit().apply(&mut actual);
    assert_eq_text!(&ra_fixture_after, &actual)
}

pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) {
    let (analysis, pos) = analysis_and_position(code);
    analysis
        .with_db(|db| {
            let sema = Semantics::new(db);
            let original_file = sema.parse(pos.file_id);
            let token = original_file.syntax().token_at_offset(pos.offset).left_biased().unwrap();
            assert!(check(NodeOrToken::Token(token)));
        })
        .unwrap();
}

fn get_all_completion_items(code: &str, options: &CompletionConfig) -> Vec<CompletionItem> {
    let (analysis, position) = analysis_and_position(code);
    analysis.completions(options, position).unwrap().unwrap().into()
}
<commit_msg>Unify naming<commit_after>//! Runs completion for testing purposes.

use hir::Semantics;
use itertools::Itertools;
use ra_syntax::{AstNode, NodeOrToken, SyntaxElement};
use stdx::{format_to, trim_indent};
use test_utils::assert_eq_text;

use crate::{
    completion::{completion_item::CompletionKind, CompletionConfig},
    mock_analysis::analysis_and_position,
    CompletionItem,
};

pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
    do_completion_with_config(code, kind, &CompletionConfig::default())
}

pub(crate) fn do_completion_with_config(
    code: &str,
    kind: CompletionKind,
    config: &CompletionConfig,
) -> Vec<CompletionItem> {
    let mut kind_completions: Vec<CompletionItem> = get_all_completion_items(code, config)
        .into_iter()
        .filter(|c| c.completion_kind == kind)
        .collect();
    kind_completions.sort_by(|l, r| l.label().cmp(r.label()));
    kind_completions
}

pub(crate) fn completion_list(code: &str, kind: CompletionKind) -> String {
    completion_list_with_config(code, kind, &CompletionConfig::default())
}

pub(crate) fn completion_list_with_config(
    code: &str,
    kind: CompletionKind,
    config: &CompletionConfig,
) -> String {
    let mut kind_completions: Vec<CompletionItem> = get_all_completion_items(code, config)
        .into_iter()
        .filter(|c| c.completion_kind == kind)
        .collect();
    kind_completions.sort_by_key(|c| c.label().to_owned());
    kind_completions
        .into_iter()
        .map(|it| {
            let mut buf = format!("{} {}", it.kind().unwrap().tag(), it.label());
            if let Some(detail) = it.detail() {
                format_to!(buf, " {}", detail);
            }
            format_to!(buf, "\n");
            buf
        })
        .collect()
}

pub(crate) fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
    check_edit_with_config(what, ra_fixture_before, ra_fixture_after, &CompletionConfig::default())
}

pub(crate) fn check_edit_with_config(
    what: &str,
    ra_fixture_before: &str,
    ra_fixture_after: &str,
    config: &CompletionConfig,
) {
    let ra_fixture_after = trim_indent(ra_fixture_after);
    let (analysis, position) = analysis_and_position(ra_fixture_before);
    let completions: Vec<CompletionItem> =
        analysis.completions(config, position).unwrap().unwrap().into();
    let (completion,) = completions
        .iter()
        .filter(|it| it.lookup() == what)
        .collect_tuple()
        .unwrap_or_else(|| panic!("can't find {:?} completion in {:#?}", what, completions));
    let mut actual = analysis.file_text(position.file_id).unwrap().to_string();
    completion.text_edit().apply(&mut actual);
    assert_eq_text!(&ra_fixture_after, &actual)
}

pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) {
    let (analysis, pos) = analysis_and_position(code);
    analysis
        .with_db(|db| {
            let sema = Semantics::new(db);
            let original_file = sema.parse(pos.file_id);
            let token = original_file.syntax().token_at_offset(pos.offset).left_biased().unwrap();
            assert!(check(NodeOrToken::Token(token)));
        })
        .unwrap();
}

fn get_all_completion_items(code: &str, options: &CompletionConfig) -> Vec<CompletionItem> {
    let (analysis, position) = analysis_and_position(code);
    analysis.completions(options, position).unwrap().unwrap().into()
}
<|endoftext|>


<commit_before>use ansi_term::Colour::{Green, Blue, Red};
use std::fmt;
use std::collections::HashSet;

#[derive(Clone, Debug, Deserialize)]
pub struct Line {
    pub id: String,
    pub name: String,
    #[serde(rename="modeName")]
    pub mode_name: String,
    #[serde(rename="routeSections")]
    pub route_sections: Vec<RouteSection>,
    pub stops: Option<Vec<Stop>>,
    pub inbound_sequence: Option<Sequence>,
    pub outbound_sequence: Option<Sequence>,
}

/// Default color string, use null so the importer can choose
const DEFAULT_COLOR : &'static str = "";

impl Line {
    /// Tube Color
    fn tube_color(&self) -> &str {
        match &self.name[..] {
            "Bakerloo" => "894E24",
            "Central" => "DC241F",
            "Circle" => "FFCE00",
            "District" => "007229",
            "Hammersmith & City" => "D799AF",
            "Jubilee" => "6A7278",
            "Metropolitan" => "751056",
            "Northern" => "000",
            "Piccadilly" => "0019A8",
            "Victoria" => "00A0E2",
            "Waterloo & City" => "76D0BD",
            _ => {
                println!("Missing tube color for {}", self.name);
                DEFAULT_COLOR
            },
        }
    }

    /// Tram Color
    fn tram_color(&self) -> &str {
        match &self.name[..] {
            "Tram 1" | "Tram 2" => "C6D834",
            "Tram 3" => "79C23F",
            "Tram 4" => "336B14",
            _ => {
                println!("Missing tram color for {}", self.name);
                DEFAULT_COLOR
            },
        }
    }

    /// National Rail Color
    fn national_rail_color(&self) -> &str {
        match &self.name[..] {
            "South West Trains" => "F11815",
            "Southeastern" => "0071BF",
            "Southern" => "00A74B",
            "Great Northern" => "00A6E2",
            "Arriva Trains Wales" => "00B9B4",
            "c2c" => "F0188C",
            "Chiltern Railways" => "B389C1",
            "Cross Country" => "A03467",
            "East Midlands Trains" => "E16C16",
            "First Great Western" => "2D2B94",
            "First Hull Trains" => "1B903F",
            "First TransPennine Express" => "F265A0",
            "Gatwick Express" => "231F20",
            "Grand Central" => "3F3F40",
            "Greater Anglia" => "8B8FA5",
            "Heathrow Connect" => "F6858D",
            "Heathrow Express" => "55C4BF",
            "Island Line" => "F8B174",
            "London Midland" => "8BC831",
            "Merseyrail" => "FEC95F",
            "Northern Rail" => "0569A8",
            "ScotRail" => "96A3A9",
            "Thameslink" => "DA4290",
            "Virgin Trains" => "A8652C",
            "Virgin Trains East Coast" => "9C0101",
            _ => {
                println!("Missing national rail color for {}", self.name);
                DEFAULT_COLOR
            },
        }
    }

    /// River Bus Color
    fn river_bus_color(&self) -> &str {
        match &self.name[..] {
            "RB1" => "2D3039",
            "RB2" => "0072BC",
            "RB4" => "61C29D",
            "RB5" => "BA6830",
            "RB6" => "DF64B0",
            "Woolwich Ferry" => "F7931D",
            _ => {
                println!("Missing rail color for {}", self.name);
                DEFAULT_COLOR
            },
        }
    }

    fn cable_car_color(&self) -> &str {
        match &self.name[..] {
            "Emirates Air Line" => "E51937",
            _ => {
                println!("Missing rail color for {}", self.name);
                DEFAULT_COLOR
            },
        }
    }

    /// The Line's Color based on the TFL colors on tfl.gov.uk
    pub fn color(&self) -> &str {
        match &self.mode_name[..] {
            "dlr" => "00AFAD",
            "overground" => "E86A10",
            "tflrail" => "0019A8",
            "tube" => self.tube_color(),
            "tram" => self.tram_color(),
            "national-rail" => self.national_rail_color(),
            "river-bus" | "river-ferry" => self.river_bus_color(),
            "cable-car" => self.cable_car_color(),
            _ => DEFAULT_COLOR,
        }
    }
}

impl fmt::Display for Line {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let id: &str = &self.id;
        write!(f, "{} {}", Green.bold().paint("Line"), Blue.bold().paint(id))
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct Stop {
    #[serde(rename="naptanId")]
    pub naptan_id: String,
    #[serde(rename="commonName")]
    pub common_name: String,
    pub lat: f64,
    pub lon: f64,
    pub children: Vec<Stop>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct RouteSection {
    pub name: String,
    pub direction: String,
    pub originator: String,
    pub destination: String,
    pub timetable: Option<TimeTableResponse>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Interval {
    #[serde(rename="stopId")]
    pub stop_id: String,
    #[serde(rename="timeToArrival")]
    pub time_to_arrival: f64,
}

#[derive(Clone, Debug, Deserialize)]
pub struct StationInterval {
    pub id: i64,
    pub intervals: Vec<Interval>
}

#[derive(Clone, Debug, Deserialize)]
pub struct KnownJourney {
    #[serde(rename="intervalId")]
    pub interval_id: i64,
    pub hour: String,
    pub minute: String,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Schedule {
    pub name: String,
    #[serde(rename="knownJourneys")]
    pub known_journeys: Vec<KnownJourney>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct TimeTable {
    #[serde(rename="stationIntervals")]
    pub station_intervals: Vec<StationInterval>,
    pub schedules: Vec<Schedule>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct RoutesTimeTables {
    pub routes: Vec<TimeTable>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Station {
    pub id: String,
    pub name: String,
    pub lat: f64,
    pub lon: f64,
}

#[derive(Clone, Debug, Deserialize)]
pub struct TimeTableResponse {
    pub stations: Vec<Station>,
    pub stops: Vec<Station>,
    pub timetable: RoutesTimeTables,
    #[serde(rename="statusErrorMessage")]
    pub status_error_message: Option<String>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Sequence {
    #[serde(rename="lineStrings")]
    pub line_strings: Vec<String>,
}

impl TimeTableResponse {
    pub fn first_timetable(&self) -> Option<&TimeTable> {
        if let Some(ref message) = self.status_error_message {
            println!("{} {}", Red.bold().paint("Error:"), message);
            None
        } else {
            Some(&self.timetable.routes[0])
        }
    }

    pub fn schedule_names(&self) -> HashSet<String> {
        if let Some(record) = *&self.first_timetable() {
            return record.schedules.iter()
                                   .map(|x| x.name.clone())
                                   .collect();
        }

        HashSet::new()
    }
}
<commit_msg>Add line ID to the status error message<commit_after>use ansi_term::Colour::{Green, Blue, Red};
use std::fmt;
use std::collections::HashSet;

#[derive(Clone, Debug, Deserialize)]
pub struct Line {
    pub id: String,
    pub name: String,
    #[serde(rename="modeName")]
    pub mode_name: String,
    #[serde(rename="routeSections")]
    pub route_sections: Vec<RouteSection>,
    pub stops: Option<Vec<Stop>>,
    pub inbound_sequence: Option<Sequence>,
    pub outbound_sequence: Option<Sequence>,
}

/// Default color string, use null so the importer can choose
const DEFAULT_COLOR : &'static str = "";

impl Line {
    /// Tube Color
    fn tube_color(&self) -> &str {
        match &self.name[..] {
            "Bakerloo" => "894E24",
            "Central" => "DC241F",
            "Circle" => "FFCE00",
            "District" => "007229",
            "Hammersmith & City" => "D799AF",
            "Jubilee" => "6A7278",
            "Metropolitan" => "751056",
            "Northern" => "000",
            "Piccadilly" => "0019A8",
            "Victoria" => "00A0E2",
            "Waterloo & City" => "76D0BD",
            _ => {
                println!("Missing tube color for {}", self.name);
                DEFAULT_COLOR
            },
        }
    }

    /// Tram Color
    fn tram_color(&self) -> &str {
        match &self.name[..] {
            "Tram 1" | "Tram 2" => "C6D834",
            "Tram 3" => "79C23F",
            "Tram 4" => "336B14",
            _ => {
                println!("Missing tram color for {}", self.name);
                DEFAULT_COLOR
            },
        }
    }

    /// National Rail Color
    fn national_rail_color(&self) -> &str {
        match &self.name[..] {
            "South West Trains" => "F11815",
            "Southeastern" => "0071BF",
            "Southern" => "00A74B",
            "Great Northern" => "00A6E2",
            "Arriva Trains Wales" => "00B9B4",
            "c2c" => "F0188C",
            "Chiltern Railways" => "B389C1",
            "Cross Country" => "A03467",
            "East Midlands Trains" => "E16C16",
            "First Great Western" => "2D2B94",
            "First Hull Trains" => "1B903F",
            "First TransPennine Express" => "F265A0",
            "Gatwick Express" => "231F20",
            "Grand Central" => "3F3F40",
            "Greater Anglia" => "8B8FA5",
            "Heathrow Connect" => "F6858D",
            "Heathrow Express" => "55C4BF",
            "Island Line" => "F8B174",
            "London Midland" => "8BC831",
            "Merseyrail" => "FEC95F",
            "Northern Rail" => "0569A8",
            "ScotRail" => "96A3A9",
            "Thameslink" => "DA4290",
            "Virgin Trains" => "A8652C",
            "Virgin Trains East Coast" => "9C0101",
            _ => {
                println!("Missing national rail color for {}", self.name);
                DEFAULT_COLOR
            },
        }
    }

    /// River Bus Color
    fn river_bus_color(&self) -> &str {
        match &self.name[..] {
            "RB1" => "2D3039",
            "RB2" => "0072BC",
            "RB4" => "61C29D",
            "RB5" => "BA6830",
            "RB6" => "DF64B0",
            "Woolwich Ferry" => "F7931D",
            _ => {
                println!("Missing rail color for {}", self.name);
                DEFAULT_COLOR
            },
        }
    }

    fn cable_car_color(&self) -> &str {
        match &self.name[..] {
            "Emirates Air Line" => "E51937",
            _ => {
                println!("Missing rail color for {}", self.name);
                DEFAULT_COLOR
            },
        }
    }

    /// The Line's Color based on the TFL colors on tfl.gov.uk
    pub fn color(&self) -> &str {
        match &self.mode_name[..] {
            "dlr" => "00AFAD",
            "overground" => "E86A10",
            "tflrail" => "0019A8",
            "tube" => self.tube_color(),
            "tram" => self.tram_color(),
            "national-rail" => self.national_rail_color(),
            "river-bus" | "river-ferry" => self.river_bus_color(),
            "cable-car" => self.cable_car_color(),
            _ => DEFAULT_COLOR,
        }
    }
}

impl fmt::Display for Line {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let id: &str = &self.id;
        write!(f, "{} {}", Green.bold().paint("Line"), Blue.bold().paint(id))
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct Stop {
    #[serde(rename="naptanId")]
    pub naptan_id: String,
    #[serde(rename="commonName")]
    pub common_name: String,
    pub lat: f64,
    pub lon: f64,
    pub children: Vec<Stop>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct RouteSection {
    pub name: String,
    pub direction: String,
    pub originator: String,
    pub destination: String,
    pub timetable: Option<TimeTableResponse>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Interval {
    #[serde(rename="stopId")]
    pub stop_id: String,
    #[serde(rename="timeToArrival")]
    pub time_to_arrival: f64,
}

#[derive(Clone, Debug, Deserialize)]
pub struct StationInterval {
    pub id: i64,
    pub intervals: Vec<Interval>
}

#[derive(Clone, Debug, Deserialize)]
pub struct KnownJourney {
    #[serde(rename="intervalId")]
    pub interval_id: i64,
    pub hour: String,
    pub minute: String,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Schedule {
    pub name: String,
    #[serde(rename="knownJourneys")]
    pub known_journeys: Vec<KnownJourney>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct TimeTable {
    #[serde(rename="stationIntervals")]
    pub station_intervals: Vec<StationInterval>,
    pub schedules: Vec<Schedule>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct RoutesTimeTables {
    pub routes: Vec<TimeTable>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Station {
    pub id: String,
    pub name: String,
    pub lat: f64,
    pub lon: f64,
}

#[derive(Clone, Debug, Deserialize)]
pub struct TimeTableResponse {
    pub stations: Vec<Station>,
    pub stops: Vec<Station>,
    pub timetable: RoutesTimeTables,
    #[serde(rename="statusErrorMessage")]
    pub status_error_message: Option<String>,
    #[serde(rename="lineId")]
    line_id: String,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Sequence {
    #[serde(rename="lineStrings")]
    pub line_strings: Vec<String>,
}

impl TimeTableResponse {
    pub fn first_timetable(&self) -> Option<&TimeTable> {
        if let Some(ref message) = self.status_error_message {
            println!("{} (line {}): {}", Red.bold().paint("Error"), Blue.bold().paint(self.line_id.clone()), message);
            None
        } else {
            Some(&self.timetable.routes[0])
        }
    }

    pub fn schedule_names(&self) -> HashSet<String> {
        if let Some(record) = *&self.first_timetable() {
            return record.schedules.iter()
                                   .map(|x| x.name.clone())
                                   .collect();
        }

        HashSet::new()
    }
}
<|endoftext|>