<commit_before>//! The `Resolve` trait, support types, and some basic implementations.
//!
//! This module contains:
//!
//! - A [`GaiResolver`](GaiResolver) that is the default resolver for the
//!   `HttpConnector`.
//! - The [`Resolve`](Resolve) trait and related types to build a custom
//!   resolver for use with the `HttpConnector`.
use std::{fmt, io, vec};
use std::error::Error;
use std::net::{
    IpAddr, Ipv4Addr, Ipv6Addr,
    SocketAddr, ToSocketAddrs,
    SocketAddrV4, SocketAddrV6,
};
use std::str::FromStr;
use std::sync::Arc;

use futures::{Async, Future, Poll};
use futures::future::{Executor, ExecuteError};
use futures::sync::oneshot;
use futures_cpupool::{Builder as CpuPoolBuilder};
use tokio_threadpool;

use self::sealed::GaiTask;

/// Resolve a hostname to a set of IP addresses.
pub trait Resolve {
    /// The set of IP addresses to try to connect to.
    type Addrs: Iterator<Item=IpAddr>;
    /// A Future of the resolved set of addresses.
    type Future: Future<Item=Self::Addrs, Error=io::Error>;
    /// Resolve a hostname.
    fn resolve(&self, name: Name) -> Self::Future;
}

/// A domain name to resolve into IP addresses.
pub struct Name {
    host: String,
}

/// A resolver using blocking `getaddrinfo` calls in a threadpool.
#[derive(Clone)]
pub struct GaiResolver {
    executor: GaiExecutor,
}

/// An iterator of IP addresses returned from `getaddrinfo`.
pub struct GaiAddrs {
    inner: IpAddrs,
}

/// A future to resole a name returned by `GaiResolver`.
pub struct GaiFuture {
    rx: oneshot::SpawnHandle<IpAddrs, io::Error>,
}

impl Name {
    pub(super) fn new(host: String) -> Name {
        Name {
            host,
        }
    }

    /// View the hostname as a string slice.
    pub fn as_str(&self) -> &str {
        &self.host
    }
}

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

impl FromStr for Name {
    type Err = InvalidNameError;

    fn from_str(host: &str) -> Result<Self, Self::Err> {
        // Possibly add validation later
        Ok(Name::new(host.to_owned()))
    }
}

/// Error indicating a given string was not a valid domain name.
#[derive(Debug)]
pub struct InvalidNameError(());

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

impl Error for InvalidNameError {
    fn description(&self) -> &str {
        "Not a valid domain name"
    }
}

impl GaiResolver {
    /// Construct a new `GaiResolver`.
    ///
    /// Takes number of DNS worker threads.
    pub fn new(threads: usize) -> Self {
        let pool = CpuPoolBuilder::new()
            .name_prefix("hyper-dns")
            .pool_size(threads)
            .create();
        GaiResolver::new_with_executor(pool)
    }

    /// Construct a new `GaiResolver` with a shared thread pool executor.
    ///
    /// Takes an executor to run blocking `getaddrinfo` tasks on.
    pub fn new_with_executor<E: 'static>(executor: E) -> Self
    where
        E: Executor<GaiTask> + Send + Sync,
    {
        GaiResolver {
            executor: GaiExecutor(Arc::new(executor)),
        }
    }
}

impl Resolve for GaiResolver {
    type Addrs = GaiAddrs;
    type Future = GaiFuture;

    fn resolve(&self, name: Name) -> Self::Future {
        let blocking = GaiBlocking::new(name.host);
        let rx = oneshot::spawn(blocking, &self.executor);
        GaiFuture {
            rx,
        }
    }
}

impl fmt::Debug for GaiResolver {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("GaiResolver")
    }
}

impl Future for GaiFuture {
    type Item = GaiAddrs;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let addrs = try_ready!(self.rx.poll());
        Ok(Async::Ready(GaiAddrs {
            inner: addrs,
        }))
    }
}

impl fmt::Debug for GaiFuture {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("GaiFuture")
    }
}

impl Iterator for GaiAddrs {
    type Item = IpAddr;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next().map(|sa| sa.ip())
    }
}

impl fmt::Debug for GaiAddrs {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("GaiAddrs")
    }
}

#[derive(Clone)]
struct GaiExecutor(Arc<Executor<GaiTask> + Send + Sync>);

impl Executor<oneshot::Execute<GaiBlocking>> for GaiExecutor {
    fn execute(&self, future: oneshot::Execute<GaiBlocking>) -> Result<(), ExecuteError<oneshot::Execute<GaiBlocking>>> {
        self.0.execute(GaiTask { work: future })
            .map_err(|err| ExecuteError::new(err.kind(), err.into_future().work))
    }
}

pub(super) struct GaiBlocking {
    host: String,
}

impl GaiBlocking {
    pub(super) fn new(host: String) -> GaiBlocking {
        GaiBlocking { host }
    }
}

impl Future for GaiBlocking {
    type Item = IpAddrs;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        debug!("resolving host={:?}", self.host);
        (&*self.host, 0).to_socket_addrs()
            .map(|i| Async::Ready(IpAddrs { iter: i }))
    }
}

pub(super) struct IpAddrs {
    iter: vec::IntoIter<SocketAddr>,
}

impl IpAddrs {
    pub(super) fn new(addrs: Vec<SocketAddr>) -> Self {
        IpAddrs { iter: addrs.into_iter() }
    }

    pub(super) fn try_parse(host: &str, port: u16) -> Option<IpAddrs> {
        if let Ok(addr) = host.parse::<Ipv4Addr>() {
            let addr = SocketAddrV4::new(addr, port);
            return Some(IpAddrs { iter: vec![SocketAddr::V4(addr)].into_iter() })
        }
        if let Ok(addr) = host.parse::<Ipv6Addr>() {
            let addr = SocketAddrV6::new(addr, port, 0, 0);
            return Some(IpAddrs { iter: vec![SocketAddr::V6(addr)].into_iter() })
        }
        None
    }

    pub(super) fn split_by_preference(self) -> (IpAddrs, IpAddrs) {
        let preferring_v6 = self.iter
            .as_slice()
            .first()
            .map(SocketAddr::is_ipv6)
            .unwrap_or(false);

        let (preferred, fallback) = self.iter
            .partition::<Vec<_>, _>(|addr| addr.is_ipv6() == preferring_v6);

        (IpAddrs::new(preferred), IpAddrs::new(fallback))
    }

    pub(super) fn is_empty(&self) -> bool {
        self.iter.as_slice().is_empty()
    }
}

impl Iterator for IpAddrs {
    type Item = SocketAddr;
    #[inline]
    fn next(&mut self) -> Option<SocketAddr> {
        self.iter.next()
    }
}

// Make this Future unnameable outside of this crate.
pub(super) mod sealed {
    use super::*;
    // Blocking task to be executed on a thread pool.
    pub struct GaiTask {
        pub(super) work: oneshot::Execute<GaiBlocking>
    }

    impl fmt::Debug for GaiTask {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.pad("GaiTask")
        }
    }

    impl Future for GaiTask {
        type Item = ();
        type Error = ();

        fn poll(&mut self) -> Poll<(), ()> {
            self.work.poll()
        }
    }
}

/// A resolver using `getaddrinfo` calls via the `tokio_threadpool::blocking` API.
///
/// Unlike the `GaiResolver` this will not spawn dedicated threads, but only works when running on the
/// multi-threaded Tokio runtime.
#[derive(Clone, Debug)]
pub struct TokioThreadpoolGaiResolver(());

/// The future returned by `TokioThreadpoolGaiResolver`.
#[derive(Debug)]
pub struct TokioThreadpoolGaiFuture {
    name: Name,
}

impl TokioThreadpoolGaiResolver {
    /// Creates a new DNS resolver that will use tokio threadpool's blocking
    /// feature.
    ///
    /// **Requires** its futures to be run on the threadpool runtime.
    pub fn new() -> Self {
        TokioThreadpoolGaiResolver(())
    }
}

impl Resolve for TokioThreadpoolGaiResolver {
    type Addrs = GaiAddrs;
    type Future = TokioThreadpoolGaiFuture;

    fn resolve(&self, name: Name) -> TokioThreadpoolGaiFuture {
        TokioThreadpoolGaiFuture { name }
    }
}

