<commit_before>use byteorder::{LittleEndian, WriteBytesExt};
use std::io::{self, Write};

use color;

const BITMAPFILEHEADER_SIZE: u32 = 14;
const BITMAPINFOHEADER_SIZE: u32 = 40;
const BITMAPV4HEADER_SIZE: u32 = 108;

/// The representation of a BMP encoder.
pub struct BMPEncoder<'a, W: 'a> {
    writer: &'a mut W,
}

impl<'a, W: Write + 'a> BMPEncoder<'a, W> {
    /// Create a new encoder that writes its output to ```w```.
    pub fn new(w: &'a mut W) -> Self {
        BMPEncoder { writer: w }
    }

    /// Encodes the image ```image```
    /// that has dimensions ```width``` and ```height```
    /// and ```ColorType``` ```c```.
    pub fn encode(
        &mut self,
        image: &[u8],
        width: u32,
        height: u32,
        c: color::ColorType,
    ) -> io::Result<()> {
        let bmp_header_size = BITMAPFILEHEADER_SIZE;

        let (dib_header_size, written_pixel_size, palette_color_count) = get_pixel_info(c)?;
        let row_pad_size = (4 - (width * written_pixel_size) % 4) % 4; // each row must be padded to a multiple of 4 bytes

        let image_size = width * height * written_pixel_size + (height * row_pad_size);
        let palette_size = palette_color_count * 4; // all palette colors are BGRA
        let file_size = bmp_header_size + dib_header_size + palette_size + image_size;

        // write BMP header
        self.writer.write_u8(b'B')?;
        self.writer.write_u8(b'M')?;
        self.writer.write_u32::<LittleEndian>(file_size)?; // file size
        self.writer.write_u16::<LittleEndian>(0)?; // reserved 1
        self.writer.write_u16::<LittleEndian>(0)?; // reserved 2
        self.writer
            .write_u32::<LittleEndian>(bmp_header_size + dib_header_size + palette_size)?; // image data offset

        // write DIB header
        self.writer.write_u32::<LittleEndian>(dib_header_size)?;
        self.writer.write_i32::<LittleEndian>(width as i32)?;
        self.writer.write_i32::<LittleEndian>(height as i32)?;
        self.writer.write_u16::<LittleEndian>(1)?; // color planes
        self.writer
            .write_u16::<LittleEndian>((written_pixel_size * 8) as u16)?; // bits per pixel
        if dib_header_size >= BITMAPV4HEADER_SIZE {
            // Assume BGRA32
            self.writer.write_u32::<LittleEndian>(3)?; // compression method - bitfields
        } else {
            self.writer.write_u32::<LittleEndian>(0)?; // compression method - no compression
        }
        self.writer.write_u32::<LittleEndian>(image_size)?;
        self.writer.write_i32::<LittleEndian>(0)?; // horizontal ppm
        self.writer.write_i32::<LittleEndian>(0)?; // vertical ppm
        self.writer.write_u32::<LittleEndian>(palette_color_count)?;
        self.writer.write_u32::<LittleEndian>(0)?; // all colors are important
        if dib_header_size >= BITMAPV4HEADER_SIZE {
            // Assume BGRA32
            self.writer.write_u32::<LittleEndian>(0xff << 16)?; // red mask
            self.writer.write_u32::<LittleEndian>(0xff << 8)?; // green mask
            self.writer.write_u32::<LittleEndian>(0xff << 0)?; // blue mask
            self.writer.write_u32::<LittleEndian>(0xff << 24)?; // alpha mask
            self.writer.write_u32::<LittleEndian>(0x73524742)?; // colorspace - sRGB

            // endpoints (3x3) and gamma (3)
            for _ in 0..12 {
                self.writer.write_u32::<LittleEndian>(0)?;
            }
        }

        // write image data
        match c {
            color::ColorType::RGB(8) => self.encode_rgb(image, width, height, row_pad_size, 3)?,
            color::ColorType::RGBA(8) => self.encode_rgba(image, width, height, row_pad_size, 4)?,
            color::ColorType::Gray(8) => self.encode_gray(image, width, height, row_pad_size, 1)?,
            color::ColorType::GrayA(8) => {
                self.encode_gray(image, width, height, row_pad_size, 2)?
            }
            _ => {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidInput,
                    &get_unsupported_error_message(c)[..],
                ))
            }
        }

        Ok(())
    }

    fn encode_rgb(
        &mut self,
        image: &[u8],
        width: u32,
        height: u32,
        row_pad_size: u32,
        bytes_per_pixel: u32,
    ) -> io::Result<()> {
        let x_stride = bytes_per_pixel;
        let y_stride = width * x_stride;
        for row in 0..height {
            // from the bottom up
            let row_start = (height - row - 1) * y_stride;
            for col in 0..width {
                let pixel_start = (row_start + (col * x_stride)) as usize;
                let r = image[pixel_start];
                let g = image[pixel_start + 1];
                let b = image[pixel_start + 2];
                // written as BGR
                self.writer.write_u8(b)?;
                self.writer.write_u8(g)?;
                self.writer.write_u8(r)?;
                // alpha is never written as it's not widely supported
            }

            self.write_row_pad(row_pad_size)?;
        }

        Ok(())
    }

    fn encode_rgba(
        &mut self,
        image: &[u8],
        width: u32,
        height: u32,
        row_pad_size: u32,
        bytes_per_pixel: u32,
    ) -> io::Result<()> {
        let x_stride = bytes_per_pixel;
        let y_stride = width * x_stride;
        for row in 0..height {
            // from the bottom up
            let row_start = (height - row - 1) * y_stride;
            for col in 0..width {
                let pixel_start = (row_start + (col * x_stride)) as usize;
                let r = image[pixel_start];
                let g = image[pixel_start + 1];
                let b = image[pixel_start + 2];
                let a = image[pixel_start + 3];
                // written as BGRA
                self.writer.write_u8(b)?;
                self.writer.write_u8(g)?;
                self.writer.write_u8(r)?;
                self.writer.write_u8(a)?;
            }

            self.write_row_pad(row_pad_size)?;
        }

        Ok(())
    }

    fn encode_gray(
        &mut self,
        image: &[u8],
        width: u32,
        height: u32,
        row_pad_size: u32,
        bytes_per_pixel: u32,
    ) -> io::Result<()> {
        // write grayscale palette
        for val in 0..256 {
            // each color is written as BGRA, where A is always 0 and since only grayscale is being written, B = G = R = index
            let val = val as u8;
            self.writer.write_u8(val)?;
            self.writer.write_u8(val)?;
            self.writer.write_u8(val)?;
            self.writer.write_u8(0)?;
        }

        // write image data
        let x_stride = bytes_per_pixel;
        let y_stride = width * x_stride;
        for row in 0..height {
            // from the bottom up
            let row_start = (height - row - 1) * y_stride;
            for col in 0..width {
                let pixel_start = (row_start + (col * x_stride)) as usize;
                // color value is equal to the palette index
                self.writer.write_u8(image[pixel_start])?;
                // alpha is never written as it's not widely supported
            }

            self.write_row_pad(row_pad_size)?;
        }

        Ok(())
    }

    fn write_row_pad(&mut self, row_pad_size: u32) -> io::Result<()> {
        for _ in 0..row_pad_size {
            self.writer.write_u8(0)?;
        }

        Ok(())
    }
}

fn get_unsupported_error_message(c: color::ColorType) -> String {
    format!(
        "Unsupported color type {:?}.  Supported types: RGB(8), RGBA(8), Gray(8), GrayA(8).",
        c
    )
}

/// Returns a tuple representing: (dib header size, written pixel size, palette color count).
fn get_pixel_info(c: color::ColorType) -> io::Result<(u32, u32, u32)> {
    let sizes = match c {
        color::ColorType::RGB(8) => (BITMAPINFOHEADER_SIZE, 3, 0),
        color::ColorType::RGBA(8) => (BITMAPV4HEADER_SIZE, 4, 0),
        color::ColorType::Gray(8) => (BITMAPINFOHEADER_SIZE, 1, 256),
        color::ColorType::GrayA(8) => (BITMAPINFOHEADER_SIZE, 1, 256),
        _ => {
            return Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                &get_unsupported_error_message(c)[..],
            ))
        }
    };

    Ok(sizes)
}

#[cfg(test)]
mod tests {
    use super::super::BMPDecoder;
    use super::BMPEncoder;
    use color::ColorType;
    use image::ImageDecoder;
    use std::io::Cursor;

    fn round_trip_image(image: &[u8], width: u32, height: u32, c: ColorType) -> Vec<u8> {
        let mut encoded_data = Vec::new();
        {
            let mut encoder = BMPEncoder::new(&mut encoded_data);
            encoder
                .encode(&image, width, height, c)
                .expect("could not encode image");
        }

        let decoder = BMPDecoder::new(Cursor::new(&encoded_data)).expect("failed to decode");
        decoder.read_image().expect("failed to decode")
    }

    #[test]
    fn round_trip_single_pixel_rgb() {
        let image = [255u8, 0, 0]; // single red pixel
        let decoded = round_trip_image(&image, 1, 1, ColorType::RGB(8));
        assert_eq!(3, decoded.len());
        assert_eq!(255, decoded[0]);
        assert_eq!(0, decoded[1]);
        assert_eq!(0, decoded[2]);
    }

    #[test]
    fn round_trip_single_pixel_rgba() {
        let image = [1, 2, 3, 4];
        let decoded = round_trip_image(&image, 1, 1, ColorType::RGBA(8));
        assert_eq!(&decoded[..], &image[..]);
    }

    #[test]
    fn round_trip_3px_rgb() {
        let image = [0u8; 3 * 3 * 3]; // 3x3 pixels, 3 bytes per pixel
        let _decoded = round_trip_image(&image, 3, 3, ColorType::RGB(8));
    }

    #[test]
    fn round_trip_gray() {
        let image = [0u8, 1, 2]; // 3 pixels
        let decoded = round_trip_image(&image, 3, 1, ColorType::Gray(8));
        // should be read back as 3 RGB pixels
        assert_eq!(9, decoded.len());
        assert_eq!(0, decoded[0]);
        assert_eq!(0, decoded[1]);
        assert_eq!(0, decoded[2]);
        assert_eq!(1, decoded[3]);
        assert_eq!(1, decoded[4]);
        assert_eq!(1, decoded[5]);
        assert_eq!(2, decoded[6]);
        assert_eq!(2, decoded[7]);
        assert_eq!(2, decoded[8]);
    }

    #[test]
    fn round_trip_graya() {
        let image = [0u8, 0, 1, 0, 2, 0]; // 3 pixels, each with an alpha channel
        let decoded = round_trip_image(&image, 1, 3, ColorType::GrayA(8));
        // should be read back as 3 RGB pixels
        assert_eq!(9, decoded.len());
        assert_eq!(0, decoded[0]);
        assert_eq!(0, decoded[1]);
        assert_eq!(0, decoded[2]);
        assert_eq!(1, decoded[3]);
        assert_eq!(1, decoded[4]);
        assert_eq!(1, decoded[5]);
        assert_eq!(2, decoded[6]);
        assert_eq!(2, decoded[7]);
        assert_eq!(2, decoded[8]);
    }
}
<commit_msg>Fixes #1090. Checks for overflowing dimensions<commit_after>use byteorder::{LittleEndian, WriteBytesExt};
use std::io::{self, Write};