impl Future for TokioThreadpoolGaiFuture {
    type Item = GaiAddrs;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<GaiAddrs, io::Error> {
        match tokio_threadpool::blocking(|| (self.name.as_str(), 0).to_socket_addrs()) {
            Ok(Async::Ready(Ok(iter))) => Ok(Async::Ready(GaiAddrs { inner: IpAddrs { iter } })),
            Ok(Async::Ready(Err(e))) => Err(e),
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Err(e) => Err(io::Error::new(io::ErrorKind::Other, e)),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::net::{Ipv4Addr, Ipv6Addr};
    use super::*;

    #[test]
    fn test_ip_addrs_split_by_preference() {
        let v4_addr = (Ipv4Addr::new(127, 0, 0, 1), 80).into();
        let v6_addr = (Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 80).into();

        let (mut preferred, mut fallback) =
            IpAddrs { iter: vec![v4_addr, v6_addr].into_iter() }.split_by_preference();
        assert!(preferred.next().unwrap().is_ipv4());
        assert!(fallback.next().unwrap().is_ipv6());

        let (mut preferred, mut fallback) =
            IpAddrs { iter: vec![v6_addr, v4_addr].into_iter() }.split_by_preference();
        assert!(preferred.next().unwrap().is_ipv6());
        assert!(fallback.next().unwrap().is_ipv4());
    }

    #[test]
    fn test_name_from_str() {
        let name = Name::from_str("test.example.com").expect("Should be a valid domain");
        assert_eq!(name.as_str(), "test.example.com");
    }
}
<commit_msg>feat(client): Add useful trait impls to Name<commit_after>//! The `Resolve` trait, support types, and some basic implementations.
//!
//! This module contains:
//!
//! - A [`GaiResolver`](GaiResolver) that is the default resolver for the
//!   `HttpConnector`.
//! - The [`Resolve`](Resolve) trait and related types to build a custom
//!   resolver for use with the `HttpConnector`.
use std::{fmt, io, vec};
use std::error::Error;
use std::net::{
    IpAddr, Ipv4Addr, Ipv6Addr,
    SocketAddr, ToSocketAddrs,
    SocketAddrV4, SocketAddrV6,
};
use std::str::FromStr;
use std::sync::Arc;

use futures::{Async, Future, Poll};
use futures::future::{Executor, ExecuteError};
use futures::sync::oneshot;
use futures_cpupool::{Builder as CpuPoolBuilder};
use tokio_threadpool;

use self::sealed::GaiTask;

/// Resolve a hostname to a set of IP addresses.
pub trait Resolve {
    /// The set of IP addresses to try to connect to.
    type Addrs: Iterator<Item=IpAddr>;
    /// A Future of the resolved set of addresses.
    type Future: Future<Item=Self::Addrs, Error=io::Error>;
    /// Resolve a hostname.
    fn resolve(&self, name: Name) -> Self::Future;
}

/// A domain name to resolve into IP addresses.
#[derive(Clone, Hash, Eq, PartialEq)]
pub struct Name {
    host: String,
}

/// A resolver using blocking `getaddrinfo` calls in a threadpool.
#[derive(Clone)]
pub struct GaiResolver {
    executor: GaiExecutor,
}

/// An iterator of IP addresses returned from `getaddrinfo`.
pub struct GaiAddrs {
    inner: IpAddrs,
}

/// A future to resole a name returned by `GaiResolver`.
pub struct GaiFuture {
    rx: oneshot::SpawnHandle<IpAddrs, io::Error>,
}

impl Name {
    pub(super) fn new(host: String) -> Name {
        Name {
            host,
        }
    }

    /// View the hostname as a string slice.
    pub fn as_str(&self) -> &str {
        &self.host
    }
}

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

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

impl FromStr for Name {
    type Err = InvalidNameError;

    fn from_str(host: &str) -> Result<Self, Self::Err> {
        // Possibly add validation later
        Ok(Name::new(host.to_owned()))
    }
}

/// Error indicating a given string was not a valid domain name.
#[derive(Debug)]
pub struct InvalidNameError(());

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

impl Error for InvalidNameError {
    fn description(&self) -> &str {
        "Not a valid domain name"
    }
}

impl GaiResolver {
    /// Construct a new `GaiResolver`.
    ///
    /// Takes number of DNS worker threads.
    pub fn new(threads: usize) -> Self {
        let pool = CpuPoolBuilder::new()
            .name_prefix("hyper-dns")
            .pool_size(threads)
            .create();
        GaiResolver::new_with_executor(pool)
    }

    /// Construct a new `GaiResolver` with a shared thread pool executor.
    ///
    /// Takes an executor to run blocking `getaddrinfo` tasks on.
    pub fn new_with_executor<E: 'static>(executor: E) -> Self
    where
        E: Executor<GaiTask> + Send + Sync,
    {
        GaiResolver {
            executor: GaiExecutor(Arc::new(executor)),
        }
    }
}

impl Resolve for GaiResolver {
    type Addrs = GaiAddrs;
    type Future = GaiFuture;

    fn resolve(&self, name: Name) -> Self::Future {
        let blocking = GaiBlocking::new(name.host);
        let rx = oneshot::spawn(blocking, &self.executor);
        GaiFuture {
            rx,
        }
    }
}

impl fmt::Debug for GaiResolver {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("GaiResolver")
    }
}

impl Future for GaiFuture {
    type Item = GaiAddrs;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let addrs = try_ready!(self.rx.poll());
        Ok(Async::Ready(GaiAddrs {
            inner: addrs,
        }))
    }
}

impl fmt::Debug for GaiFuture {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("GaiFuture")
    }
}

impl Iterator for GaiAddrs {
    type Item = IpAddr;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next().map(|sa| sa.ip())
    }
}

impl fmt::Debug for GaiAddrs {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("GaiAddrs")
    }
}

#[derive(Clone)]
struct GaiExecutor(Arc<Executor<GaiTask> + Send + Sync>);

impl Executor<oneshot::Execute<GaiBlocking>> for GaiExecutor {
    fn execute(&self, future: oneshot::Execute<GaiBlocking>) -> Result<(), ExecuteError<oneshot::Execute<GaiBlocking>>> {
        self.0.execute(GaiTask { work: future })
            .map_err(|err| ExecuteError::new(err.kind(), err.into_future().work))
    }
}

pub(super) struct GaiBlocking {
    host: String,
}

impl GaiBlocking {
    pub(super) fn new(host: String) -> GaiBlocking {
        GaiBlocking { host }
    }
}

impl Future for GaiBlocking {
    type Item = IpAddrs;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        debug!("resolving host={:?}", self.host);
        (&*self.host, 0).to_socket_addrs()
            .map(|i| Async::Ready(IpAddrs { iter: i }))
    }
}

pub(super) struct IpAddrs {
    iter: vec::IntoIter<SocketAddr>,
}

impl IpAddrs {
    pub(super) fn new(addrs: Vec<SocketAddr>) -> Self {
        IpAddrs { iter: addrs.into_iter() }
    }

    pub(super) fn try_parse(host: &str, port: u16) -> Option<IpAddrs> {
        if let Ok(addr) = host.parse::<Ipv4Addr>() {
            let addr = SocketAddrV4::new(addr, port);
            return Some(IpAddrs { iter: vec![SocketAddr::V4(addr)].into_iter() })
        }
        if let Ok(addr) = host.parse::<Ipv6Addr>() {
            let addr = SocketAddrV6::new(addr, port, 0, 0);
            return Some(IpAddrs { iter: vec![SocketAddr::V6(addr)].into_iter() })
        }
        None
    }

    pub(super) fn split_by_preference(self) -> (IpAddrs, IpAddrs) {
        let preferring_v6 = self.iter
            .as_slice()
            .first()
            .map(SocketAddr::is_ipv6)
            .unwrap_or(false);

        let (preferred, fallback) = self.iter
            .partition::<Vec<_>, _>(|addr| addr.is_ipv6() == preferring_v6);

        (IpAddrs::new(preferred), IpAddrs::new(fallback))
    }

    pub(super) fn is_empty(&self) -> bool {
        self.iter.as_slice().is_empty()
    }
}

impl Iterator for IpAddrs {
    type Item = SocketAddr;
    #[inline]
    fn next(&mut self) -> Option<SocketAddr> {
        self.iter.next()
    }
}

// Make this Future unnameable outside of this crate.
pub(super) mod sealed {
    use super::*;
    // Blocking task to be executed on a thread pool.
    pub struct GaiTask {
        pub(super) work: oneshot::Execute<GaiBlocking>
    }

    impl fmt::Debug for GaiTask {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.pad("GaiTask")
        }
    }

    impl Future for GaiTask {
        type Item = ();
        type Error = ();

        fn poll(&mut self) -> Poll<(), ()> {
            self.work.poll()
        }
    }
}

/// A resolver using `getaddrinfo` calls via the `tokio_threadpool::blocking` API.
///
/// Unlike the `GaiResolver` this will not spawn dedicated threads, but only works when running on the
/// multi-threaded Tokio runtime.
#[derive(Clone, Debug)]
pub struct TokioThreadpoolGaiResolver(());

/// The future returned by `TokioThreadpoolGaiResolver`.
#[derive(Debug)]
pub struct TokioThreadpoolGaiFuture {
    name: Name,
}

impl TokioThreadpoolGaiResolver {
    /// Creates a new DNS resolver that will use tokio threadpool's blocking
    /// feature.
    ///
    /// **Requires** its futures to be run on the threadpool runtime.
    pub fn new() -> Self {
        TokioThreadpoolGaiResolver(())
    }
}

impl Resolve for TokioThreadpoolGaiResolver {
    type Addrs = GaiAddrs;
    type Future = TokioThreadpoolGaiFuture;

    fn resolve(&self, name: Name) -> TokioThreadpoolGaiFuture {
        TokioThreadpoolGaiFuture { name }
    }
}

impl Future for TokioThreadpoolGaiFuture {
    type Item = GaiAddrs;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<GaiAddrs, io::Error> {
        match tokio_threadpool::blocking(|| (self.name.as_str(), 0).to_socket_addrs()) {
            Ok(Async::Ready(Ok(iter))) => Ok(Async::Ready(GaiAddrs { inner: IpAddrs { iter } })),
            Ok(Async::Ready(Err(e))) => Err(e),
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Err(e) => Err(io::Error::new(io::ErrorKind::Other, e)),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::net::{Ipv4Addr, Ipv6Addr};
    use super::*;

    #[test]
    fn test_ip_addrs_split_by_preference() {
        let v4_addr = (Ipv4Addr::new(127, 0, 0, 1), 80).into();
        let v6_addr = (Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 80).into();

        let (mut preferred, mut fallback) =
            IpAddrs { iter: vec![v4_addr, v6_addr].into_iter() }.split_by_preference();
        assert!(preferred.next().unwrap().is_ipv4());
        assert!(fallback.next().unwrap().is_ipv6());

        let (mut preferred, mut fallback) =
            IpAddrs { iter: vec![v6_addr, v4_addr].into_iter() }.split_by_preference();
        assert!(preferred.next().unwrap().is_ipv6());
        assert!(fallback.next().unwrap().is_ipv4());
    }

    #[test]
    fn test_name_from_str() {
        const DOMAIN: &str = "test.example.com";
        let name = Name::from_str(DOMAIN).expect("Should be a valid domain");
        assert_eq!(name.as_str(), DOMAIN);
        assert_eq!(name.to_string(), DOMAIN);
    }
}
<|endoftext|>


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

use crate::color;
use crate::error::{ImageError, ImageResult, ParameterError, ParameterErrorKind};
use crate::image::ImageEncoder;

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,
}

/// BMP Encoder
///
/// An alias of [`BmpEncoder`].
///
/// TODO: remove
///
/// [`BmpEncoder`]: struct.BmpEncoder.html
#[allow(dead_code)]
#[deprecated(note = "Use `BmpEncoder` instead")]
pub type BMPEncoder<'a, W> = BmpEncoder<'a, 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,
    ) -> ImageResult<()> {
        self.encode_with_palette(image, width, height, c, None)
    }

    /// Same as ```encode```, but allow a palette to be passed in
    pub fn encode_with_palette(
        &mut self,
        image: &[u8],
        width: u32,
        height: u32,
        c: color::ColorType,
        palette: Option<&[[u8; 3]]>,
    ) -> ImageResult<()> {
        let bmp_header_size = BITMAPFILEHEADER_SIZE;

        let (dib_header_size, written_pixel_size, palette_color_count) = get_pixel_info(c, palette)?;
        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)
            .and_then(|v| v.checked_mul(written_pixel_size))
            .and_then(|v| v.checked_add(height * row_pad_size))
            .ok_or_else(|| {
                ImageError::Parameter(ParameterError::from_kind(
                    ParameterErrorKind::DimensionMismatch,
                ))
            })?;
        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)?; // 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::Rgb8 => {
                self.encode_rgb(image, width, height, row_pad_size, 3)?
            }
            color::ColorType::Rgba8 => {
                self.encode_rgba(image, width, height, row_pad_size, 4)?
            }
            color::ColorType::L8 => {
                self.encode_gray(image, width, height, row_pad_size, 1, palette)?
            }
            color::ColorType::La8 => {
                self.encode_gray(image, width, height, row_pad_size, 2, palette)?
            }
            _ => {
                return Err(ImageError::IoError(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 width = width as usize;
        let height = height as usize;
        let x_stride = bytes_per_pixel as usize;
        let y_stride = width * x_stride;
        for row in (0..height).rev() {
            // from the bottom up
            let row_start = row * y_stride;
            for px in image[row_start..][..y_stride].chunks_exact(x_stride) {
                let r = px[0];
                let g = px[1];
                let b = px[2];
                // written as BGR
                self.writer.write_all(&[b, g, r])?;
            }
            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 width = width as usize;
        let height = height as usize;
        let x_stride = bytes_per_pixel as usize;
        let y_stride = width * x_stride;
        for row in (0..height).rev() {
            // from the bottom up
            let row_start = row * y_stride;
            for px in image[row_start..][..y_stride].chunks_exact(x_stride) {
                let r = px[0];
                let g = px[1];
                let b = px[2];
                let a = px[3];
                // written as BGRA
                self.writer.write_all(&[b, g, r, 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,
        palette: Option<&[[u8; 3]]>,
    ) -> io::Result<()> {
        // write grayscale palette
        if let Some(palette) = palette {
            for item in palette {
                // each color is written as BGRA, where A is always 0
                self.writer.write_all(&[item[2], item[1], item[0], 0])?;
            }
        } else {
            for val in 0u8..=255 {
                // each color is written as BGRA, where A is always 0 and since only grayscale is being written, B = G = R = index
                self.writer.write_all(&[val, val, val, 0])?;
            }
        }

        // write image data
        let x_stride = bytes_per_pixel;
        let y_stride = width * x_stride;
        for row in (0..height).rev() {
            // from the bottom up
            let row_start = row * 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(())
    }
}

impl<'a, W: Write> ImageEncoder for BmpEncoder<'a, W> {
    fn write_image(
        mut self,
        buf: &[u8],
        width: u32,
        height: u32,
        color_type: color::ColorType,
    ) -> ImageResult<()> {
        self.encode(buf, width, height, color_type)
    }
}

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, palette: Option<&[[u8; 3]]>) -> io::Result<(u32, u32, u32)> {
    let sizes = match c {
        color::ColorType::Rgb8 => (BITMAPINFOHEADER_SIZE, 3, 0),
        color::ColorType::Rgba8 => (BITMAPV4HEADER_SIZE, 4, 0),
        color::ColorType::L8 => (BITMAPINFOHEADER_SIZE, 1, palette.map(|p| p.len()).unwrap_or(256) as u32),
        color::ColorType::La8 => (BITMAPINFOHEADER_SIZE, 1, palette.map(|p| p.len()).unwrap_or(256) as u32),
        _ => {
            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 crate::color::ColorType;
    use crate::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");

        let mut buf = vec![0; decoder.total_bytes() as usize];
        decoder.read_image(&mut buf).expect("failed to decode");
        buf
    }

    #[test]
    fn round_trip_single_pixel_rgb() {
        let image = [255u8, 0, 0]; // single red pixel
        let decoded = round_trip_image(&image, 1, 1, ColorType::Rgb8);
        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::Rgb8);
        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::Rgba8);
        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::Rgb8);
    }

    #[test]
    fn round_trip_gray() {
        let image = [0u8, 1, 2]; // 3 pixels
        let decoded = round_trip_image(&image, 3, 1, ColorType::L8);
        // 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::La8);
        // 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>add comments and checks for encode_with_palette<commit_after>use byteorder::{LittleEndian, WriteBytesExt};
use std::io::{self, Write};

use crate::color;
use crate::error::{ImageError, ImageResult, ParameterError, ParameterErrorKind};
use crate::image::ImageEncoder;

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,
}

/// BMP Encoder
///
/// An alias of [`BmpEncoder`].
///
/// TODO: remove
///
/// [`BmpEncoder`]: struct.BmpEncoder.html
#[allow(dead_code)]
#[deprecated(note = "Use `BmpEncoder` instead")]
pub type BMPEncoder<'a, W> = BmpEncoder<'a, 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,
    ) -> ImageResult<()> {
        self.encode_with_palette(image, width, height, c, None)
    }

    /// Same as ```encode```, but allow a palette to be passed in.
    /// The ```palette``` is ignored for color types other than Luma/Luma-with-alpha.
    pub fn encode_with_palette(
        &mut self,
        image: &[u8],
        width: u32,
        height: u32,
        c: color::ColorType,
        palette: Option<&[[u8; 3]]>,
    ) -> ImageResult<()> {
        if palette.is_some() && c != color::ColorType::L8 && c != color::ColorType::La8 {
            return Err(ImageError::IoError(io::Error::new(
                io::ErrorKind::InvalidInput,
                format!(
                    "Unsupported color type {:?} when using a non-empty palette. Supported types: Gray(8), GrayA(8).",
                    c
                ),
            )))
        }

        let bmp_header_size = BITMAPFILEHEADER_SIZE;

        let (dib_header_size, written_pixel_size, palette_color_count) = get_pixel_info(c, palette)?;
        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)
            .and_then(|v| v.checked_mul(written_pixel_size))
            .and_then(|v| v.checked_add(height * row_pad_size))
            .ok_or_else(|| {
                ImageError::Parameter(ParameterError::from_kind(
                    ParameterErrorKind::DimensionMismatch,
                ))
            })?;
        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)?; // 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::Rgb8 => {
                self.encode_rgb(image, width, height, row_pad_size, 3)?
            }
            color::ColorType::Rgba8 => {
                self.encode_rgba(image, width, height, row_pad_size, 4)?
            }
            color::ColorType::L8 => {
                self.encode_gray(image, width, height, row_pad_size, 1, palette)?
            }
            color::ColorType::La8 => {
                self.encode_gray(image, width, height, row_pad_size, 2, palette)?
            }
            _ => {
                return Err(ImageError::IoError(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 width = width as usize;
        let height = height as usize;
        let x_stride = bytes_per_pixel as usize;
        let y_stride = width * x_stride;
        for row in (0..height).rev() {
            // from the bottom up
            let row_start = row * y_stride;
            for px in image[row_start..][..y_stride].chunks_exact(x_stride) {
                let r = px[0];
                let g = px[1];
                let b = px[2];
                // written as BGR
                self.writer.write_all(&[b, g, r])?;
            }
            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 width = width as usize;
        let height = height as usize;
        let x_stride = bytes_per_pixel as usize;
        let y_stride = width * x_stride;
        for row in (0..height).rev() {
            // from the bottom up
            let row_start = row * y_stride;
            for px in image[row_start..][..y_stride].chunks_exact(x_stride) {
                let r = px[0];
                let g = px[1];
                let b = px[2];
                let a = px[3];
                // written as BGRA
                self.writer.write_all(&[b, g, r, 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,
        palette: Option<&[[u8; 3]]>,
    ) -> io::Result<()> {
        // write grayscale palette
        if let Some(palette) = palette {
            for item in palette {
                // each color is written as BGRA, where A is always 0
                self.writer.write_all(&[item[2], item[1], item[0], 0])?;
            }
        } else {
            for val in 0u8..=255 {
                // each color is written as BGRA, where A is always 0 and since only grayscale is being written, B = G = R = index
                self.writer.write_all(&[val, val, val, 0])?;
            }
        }

        // write image data
        let x_stride = bytes_per_pixel;
        let y_stride = width * x_stride;
        for row in (0..height).rev() {
            // from the bottom up
            let row_start = row * 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(())
    }
}

impl<'a, W: Write> ImageEncoder for BmpEncoder<'a, W> {
    fn write_image(
        mut self,
        buf: &[u8],
        width: u32,
        height: u32,
        color_type: color::ColorType,
    ) -> ImageResult<()> {
        self.encode(buf, width, height, color_type)
    }
}

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, palette: Option<&[[u8; 3]]>) -> io::Result<(u32, u32, u32)> {
    let sizes = match c {
        color::ColorType::Rgb8 => (BITMAPINFOHEADER_SIZE, 3, 0),
        color::ColorType::Rgba8 => (BITMAPV4HEADER_SIZE, 4, 0),
        color::ColorType::L8 => (BITMAPINFOHEADER_SIZE, 1, palette.map(|p| p.len()).unwrap_or(256) as u32),
        color::ColorType::La8 => (BITMAPINFOHEADER_SIZE, 1, palette.map(|p| p.len()).unwrap_or(256) as u32),
        _ => {
            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 crate::color::ColorType;
    use crate::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");

        let mut buf = vec![0; decoder.total_bytes() as usize];
        decoder.read_image(&mut buf).expect("failed to decode");
        buf
    }

    #[test]
    fn round_trip_single_pixel_rgb() {
        let image = [255u8, 0, 0]; // single red pixel
        let decoded = round_trip_image(&image, 1, 1, ColorType::Rgb8);
        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::Rgb8);
        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::Rgba8);
        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::Rgb8);
    }

    #[test]
    fn round_trip_gray() {
        let image = [0u8, 1, 2]; // 3 pixels
        let decoded = round_trip_image(&image, 3, 1, ColorType::L8);
        // 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::La8);
        // 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>use std::mem;
use gapbuffer::GapBuffer;

pub struct Lines<'a> {
    pub buffer: &'a GapBuffer<u8>,
    pub tail: usize,
    pub head: usize,
}

impl<'a> Iterator for Lines<'a> {
    type Item = Vec<u8>;

    fn next(&mut self) -> Option<Vec<u8>> {
        if self.tail != self.head {
            let old_tail = self.tail;
            //update tail to either the first char after the next \n or to self.head
            self.tail = (old_tail..self.head).filter(|i| { *i + 1 == self.head
                                                           || self.buffer[*i] == b'\n' })
                                             .take(1)
                                             .next()
                                             .unwrap() + 1;
            Some((old_tail..if self.tail == self.head { self.tail - 1 } else { self.tail })
                .map( |i| self.buffer[i] ).collect())
        } else { None }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        //TODO: this is technically correct but a better estimate could be implemented
        (1, Some(self.head))
    }

}

/// Iterator traversing GapBuffer as chars
/// Can be made to traverse forwards or backwards with the methods
/// `rev()` `forward()` and `backward()`
pub struct Chars<'a> {
    pub buffer: &'a GapBuffer<u8>,
    pub idx: usize,
    pub forward: bool,
}

/// Iterator traversing GapBuffer as tuples of (buffer_index, char)
/// Can be made to traverse forwards or backwards with the methods
/// `rev()` `forward()` and `backward()`
pub struct CharIndices<'a> {
    iter: Chars<'a>
}

// helper macros/constants
// u8 -> char code is mostly copied from core::str::Chars
const CONT_MASK:   u8 = 0b0011_1111u8;
const TAG_CONT_U8: u8 = 0b1000_0000u8;

// Return the initial codepoint accumulator for the first byte.
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
// for width 3, and 3 bits for width 4
macro_rules! utf8_first_byte {
    ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32)
}

// return the value of $ch updated with continuation byte $byte
macro_rules! utf8_acc_cont_byte {
    ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & CONT_MASK) as u32)
}

macro_rules! utf8_is_cont_byte {
    ($byte:expr) => (($byte & !CONT_MASK) == TAG_CONT_U8)
}

impl<'a> Chars<'a> {
    pub fn reverse(mut self) -> Chars<'a> {
        self.forward = !self.forward;
        self
    }
    pub fn forward(mut self) -> Chars<'a> {
        self.forward = true;
        self
    }
    pub fn backward(mut self) -> Chars<'a> {
        self.forward = false;
        self
    }

    /// Return an iterator over (byte-index, char)
    pub fn indices(mut self) -> CharIndices<'a> {
        CharIndices {
            iter: self
        }
    }

    fn next_u8(&mut self) -> Option<u8> {
        let n = if self.idx < self.buffer.len() {
            Some(self.buffer[self.idx])
        } else { None };

        if self.forward {
            self.idx += 1;
        } else {
            self.idx -= 1;
        }
        n
    }
}