use color;

const BITMAPFILEHEADER_SIZE: u32 = 14;
const BITMAPINFOHEADER_SIZE: u32 = 40;
const BITMAPV4HEADER_SIZE: u32 = 108;

/// The representation of a BMP encoder.
pub struct BMPEncoder<'a, W: 'a> {
    writer: &'a mut W,
}

impl<'a, W: Write + 'a> BMPEncoder<'a, W> {
    /// Create a new encoder that writes its output to ```w```.
    pub fn new(w: &'a mut W) -> Self {
        BMPEncoder { writer: w }
    }

    /// Encodes the image ```image```
    /// that has dimensions ```width``` and ```height```
    /// and ```ColorType``` ```c```.
    pub fn encode(
        &mut self,
        image: &[u8],
        width: u32,
        height: u32,
        c: color::ColorType,
    ) -> io::Result<()> {
        let bmp_header_size = BITMAPFILEHEADER_SIZE;

        let (dib_header_size, written_pixel_size, palette_color_count) = get_pixel_info(c)?;
        let row_pad_size = (4 - (width * written_pixel_size) % 4) % 4; // each row must be padded to a multiple of 4 bytes

        let image_size = width
            .checked_mul(height)
            .ok_or(io::Error::new(
                io::ErrorKind::InvalidInput,
                "Overflowing dimensions",
            ))?
            .checked_mul(written_pixel_size)
            .ok_or(io::Error::new(
                io::ErrorKind::InvalidInput,
                "Overflowing dimensions",
            ))?
            .checked_add(height * row_pad_size)
            .ok_or(io::Error::new(
                io::ErrorKind::InvalidInput,
                "Overflowing dimensions",
            ))?;
        let palette_size = palette_color_count * 4; // all palette colors are BGRA
        let file_size = bmp_header_size + dib_header_size + palette_size + image_size;

        // write BMP header
        self.writer.write_u8(b'B')?;
        self.writer.write_u8(b'M')?;
        self.writer.write_u32::<LittleEndian>(file_size)?; // file size
        self.writer.write_u16::<LittleEndian>(0)?; // reserved 1
        self.writer.write_u16::<LittleEndian>(0)?; // reserved 2
        self.writer
            .write_u32::<LittleEndian>(bmp_header_size + dib_header_size + palette_size)?; // image data offset

        // write DIB header
        self.writer.write_u32::<LittleEndian>(dib_header_size)?;
        self.writer.write_i32::<LittleEndian>(width as i32)?;
        self.writer.write_i32::<LittleEndian>(height as i32)?;
        self.writer.write_u16::<LittleEndian>(1)?; // color planes
        self.writer
            .write_u16::<LittleEndian>((written_pixel_size * 8) as u16)?; // bits per pixel
        if dib_header_size >= BITMAPV4HEADER_SIZE {
            // Assume BGRA32
            self.writer.write_u32::<LittleEndian>(3)?; // compression method - bitfields
        } else {
            self.writer.write_u32::<LittleEndian>(0)?; // compression method - no compression
        }
        self.writer.write_u32::<LittleEndian>(image_size)?;
        self.writer.write_i32::<LittleEndian>(0)?; // horizontal ppm
        self.writer.write_i32::<LittleEndian>(0)?; // vertical ppm
        self.writer.write_u32::<LittleEndian>(palette_color_count)?;
        self.writer.write_u32::<LittleEndian>(0)?; // all colors are important
        if dib_header_size >= BITMAPV4HEADER_SIZE {
            // Assume BGRA32
            self.writer.write_u32::<LittleEndian>(0xff << 16)?; // red mask
            self.writer.write_u32::<LittleEndian>(0xff << 8)?; // green mask
            self.writer.write_u32::<LittleEndian>(0xff << 0)?; // blue mask
            self.writer.write_u32::<LittleEndian>(0xff << 24)?; // alpha mask
            self.writer.write_u32::<LittleEndian>(0x73524742)?; // colorspace - sRGB

            // endpoints (3x3) and gamma (3)
            for _ in 0..12 {
                self.writer.write_u32::<LittleEndian>(0)?;
            }
        }

        // write image data
        match c {
            color::ColorType::RGB(8) => self.encode_rgb(image, width, height, row_pad_size, 3)?,
            color::ColorType::RGBA(8) => self.encode_rgba(image, width, height, row_pad_size, 4)?,
            color::ColorType::Gray(8) => self.encode_gray(image, width, height, row_pad_size, 1)?,
            color::ColorType::GrayA(8) => {
                self.encode_gray(image, width, height, row_pad_size, 2)?
            }
            _ => {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidInput,
                    &get_unsupported_error_message(c)[..],
                ))
            }
        }

        Ok(())
    }

    fn encode_rgb(
        &mut self,
        image: &[u8],
        width: u32,
        height: u32,
        row_pad_size: u32,
        bytes_per_pixel: u32,
    ) -> io::Result<()> {
        let x_stride = bytes_per_pixel;
        let y_stride = width * x_stride;
        for row in 0..height {
            // from the bottom up
            let row_start = (height - row - 1) * y_stride;
            for col in 0..width {
                let pixel_start = (row_start + (col * x_stride)) as usize;
                let r = image[pixel_start];
                let g = image[pixel_start + 1];
                let b = image[pixel_start + 2];
                // written as BGR
                self.writer.write_u8(b)?;
                self.writer.write_u8(g)?;
                self.writer.write_u8(r)?;
                // alpha is never written as it's not widely supported
            }

            self.write_row_pad(row_pad_size)?;
        }

        Ok(())
    }

    fn encode_rgba(
        &mut self,
        image: &[u8],
        width: u32,
        height: u32,
        row_pad_size: u32,
        bytes_per_pixel: u32,
    ) -> io::Result<()> {
        let x_stride = bytes_per_pixel;
        let y_stride = width * x_stride;
        for row in 0..height {
            // from the bottom up
            let row_start = (height - row - 1) * y_stride;
            for col in 0..width {
                let pixel_start = (row_start + (col * x_stride)) as usize;
                let r = image[pixel_start];
                let g = image[pixel_start + 1];
                let b = image[pixel_start + 2];
                let a = image[pixel_start + 3];
                // written as BGRA
                self.writer.write_u8(b)?;
                self.writer.write_u8(g)?;
                self.writer.write_u8(r)?;
                self.writer.write_u8(a)?;
            }

            self.write_row_pad(row_pad_size)?;
        }

        Ok(())
    }

    fn encode_gray(
        &mut self,
        image: &[u8],
        width: u32,
        height: u32,
        row_pad_size: u32,
        bytes_per_pixel: u32,
    ) -> io::Result<()> {
        // write grayscale palette
        for val in 0..256 {
            // each color is written as BGRA, where A is always 0 and since only grayscale is being written, B = G = R = index
            let val = val as u8;
            self.writer.write_u8(val)?;
            self.writer.write_u8(val)?;
            self.writer.write_u8(val)?;
            self.writer.write_u8(0)?;
        }

        // write image data
        let x_stride = bytes_per_pixel;
        let y_stride = width * x_stride;
        for row in 0..height {
            // from the bottom up
            let row_start = (height - row - 1) * y_stride;
            for col in 0..width {
                let pixel_start = (row_start + (col * x_stride)) as usize;
                // color value is equal to the palette index
                self.writer.write_u8(image[pixel_start])?;
                // alpha is never written as it's not widely supported
            }

            self.write_row_pad(row_pad_size)?;
        }

        Ok(())
    }

    fn write_row_pad(&mut self, row_pad_size: u32) -> io::Result<()> {
        for _ in 0..row_pad_size {
            self.writer.write_u8(0)?;
        }

        Ok(())
    }
}

fn get_unsupported_error_message(c: color::ColorType) -> String {
    format!(
        "Unsupported color type {:?}.  Supported types: RGB(8), RGBA(8), Gray(8), GrayA(8).",
        c
    )
}

/// Returns a tuple representing: (dib header size, written pixel size, palette color count).
fn get_pixel_info(c: color::ColorType) -> io::Result<(u32, u32, u32)> {
    let sizes = match c {
        color::ColorType::RGB(8) => (BITMAPINFOHEADER_SIZE, 3, 0),
        color::ColorType::RGBA(8) => (BITMAPV4HEADER_SIZE, 4, 0),
        color::ColorType::Gray(8) => (BITMAPINFOHEADER_SIZE, 1, 256),
        color::ColorType::GrayA(8) => (BITMAPINFOHEADER_SIZE, 1, 256),
        _ => {
            return Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                &get_unsupported_error_message(c)[..],
            ))
        }
    };

    Ok(sizes)
}

#[cfg(test)]
mod tests {
    use super::super::BMPDecoder;
    use super::BMPEncoder;
    use color::ColorType;
    use image::ImageDecoder;
    use std::io::Cursor;

    fn round_trip_image(image: &[u8], width: u32, height: u32, c: ColorType) -> Vec<u8> {
        let mut encoded_data = Vec::new();
        {
            let mut encoder = BMPEncoder::new(&mut encoded_data);
            encoder
                .encode(&image, width, height, c)
                .expect("could not encode image");
        }

        let decoder = BMPDecoder::new(Cursor::new(&encoded_data)).expect("failed to decode");
        decoder.read_image().expect("failed to decode")
    }

    #[test]
    fn round_trip_single_pixel_rgb() {
        let image = [255u8, 0, 0]; // single red pixel
        let decoded = round_trip_image(&image, 1, 1, ColorType::RGB(8));
        assert_eq!(3, decoded.len());
        assert_eq!(255, decoded[0]);
        assert_eq!(0, decoded[1]);
        assert_eq!(0, decoded[2]);
    }

    #[test]
    fn huge_files_return_error() {
        let mut encoded_data = Vec::new();
        let image = vec![0u8; 3 * 40_000 * 40_000]; // 40_000x40_000 pixels, 3 bytes per pixel, allocated on the heap
        let mut encoder = BMPEncoder::new(&mut encoded_data);
        let result = encoder.encode(&image, 40_000, 40_000, ColorType::RGB(8));
        assert!(result.is_err());
    }

    #[test]
    fn round_trip_single_pixel_rgba() {
        let image = [1, 2, 3, 4];
        let decoded = round_trip_image(&image, 1, 1, ColorType::RGBA(8));
        assert_eq!(&decoded[..], &image[..]);
    }

    #[test]
    fn round_trip_3px_rgb() {
        let image = [0u8; 3 * 3 * 3]; // 3x3 pixels, 3 bytes per pixel
        let _decoded = round_trip_image(&image, 3, 3, ColorType::RGB(8));
    }

    #[test]
    fn round_trip_gray() {
        let image = [0u8, 1, 2]; // 3 pixels
        let decoded = round_trip_image(&image, 3, 1, ColorType::Gray(8));
        // should be read back as 3 RGB pixels
        assert_eq!(9, decoded.len());
        assert_eq!(0, decoded[0]);
        assert_eq!(0, decoded[1]);
        assert_eq!(0, decoded[2]);
        assert_eq!(1, decoded[3]);
        assert_eq!(1, decoded[4]);
        assert_eq!(1, decoded[5]);
        assert_eq!(2, decoded[6]);
        assert_eq!(2, decoded[7]);
        assert_eq!(2, decoded[8]);
    }

    #[test]
    fn round_trip_graya() {
        let image = [0u8, 0, 1, 0, 2, 0]; // 3 pixels, each with an alpha channel
        let decoded = round_trip_image(&image, 1, 3, ColorType::GrayA(8));
        // should be read back as 3 RGB pixels
        assert_eq!(9, decoded.len());
        assert_eq!(0, decoded[0]);
        assert_eq!(0, decoded[1]);
        assert_eq!(0, decoded[2]);
        assert_eq!(1, decoded[3]);
        assert_eq!(1, decoded[4]);
        assert_eq!(1, decoded[5]);
        assert_eq!(2, decoded[6]);
        assert_eq!(2, decoded[7]);
        assert_eq!(2, decoded[8]);
    }
}
<|endoftext|>


<commit_before>extern crate backtrace;
extern crate libc;

use std::fmt;
use std::ops::Deref;
use std::io;
use std::string::FromUtf8Error;

use self::backtrace::Backtrace;
use self::backtrace::BacktraceFrame;

#[derive(Debug)]
pub struct RError<E> {
    e: E,
    bt: Option<Backtrace>,
}

pub fn is_enoent(e: &io::Error) -> bool {
    return e.kind() == io::ErrorKind::NotFound;
}

pub fn try_enoent(e: io::Error) -> Result<bool> {
    if is_enoent(&e) {
        return Ok(true);
    } else {
        return Err(RError::from(e));
    }
}

pub fn propagate<T>(e: io::Error) -> Result<T> {
    return Err(RError::propagate(e));
}

pub fn errno(e: &RError<io::Error>) -> libc::c_int {
    if RError::expected(e) {
        return e.e.raw_os_error().unwrap();
    } else {
        return libc::EIO;
    }
}

impl<E> RError<E> {
    pub fn propagate(e: E) -> RError<E> {
        RError {
            e: e,
            bt: Default::default(),
        }
    }

    pub fn from(e: E) -> RError<E> {
        let mut bt = Backtrace::new();
        let mut i: usize = 0;
        let mut chop: usize = 0;
        for f in bt.frames() {
            if let Some(p) = f.symbols()[0].filename() {
                if p.file_name().unwrap() == "error.rs" {
                    chop = i;
                    break;
                }
            }
            i += 1;
        }

        if chop != 0 {
            let mut frames: Vec<BacktraceFrame> = bt.into();
            let _: Vec<_> = frames.drain(0..i).collect();
            bt = Backtrace::from(frames);
        }

        RError { e: e, bt: Some(bt) }
    }

    fn expected(&self) -> bool {
        return self.bt.is_none();
    }
}

impl RError<io::Error> {
    pub fn errno(&self) -> i32 {
        return self.e.raw_os_error().unwrap();
    }
}

impl fmt::Display for RError<io::Error> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.bt {
            Some(ref bt) => write!(f, "{} {:?}", self.e, bt),
            None => write!(f, "{}", self.e),
        }

    }
}

impl<E> Deref for RError<E> {
    type Target = E;

    fn deref(&self) -> &E {
        &self.e
    }
}

// XXX not really a clone
impl Clone for RError<io::Error> {
    fn clone(&self) -> Self {
        RError {
            e: io::Error::from_raw_os_error(self.e.raw_os_error().unwrap()),
            bt: Default::default(),
        }
    }
}

impl From<io::Error> for RError<io::Error> {
    fn from(e: io::Error) -> RError<io::Error> {
        RError::from(e)
    }
}

impl From<FromUtf8Error> for RError<FromUtf8Error> {
    fn from(e: FromUtf8Error) -> RError<FromUtf8Error> {
        RError::from(e)
    }
}

pub type Result<T> = ::std::result::Result<T, RError<io::Error>>;
<commit_msg>Avoid out-of-bounds access in RError<commit_after>extern crate backtrace;
extern crate libc;

use std::fmt;
use std::ops::Deref;
use std::io;
use std::string::FromUtf8Error;

use self::backtrace::Backtrace;
use self::backtrace::BacktraceFrame;

#[derive(Debug)]
pub struct RError<E> {
    e: E,
    bt: Option<Backtrace>,
}

pub fn is_enoent(e: &io::Error) -> bool {
    return e.kind() == io::ErrorKind::NotFound;
}

pub fn try_enoent(e: io::Error) -> Result<bool> {
    if is_enoent(&e) {
        return Ok(true);
    } else {
        return Err(RError::from(e));
    }
}

pub fn propagate<T>(e: io::Error) -> Result<T> {
    return Err(RError::propagate(e));
}

pub fn errno(e: &RError<io::Error>) -> libc::c_int {
    if RError::expected(e) {
        return e.e.raw_os_error().unwrap();
    } else {
        return libc::EIO;
    }
}

impl<E> RError<E> {
    pub fn propagate(e: E) -> RError<E> {
        RError {
            e: e,
            bt: Default::default(),
        }
    }

    pub fn from(e: E) -> RError<E> {
        let mut bt = Backtrace::new();
        let mut i: usize = 0;
        let mut chop: usize = 0;
        for f in bt.frames() {
            if let Some(sym) = f.symbols().first() {
                if let Some(p) = sym.filename() {
                    if p.file_name().unwrap() == "error.rs" {
                        chop = i;
                        break;
                    }
                }
            }
            i += 1;
        }

        if chop != 0 {
            let mut frames: Vec<BacktraceFrame> = bt.into();
            let _: Vec<_> = frames.drain(0..i).collect();
            bt = Backtrace::from(frames);
        }

        RError { e: e, bt: Some(bt) }
    }

    fn expected(&self) -> bool {
        return self.bt.is_none();
    }
}

impl RError<io::Error> {
    pub fn errno(&self) -> i32 {
        return self.e.raw_os_error().unwrap();
    }
}

impl fmt::Display for RError<io::Error> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.bt {
            Some(ref bt) => write!(f, "{} {:?}", self.e, bt),
            None => write!(f, "{}", self.e),
        }

    }
}

impl<E> Deref for RError<E> {
    type Target = E;

    fn deref(&self) -> &E {
        &self.e
    }
}

// XXX not really a clone
impl Clone for RError<io::Error> {
    fn clone(&self) -> Self {
        RError {
            e: io::Error::from_raw_os_error(self.e.raw_os_error().unwrap()),
            bt: Default::default(),
        }
    }
}

impl From<io::Error> for RError<io::Error> {
    fn from(e: io::Error) -> RError<io::Error> {
        RError::from(e)
    }
}

impl From<FromUtf8Error> for RError<FromUtf8Error> {
    fn from(e: FromUtf8Error) -> RError<FromUtf8Error> {
        RError::from(e)
    }
}

pub type Result<T> = ::std::result::Result<T, RError<io::Error>>;
<|endoftext|>


<commit_before>//! The Pattern Memory layer

use std::cell::Cell;
use std::rc::Rc;

use Pooling;
use topology::Topology;

struct Synapse {
    source: usize,
    destination: usize,
    permanence: Cell<f64>
}

struct Column {
    inputs: Vec<Rc<Synapse>>,
    boost: f64,
    active_duty_cycle: f64,
    overlap_duty_cycle: f64,
}

impl Column {
    fn new() -> Column {
        Column {
            inputs: Vec::new(),
            boost: 1.0,
            active_duty_cycle: 0.0,
            overlap_duty_cycle: 0.0
        }
    }
}

/// Parameters of a PatternMemory layer.
pub struct PatternMemoryConfig {
    /// The permanence threasold to count a synapse as connected
    ///
    /// Between `0.0` and `1.0`, an example value would be `0.2`.
    pub connected_perm: f64,
    /// The amplitude of increase when reinforcing a synapse
    ///
    /// An example value would be `0.003`
    pub permanence_inc: f64,
    /// The amplitude of decrease when weakening a synapse
    ///
    /// An example value would be `0.0005`
    pub permanence_dec: f64,
    /// The weight of a new value in the exponential sliding average of activity
    ///
    /// An example value would be `0.01` to make it count for 1/100 of the total activity
    pub sliding_average_factor: f64,
    /// The minimum overlap of a segment with the input pattern for it to count as activated
    ///
    /// An example value would be around the same order of magnitude of the expected activity of the input
    pub min_overlap: usize,
    /// The target number of active cells in a neighborhood
    ///
    /// An example value would be around 2% of the number of outputs
    pub desired_local_activity: usize,
    /// The initial deviation of permanence values around connected_perm
    ///
    /// A typical value would be `0.1`
    pub initial_dev: f64,
    /// The number of potential synapses in a segment
    ///
    /// An example value would be around a 3 or 4 times `min_overlap`
    pub proximal_segment_size: usize,
}

/// A layer recognising spatial patterns.
///
/// Formerly known as Spatial Pooling, this layer is state-less, and can be used
/// for spatial sampling of patterns in the input.
pub struct PatternMemory<T: Topology> {
    _input_size: usize,
    columns: Vec<Column>,
    inputs: Vec<Vec<Rc<Synapse>>>,
    topology: T,
    config: PatternMemoryConfig,
    inhibition_radius: f64
}

/*
 * Preparation
 */

impl<T: Topology> PatternMemory<T> {
    /// Create a new Pattern Memory
    ///
    /// Using given number of inputs, of outputs, the given topology and given parameters.
    ///
    /// The topology must be configured for the same number of indexes as the outputs count.
    pub fn new(input_size: usize, output_size: usize, topology: T, config: PatternMemoryConfig) -> PatternMemory<T> {
        use rand::distributions::{Normal, Sample};
        let mut normal = Normal::new(config.connected_perm, config.initial_dev);
        let mut rng = ::rand::weak_rng();

        let mut columns: Vec<_> = (0..output_size).map(|_| Column::new()).collect();
        let mut inputs = vec![Vec::new(); input_size];

        for c in 0..output_size {
            for i in ::rand::sample(&mut rng, 0..input_size, config.proximal_segment_size) {
                let rc = Rc::new(Synapse { source: i, destination: c, permanence: Cell::new(normal.sample(&mut rng)) });
                columns[c].inputs.push(rc.clone());
                inputs[i].push(rc.clone());
            }
        }

        PatternMemory {
            columns: columns,
            _input_size: input_size,
            inputs: inputs,
            topology: topology,
            config: config,
            inhibition_radius: 1.0
        }
    }
}

/*
 * Cortical Learning impl
 */

impl<T: Topology> Pooling for PatternMemory<T> {
    fn pool(&mut self, inputs: &[usize]) -> Vec<usize> {
        // phase 1: Overlaps
        let overlaps = self.cortical_spatial_phase_1(inputs);
        // phase 2: Inhibition
        self.cortical_spatial_phase_2(&overlaps)
    }

    fn pool_train(&mut self, inputs: &[usize]) -> Vec<usize> {
        // phase 1: Overlaps
        let overlaps = self.cortical_spatial_phase_1(inputs);
        // phase 2: Inhibition
        let actives = self.cortical_spatial_phase_2(&overlaps);
        // phase 3: Learning
        self.cortical_spatial_phase_3(inputs, &overlaps, &actives);
        actives
    }