impl<'a> Iterator for Chars<'a> {
    type Item = char;

    #[inline]
    fn next(&mut self) -> Option<char> {
        if self.forward {
            // read u8s forwards into char (largely copied from core::str::Chars)
            let x = match self.next_u8() {
                None => return None,
                Some(next_byte) if next_byte < 128 => return Some(next_byte as char),
                Some(next_byte) => next_byte
            };

            // Multibyte case follows
            // Decode from a byte combination out of: [[[x y] z] w]
            let init = utf8_first_byte!(x, 2);
            let y = self.next_u8().unwrap_or(0);
            let mut ch = utf8_acc_cont_byte!(init, y);
            if x >= 0xE0 {
                // [[x y z] w] case
                // 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid
                let z = self.next_u8().unwrap_or(0);
                let y_z = utf8_acc_cont_byte!((y & CONT_MASK) as u32, z);
                ch = init << 12 | y_z;
                if x >= 0xF0 {
                    // [x y z w] case
                    // use only the lower 3 bits of `init`
                    let w = self.next_u8().unwrap_or(0);
                    ch = (init & 7) << 18 | utf8_acc_cont_byte!(y_z, w);
                }
            }

            // str invariant says `ch` is a valid Unicode Scalar Value
            return unsafe { Some(mem::transmute(ch)) };
        } else {
            // read u8s backwards into char (largely copied from core::str::Chars)
            let w = match self.next_u8() {
                None => return None,
                Some(back_byte) if back_byte < 128 => return Some(back_byte as char),
                Some(back_byte) => back_byte,
            };

            // Multibyte case follows
            // Decode from a byte combination out of: [x [y [z w]]]
            let mut ch;
            let z = self.next_u8().unwrap_or(0);
            ch = utf8_first_byte!(z, 2);
            if utf8_is_cont_byte!(z) {
                let y = self.next_u8().unwrap_or(0);
                ch = utf8_first_byte!(y, 3);
                if utf8_is_cont_byte!(y) {
                    let x = self.next_u8().unwrap_or(0);
                    ch = utf8_first_byte!(x, 4);
                    ch = utf8_acc_cont_byte!(ch, y);
                }
                ch = utf8_acc_cont_byte!(ch, z);
            }
            ch = utf8_acc_cont_byte!(ch, w);

            // str invariant says `ch` is a valid Unicode Scalar Value
            return unsafe { Some(mem::transmute(ch)) };
        }
    }
}

impl<'a> CharIndices<'a> {
    pub fn rev(mut self) -> CharIndices<'a> {
        self.iter.forward = !self.iter.forward;
        self
    }
    pub fn forward(mut self) -> CharIndices<'a> {
        self.iter.forward = true;
        self
    }
    pub fn backward(mut self) -> CharIndices<'a> {
        self.iter.forward = false;
        self
    }
}

impl<'a> Iterator for CharIndices<'a> {
    type Item = (usize, char);

    #[inline]
    fn next(&mut self) -> Option<(usize, char)> {
        if let Some(c) = self.iter.next() {
            Some((self.iter.idx, c))
        } else {
            None
        }
    }
}
<commit_msg>fixed warning about an unnecessary 'mut'<commit_after>use std::mem;
use gapbuffer::GapBuffer;

pub struct Lines<'a> {
    pub buffer: &'a GapBuffer<u8>,
    pub tail: usize,
    pub head: usize,
}

impl<'a> Iterator for Lines<'a> {
    type Item = Vec<u8>;

    fn next(&mut self) -> Option<Vec<u8>> {
        if self.tail != self.head {
            let old_tail = self.tail;
            //update tail to either the first char after the next \n or to self.head
            self.tail = (old_tail..self.head).filter(|i| { *i + 1 == self.head
                                                           || self.buffer[*i] == b'\n' })
                                             .take(1)
                                             .next()
                                             .unwrap() + 1;
            Some((old_tail..if self.tail == self.head { self.tail - 1 } else { self.tail })
                .map( |i| self.buffer[i] ).collect())
        } else { None }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        //TODO: this is technically correct but a better estimate could be implemented
        (1, Some(self.head))
    }

}

/// Iterator traversing GapBuffer as chars
/// Can be made to traverse forwards or backwards with the methods
/// `rev()` `forward()` and `backward()`
pub struct Chars<'a> {
    pub buffer: &'a GapBuffer<u8>,
    pub idx: usize,
    pub forward: bool,
}

/// Iterator traversing GapBuffer as tuples of (buffer_index, char)
/// Can be made to traverse forwards or backwards with the methods
/// `rev()` `forward()` and `backward()`
pub struct CharIndices<'a> {
    iter: Chars<'a>
}

// helper macros/constants
// u8 -> char code is mostly copied from core::str::Chars
const CONT_MASK:   u8 = 0b0011_1111u8;
const TAG_CONT_U8: u8 = 0b1000_0000u8;

// Return the initial codepoint accumulator for the first byte.
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
// for width 3, and 3 bits for width 4
macro_rules! utf8_first_byte {
    ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32)
}

// return the value of $ch updated with continuation byte $byte
macro_rules! utf8_acc_cont_byte {
    ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & CONT_MASK) as u32)
}

macro_rules! utf8_is_cont_byte {
    ($byte:expr) => (($byte & !CONT_MASK) == TAG_CONT_U8)
}

impl<'a> Chars<'a> {
    pub fn reverse(mut self) -> Chars<'a> {
        self.forward = !self.forward;
        self
    }
    pub fn forward(mut self) -> Chars<'a> {
        self.forward = true;
        self
    }
    pub fn backward(mut self) -> Chars<'a> {
        self.forward = false;
        self
    }

    /// Return an iterator over (byte-index, char)
    pub fn indices(self) -> CharIndices<'a> {
        CharIndices {
            iter: self
        }
    }

    fn next_u8(&mut self) -> Option<u8> {
        let n = if self.idx < self.buffer.len() {
            Some(self.buffer[self.idx])
        } else { None };

        if self.forward {
            self.idx += 1;
        } else {
            self.idx -= 1;
        }
        n
    }
}

impl<'a> Iterator for Chars<'a> {
    type Item = char;

    #[inline]
    fn next(&mut self) -> Option<char> {
        if self.forward {
            // read u8s forwards into char (largely copied from core::str::Chars)
            let x = match self.next_u8() {
                None => return None,
                Some(next_byte) if next_byte < 128 => return Some(next_byte as char),
                Some(next_byte) => next_byte
            };

            // Multibyte case follows
            // Decode from a byte combination out of: [[[x y] z] w]
            let init = utf8_first_byte!(x, 2);
            let y = self.next_u8().unwrap_or(0);
            let mut ch = utf8_acc_cont_byte!(init, y);
            if x >= 0xE0 {
                // [[x y z] w] case
                // 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid
                let z = self.next_u8().unwrap_or(0);
                let y_z = utf8_acc_cont_byte!((y & CONT_MASK) as u32, z);
                ch = init << 12 | y_z;
                if x >= 0xF0 {
                    // [x y z w] case
                    // use only the lower 3 bits of `init`
                    let w = self.next_u8().unwrap_or(0);
                    ch = (init & 7) << 18 | utf8_acc_cont_byte!(y_z, w);
                }
            }

            // str invariant says `ch` is a valid Unicode Scalar Value
            return unsafe { Some(mem::transmute(ch)) };
        } else {
            // read u8s backwards into char (largely copied from core::str::Chars)
            let w = match self.next_u8() {
                None => return None,
                Some(back_byte) if back_byte < 128 => return Some(back_byte as char),
                Some(back_byte) => back_byte,
            };

            // Multibyte case follows
            // Decode from a byte combination out of: [x [y [z w]]]
            let mut ch;
            let z = self.next_u8().unwrap_or(0);
            ch = utf8_first_byte!(z, 2);
            if utf8_is_cont_byte!(z) {
                let y = self.next_u8().unwrap_or(0);
                ch = utf8_first_byte!(y, 3);
                if utf8_is_cont_byte!(y) {
                    let x = self.next_u8().unwrap_or(0);
                    ch = utf8_first_byte!(x, 4);
                    ch = utf8_acc_cont_byte!(ch, y);
                }
                ch = utf8_acc_cont_byte!(ch, z);
            }
            ch = utf8_acc_cont_byte!(ch, w);

            // str invariant says `ch` is a valid Unicode Scalar Value
            return unsafe { Some(mem::transmute(ch)) };
        }
    }
}

impl<'a> CharIndices<'a> {
    pub fn rev(mut self) -> CharIndices<'a> {
        self.iter.forward = !self.iter.forward;
        self
    }
    pub fn forward(mut self) -> CharIndices<'a> {
        self.iter.forward = true;
        self
    }
    pub fn backward(mut self) -> CharIndices<'a> {
        self.iter.forward = false;
        self
    }
}

impl<'a> Iterator for CharIndices<'a> {
    type Item = (usize, char);

    #[inline]
    fn next(&mut self) -> Option<(usize, char)> {
        if let Some(c) = self.iter.next() {
            Some((self.iter.idx, c))
        } else {
            None
        }
    }
}
<|endoftext|>


<commit_before>use super::Orthogonalizer;
use crate::types::*;
use ndarray::*;

pub struct Arnoldi<S, F, Ortho>
where
    S: DataMut,
    F: Fn(&mut ArrayBase<S, Ix1>),
    Ortho: Orthogonalizer,
{
    a: F,
    v: ArrayBase<S, Ix1>,
    ortho: Ortho,
}

impl<S, F, Ortho> Arnoldi<S, F, Ortho>
where
    S: DataMut,
    F: Fn(&mut ArrayBase<S, Ix1>),
    Ortho: Orthogonalizer,
{
    pub fn new(a: F, v: ArrayBase<S, Ix1>, ortho: Ortho) -> Self {
        Arnoldi { a, v, ortho }
    }
}

impl<A, S, F, Ortho> Iterator for Arnoldi<S, F, Ortho>
where
    A: Scalar,
    S: DataMut<Elem = A>,
    F: Fn(&mut ArrayBase<S, Ix1>),
    Ortho: Orthogonalizer<Elem = A>,
{
    type Item = (Array2<A>, Array2<A>);

    fn next(&mut self) -> Option<Self::Item> {
        (self.a)(&mut self.v);
        let coef = self.ortho.decompose(&mut self.v);
        unimplemented!()
    }
}
<commit_msg>Use div_append<commit_after>use super::*;

pub struct Arnoldi<A, S, F, Ortho>
where
    A: Scalar,
    S: DataMut<Elem = A>,
    F: Fn(&mut ArrayBase<S, Ix1>),
    Ortho: Orthogonalizer<Elem = A>,
{
    a: F,
    v: ArrayBase<S, Ix1>,
    ortho: Ortho,
}

impl<A, S, F, Ortho> Arnoldi<A, S, F, Ortho>
where
    A: Scalar,
    S: DataMut<Elem = A>,
    F: Fn(&mut ArrayBase<S, Ix1>),
    Ortho: Orthogonalizer<Elem = A>,
{
    pub fn new(a: F, v: ArrayBase<S, Ix1>, ortho: Ortho) -> Self {
        Arnoldi { a, v, ortho }
    }
}

impl<A, S, F, Ortho> Iterator for Arnoldi<A, S, F, Ortho>
where
    A: Scalar,
    S: DataMut<Elem = A> + DataClone,
    F: Fn(&mut ArrayBase<S, Ix1>),
    Ortho: Orthogonalizer<Elem = A>,
{
    type Item = Array1<A>;

    fn next(&mut self) -> Option<Self::Item> {
        (self.a)(&mut self.v);
        match self.ortho.div_append(&mut self.v) {
            AppendResult::Added(coef) => {
                let norm = coef[coef.len() - 1].abs();
                azip!(mut a(&mut self.v) in { *a = a.div_real(norm) });
                Some(coef)
            }
            AppendResult::Dependent(_) => None,
        }
    }
}
<|endoftext|>


<commit_before>use collections::hashmap::HashMap;
use std::vec::FromVec;
use core::*;
use types::function_type_;
use renamer::NameSupply;

pub type TypeAndStr = Id;

pub fn do_lambda_lift(module: Module<TypeAndStr>) -> Module<Id> {
    lift_lambdas(abstract_module(module))
}

struct FreeVariables {
    name_supply: NameSupply
}

fn each_pattern_variables(pattern: &Pattern<Id>, f: &mut |&Name|) {
    match *pattern {
        IdentifierPattern(ref ident) => (*f)(&ident.name),
        ConstructorPattern(_, ref patterns) => {
            for p in patterns.iter() {
                (*f)(&p.name);
            }
        }
        _ => ()
    }
}

impl FreeVariables {

//Walks through an expression and notes all the free variables and for each lambda, adds the
//free variables to its arguments and performs an immediate application
//@variables All the local variables in scope, values are how many of the name there exists
//@free_vars The free variables for the returned expression
fn free_variables(&mut self, variables: &mut HashMap<Name, int>, free_vars: &mut HashMap<Name, TypeAndStr>, expr: Expr<TypeAndStr>) -> Expr<TypeAndStr> {
    match expr {
        Identifier(i) => {
            //If the identifier is a local, add it to the free variables
            if variables.find(&i.name).map(|x| *x > 0).unwrap_or(false) {
                free_vars.insert(i.name.clone(), i.clone());
            }
            Identifier(i)
        }
        Apply(func, arg) => {
            let f = box self.free_variables(variables, free_vars, *func);
            let a = box self.free_variables(variables, free_vars, *arg);
            Apply(f, a)
        }
        Lambda(arg, body) => {
            variables.insert_or_update_with(arg.name.clone(), 1, |_, v| *v += 1);
            let b = self.free_variables(variables, free_vars, *body);
            *variables.get_mut(&arg.name) -= 1;
            free_vars.remove(&arg.name);//arg was not actually a free variable
            Lambda(arg, box b)
        }
        Let(mut bindings, expr) => {
            for bind in bindings.iter() {
                variables.insert_or_update_with(bind.name.name.clone(), 1, |_, v| *v += 1);
            }
            let mut free_vars2 = HashMap::new();
            for bind in bindings.mut_iter() {
                free_vars2.clear();
                update(&mut bind.expression, |bind_expr| self.free_variables(variables, &mut free_vars2, bind_expr));
                //free_vars2 is the free variables for this binding
                for (k, v) in free_vars2.iter() {
                    free_vars.insert(k.clone(), v.clone());
                }
                update(&mut bind.expression, |e| self.abstract(&free_vars2, e));
            }
            let e = box self.free_variables(variables, free_vars, *expr);
            for bind in bindings.iter() {
                *variables.get_mut(&bind.name.name) -= 1;
                free_vars.remove(&bind.name.name);
            }
            Let(bindings, e)
        }
        Case(expr, mut alts) => {
            let e = self.free_variables(variables, free_vars, *expr);
            for alt in alts.mut_iter() {
                each_pattern_variables(&alt.pattern, &mut |name| {
                    variables.insert_or_update_with(name.clone(), 1, |_, v| *v += 1);
                });
                update(&mut alt.expression, |expression| self.free_variables(variables, free_vars, expression));
                each_pattern_variables(&alt.pattern, &mut |name| {
                    *variables.get_mut(name) -= 1;
                    free_vars.remove(name);//arg was not actually a free variable
                });
            }
            Case(box e, alts)
        }
        e => e
    }
}
///Adds the free variables, if any, to the expression
fn abstract(&mut self, free_vars: &HashMap<Name, TypeAndStr>, input_expr: Expr<TypeAndStr>) -> Expr<TypeAndStr> {
    if free_vars.len() == 0 {
        input_expr
    }
    else {
        let mut e = {
            let mut rhs = input_expr;
            let mut typ = rhs.get_type().clone();
            for (_, var) in free_vars.iter() {
                rhs = Lambda(var.clone(), box rhs);
                typ = function_type_(var.get_type().clone(), typ);
            }
            let id = Id::new(self.name_supply.from_str("#sc"), typ.clone(), box []);
            let bind = Binding {
                name: id.clone(),
                expression: rhs
            };
            Let(~[bind], box Identifier(id))
        };
        for (_, var) in free_vars.iter() {
            e = Apply(box e, box Identifier(var.clone()));
        }
        e
    }
}
}

///Lifts all lambdas in the expression to the top level of the program
fn lift_lambdas_expr<T>(expr: Expr<T>, out_lambdas: &mut Vec<Binding<T>>) -> Expr<T> {
    match expr {
        Apply(func, arg) => Apply(box lift_lambdas_expr(*func, out_lambdas), box lift_lambdas_expr(*arg, out_lambdas)),
        Lambda(arg, body) => Lambda(arg, box lift_lambdas_expr(*body, out_lambdas)),
        Let(bindings, expr) => {
            let mut new_binds = Vec::new();
            for mut bind in bindings.move_iter() {
                let is_lambda = match bind.expression {
                    Lambda(..) => true,
                    _ => false
                };
                update(&mut bind.expression, |expression| lift_lambdas_expr(expression, out_lambdas));
                if is_lambda {
                    out_lambdas.push(bind);
                }
                else {
                    new_binds.push(bind);
                }
            }
            if new_binds.len() == 0 {
                lift_lambdas_expr(*expr, out_lambdas)
            }
            else {
                Let(FromVec::from_vec(new_binds), box lift_lambdas_expr(*expr, out_lambdas))
            }
        }
        Case(expr, mut alts) => {
            for alt in alts.mut_iter() {
                update(&mut alt.expression, |expression| lift_lambdas_expr(expression, out_lambdas));
            }
            Case(box lift_lambdas_expr(*expr, out_lambdas), alts)
        }
        _ => expr
    }
}
pub fn lift_lambdas<T>(mut module: Module<T>) -> Module<T> {
    update(&mut module.bindings, |bindings| {
        let mut new_bindings : Vec<Binding<T>> = Vec::new();
        let mut bindings2 : Vec<Binding<T>> = bindings.move_iter()
            .map(|mut bind| {
                update(&mut bind.expression, |expression| lift_lambdas_expr(expression, &mut new_bindings));
                bind
            }).collect();
        bindings2.extend(new_bindings.move_iter());
        FromVec::from_vec(bindings2)
    });
    module
}