    fn anomaly(&self) -> f64 { 0.0 }
}

/*
 * Spatial Pooling
 */

impl<T: Topology> PatternMemory<T> {

    fn cortical_spatial_phase_1(&self, inputs: &[usize]) -> Vec<f64> {
        let mut overlaps = vec![0f64; self.columns.len()];
        for &i in inputs {
            for s in &self.inputs[i] {
                if s.permanence.get() >= self.config.connected_perm {
                    overlaps[s.destination] += 1.;
                }
            }
        }
        let min_overlap = self.config.min_overlap as f64;
        for (o, b) in overlaps.iter_mut().zip(self.columns.iter().map(|c| c.boost)) {
            if *o >= min_overlap {
                *o *= b;
            } else {
                *o = 0.;
            }
        }
        overlaps
    }

    fn cortical_spatial_phase_2(&self, overlaps: &[f64]) -> Vec<usize> {
        overlaps.iter().enumerate().filter_map( |(i, &o)| {
            let rank = self.topology.neighbors(i, self.inhibition_radius)
                                        .map(|j| (overlaps[j] > o) as usize).fold(0, ::std::ops::Add::add);
            if rank < self.config.desired_local_activity && o > 0.0 {
                Some(i)
            } else {
                None
            }
        }).collect()
    }

    fn cortical_spatial_phase_3(&mut self, inputs: &[usize], overlaps: &[f64], actives: &[usize]) {
        for &i in actives.iter() {
            let col = &self.columns[i];
            for s in &col.inputs {
                let mut p = s.permanence.get();
                if inputs.contains(&s.source) {
                    p += self.config.permanence_inc;
                    if p > 1.0 { p = 1.0 }
                } else {
                    p -= self.config.permanence_dec;
                    if p < 0.0 { p = 0.0 }
                }
                s.permanence.set(p);
            }
        }

        let min_duty_cycles = (0..self.columns.len()).map(|i| {
            self.topology.neighbors(i, self.inhibition_radius)
                         .map(|j| self.columns[j].active_duty_cycle)
                         .fold(0.0, |a, b| if a > b { a } else { b })
             * 0.01
        }).collect::<Vec<_>>();

        let alpha = self.config.sliding_average_factor;
        for (((i, c), min_duty_cycle), overlap) in self.columns.iter_mut().enumerate().zip(min_duty_cycles.into_iter()).zip(overlaps.iter()) {
            c.active_duty_cycle *= (1.0 - alpha) * c.active_duty_cycle;
            if actives.contains(&i) { c.active_duty_cycle += alpha }
            c.boost = if c.active_duty_cycle >= min_duty_cycle { 1.0 } else { min_duty_cycle / c.active_duty_cycle };

            c.overlap_duty_cycle *= (1.0 - alpha) * c.overlap_duty_cycle;
            if *overlap >= self.config.connected_perm { c.overlap_duty_cycle += alpha }
            if c.overlap_duty_cycle < min_duty_cycle {
                let factor = 1.0 + 0.1 * self.config.connected_perm;
                for s in &mut c.inputs {
                    let mut p = s.permanence.get();
                    p *= factor;
                    if p > 1.0 { p = 1.0 }
                    s.permanence.set(p);
                }
            }
        }

        self.inhibition_radius = self.columns.iter().enumerate().map(|(i, c)| {
            self.topology.radius(i, c.inputs.iter().map(|s| s.source))
        }).fold(0., ::std::ops::Add::add) / (self.columns.len() as f64);

    }
}

#[cfg(all(test, feature = "nightly"))]
mod benches {
    use test::Bencher;
    use super::{PatternMemoryConfig, PatternMemory};
    use topology::OneDimension;
    use Pooling;

    static INPUT_SIZE: usize = 1024;
    static COL_COUNT: usize = 2048;

    #[bench]
    fn bench_pool(b: &mut Bencher) {
        let mut rng = ::rand::weak_rng();
        let input = (0..8).map(|_|
            ::rand::sample(&mut rng, 0..INPUT_SIZE, INPUT_SIZE/50)
        ).collect::<Vec<_>>();

        let mut pooler = PatternMemory::new(
            COL_COUNT,
            OneDimension::new(COL_COUNT),
            PatternMemoryConfig {
                input_size: INPUT_SIZE,
                connected_perm: 0.2,
                permanence_inc: 0.003,
                permanence_dec: 0.0005,
                sliding_average_factor: 0.01,
                min_overlap: 1,
                desired_local_activity: 40,
                initial_dev: 0.1,
                proximal_segment_size: 16,
            }
        );

        let mut i = 0;

        b.bench_n(3, |b| b.iter(|| { pooler.pool(&input[i]); i = (i+1) % 8; }));
    }

    #[bench]
    fn bench_train(b: &mut Bencher) {
        let mut rng = ::rand::weak_rng();
        let input = (0..8).map(|_|
            ::rand::sample(&mut rng, 0..INPUT_SIZE, INPUT_SIZE/50)
        ).collect::<Vec<_>>();

        let mut pooler = PatternMemory::new(
            COL_COUNT,
            OneDimension::new(COL_COUNT),
            PatternMemoryConfig {
                input_size: INPUT_SIZE,
                connected_perm: 0.2,
                permanence_inc: 0.003,
                permanence_dec: 0.0005,
                sliding_average_factor: 0.01,
                min_overlap: 1,
                desired_local_activity: 40,
                initial_dev: 0.1,
                proximal_segment_size: 16,
            }
        );

        let mut i = 0;

        b.bench_n(3, |b| b.iter(|| { pooler.pool_train(&input[i]); i = (i+1) % 8; }));
    }
}<commit_msg>Fix benches.<commit_after>//! The Pattern Memory layer

use std::cell::Cell;
use std::rc::Rc;

use Pooling;
use topology::Topology;

struct Synapse {
    source: usize,
    destination: usize,
    permanence: Cell<f64>
}

struct Column {
    inputs: Vec<Rc<Synapse>>,
    boost: f64,
    active_duty_cycle: f64,
    overlap_duty_cycle: f64,
}

impl Column {
    fn new() -> Column {
        Column {
            inputs: Vec::new(),
            boost: 1.0,
            active_duty_cycle: 0.0,
            overlap_duty_cycle: 0.0
        }
    }
}

/// Parameters of a PatternMemory layer.
pub struct PatternMemoryConfig {
    /// The permanence threasold to count a synapse as connected
    ///
    /// Between `0.0` and `1.0`, an example value would be `0.2`.
    pub connected_perm: f64,
    /// The amplitude of increase when reinforcing a synapse
    ///
    /// An example value would be `0.003`
    pub permanence_inc: f64,
    /// The amplitude of decrease when weakening a synapse
    ///
    /// An example value would be `0.0005`
    pub permanence_dec: f64,
    /// The weight of a new value in the exponential sliding average of activity
    ///
    /// An example value would be `0.01` to make it count for 1/100 of the total activity
    pub sliding_average_factor: f64,
    /// The minimum overlap of a segment with the input pattern for it to count as activated
    ///
    /// An example value would be around the same order of magnitude of the expected activity of the input
    pub min_overlap: usize,
    /// The target number of active cells in a neighborhood
    ///
    /// An example value would be around 2% of the number of outputs
    pub desired_local_activity: usize,
    /// The initial deviation of permanence values around connected_perm
    ///
    /// A typical value would be `0.1`
    pub initial_dev: f64,
    /// The number of potential synapses in a segment
    ///
    /// An example value would be around a 3 or 4 times `min_overlap`
    pub proximal_segment_size: usize,
}

/// A layer recognising spatial patterns.
///
/// Formerly known as Spatial Pooling, this layer is state-less, and can be used
/// for spatial sampling of patterns in the input.
pub struct PatternMemory<T: Topology> {
    _input_size: usize,
    columns: Vec<Column>,
    inputs: Vec<Vec<Rc<Synapse>>>,
    topology: T,
    config: PatternMemoryConfig,
    inhibition_radius: f64
}

/*
 * Preparation
 */

impl<T: Topology> PatternMemory<T> {
    /// Create a new Pattern Memory
    ///
    /// Using given number of inputs, of outputs, the given topology and given parameters.
    ///
    /// The topology must be configured for the same number of indexes as the outputs count.
    pub fn new(input_size: usize, output_size: usize, topology: T, config: PatternMemoryConfig) -> PatternMemory<T> {
        use rand::distributions::{Normal, Sample};
        let mut normal = Normal::new(config.connected_perm, config.initial_dev);
        let mut rng = ::rand::weak_rng();

        let mut columns: Vec<_> = (0..output_size).map(|_| Column::new()).collect();
        let mut inputs = vec![Vec::new(); input_size];

        for c in 0..output_size {
            for i in ::rand::sample(&mut rng, 0..input_size, config.proximal_segment_size) {
                let rc = Rc::new(Synapse { source: i, destination: c, permanence: Cell::new(normal.sample(&mut rng)) });
                columns[c].inputs.push(rc.clone());
                inputs[i].push(rc.clone());
            }
        }

        PatternMemory {
            columns: columns,
            _input_size: input_size,
            inputs: inputs,
            topology: topology,
            config: config,
            inhibition_radius: 1.0
        }
    }
}

/*
 * Cortical Learning impl
 */

impl<T: Topology> Pooling for PatternMemory<T> {
    fn pool(&mut self, inputs: &[usize]) -> Vec<usize> {
        // phase 1: Overlaps
        let overlaps = self.cortical_spatial_phase_1(inputs);
        // phase 2: Inhibition
        self.cortical_spatial_phase_2(&overlaps)
    }

    fn pool_train(&mut self, inputs: &[usize]) -> Vec<usize> {
        // phase 1: Overlaps
        let overlaps = self.cortical_spatial_phase_1(inputs);
        // phase 2: Inhibition
        let actives = self.cortical_spatial_phase_2(&overlaps);
        // phase 3: Learning
        self.cortical_spatial_phase_3(inputs, &overlaps, &actives);
        actives
    }

    fn anomaly(&self) -> f64 { 0.0 }
}

/*
 * Spatial Pooling
 */

impl<T: Topology> PatternMemory<T> {

    fn cortical_spatial_phase_1(&self, inputs: &[usize]) -> Vec<f64> {
        let mut overlaps = vec![0f64; self.columns.len()];
        for &i in inputs {
            for s in &self.inputs[i] {
                if s.permanence.get() >= self.config.connected_perm {
                    overlaps[s.destination] += 1.;
                }
            }
        }
        let min_overlap = self.config.min_overlap as f64;
        for (o, b) in overlaps.iter_mut().zip(self.columns.iter().map(|c| c.boost)) {
            if *o >= min_overlap {
                *o *= b;
            } else {
                *o = 0.;
            }
        }
        overlaps
    }

    fn cortical_spatial_phase_2(&self, overlaps: &[f64]) -> Vec<usize> {
        overlaps.iter().enumerate().filter_map( |(i, &o)| {
            let rank = self.topology.neighbors(i, self.inhibition_radius)
                                        .map(|j| (overlaps[j] > o) as usize).fold(0, ::std::ops::Add::add);
            if rank < self.config.desired_local_activity && o > 0.0 {
                Some(i)
            } else {
                None
            }
        }).collect()
    }