///TODO Not safe if the task fails since uninitalized memory will be freed
fn update<T>(x: &mut T, f: |T| -> T) {
    use std::mem::{swap, forget, uninitialized};
    let mut temp = unsafe { uninitialized() };
    swap(x, &mut temp);
    temp = f(temp);
    swap(x, &mut temp);
    unsafe { forget(temp) };
}

///Takes a module and adds all variables which are captured into a lambda to its arguments
pub fn abstract_module(module: Module<TypeAndStr>) -> Module<TypeAndStr> {
    use core::result::*;
    impl Visitor<TypeAndStr> for FreeVariables {
        fn visit_binding(&mut self, bind: Binding<TypeAndStr>) -> Binding<TypeAndStr> {
            let Binding { name: name, expression: bind_expr } = bind;
            let mut variables = HashMap::new();
            let mut free_vars = HashMap::new();
            let e = self.free_variables(&mut variables, &mut free_vars, bind_expr);
            Binding { name: name, expression: e }
        }
    }
    let mut this = FreeVariables { name_supply: NameSupply::new() };
    this.visit_module(module)
}

#[cfg(test)]
mod tests {
    use test::Bencher;
    use interner::*;
    use lambda_lift::*;
    use collections::hashmap::HashSet;
    use parser::Parser;
    use core::*;
    use core::translate::translate_module;
    use renamer::rename_module;
    use typecheck::TypeEnvironment;

    struct CheckUniques {
        found: HashSet<Id>
    }

    impl Visitor<Id> for CheckUniques {
        fn visit_binding(&mut self, bind: &Binding<Id>) {
            assert!(self.found.insert(bind.name.clone()));
            self.visit_expr(&bind.expression);
        }
        fn visit_expr(&mut self, expr: &Expr<Id>) {
            match expr {
                &Lambda(ref i, _) => {
                    assert!(self.found.insert(i.clone()));
                }
                _ => ()
            }
            walk_expr(self, expr)
        }
    }

    #[test]
    fn all_uniques() {
        let mut visitor = CheckUniques { found: HashSet::new() };
        let mut parser = Parser::new(
r"add x y = 2
test = 3.14
test2 x =
    let
        test = 2
        f x =
            let g y = add x (f y)
            in add x test
    in f x".chars());
        let module = translate_module(rename_module(parser.module()));
        (&mut visitor as &mut Visitor<Id>).visit_module(&module);
    }

    fn check_args(expr: &Expr<Id>, args: &[InternedStr]) -> bool {
        match expr {
            &Lambda(ref arg, ref body) => arg.name.name == args[0] && check_args(*body, args.slice_from(1)),
            _ => args.len() == 0
        }
    }

    struct CheckAbstract {
        count: int
    }

    fn get_let<'a>(expr: &'a Expr<Id>, args: &mut Vec<InternedStr>) -> &'a Expr<Id> {
        match expr {
            &Apply(ref f, ref arg) => {
                let a: &Expr<Id> = *arg;
                match a {
                    &Identifier(ref i) => args.push(i.name.name),
                    _ => fail!("Expected identifier as argument")
                }
                get_let(*f, args)
            }
            _ => expr
        }
    }

    impl Visitor<Id> for CheckAbstract {
        fn visit_binding(&mut self, bind: &Binding<Id>) {
            if intern("f") == bind.name.name.name {
                let mut args = Vec::new();
                match get_let(&bind.expression, &mut args) {
                    &Let(ref binds, ref body) => {
                        //Push the argument of the function itself
                        args.push(intern("x"));
                        assert!(check_args(&binds[0].expression, args.as_slice()));
                        assert_eq!(Identifier(binds[0].name.clone()), **body);
                    }
                    _ => assert!(false, "Expected Let, found {}", bind.expression)
                }
                self.count += 1;
            }
            else if intern("g") == bind.name.name.name {
                let mut args = Vec::new();
                match get_let(&bind.expression, &mut args) {
                    &Let(ref binds, ref body) => {
                        args.push(intern("y"));
                        assert!(check_args(&binds[0].expression, args.as_slice()));
                        assert_eq!(Identifier(binds[0].name.clone()), **body);
                    }
                    _ => assert!(false, "Expected Let")
                }
                self.count += 1;
            }
            self.visit_expr(&bind.expression);
        }
    }

    #[test]
    fn all_free_vars() {
        let mut visitor = CheckAbstract { count: 0 };
        let mut parser = Parser::new(
r"add x y = 2
test = 3.14
test2 x =
    let
        test = 2
        f x =
            let g y = add x (f y)
            in add x test
    in f x".chars());
	let mut module = rename_module(parser.module());
	TypeEnvironment::new().typecheck_module(&mut module);
        let m = translate_module(module);
        let module = abstract_module(m);
        (&mut visitor as &mut Visitor<Id>).visit_module(&module);
        assert_eq!(visitor.count, 2);
    }

    struct NoLambdas;

    impl <T> Visitor<T> for NoLambdas {
        fn visit_expr(&mut self, expr: &Expr<T>) {
            match expr {
                &Lambda(..) => assert!(false, "Found lambda in expression"),
                _ => ()
            }
            walk_expr(self, expr);
        }
    }
    #[test]
    fn no_local_lambdas() {
        fn skip_lambdas<'a, T>(expr: &'a Expr<T>) -> &'a Expr<T> {
            match expr {
                &Lambda(_, ref body) => skip_lambdas(*body),
                _ => expr
            }
        }

        let mut visitor = NoLambdas;
        let mut parser = Parser::new(
r"add x y = 2
test = 3.14
test2 x =
    let
        test = 2
        f x =
            let g y = add x (f y)
            in add x test
    in f x".chars());
        let m = translate_module(rename_module(parser.module()));
        let module = lift_lambdas(m);
        for bind in module.bindings.iter() {
            (&mut visitor as &mut Visitor<TypeAndStr>).visit_expr(skip_lambdas(&bind.expression));
        }
    }

    #[bench]
    fn bench(b: &mut Bencher) {
        use std::io::File;
        use typecheck::test::do_typecheck;

        let path = &Path::new("Prelude.hs");
        let contents = File::open(path).read_to_str().unwrap();
        let module = do_typecheck(contents.as_slice());
        b.iter(|| {
            do_lambda_lift(translate_module(module.clone()))
        });
    }
}
<commit_msg>Fix lambda lifting not being done on class and instance bindings<commit_after>use collections::hashmap::HashMap;
use std::vec::FromVec;
use core::*;
use types::function_type_;
use renamer::NameSupply;

pub type TypeAndStr = Id;

pub fn do_lambda_lift(module: Module<TypeAndStr>) -> Module<Id> {
    lift_lambdas(abstract_module(module))
}

struct FreeVariables {
    name_supply: NameSupply
}

fn each_pattern_variables(pattern: &Pattern<Id>, f: &mut |&Name|) {
    match *pattern {
        IdentifierPattern(ref ident) => (*f)(&ident.name),
        ConstructorPattern(_, ref patterns) => {
            for p in patterns.iter() {
                (*f)(&p.name);
            }
        }
        _ => ()
    }
}

impl FreeVariables {

//Walks through an expression and notes all the free variables and for each lambda, adds the
//free variables to its arguments and performs an immediate application
//@variables All the local variables in scope, values are how many of the name there exists
//@free_vars The free variables for the returned expression
fn free_variables(&mut self, variables: &mut HashMap<Name, int>, free_vars: &mut HashMap<Name, TypeAndStr>, expr: Expr<TypeAndStr>) -> Expr<TypeAndStr> {
    match expr {
        Identifier(i) => {
            //If the identifier is a local, add it to the free variables
            if variables.find(&i.name).map(|x| *x > 0).unwrap_or(false) {
                free_vars.insert(i.name.clone(), i.clone());
            }
            Identifier(i)
        }
        Apply(func, arg) => {
            let f = box self.free_variables(variables, free_vars, *func);
            let a = box self.free_variables(variables, free_vars, *arg);
            Apply(f, a)
        }
        Lambda(arg, body) => {
            variables.insert_or_update_with(arg.name.clone(), 1, |_, v| *v += 1);
            let b = self.free_variables(variables, free_vars, *body);
            *variables.get_mut(&arg.name) -= 1;
            free_vars.remove(&arg.name);//arg was not actually a free variable
            Lambda(arg, box b)
        }
        Let(mut bindings, expr) => {
            for bind in bindings.iter() {
                variables.insert_or_update_with(bind.name.name.clone(), 1, |_, v| *v += 1);
            }
            let mut free_vars2 = HashMap::new();
            for bind in bindings.mut_iter() {
                free_vars2.clear();
                update(&mut bind.expression, |bind_expr| self.free_variables(variables, &mut free_vars2, bind_expr));
                //free_vars2 is the free variables for this binding
                for (k, v) in free_vars2.iter() {
                    free_vars.insert(k.clone(), v.clone());
                }
                update(&mut bind.expression, |e| self.abstract(&free_vars2, e));
            }
            let e = box self.free_variables(variables, free_vars, *expr);
            for bind in bindings.iter() {
                *variables.get_mut(&bind.name.name) -= 1;
                free_vars.remove(&bind.name.name);
            }
            Let(bindings, e)
        }
        Case(expr, mut alts) => {
            let e = self.free_variables(variables, free_vars, *expr);
            for alt in alts.mut_iter() {
                each_pattern_variables(&alt.pattern, &mut |name| {
                    variables.insert_or_update_with(name.clone(), 1, |_, v| *v += 1);
                });
                update(&mut alt.expression, |expression| self.free_variables(variables, free_vars, expression));
                each_pattern_variables(&alt.pattern, &mut |name| {
                    *variables.get_mut(name) -= 1;
                    free_vars.remove(name);//arg was not actually a free variable
                });
            }
            Case(box e, alts)
        }
        e => e
    }
}
///Adds the free variables, if any, to the expression
fn abstract(&mut self, free_vars: &HashMap<Name, TypeAndStr>, input_expr: Expr<TypeAndStr>) -> Expr<TypeAndStr> {
    if free_vars.len() == 0 {
        input_expr
    }
    else {
        let mut e = {
            let mut rhs = input_expr;
            let mut typ = rhs.get_type().clone();
            for (_, var) in free_vars.iter() {
                rhs = Lambda(var.clone(), box rhs);
                typ = function_type_(var.get_type().clone(), typ);
            }
            let id = Id::new(self.name_supply.from_str("#sc"), typ.clone(), box []);
            let bind = Binding {
                name: id.clone(),
                expression: rhs
            };
            Let(~[bind], box Identifier(id))
        };
        for (_, var) in free_vars.iter() {
            e = Apply(box e, box Identifier(var.clone()));
        }
        e
    }
}
}