    fn cortical_spatial_phase_3(&mut self, inputs: &[usize], overlaps: &[f64], actives: &[usize]) {
        for &i in actives.iter() {
            let col = &self.columns[i];
            for s in &col.inputs {
                let mut p = s.permanence.get();
                if inputs.contains(&s.source) {
                    p += self.config.permanence_inc;
                    if p > 1.0 { p = 1.0 }
                } else {
                    p -= self.config.permanence_dec;
                    if p < 0.0 { p = 0.0 }
                }
                s.permanence.set(p);
            }
        }

        let min_duty_cycles = (0..self.columns.len()).map(|i| {
            self.topology.neighbors(i, self.inhibition_radius)
                         .map(|j| self.columns[j].active_duty_cycle)
                         .fold(0.0, |a, b| if a > b { a } else { b })
             * 0.01
        }).collect::<Vec<_>>();

        let alpha = self.config.sliding_average_factor;
        for (((i, c), min_duty_cycle), overlap) in self.columns.iter_mut().enumerate().zip(min_duty_cycles.into_iter()).zip(overlaps.iter()) {
            c.active_duty_cycle *= (1.0 - alpha) * c.active_duty_cycle;
            if actives.contains(&i) { c.active_duty_cycle += alpha }
            c.boost = if c.active_duty_cycle >= min_duty_cycle { 1.0 } else { min_duty_cycle / c.active_duty_cycle };

            c.overlap_duty_cycle *= (1.0 - alpha) * c.overlap_duty_cycle;
            if *overlap >= self.config.connected_perm { c.overlap_duty_cycle += alpha }
            if c.overlap_duty_cycle < min_duty_cycle {
                let factor = 1.0 + 0.1 * self.config.connected_perm;
                for s in &mut c.inputs {
                    let mut p = s.permanence.get();
                    p *= factor;
                    if p > 1.0 { p = 1.0 }
                    s.permanence.set(p);
                }
            }
        }

        self.inhibition_radius = self.columns.iter().enumerate().map(|(i, c)| {
            self.topology.radius(i, c.inputs.iter().map(|s| s.source))
        }).fold(0., ::std::ops::Add::add) / (self.columns.len() as f64);

    }
}

#[cfg(all(test, feature = "nightly"))]
mod benches {
    use test::Bencher;
    use super::{PatternMemoryConfig, PatternMemory};
    use topology::OneDimension;
    use Pooling;

    static INPUT_SIZE: usize = 1024;
    static COL_COUNT: usize = 2048;

    #[bench]
    fn bench_pool(b: &mut Bencher) {
        let mut rng = ::rand::weak_rng();
        let input = (0..8).map(|_|
            ::rand::sample(&mut rng, 0..INPUT_SIZE, INPUT_SIZE/50)
        ).collect::<Vec<_>>();

        let mut pooler = PatternMemory::new(
            INPUT_SIZE,
            COL_COUNT,
            OneDimension::new(COL_COUNT),
            PatternMemoryConfig {
                connected_perm: 0.2,
                permanence_inc: 0.003,
                permanence_dec: 0.0005,
                sliding_average_factor: 0.01,
                min_overlap: 1,
                desired_local_activity: 40,
                initial_dev: 0.1,
                proximal_segment_size: 16,
            }
        );

        let mut i = 0;

        b.bench_n(3, |b| b.iter(|| { pooler.pool(&input[i]); i = (i+1) % 8; }));
    }

    #[bench]
    fn bench_train(b: &mut Bencher) {
        let mut rng = ::rand::weak_rng();
        let input = (0..8).map(|_|
            ::rand::sample(&mut rng, 0..INPUT_SIZE, INPUT_SIZE/50)
        ).collect::<Vec<_>>();

        let mut pooler = PatternMemory::new(
            INPUT_SIZE,
            COL_COUNT,
            OneDimension::new(COL_COUNT),
            PatternMemoryConfig {
                connected_perm: 0.2,
                permanence_inc: 0.003,
                permanence_dec: 0.0005,
                sliding_average_factor: 0.01,
                min_overlap: 1,
                desired_local_activity: 40,
                initial_dev: 0.1,
                proximal_segment_size: 16,
            }
        );

        let mut i = 0;

        b.bench_n(3, |b| b.iter(|| { pooler.pool_train(&input[i]); i = (i+1) % 8; }));
    }
}<|endoftext|>


<commit_before>use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sync::mpsc::channel;
use crate::sync::{Arc, Condvar, Mutex};
use crate::thread;
use crate::time::Duration;