///Lifts all lambdas in the expression to the top level of the program
fn lift_lambdas_expr<T>(expr: Expr<T>, out_lambdas: &mut Vec<Binding<T>>) -> Expr<T> {
    match expr {
        Apply(func, arg) => Apply(box lift_lambdas_expr(*func, out_lambdas), box lift_lambdas_expr(*arg, out_lambdas)),
        Lambda(arg, body) => Lambda(arg, box lift_lambdas_expr(*body, out_lambdas)),
        Let(bindings, expr) => {
            let mut new_binds = Vec::new();
            for mut bind in bindings.move_iter() {
                let is_lambda = match bind.expression {
                    Lambda(..) => true,
                    _ => false
                };
                update(&mut bind.expression, |expression| lift_lambdas_expr(expression, out_lambdas));
                if is_lambda {
                    out_lambdas.push(bind);
                }
                else {
                    new_binds.push(bind);
                }
            }
            if new_binds.len() == 0 {
                lift_lambdas_expr(*expr, out_lambdas)
            }
            else {
                Let(FromVec::from_vec(new_binds), box lift_lambdas_expr(*expr, out_lambdas))
            }
        }
        Case(expr, mut alts) => {
            for alt in alts.mut_iter() {
                update(&mut alt.expression, |expression| lift_lambdas_expr(expression, out_lambdas));
            }
            Case(box lift_lambdas_expr(*expr, out_lambdas), alts)
        }
        _ => expr
    }
}
pub fn lift_lambdas<T>(mut module: Module<T>) -> Module<T> {
    let mut new_bindings : Vec<Binding<T>> = Vec::new();
    {
        let mut bind_iter = module.bindings.mut_iter()
            .chain(module.classes.mut_iter().flat_map(|c| c.bindings.mut_iter()))
            .chain(module.instances.mut_iter().flat_map(|i| i.bindings.mut_iter()));

        for bind in bind_iter {
            update(&mut bind.expression, |expr| lift_lambdas_expr(expr, &mut new_bindings));
        }
    }
    let mut temp = box [];
    ::std::mem::swap(&mut temp, &mut module.bindings);
    let vec : Vec<Binding<T>> = temp.move_iter()
        .chain(new_bindings.move_iter())
        .collect();
    module.bindings = FromVec::from_vec(vec);
    module
}

///TODO Not safe if the task fails since uninitalized memory will be freed
fn update<T>(x: &mut T, f: |T| -> T) {
    use std::mem::{swap, forget, uninitialized};
    let mut temp = unsafe { uninitialized() };
    swap(x, &mut temp);
    temp = f(temp);
    swap(x, &mut temp);
    unsafe { forget(temp) };
}

///Takes a module and adds all variables which are captured into a lambda to its arguments
pub fn abstract_module(module: Module<TypeAndStr>) -> Module<TypeAndStr> {
    use core::result::*;
    impl Visitor<TypeAndStr> for FreeVariables {
        fn visit_binding(&mut self, bind: Binding<TypeAndStr>) -> Binding<TypeAndStr> {
            let Binding { name: name, expression: bind_expr } = bind;
            let mut variables = HashMap::new();
            let mut free_vars = HashMap::new();
            let e = self.free_variables(&mut variables, &mut free_vars, bind_expr);
            Binding { name: name, expression: e }
        }
    }
    let mut this = FreeVariables { name_supply: NameSupply::new() };
    this.visit_module(module)
}

#[cfg(test)]
mod tests {
    use test::Bencher;
    use interner::*;
    use lambda_lift::*;
    use collections::hashmap::HashSet;
    use parser::Parser;
    use core::*;
    use core::translate::translate_module;
    use renamer::rename_module;
    use typecheck::TypeEnvironment;

    struct CheckUniques {
        found: HashSet<Id>
    }

    impl Visitor<Id> for CheckUniques {
        fn visit_binding(&mut self, bind: &Binding<Id>) {
            assert!(self.found.insert(bind.name.clone()));
            self.visit_expr(&bind.expression);
        }
        fn visit_expr(&mut self, expr: &Expr<Id>) {
            match expr {
                &Lambda(ref i, _) => {
                    assert!(self.found.insert(i.clone()));
                }
                _ => ()
            }
            walk_expr(self, expr)
        }
    }

    #[test]
    fn all_uniques() {
        let mut visitor = CheckUniques { found: HashSet::new() };
        let mut parser = Parser::new(
r"add x y = 2
test = 3.14
test2 x =
    let
        test = 2
        f x =
            let g y = add x (f y)
            in add x test
    in f x".chars());
        let module = translate_module(rename_module(parser.module()));
        (&mut visitor as &mut Visitor<Id>).visit_module(&module);
    }

    fn check_args(expr: &Expr<Id>, args: &[InternedStr]) -> bool {
        match expr {
            &Lambda(ref arg, ref body) => arg.name.name == args[0] && check_args(*body, args.slice_from(1)),
            _ => args.len() == 0
        }
    }

    struct CheckAbstract {
        count: int
    }

    fn get_let<'a>(expr: &'a Expr<Id>, args: &mut Vec<InternedStr>) -> &'a Expr<Id> {
        match expr {
            &Apply(ref f, ref arg) => {
                let a: &Expr<Id> = *arg;
                match a {
                    &Identifier(ref i) => args.push(i.name.name),
                    _ => fail!("Expected identifier as argument")
                }
                get_let(*f, args)
            }
            _ => expr
        }
    }

    impl Visitor<Id> for CheckAbstract {
        fn visit_binding(&mut self, bind: &Binding<Id>) {
            if intern("f") == bind.name.name.name {
                let mut args = Vec::new();
                match get_let(&bind.expression, &mut args) {
                    &Let(ref binds, ref body) => {
                        //Push the argument of the function itself
                        args.push(intern("x"));
                        assert!(check_args(&binds[0].expression, args.as_slice()));
                        assert_eq!(Identifier(binds[0].name.clone()), **body);
                    }
                    _ => assert!(false, "Expected Let, found {}", bind.expression)
                }
                self.count += 1;
            }
            else if intern("g") == bind.name.name.name {
                let mut args = Vec::new();
                match get_let(&bind.expression, &mut args) {
                    &Let(ref binds, ref body) => {
                        args.push(intern("y"));
                        assert!(check_args(&binds[0].expression, args.as_slice()));
                        assert_eq!(Identifier(binds[0].name.clone()), **body);
                    }
                    _ => assert!(false, "Expected Let")
                }
                self.count += 1;
            }
            self.visit_expr(&bind.expression);
        }
    }

    #[test]
    fn all_free_vars() {
        let mut visitor = CheckAbstract { count: 0 };
        let mut parser = Parser::new(
r"add x y = 2
test = 3.14
test2 x =
    let
        test = 2
        f x =
            let g y = add x (f y)
            in add x test
    in f x".chars());
	let mut module = rename_module(parser.module());
	TypeEnvironment::new().typecheck_module(&mut module);
        let m = translate_module(module);
        let module = abstract_module(m);
        (&mut visitor as &mut Visitor<Id>).visit_module(&module);
        assert_eq!(visitor.count, 2);
    }

    struct NoLambdas;

    impl <T> Visitor<T> for NoLambdas {
        fn visit_expr(&mut self, expr: &Expr<T>) {
            match expr {
                &Lambda(..) => assert!(false, "Found lambda in expression"),
                _ => ()
            }
            walk_expr(self, expr);
        }
    }
    #[test]
    fn no_local_lambdas() {
        fn skip_lambdas<'a, T>(expr: &'a Expr<T>) -> &'a Expr<T> {
            match expr {
                &Lambda(_, ref body) => skip_lambdas(*body),
                _ => expr
            }
        }

        let mut visitor = NoLambdas;
        let mut parser = Parser::new(
r"add x y = 2
test = 3.14
test2 x =
    let
        test = 2
        f x =
            let g y = add x (f y)
            in add x test
    in f x".chars());
        let m = translate_module(rename_module(parser.module()));
        let module = lift_lambdas(m);
        for bind in module.bindings.iter() {
            (&mut visitor as &mut Visitor<TypeAndStr>).visit_expr(skip_lambdas(&bind.expression));
        }
    }

    #[bench]
    fn bench(b: &mut Bencher) {
        use std::io::File;
        use typecheck::test::do_typecheck;

        let path = &Path::new("Prelude.hs");
        let contents = File::open(path).read_to_str().unwrap();
        let module = do_typecheck(contents.as_slice());
        b.iter(|| {
            do_lambda_lift(translate_module(module.clone()))
        });
    }
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]