#[test]
fn smoke() {
    let c = Condvar::new();
    c.notify_one();
    c.notify_all();
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn notify_one() {
    let m = Arc::new(Mutex::new(()));
    let m2 = m.clone();
    let c = Arc::new(Condvar::new());
    let c2 = c.clone();

    let g = m.lock().unwrap();
    let _t = thread::spawn(move || {
        let _g = m2.lock().unwrap();
        c2.notify_one();
    });
    let g = c.wait(g).unwrap();
    drop(g);
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn notify_all() {
    const N: usize = 10;

    let data = Arc::new((Mutex::new(0), Condvar::new()));
    let (tx, rx) = channel();
    for _ in 0..N {
        let data = data.clone();
        let tx = tx.clone();
        thread::spawn(move || {
            let &(ref lock, ref cond) = &*data;
            let mut cnt = lock.lock().unwrap();
            *cnt += 1;
            if *cnt == N {
                tx.send(()).unwrap();
            }
            while *cnt != 0 {
                cnt = cond.wait(cnt).unwrap();
            }
            tx.send(()).unwrap();
        });
    }
    drop(tx);

    let &(ref lock, ref cond) = &*data;
    rx.recv().unwrap();
    let mut cnt = lock.lock().unwrap();
    *cnt = 0;
    cond.notify_all();
    drop(cnt);

    for _ in 0..N {
        rx.recv().unwrap();
    }
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_while() {
    let pair = Arc::new((Mutex::new(false), Condvar::new()));
    let pair2 = pair.clone();

    // Inside of our lock, spawn a new thread, and then wait for it to start.
    thread::spawn(move || {
        let &(ref lock, ref cvar) = &*pair2;
        let mut started = lock.lock().unwrap();
        *started = true;
        // We notify the condvar that the value has changed.
        cvar.notify_one();
    });

    // Wait for the thread to start up.
    let &(ref lock, ref cvar) = &*pair;
    let guard = cvar.wait_while(lock.lock().unwrap(), |started| !*started);
    assert!(*guard.unwrap());
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_timeout_wait() {
    let m = Arc::new(Mutex::new(()));
    let c = Arc::new(Condvar::new());

    loop {
        let g = m.lock().unwrap();
        let (_g, no_timeout) = c.wait_timeout(g, Duration::from_millis(1)).unwrap();
        // spurious wakeups mean this isn't necessarily true
        // so execute test again, if not timeout
        if !no_timeout.timed_out() {
            continue;
        }

        break;
    }
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_timeout_while_wait() {
    let m = Arc::new(Mutex::new(()));
    let c = Arc::new(Condvar::new());

    let g = m.lock().unwrap();
    let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(1), |_| true).unwrap();
    // no spurious wakeups. ensure it timed-out
    assert!(wait.timed_out());
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_timeout_while_instant_satisfy() {
    let m = Arc::new(Mutex::new(()));
    let c = Arc::new(Condvar::new());

    let g = m.lock().unwrap();
    let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(0), |_| false).unwrap();
    // ensure it didn't time-out even if we were not given any time.
    assert!(!wait.timed_out());
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_timeout_while_wake() {
    let pair = Arc::new((Mutex::new(false), Condvar::new()));
    let pair_copy = pair.clone();

    let &(ref m, ref c) = &*pair;
    let g = m.lock().unwrap();
    let _t = thread::spawn(move || {
        let &(ref lock, ref cvar) = &*pair_copy;
        let mut started = lock.lock().unwrap();
        thread::sleep(Duration::from_millis(1));
        *started = true;
        cvar.notify_one();
    });
    let (g2, wait) = c
        .wait_timeout_while(g, Duration::from_millis(u64::MAX), |&mut notified| !notified)
        .unwrap();
    // ensure it didn't time-out even if we were not given any time.
    assert!(!wait.timed_out());
    assert!(*g2);
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_timeout_wake() {
    let m = Arc::new(Mutex::new(()));
    let c = Arc::new(Condvar::new());

    loop {
        let g = m.lock().unwrap();

        let c2 = c.clone();
        let m2 = m.clone();

        let notified = Arc::new(AtomicBool::new(false));
        let notified_copy = notified.clone();

        let t = thread::spawn(move || {
            let _g = m2.lock().unwrap();
            thread::sleep(Duration::from_millis(1));
            notified_copy.store(true, Ordering::SeqCst);
            c2.notify_one();
        });
        let (g, timeout_res) = c.wait_timeout(g, Duration::from_millis(u64::MAX)).unwrap();
        assert!(!timeout_res.timed_out());
        // spurious wakeups mean this isn't necessarily true
        // so execute test again, if not notified
        if !notified.load(Ordering::SeqCst) {
            t.join().unwrap();
            continue;
        }
        drop(g);

        t.join().unwrap();

        break;
    }
}

#[test]
#[should_panic]
#[cfg_attr(target_os = "emscripten", ignore)]
fn two_mutexes() {
    let m = Arc::new(Mutex::new(()));
    let m2 = m.clone();
    let c = Arc::new(Condvar::new());
    let c2 = c.clone();

    let mut g = m.lock().unwrap();
    let _t = thread::spawn(move || {
        let _g = m2.lock().unwrap();
        c2.notify_one();
    });
    g = c.wait(g).unwrap();
    drop(g);

    let m = Mutex::new(());
    let _ = c.wait(m.lock().unwrap()).unwrap();
}
<commit_msg>Disable condvar::two_mutexes test on non-unix platforms.<commit_after>use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sync::mpsc::channel;
use crate::sync::{Arc, Condvar, Mutex};
use crate::thread;
use crate::time::Duration;

#[test]
fn smoke() {
    let c = Condvar::new();
    c.notify_one();
    c.notify_all();
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn notify_one() {
    let m = Arc::new(Mutex::new(()));
    let m2 = m.clone();
    let c = Arc::new(Condvar::new());
    let c2 = c.clone();

    let g = m.lock().unwrap();
    let _t = thread::spawn(move || {
        let _g = m2.lock().unwrap();
        c2.notify_one();
    });
    let g = c.wait(g).unwrap();
    drop(g);
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn notify_all() {
    const N: usize = 10;

    let data = Arc::new((Mutex::new(0), Condvar::new()));
    let (tx, rx) = channel();
    for _ in 0..N {
        let data = data.clone();
        let tx = tx.clone();
        thread::spawn(move || {
            let &(ref lock, ref cond) = &*data;
            let mut cnt = lock.lock().unwrap();
            *cnt += 1;
            if *cnt == N {
                tx.send(()).unwrap();
            }
            while *cnt != 0 {
                cnt = cond.wait(cnt).unwrap();
            }
            tx.send(()).unwrap();
        });
    }
    drop(tx);

    let &(ref lock, ref cond) = &*data;
    rx.recv().unwrap();
    let mut cnt = lock.lock().unwrap();
    *cnt = 0;
    cond.notify_all();
    drop(cnt);

    for _ in 0..N {
        rx.recv().unwrap();
    }
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_while() {
    let pair = Arc::new((Mutex::new(false), Condvar::new()));
    let pair2 = pair.clone();

    // Inside of our lock, spawn a new thread, and then wait for it to start.
    thread::spawn(move || {
        let &(ref lock, ref cvar) = &*pair2;
        let mut started = lock.lock().unwrap();
        *started = true;
        // We notify the condvar that the value has changed.
        cvar.notify_one();
    });

    // Wait for the thread to start up.
    let &(ref lock, ref cvar) = &*pair;
    let guard = cvar.wait_while(lock.lock().unwrap(), |started| !*started);
    assert!(*guard.unwrap());
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_timeout_wait() {
    let m = Arc::new(Mutex::new(()));
    let c = Arc::new(Condvar::new());

    loop {
        let g = m.lock().unwrap();
        let (_g, no_timeout) = c.wait_timeout(g, Duration::from_millis(1)).unwrap();
        // spurious wakeups mean this isn't necessarily true
        // so execute test again, if not timeout
        if !no_timeout.timed_out() {
            continue;
        }

        break;
    }
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_timeout_while_wait() {
    let m = Arc::new(Mutex::new(()));
    let c = Arc::new(Condvar::new());

    let g = m.lock().unwrap();
    let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(1), |_| true).unwrap();
    // no spurious wakeups. ensure it timed-out
    assert!(wait.timed_out());
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_timeout_while_instant_satisfy() {
    let m = Arc::new(Mutex::new(()));
    let c = Arc::new(Condvar::new());

    let g = m.lock().unwrap();
    let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(0), |_| false).unwrap();
    // ensure it didn't time-out even if we were not given any time.
    assert!(!wait.timed_out());
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_timeout_while_wake() {
    let pair = Arc::new((Mutex::new(false), Condvar::new()));
    let pair_copy = pair.clone();

    let &(ref m, ref c) = &*pair;
    let g = m.lock().unwrap();
    let _t = thread::spawn(move || {
        let &(ref lock, ref cvar) = &*pair_copy;
        let mut started = lock.lock().unwrap();
        thread::sleep(Duration::from_millis(1));
        *started = true;
        cvar.notify_one();
    });
    let (g2, wait) = c
        .wait_timeout_while(g, Duration::from_millis(u64::MAX), |&mut notified| !notified)
        .unwrap();
    // ensure it didn't time-out even if we were not given any time.
    assert!(!wait.timed_out());
    assert!(*g2);
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn wait_timeout_wake() {
    let m = Arc::new(Mutex::new(()));
    let c = Arc::new(Condvar::new());

    loop {
        let g = m.lock().unwrap();

        let c2 = c.clone();
        let m2 = m.clone();

        let notified = Arc::new(AtomicBool::new(false));
        let notified_copy = notified.clone();

        let t = thread::spawn(move || {
            let _g = m2.lock().unwrap();
            thread::sleep(Duration::from_millis(1));
            notified_copy.store(true, Ordering::SeqCst);
            c2.notify_one();
        });
        let (g, timeout_res) = c.wait_timeout(g, Duration::from_millis(u64::MAX)).unwrap();
        assert!(!timeout_res.timed_out());
        // spurious wakeups mean this isn't necessarily true
        // so execute test again, if not notified
        if !notified.load(Ordering::SeqCst) {
            t.join().unwrap();
            continue;
        }
        drop(g);

        t.join().unwrap();

        break;
    }
}

#[test]
#[should_panic]
#[cfg_attr(not(unix), ignore)]
fn two_mutexes() {
    let m = Arc::new(Mutex::new(()));
    let m2 = m.clone();
    let c = Arc::new(Condvar::new());
    let c2 = c.clone();

    let mut g = m.lock().unwrap();
    let _t = thread::spawn(move || {
        let _g = m2.lock().unwrap();
        c2.notify_one();
    });
    g = c.wait(g).unwrap();
    drop(g);

    let m = Mutex::new(());
    let _ = c.wait(m.lock().unwrap()).unwrap();
}
<|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
use std::collections::HashMap;

use pest_meta::ast::*;

pub fn restore_on_err(rule: Rule, rules_to_exprs: &HashMap<String, Expr>) -> Rule {
    match rule {
        Rule { name, ty, expr } => {
            let expr = expr.map_bottom_up(|expr| {
                wrap_branching_exprs(expr, rules_to_exprs)
            });

            Rule {
                name,
                ty,
                expr
            }
        }
    }
}

fn child_modifies_state(expr: &Expr, rules_to_exprs: &HashMap<String, Expr>) -> bool {
    expr.iter_top_down().any(|expr| {
        match expr {
            Expr::Push(_) => true,
            Expr::Ident(ref s) if s == "pop" => true,
            Expr::Ident(ref name) => {
                let mut map = rules_to_exprs.clone();
                match map.remove(name) {
                    Some(rule_expr) => child_modifies_state(&rule_expr, &map),
                    None => false
                }
            },
            _ => false
        }
    })
}

fn wrap_branching_exprs(expr: Expr, rules_to_exprs: &HashMap<String, Expr>) -> Expr {
    match expr {
        Expr::Opt(expr) => {
            if child_modifies_state(&expr, rules_to_exprs) {
                Expr::Opt(Box::new(Expr::RestoreOnErr(expr)))
            } else {
                Expr::Opt(expr)
            }
        }
        Expr::Choice(lhs, rhs) => {
            let wrapped_lhs = if child_modifies_state(&lhs, rules_to_exprs) {
                Box::new(Expr::RestoreOnErr(lhs))
            } else {
                lhs
            };
            let wrapped_rhs = if child_modifies_state(&rhs, rules_to_exprs) {
                Box::new(Expr::RestoreOnErr(rhs))
            } else {
                rhs
            };
            Expr::Choice(wrapped_lhs, wrapped_rhs)
        }
        Expr::Rep(expr) => {
            if child_modifies_state(&expr, rules_to_exprs) {
                Expr::Rep(Box::new(Expr::RestoreOnErr(expr)))
            } else {
                Expr::Rep(expr)
            }
        }
        _ => expr
    }
}
<commit_msg>The order of the methods really should have been swapped<commit_after>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
use std::collections::HashMap;

use pest_meta::ast::*;

pub fn restore_on_err(rule: Rule, rules_to_exprs: &HashMap<String, Expr>) -> Rule {
    match rule {
        Rule { name, ty, expr } => {
            let expr = expr.map_bottom_up(|expr| {
                wrap_branching_exprs(expr, rules_to_exprs)
            });

            Rule {
                name,
                ty,
                expr
            }
        }
    }
}

fn wrap_branching_exprs(expr: Expr, rules_to_exprs: &HashMap<String, Expr>) -> Expr {
    match expr {
        Expr::Opt(expr) => {
            if child_modifies_state(&expr, rules_to_exprs) {
                Expr::Opt(Box::new(Expr::RestoreOnErr(expr)))
            } else {
                Expr::Opt(expr)
            }
        }
        Expr::Choice(lhs, rhs) => {
            let wrapped_lhs = if child_modifies_state(&lhs, rules_to_exprs) {
                Box::new(Expr::RestoreOnErr(lhs))
            } else {
                lhs
            };
            let wrapped_rhs = if child_modifies_state(&rhs, rules_to_exprs) {
                Box::new(Expr::RestoreOnErr(rhs))
            } else {
                rhs
            };
            Expr::Choice(wrapped_lhs, wrapped_rhs)
        }
        Expr::Rep(expr) => {
            if child_modifies_state(&expr, rules_to_exprs) {
                Expr::Rep(Box::new(Expr::RestoreOnErr(expr)))
            } else {
                Expr::Rep(expr)
            }
        }
        _ => expr
    }
}

fn child_modifies_state(expr: &Expr, rules_to_exprs: &HashMap<String, Expr>) -> bool {
    expr.iter_top_down().any(|expr| {
        match expr {
            Expr::Push(_) => true,
            Expr::Ident(ref s) if s == "pop" => true,
            Expr::Ident(ref name) => {
                let mut map = rules_to_exprs.clone();
                match map.remove(name) {
                    Some(rule_expr) => child_modifies_state(&rule_expr, &map),
                    None => false
                }
            },
            _ => false
        }
    })
}
<|endoftext|>


<commit_before>use self::private::LoadIter;
use super::RunQueryDsl;
use crate::backend::Backend;
use crate::connection::{Connection, ConnectionGatWorkaround, DefaultLoadingMode, LoadConnection};
use crate::deserialize::FromSqlRow;
use crate::expression::QueryMetadata;
use crate::query_builder::{AsQuery, QueryFragment, QueryId};
use crate::result::QueryResult;

#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
pub use self::private::{CompatibleType, LoadQueryGatWorkaround};

#[cfg(not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))]
pub(crate) use self::private::{CompatibleType, LoadQueryGatWorkaround};

/// The `load` method
///
/// This trait should not be relied on directly by most apps. Its behavior is
/// provided by [`RunQueryDsl`]. However, you may need a where clause on this trait
/// to call `load` from generic code.
///
/// [`RunQueryDsl`]: crate::RunQueryDsl
pub trait LoadQuery<'query, Conn, U, B = DefaultLoadingMode>: RunQueryDsl<Conn>
where
    for<'a> Self: LoadQueryGatWorkaround<'a, 'query, Conn, U, B>,
{
    /// Load this query
    #[diesel_derives::__diesel_public_if(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
    )]
    fn internal_load<'conn>(
        self,
        conn: &'conn mut Conn,
    ) -> QueryResult<<Self as LoadQueryGatWorkaround<'conn, 'query, Conn, U, B>>::Ret>;
}

/// The return type of [`LoadQuery<C, U>::internal_load()`]
///
/// Users should thread this type as `impl Iterator<Item = QueryResult<U>>`
pub type LoadRet<'conn, 'query, Q, C, U, B = DefaultLoadingMode> =
    <Q as LoadQueryGatWorkaround<'conn, 'query, C, U, B>>::Ret;

impl<'conn, 'query, Conn, T, U, DB, B> LoadQueryGatWorkaround<'conn, 'query, Conn, U, B> for T
where
    Conn: Connection<Backend = DB> + ConnectionGatWorkaround<'conn, 'query, DB, B>,
    T: AsQuery + RunQueryDsl<Conn>,
    T::Query: QueryFragment<DB> + QueryId,
    T::SqlType: CompatibleType<U, DB>,
    DB: Backend + QueryMetadata<T::SqlType> + 'static,
    U: FromSqlRow<<T::SqlType as CompatibleType<U, DB>>::SqlType, DB> + 'static,
    <T::SqlType as CompatibleType<U, DB>>::SqlType: 'static,
{
    type Ret = LoadIter<
        'conn,
        U,
        <Conn as ConnectionGatWorkaround<'conn, 'query, DB, B>>::Cursor,
        <T::SqlType as CompatibleType<U, DB>>::SqlType,
        DB,
    >;
}

impl<'query, Conn, T, U, DB, B> LoadQuery<'query, Conn, U, B> for T
where
    Conn: Connection<Backend = DB> + LoadConnection<B>,
    T: AsQuery + RunQueryDsl<Conn>,
    T::Query: QueryFragment<DB> + QueryId + 'query,
    T::SqlType: CompatibleType<U, DB>,
    DB: Backend + QueryMetadata<T::SqlType> + 'static,
    U: FromSqlRow<<T::SqlType as CompatibleType<U, DB>>::SqlType, DB> + 'static,
    <T::SqlType as CompatibleType<U, DB>>::SqlType: 'static,
{
    fn internal_load<'conn>(
        self,
        conn: &'conn mut Conn,
    ) -> QueryResult<<Self as LoadQueryGatWorkaround<'conn, 'query, Conn, U, B>>::Ret> {
        Ok(LoadIter {
            cursor: conn.load(self.as_query())?,
            _marker: Default::default(),
        })
    }
}

/// The `execute` method
///
/// This trait should not be relied on directly by most apps. Its behavior is
/// provided by [`RunQueryDsl`]. However, you may need a where clause on this trait
/// to call `execute` from generic code.
///
/// [`RunQueryDsl`]: crate::RunQueryDsl
pub trait ExecuteDsl<Conn: Connection<Backend = DB>, DB: Backend = <Conn as Connection>::Backend>:
    Sized
{
    /// Execute this command
    fn execute(query: Self, conn: &mut Conn) -> QueryResult<usize>;
}

use crate::result::Error;

impl<Conn, DB, T> ExecuteDsl<Conn, DB> for T
where
    Conn: Connection<Backend = DB>,
    DB: Backend,
    T: QueryFragment<DB> + QueryId,
{
    fn execute(query: T, conn: &mut Conn) -> Result<usize, Error> {
        conn.execute_returning_count(&query)
    }
}

// These types and traits are not part of the public API.
//
// * LoadQueryGatWorkaround to allow us replacing it with real GAT later on
// * CompatibleType as we consider this as "sealed" trait. It shouldn't
// be implemented by a third party
// * LoadIter as it's an implementation detail
mod private {
    use crate::backend::Backend;
    use crate::connection::DefaultLoadingMode;
    use crate::deserialize::FromSqlRow;
    use crate::expression::select_by::SelectBy;
    use crate::expression::{Expression, TypedExpressionType};
    use crate::sql_types::{SqlType, Untyped};
    use crate::{QueryResult, Selectable};

    #[cfg_attr(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
        cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")
    )]
    pub trait LoadQueryGatWorkaround<'conn, 'query, Conn, U, B = DefaultLoadingMode> {
        type Ret: Iterator<Item = QueryResult<U>>;
    }

    #[allow(missing_debug_implementations)]
    pub struct LoadIter<'a, U, C, ST, DB> {
        pub(super) cursor: C,
        pub(super) _marker: std::marker::PhantomData<&'a (ST, U, DB)>,
    }

    impl<'a, C, U, ST, DB, R> LoadIter<'a, U, C, ST, DB>
    where
        DB: Backend,
        C: Iterator<Item = QueryResult<R>>,
        R: crate::row::Row<'a, DB>,
        U: FromSqlRow<ST, DB>,
    {
        pub(super) fn map_row(row: Option<QueryResult<R>>) -> Option<QueryResult<U>> {
            match row? {
                Ok(row) => Some(
                    U::build_from_row(&row).map_err(crate::result::Error::DeserializationError),
                ),
                Err(e) => Some(Err(e)),
            }
        }
    }

    impl<'a, C, U, ST, DB, R> Iterator for LoadIter<'a, U, C, ST, DB>
    where
        DB: Backend,
        C: Iterator<Item = QueryResult<R>>,
        R: crate::row::Row<'a, DB>,
        U: FromSqlRow<ST, DB>,
    {
        type Item = QueryResult<U>;

        fn next(&mut self) -> Option<Self::Item> {
            Self::map_row(self.cursor.next())
        }

        fn size_hint(&self) -> (usize, Option<usize>) {
            self.cursor.size_hint()
        }

        fn count(self) -> usize
        where
            Self: Sized,
        {
            self.cursor.count()
        }

        fn last(self) -> Option<Self::Item>
        where
            Self: Sized,
        {
            Self::map_row(self.cursor.last())
        }

        fn nth(&mut self, n: usize) -> Option<Self::Item> {
            Self::map_row(self.cursor.nth(n))
        }
    }

    impl<'a, C, U, ST, DB, R> ExactSizeIterator for LoadIter<'a, U, C, ST, DB>
    where
        DB: Backend,
        C: ExactSizeIterator + Iterator<Item = QueryResult<R>>,
        R: crate::row::Row<'a, DB>,
        U: FromSqlRow<ST, DB>,
    {
        fn len(&self) -> usize {
            self.cursor.len()
        }
    }

    #[cfg_attr(
        doc_cfg,
        doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))
    )]
    pub trait CompatibleType<U, DB> {
        type SqlType;
    }

    impl<ST, U, DB> CompatibleType<U, DB> for ST
    where
        DB: Backend,
        ST: SqlType + crate::sql_types::SingleValue,
        U: FromSqlRow<ST, DB>,
    {
        type SqlType = ST;
    }

    impl<U, DB> CompatibleType<U, DB> for Untyped
    where
        U: FromSqlRow<Untyped, DB>,
        DB: Backend,
    {
        type SqlType = Untyped;
    }

    impl<U, DB, E, ST> CompatibleType<U, DB> for SelectBy<U, DB>
    where
        DB: Backend,
        ST: SqlType + TypedExpressionType,
        U: Selectable<DB, SelectExpression = E>,
        E: Expression<SqlType = ST>,
        U: FromSqlRow<ST, DB>,
    {
        type SqlType = ST;
    }
}
<commit_msg>Remove unneeded lifetime from `LoadIter`<commit_after>use self::private::LoadIter;
use super::RunQueryDsl;
use crate::backend::Backend;
use crate::connection::{Connection, ConnectionGatWorkaround, DefaultLoadingMode, LoadConnection};
use crate::deserialize::FromSqlRow;
use crate::expression::QueryMetadata;
use crate::query_builder::{AsQuery, QueryFragment, QueryId};
use crate::result::QueryResult;

#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
pub use self::private::{CompatibleType, LoadQueryGatWorkaround};

#[cfg(not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))]
pub(crate) use self::private::{CompatibleType, LoadQueryGatWorkaround};

/// The `load` method
///
/// This trait should not be relied on directly by most apps. Its behavior is
/// provided by [`RunQueryDsl`]. However, you may need a where clause on this trait
/// to call `load` from generic code.
///
/// [`RunQueryDsl`]: crate::RunQueryDsl
pub trait LoadQuery<'query, Conn, U, B = DefaultLoadingMode>: RunQueryDsl<Conn>
where
    for<'a> Self: LoadQueryGatWorkaround<'a, 'query, Conn, U, B>,
{
    /// Load this query
    #[diesel_derives::__diesel_public_if(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
    )]
    fn internal_load<'conn>(
        self,
        conn: &'conn mut Conn,
    ) -> QueryResult<<Self as LoadQueryGatWorkaround<'conn, 'query, Conn, U, B>>::Ret>;
}

/// The return type of [`LoadQuery<C, U>::internal_load()`]
///
/// Users should thread this type as `impl Iterator<Item = QueryResult<U>>`
pub type LoadRet<'conn, 'query, Q, C, U, B = DefaultLoadingMode> =
    <Q as LoadQueryGatWorkaround<'conn, 'query, C, U, B>>::Ret;

impl<'conn, 'query, Conn, T, U, DB, B> LoadQueryGatWorkaround<'conn, 'query, Conn, U, B> for T
where
    Conn: Connection<Backend = DB> + ConnectionGatWorkaround<'conn, 'query, DB, B>,
    T: AsQuery + RunQueryDsl<Conn>,
    T::Query: QueryFragment<DB> + QueryId,
    T::SqlType: CompatibleType<U, DB>,
    DB: Backend + QueryMetadata<T::SqlType> + 'static,
    U: FromSqlRow<<T::SqlType as CompatibleType<U, DB>>::SqlType, DB> + 'static,
    <T::SqlType as CompatibleType<U, DB>>::SqlType: 'static,
{
    type Ret = LoadIter<
        U,
        <Conn as ConnectionGatWorkaround<'conn, 'query, DB, B>>::Cursor,
        <T::SqlType as CompatibleType<U, DB>>::SqlType,
        DB,
    >;
}

impl<'query, Conn, T, U, DB, B> LoadQuery<'query, Conn, U, B> for T
where
    Conn: Connection<Backend = DB> + LoadConnection<B>,
    T: AsQuery + RunQueryDsl<Conn>,
    T::Query: QueryFragment<DB> + QueryId + 'query,
    T::SqlType: CompatibleType<U, DB>,
    DB: Backend + QueryMetadata<T::SqlType> + 'static,
    U: FromSqlRow<<T::SqlType as CompatibleType<U, DB>>::SqlType, DB> + 'static,
    <T::SqlType as CompatibleType<U, DB>>::SqlType: 'static,
{
    fn internal_load<'conn>(
        self,
        conn: &'conn mut Conn,
    ) -> QueryResult<<Self as LoadQueryGatWorkaround<'conn, 'query, Conn, U, B>>::Ret> {
        Ok(LoadIter {
            cursor: conn.load(self.as_query())?,
            _marker: Default::default(),
        })
    }
}

/// The `execute` method
///
/// This trait should not be relied on directly by most apps. Its behavior is
/// provided by [`RunQueryDsl`]. However, you may need a where clause on this trait
/// to call `execute` from generic code.
///
/// [`RunQueryDsl`]: crate::RunQueryDsl
pub trait ExecuteDsl<Conn: Connection<Backend = DB>, DB: Backend = <Conn as Connection>::Backend>:
    Sized
{
    /// Execute this command
    fn execute(query: Self, conn: &mut Conn) -> QueryResult<usize>;
}

use crate::result::Error;

impl<Conn, DB, T> ExecuteDsl<Conn, DB> for T
where
    Conn: Connection<Backend = DB>,
    DB: Backend,
    T: QueryFragment<DB> + QueryId,
{
    fn execute(query: T, conn: &mut Conn) -> Result<usize, Error> {
        conn.execute_returning_count(&query)
    }
}

// These types and traits are not part of the public API.
//
// * LoadQueryGatWorkaround to allow us replacing it with real GAT later on
// * CompatibleType as we consider this as "sealed" trait. It shouldn't
// be implemented by a third party
// * LoadIter as it's an implementation detail
mod private {
    use crate::backend::Backend;
    use crate::connection::DefaultLoadingMode;
    use crate::deserialize::FromSqlRow;
    use crate::expression::select_by::SelectBy;
    use crate::expression::{Expression, TypedExpressionType};
    use crate::sql_types::{SqlType, Untyped};
    use crate::{QueryResult, Selectable};