/**
This macro provides a way to initialise any container for which there is a FromIterator implementation.  It allows for both sequence and map syntax to be used, as well as inline type ascription for the result.

For example:

```
# #![feature(phase)]
# #[phase(plugin)] extern crate grabbag_macros;
# use std::collections::{HashMap, VecMap};
# fn main() {
// Initialise an empty collection.
let a: Vec<int> = collect![];
let b: HashMap<String, bool> = collect![];

// Initialise a sequence.
let c: String = collect!['a', 'b', 'c'];

// Initialise a sequence with a type constraint.
let d = collect![into Vec<_>: 0i, 1, 2];

// Initialise a map collection.
let e: VecMap<&str> = collect![1:"one", 2:"two", 3:"many", 4:"lots"];

// Initialise a map with a type constraint.
let f: HashMap<_, u8> = collect![into HashMap<int, _>: 42: 0, -11: 2];
# }
```
*/
#[macro_export]
macro_rules! collect {
    // Short-hands for initialising an empty collection.
    [] => { collect![into _] };
    [into $col_ty:ty] => { collect![into $col_ty:] };
    [into $col_ty:ty:] => {
        {
            let col: $col_ty = ::std::iter::FromIterator::from_iter(None.into_iter());
            col
        }
    };

    // Initialise a sequence with a constrained container type.
    [into $col_ty:ty: $($vs:expr),+] => {
        {
            // This is inefficient.  Ideally, we'd do all this on the stack, with the target collection being the only thing to allocate.
            let vs = vec![$($vs),+];
            let col: $col_ty = ::std::iter::FromIterator::from_iter(vs.into_iter());
            col
        }
    };

    // Initialise a sequence with a fully inferred contained type.
    [$($vs:expr),+] => { collect![into _: $($vs),+] };

    // Initialise a map with a constrained container type.
    [into $col_ty:ty: $($ks:expr: $vs:expr),+] => {
        // Maps implement FromIterator by taking tuples, so we just need to rewrite each `a:b` as `(a,b)`.
        collect![into $col_ty: $(($ks, $vs)),+]
    };

    // Initialise a map with a fully inferred contained type.
    [$($ks:expr: $vs:expr),+] => { collect![into _: $($ks: $vs),+] };
}

/**
Counts the number of comma-delimited expressions passed to it.  The result is a compile-time evaluable expression, suitable for use as a static array size, or the value of a `const`.

Example:

```
# #![feature(phase)]
# #[phase(plugin)] extern crate grabbag_macros;
# fn main() {
const COUNT: uint = count_exprs!(a, 5+1, "hi there!".into_string());
assert_eq!(COUNT, 3);
# }
```
*/
#[macro_export]
macro_rules! count_exprs {
    () => { 0 };
    ($e:expr $(, $es:expr)*) => { 1 + count_exprs!($($es),*) };
}
<commit_msg>Added sequence! and recurrence! macros.<commit_after>#![feature(macro_rules)]

/**
This macro provides a way to initialise any container for which there is a FromIterator implementation.  It allows for both sequence and map syntax to be used, as well as inline type ascription for the result.

For example:

```
# #![feature(phase)]
# #[phase(plugin)] extern crate grabbag_macros;
# use std::collections::{HashMap, VecMap};
# fn main() {
// Initialise an empty collection.
let a: Vec<int> = collect![];
let b: HashMap<String, bool> = collect![];

// Initialise a sequence.
let c: String = collect!['a', 'b', 'c'];

// Initialise a sequence with a type constraint.
let d = collect![into Vec<_>: 0i, 1, 2];

// Initialise a map collection.
let e: VecMap<&str> = collect![1:"one", 2:"two", 3:"many", 4:"lots"];

// Initialise a map with a type constraint.
let f: HashMap<_, u8> = collect![into HashMap<int, _>: 42: 0, -11: 2];
# }
```
*/
#[macro_export]
macro_rules! collect {
    // Short-hands for initialising an empty collection.
    [] => { collect![into _] };
    [into $col_ty:ty] => { collect![into $col_ty:] };
    [into $col_ty:ty:] => {
        {
            let col: $col_ty = ::std::iter::FromIterator::from_iter(None.into_iter());
            col
        }
    };

    // Initialise a sequence with a constrained container type.
    [into $col_ty:ty: $($vs:expr),+] => {
        {
            // This is inefficient.  Ideally, we'd do all this on the stack, with the target collection being the only thing to allocate.
            let vs = vec![$($vs),+];
            let col: $col_ty = ::std::iter::FromIterator::from_iter(vs.into_iter());
            col
        }
    };

    // Initialise a sequence with a fully inferred contained type.
    [$($vs:expr),+] => { collect![into _: $($vs),+] };

    // Initialise a map with a constrained container type.
    [into $col_ty:ty: $($ks:expr: $vs:expr),+] => {
        // Maps implement FromIterator by taking tuples, so we just need to rewrite each `a:b` as `(a,b)`.
        collect![into $col_ty: $(($ks, $vs)),+]
    };

    // Initialise a map with a fully inferred contained type.
    [$($ks:expr: $vs:expr),+] => { collect![into _: $($ks: $vs),+] };
}

/**
Counts the number of comma-delimited expressions passed to it.  The result is a compile-time evaluable expression, suitable for use as a static array size, or the value of a `const`.

Example:

```
# #![feature(phase)]
# #[phase(plugin)] extern crate grabbag_macros;
# fn main() {
const COUNT: uint = count_exprs!(a, 5+1, "hi there!".into_string());
assert_eq!(COUNT, 3);
# }
```
*/
#[macro_export]
macro_rules! count_exprs {
    () => { 0 };
    ($e:expr $(, $es:expr)*) => { 1 + count_exprs!($($es),*) };
}

/**
Expands to an expression implementing the `Iterator` trait, which yields successive
elements of the given closed-form sequence.

For example, you can define the sequence of positive odd integers like so:

```
# #![feature(phase)]
# #[phase(plugin)] extern crate grabbag_macros;
# fn main() {
#     let _ =
sequence![ n: u64 = 2*(n as u64) + 1 ]
#     ;
# }
```

You can also specify one or more initial members of the sequence that are also used in the closed form expression like so:

```
# #![feature(phase)]
# #[phase(plugin)] extern crate grabbag_macros;
# fn main() {
#     let _ =
sequence![ a[n]: u64 = 1, 2... a[0]*(n as u64) + a[1] ]
#     ;
# }
```
*/
#[macro_export]
macro_rules! sequence {
    ( $ind:ident: $sty:ty = $closed_form:expr ) => {
        {
            struct Sequence {
                pos: uint,
            }

            impl Iterator<$sty> for Sequence {
                #[inline]
                fn next(&mut self) -> Option<$sty> {
                    let next_val: $sty = {
                        let $ind = self.pos;
                        $closed_form
                    };

                    self.pos += 1;
                    Some(next_val)
                }
            }

            Sequence { pos: 0 }
        }
    };
    ( $seq:ident [ $ind:ident ]: $sty:ty = $($inits:expr),+ ... $closed_form:expr ) => {
        {
            const INITS: uint = count_exprs!($($inits),+);

            struct Sequence {
                inits: [$sty, ..INITS],
                pos: uint,
            }

            impl Iterator<$sty> for Sequence {
                #[inline]
                fn next(&mut self) -> Option<$sty> {
                    if self.pos < INITS {
                        let next_val = self.inits[self.pos];
                        self.pos += 1;
                        Some(next_val)
                    } else {
                        let next_val: $sty = {
                            let $ind = self.pos;
                            let $seq = &self.inits;
                            $closed_form
                        };

                        self.pos += 1;
                        Some(next_val)
                    }
                }
            }

            Sequence { inits: [$($inits),+], pos: 0 }
        }
    };
}

/**
Expands to an expression implementing the `Iterator` trait, which yields successive
elements of the given recurrence relationship.

For example, you can define a Fibonnaci sequence iterator like so:

```
# #![feature(phase)]
# #[phase(plugin)] extern crate grabbag_macros;
# fn main() {
#     let _ =
recurrence![ fib[n]: f64 = 0.0, 1.0 ... fib[n-1] + fib[n-2] ]
#     ;
# }
```
*/
#[macro_export]
macro_rules! recurrence {
    ( $seq:ident [ $ind:ident ]: $sty:ty = $($inits:expr),+ ... $recur:expr ) => {
        {
            const MEMORY: uint = count_exprs!($($inits),+);

            struct Recurrence {
                mem: [$sty, ..MEMORY],
                pos: uint,
            }

            struct IndexOffset<'a> {
                slice: &'a [$sty, ..MEMORY],
                offset: uint,
            }

            impl<'a> Index<uint, $sty> for IndexOffset<'a> {
                #[inline(always)]
                fn index<'b>(&'b self, index: &uint) -> &'b $sty {
                    let real_index = *index - self.offset + MEMORY;
                    &self.slice[real_index]
                }
            }

            impl Iterator<$sty> for Recurrence {
                #[inline]
                fn next(&mut self) -> Option<$sty> {
                    if self.pos < MEMORY {
                        let next_val = self.mem[self.pos];
                        self.pos += 1;
                        Some(next_val)
                    } else {
                        let next_val: $sty = {
                            let $ind = self.pos;
                            let $seq = IndexOffset { slice: &self.mem, offset: $ind };
                            $recur
                        };

                        {
                            use std::mem::swap;

                            let mut swap_tmp = next_val;
                            for i in range(0, MEMORY).rev() {
                                swap(&mut swap_tmp, &mut self.mem[i]);
                            }
                        }

                        self.pos += 1;
                        Some(next_val)
                    }
                }
            }

            Recurrence { mem: [$($inits),+], pos: 0 }
        }
    };
}
<|endoftext|>


<commit_before>//! Types and functions related to PG's and Sqlite's `ON CONFLICT` clause
//!
//! See [the methods on `InsertStatement`](../../query_builder/struct.InsertStatement.html#impl-1)
//! for usage examples.

mod on_conflict_actions;
mod on_conflict_clause;
mod on_conflict_extension;
mod on_conflict_target;

pub use self::on_conflict_actions::excluded;
pub use self::on_conflict_extension::*;
pub use self::on_conflict_target::*;
<commit_msg>Add available version information<commit_after>//! Types and functions related to PG's and Sqlite's `ON CONFLICT` clause
//! If you use upsert, you need use PostgreSQL since version 9.0 or Sqlite3 since version 3.24.0.
//!
//! See [the methods on `InsertStatement`](../../query_builder/struct.InsertStatement.html#impl-1)
//! for usage examples.

mod on_conflict_actions;
mod on_conflict_clause;
mod on_conflict_extension;
mod on_conflict_target;

pub use self::on_conflict_actions::excluded;
pub use self::on_conflict_extension::*;
pub use self::on_conflict_target::*;
<|endoftext|>