    #[cfg_attr(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
        cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")
    )]
    pub trait LoadQueryGatWorkaround<'conn, 'query, Conn, U, B = DefaultLoadingMode> {
        type Ret: Iterator<Item = QueryResult<U>>;
    }

    #[allow(missing_debug_implementations)]
    pub struct LoadIter<U, C, ST, DB> {
        pub(super) cursor: C,
        pub(super) _marker: std::marker::PhantomData<(ST, U, DB)>,
    }

    impl<'a, C, U, ST, DB, R> LoadIter<U, C, ST, DB>
    where
        DB: Backend,
        C: Iterator<Item = QueryResult<R>>,
        R: crate::row::Row<'a, DB>,
        U: FromSqlRow<ST, DB>,
    {
        pub(super) fn map_row(row: Option<QueryResult<R>>) -> Option<QueryResult<U>> {
            match row? {
                Ok(row) => Some(
                    U::build_from_row(&row).map_err(crate::result::Error::DeserializationError),
                ),
                Err(e) => Some(Err(e)),
            }
        }
    }

    impl<'a, C, U, ST, DB, R> Iterator for LoadIter<U, C, ST, DB>
    where
        DB: Backend,
        C: Iterator<Item = QueryResult<R>>,
        R: crate::row::Row<'a, DB>,
        U: FromSqlRow<ST, DB>,
    {
        type Item = QueryResult<U>;

        fn next(&mut self) -> Option<Self::Item> {
            Self::map_row(self.cursor.next())
        }

        fn size_hint(&self) -> (usize, Option<usize>) {
            self.cursor.size_hint()
        }

        fn count(self) -> usize
        where
            Self: Sized,
        {
            self.cursor.count()
        }

        fn last(self) -> Option<Self::Item>
        where
            Self: Sized,
        {
            Self::map_row(self.cursor.last())
        }

        fn nth(&mut self, n: usize) -> Option<Self::Item> {
            Self::map_row(self.cursor.nth(n))
        }
    }

    impl<'a, C, U, ST, DB, R> ExactSizeIterator for LoadIter<U, C, ST, DB>
    where
        DB: Backend,
        C: ExactSizeIterator + Iterator<Item = QueryResult<R>>,
        R: crate::row::Row<'a, DB>,
        U: FromSqlRow<ST, DB>,
    {
        fn len(&self) -> usize {
            self.cursor.len()
        }
    }

    #[cfg_attr(
        doc_cfg,
        doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))
    )]
    pub trait CompatibleType<U, DB> {
        type SqlType;
    }

    impl<ST, U, DB> CompatibleType<U, DB> for ST
    where
        DB: Backend,
        ST: SqlType + crate::sql_types::SingleValue,
        U: FromSqlRow<ST, DB>,
    {
        type SqlType = ST;
    }

    impl<U, DB> CompatibleType<U, DB> for Untyped
    where
        U: FromSqlRow<Untyped, DB>,
        DB: Backend,
    {
        type SqlType = Untyped;
    }

    impl<U, DB, E, ST> CompatibleType<U, DB> for SelectBy<U, DB>
    where
        DB: Backend,
        ST: SqlType + TypedExpressionType,
        U: Selectable<DB, SelectExpression = E>,
        E: Expression<SqlType = ST>,
        U: FromSqlRow<ST, DB>,
    {
        type SqlType = ST;
    }
}
<|endoftext|>


<commit_before>extern crate shader_version;
extern crate graphics;
extern crate event;
extern crate input;
extern crate sdl2_window;
extern crate opengl_graphics;
extern crate drag_controller;

use std::cell::RefCell;
use opengl_graphics::{
    Gl,
    Texture,
};
use sdl2_window::Sdl2Window;
use event::{ Events, WindowSettings };
use graphics::{
    AddBorder,
    AddEllipse,
    AddRectangle,
    AddColor,
    Context,
    Draw,
    ImageSize,
};
use graphics::deform::DeformGrid;
use drag_controller::{
    DragController,
    StartDrag,
    MoveDrag,
    EndDrag,
    InterruptDrag,
};
use event::{
    PressEvent,
    RenderEvent,
};
use input::{
    keyboard,
    Keyboard,
};

fn main() {
    println!("Click in the red square and drag.");
    println!("Toggle grid with G.");
    println!("Reset grid with R.");

    let opengl = shader_version::opengl::OpenGL_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: "Deform".to_string(),
            size: [300, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 4,
        }
    );

    let image = Path::new("./bin/assets/rust-logo.png");
    let image = Texture::from_path(&image).unwrap();

    let (width, height) = image.get_size();
    let width = width as f64;
    let height = height as f64;
    let mut grid = DeformGrid::new(
        [0.0, 0.0, width, height],
        20, 20
    );

    let ref mut gl = Gl::new(opengl);
    let mut drag = DragController::new();
    let mut draw_grid = true;
    let window = RefCell::new(window);
    for e in Events::new(&window) {
        drag.event(&e, |action| {
            match action {
                StartDrag(x, y) => {
                    match grid.hit([x, y]) {
                        None => {
                            // Did not hit deformed grid.
                            grid.add_control_point([x, y]);
                        }
                        Some(pos) => {
                            // Add point to deformed grid.
                            grid.add_control_point(pos);
                            let n = grid.ps.len();
                            grid.set_current(n - 1, [x, y]);
                        }
                    }
                    grid.update();
                    true
                }
                MoveDrag(x, y) => {
                    let n = grid.ps.len();
                    grid.set_current(n - 1, [x, y]);
                    grid.update();
                    true
                }
                EndDrag(_, _) => false,
                // Continue dragging when receiving focus.
                InterruptDrag => true,
            }
        });
        e.press(|button| {
            if button == Keyboard(keyboard::G) {
                draw_grid = !draw_grid;
                println!("Draw grid {}", draw_grid);
            } else if button == Keyboard(keyboard::R) {
                grid.reset_control_points();
                grid.reset_vertices_and_texture_coords();
                grid.update();
                println!("Reset grid");
            }
        });
        e.render(|args| {
            gl.viewport(0, 0,
                        args.width as i32, args.height as i32);
            let c = Context::abs(
                args.width as f64,
                args.height as f64
            );
            // Clear background.
            c.rgb(1.0, 1.0, 1.0).draw(gl);

            // Draw deformed image.
            grid.draw_image(&c, gl, &image);

            if draw_grid {
                // Draw grid.
                grid.draw_vertical_lines(
                    &c.rgb(0.0, 1.0, 0.0),
                    gl, 1.0
                );
                grid.draw_horizontal_lines(
                    &c.rgb(0.0, 0.0, 1.0),
                    gl, 1.0
                );
            }

            // Draw rect of the original grid.
            c.rgb(1.0, 0.0, 0.0)
            .rect(0.0, 0.0, width, height)
            .border_width(3.0)
            .draw(gl);

            // Draw control points.
            for i in range(0, grid.ps.len()) {
                // Original positions.
                let x = grid.ps[i][0];
                let y = grid.ps[i][1];
                c.rgba(1.0, 0.0, 0.0, 0.5)
                .circle(x, y, 3.0)
                .draw(gl);

                // Current positions.
                let x = grid.qs[i][0];
                let y = grid.qs[i][1];
                c.rgba(0.0, 0.0, 0.0, 0.5)
                .circle(x, y, 3.0)
                .draw(gl)
            };
        });
    }
}

<commit_msg>Updating deform example for changes in drag_controller<commit_after>extern crate shader_version;
extern crate graphics;
extern crate event;
extern crate input;
extern crate sdl2_window;
extern crate opengl_graphics;
extern crate drag_controller;

use std::cell::RefCell;
use opengl_graphics::{
    Gl,
    Texture,
};
use sdl2_window::Sdl2Window;
use event::{ Events, WindowSettings };
use graphics::{
    AddBorder,
    AddEllipse,
    AddRectangle,
    AddColor,
    Context,
    Draw,
    ImageSize,
};
use graphics::deform::DeformGrid;
use drag_controller::{
    DragController,
    Drag
};
use event::{
    PressEvent,
    RenderEvent,
};
use input::{
    keyboard,
    Keyboard,
};

fn main() {
    println!("Click in the red square and drag.");
    println!("Toggle grid with G.");
    println!("Reset grid with R.");

    let opengl = shader_version::opengl::OpenGL_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: "Deform".to_string(),
            size: [300, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 4,
        }
    );

    let image = Path::new("./bin/assets/rust-logo.png");
    let image = Texture::from_path(&image).unwrap();

    let (width, height) = image.get_size();
    let width = width as f64;
    let height = height as f64;
    let mut grid = DeformGrid::new(
        [0.0, 0.0, width, height],
        20, 20
    );

    let ref mut gl = Gl::new(opengl);
    let mut drag = DragController::new();
    let mut draw_grid = true;
    let window = RefCell::new(window);
    for e in Events::new(&window) {
        drag.event(&e, |action| {
            match action {
                Drag::Start(x, y) => {
                    match grid.hit([x, y]) {
                        None => {
                            // Did not hit deformed grid.
                            grid.add_control_point([x, y]);
                        }
                        Some(pos) => {
                            // Add point to deformed grid.
                            grid.add_control_point(pos);
                            let n = grid.ps.len();
                            grid.set_current(n - 1, [x, y]);
                        }
                    }
                    grid.update();
                    true
                }
                Drag::Move(x, y) => {
                    let n = grid.ps.len();
                    grid.set_current(n - 1, [x, y]);
                    grid.update();
                    true
                }
                Drag::End(_, _) => false,
                // Continue dragging when receiving focus.
                Drag::Interrupt => true,
            }
        });
        e.press(|button| {
            if button == Keyboard(keyboard::G) {
                draw_grid = !draw_grid;
                println!("Draw grid {}", draw_grid);
            } else if button == Keyboard(keyboard::R) {
                grid.reset_control_points();
                grid.reset_vertices_and_texture_coords();
                grid.update();
                println!("Reset grid");
            }
        });
        e.render(|args| {
            gl.viewport(0, 0,
                        args.width as i32, args.height as i32);
            let c = Context::abs(
                args.width as f64,
                args.height as f64
            );
            // Clear background.
            c.rgb(1.0, 1.0, 1.0).draw(gl);

            // Draw deformed image.
            grid.draw_image(&c, gl, &image);

            if draw_grid {
                // Draw grid.
                grid.draw_vertical_lines(
                    &c.rgb(0.0, 1.0, 0.0),
                    gl, 1.0
                );
                grid.draw_horizontal_lines(
                    &c.rgb(0.0, 0.0, 1.0),
                    gl, 1.0
                );
            }

            // Draw rect of the original grid.
            c.rgb(1.0, 0.0, 0.0)
            .rect(0.0, 0.0, width, height)
            .border_width(3.0)
            .draw(gl);

            // Draw control points.
            for i in range(0, grid.ps.len()) {
                // Original positions.
                let x = grid.ps[i][0];
                let y = grid.ps[i][1];
                c.rgba(1.0, 0.0, 0.0, 0.5)
                .circle(x, y, 3.0)
                .draw(gl);

                // Current positions.
                let x = grid.qs[i][0];
                let y = grid.qs[i][1];
                c.rgba(0.0, 0.0, 0.0, 0.5)
                .circle(x, y, 3.0)
                .draw(gl)
            };
        });
    }
}

<|endoftext|>