<commit_before>//! Shared access to Cairo image surfaces.
use std::ptr::NonNull;

use cairo::prelude::SurfaceExt;
use cairo::{self, ImageSurface};
use cairo_sys;
use glib::translate::{Stash, ToGlibPtr};
use rulinalg::matrix::{BaseMatrix, Matrix};

use filters::context::IRect;
use util::clamp;

use super::{
    iterators::{PixelRectangle, Pixels},
    EdgeMode,
    ImageSurfaceDataExt,
    Pixel,
};

/// Wrapper for a Cairo image surface that allows shared access.
///
/// There doesn't seem to be any good way of making safe shared access to `ImageSurface` pixel
/// data, since a read-only borrowed reference can still be cloned and then modified (for example,
/// via a `Context`). We can't simply use `ImageSurface::get_data()` because in the filter code we
/// have surfaces referenced from multiple places and it would probably add more complexity to
/// remove that and start passing around references.
///
/// This wrapper asserts the uniqueness of its image surface and doesn't permit modifying it.
///
/// Note: originally I had an idea of using `Rc<RefCell<ImageSurface>>` here which allows to create
/// both read-only and unique read-write accessors safely, however then I realized a read-write
/// accessor isn't of much use if it can't expose a Cairo context interface. Cairo contexts have
/// the very same issue that they can be cloned from a read-only reference and break all safety
/// constraints in this way. Thus the only safe way of exposing a Cairo context seemed to be to
/// manually add all Cairo context methods on the accessor forwarding to the underlying Cairo
/// context (without exposing the context itself to prevent cloning), which would result in too
/// much code. Unless it's absolutely required, I'd like to avoid that.
///
/// Having just read-only access simplifies things further dropping the need for `Rc<RefCell<>>`
/// altogether.
#[derive(Debug, Clone)]
pub struct SharedImageSurface {
    surface: ImageSurface,

    data_ptr: NonNull<u8>, // *const.
    width: i32,
    height: i32,
    stride: isize,

    /// Whether this surface contains meaningful data only in the alpha channel.
    ///
    /// This is used for optimizations, particularly in `convolve()` to skip processing other
    /// channels.
    alpha_only: bool,
}

impl SharedImageSurface {
    /// Creates a `SharedImageSurface` from a unique `ImageSurface`.
    ///
    /// # Panics
    /// Panics if the surface format isn't `ARgb32` and if the surface is not unique, that is, its
    /// reference count isn't 1.
    #[inline]
    pub fn new(surface: ImageSurface) -> Result<Self, cairo::Status> {
        // get_pixel() assumes ARgb32.
        assert_eq!(surface.get_format(), cairo::Format::ARgb32);

        let reference_count =
            unsafe { cairo_sys::cairo_surface_get_reference_count(surface.to_raw_none()) };
        assert_eq!(reference_count, 1);

        surface.flush();
        if surface.status() != cairo::Status::Success {
            return Err(surface.status());
        }

        let data_ptr = NonNull::new(unsafe {
            cairo_sys::cairo_image_surface_get_data(surface.to_raw_none())
        }).unwrap();

        let width = surface.get_width();
        let height = surface.get_height();
        let stride = surface.get_stride() as isize;

        Ok(Self {
            surface,
            data_ptr,
            width,
            height,
            stride,
            alpha_only: false,
        })
    }

    /// Creates a `SharedImageSurface` from a unique `ImageSurface` with meaningful data only in
    /// the alpha channel.
    ///
    /// # Panics
    /// Panics if the surface format isn't `ARgb32` and if the surface is not unique, that is, its
    /// reference count isn't 1.
    #[inline]
    pub fn new_alpha_only(surface: ImageSurface) -> Result<Self, cairo::Status> {
        let mut rv = Self::new(surface)?;
        rv.alpha_only = true;
        Ok(rv)
    }

    /// Converts this `SharedImageSurface` back into a Cairo image surface.
    #[inline]
    pub fn into_image_surface(self) -> Result<ImageSurface, cairo::Status> {
        let reference_count =
            unsafe { cairo_sys::cairo_surface_get_reference_count(self.surface.to_raw_none()) };

        if reference_count == 1 {
            Ok(self.surface)
        } else {
            // If there are any other references, copy the underlying surface.
            let bounds = IRect {
                x0: 0,
                y0: 0,
                x1: self.width,
                y1: self.height,
            };

            self.copy_surface(bounds)
        }
    }

    /// Returns the surface width.
    #[inline]
    pub fn width(&self) -> i32 {
        self.width
    }

    /// Returns the surface height.
    #[inline]
    pub fn height(&self) -> i32 {
        self.height
    }

    /// Returns `true` if the surface contains meaningful data only in the alpha channel.
    #[inline]
    pub fn is_alpha_only(&self) -> bool {
        self.alpha_only
    }

    /// Retrieves the pixel value at the given coordinates.
    #[inline]
    pub fn get_pixel(&self, x: u32, y: u32) -> Pixel {
        assert!(x < self.width as u32);
        assert!(y < self.height as u32);

        let value = unsafe {
            *(self
                .data_ptr
                .as_ptr()
                .offset(y as isize * self.stride + x as isize * 4) as *const u32)
        };

        Pixel {
            r: ((value >> 16) & 0xFF) as u8,
            g: ((value >> 8) & 0xFF) as u8,
            b: (value & 0xFF) as u8,
            a: ((value >> 24) & 0xFF) as u8,
        }
    }

    /// Calls `set_source_surface()` on the given Cairo context.
    #[inline]
    pub fn set_as_source_surface(&self, cr: &cairo::Context, x: f64, y: f64) {
        cr.set_source_surface(&self.surface, x, y);
    }

    /// Returns a new `ImageSurface` with the same contents as the one stored in this
    /// `SharedImageSurface` within the given bounds.
    pub fn copy_surface(&self, bounds: IRect) -> Result<ImageSurface, cairo::Status> {
        let output_surface = ImageSurface::create(cairo::Format::ARgb32, self.width, self.height)?;

        let cr = cairo::Context::new(&output_surface);
        cr.rectangle(
            bounds.x0 as f64,
            bounds.y0 as f64,
            (bounds.x1 - bounds.x0) as f64,
            (bounds.y1 - bounds.y0) as f64,
        );
        cr.clip();

        cr.set_source_surface(&self.surface, 0f64, 0f64);
        cr.paint();

        Ok(output_surface)
    }

    /// Scales the given surface by `x` and `y` into a surface `width`×`height` in size, clipped by
    /// `bounds`.
    pub fn scale_to(
        &self,
        width: i32,
        height: i32,
        bounds: IRect,
        x: f64,
        y: f64,
    ) -> Result<SharedImageSurface, cairo::Status> {
        let output_surface = ImageSurface::create(cairo::Format::ARgb32, width, height)?;

        {
            let cr = cairo::Context::new(&output_surface);
            cr.rectangle(
                bounds.x0 as f64,
                bounds.y0 as f64,
                (bounds.x1 - bounds.x0) as f64,
                (bounds.y1 - bounds.y0) as f64,
            );
            cr.clip();

            cr.scale(x, y);
            self.set_as_source_surface(&cr, 0.0, 0.0);
            cr.paint();
        }

        SharedImageSurface::new(output_surface)
    }

    /// Returns a scaled version of a surface and bounds.
    #[inline]
    pub fn scale(
        &self,
        bounds: IRect,
        x: f64,
        y: f64,
    ) -> Result<(SharedImageSurface, IRect), cairo::Status> {
        let new_width = (f64::from(self.width) * x).ceil() as i32;
        let new_height = (f64::from(self.height) * y).ceil() as i32;
        let new_bounds = bounds.scale(x, y);

        Ok((
            self.scale_to(new_width, new_height, new_bounds, x, y)?,
            new_bounds,
        ))
    }

    /// Returns a surface with black background and alpha channel matching this surface.
    pub fn extract_alpha(&self, bounds: IRect) -> Result<SharedImageSurface, cairo::Status> {
        let mut output_surface =
            ImageSurface::create(cairo::Format::ARgb32, self.width, self.height)?;

        let output_stride = output_surface.get_stride() as usize;
        {
            let mut output_data = output_surface.get_data().unwrap();

            for (x, y, Pixel { a, .. }) in Pixels::new(self, bounds) {
                let output_pixel = Pixel {
                    r: 0,
                    g: 0,
                    b: 0,
                    a,
                };
                output_data.set_pixel(output_stride, output_pixel, x, y);
            }
        }

        SharedImageSurface::new_alpha_only(output_surface)
    }

    /// Returns a surface with pre-multiplication of color values undone.
    ///
    /// HACK: this is storing unpremultiplied pixels in an ARGB32 image surface (which is supposed
    /// to be premultiplied pixels).
    pub fn unpremultiply(&self, bounds: IRect) -> Result<SharedImageSurface, cairo::Status> {
        // Unpremultiplication doesn't affect the alpha channel.
        if self.alpha_only {
            return Ok(self.clone());
        }

        let mut output_surface =
            ImageSurface::create(cairo::Format::ARgb32, self.width, self.height)?;

        let stride = output_surface.get_stride() as usize;
        {
            let mut data = output_surface.get_data().unwrap();

            for (x, y, pixel) in Pixels::new(self, bounds) {
                data.set_pixel(stride, pixel.unpremultiply(), x, y);
            }
        }

        SharedImageSurface::new(output_surface)
    }

    /// Performs a convolution.
    ///
    /// Note that `kernel` is rotated 180 degrees.
    ///
    /// The `target` parameter determines the position of the kernel relative to each pixel of the
    /// image. The value of `(0, 0)` indicates that the top left pixel of the (180-degrees-rotated)
    /// kernel corresponds to the current pixel, and the rest of the kernel is to the right and
    /// bottom of the pixel. The value of `(cols / 2, rows / 2)` centers a kernel with an odd
    /// number of rows and columns.
    ///
    /// # Panics
    /// Panics if `kernel` has zero rows or columns.
    pub fn convolve(
        &self,
        bounds: IRect,
        target: (i32, i32),
        kernel: &Matrix<f64>,
        edge_mode: EdgeMode,
    ) -> Result<SharedImageSurface, cairo::Status> {
        assert!(kernel.rows() >= 1);
        assert!(kernel.cols() >= 1);

        let mut output_surface =
            ImageSurface::create(cairo::Format::ARgb32, self.width, self.height)?;

        let output_stride = output_surface.get_stride() as usize;
        {
            let mut output_data = output_surface.get_data().unwrap();

            for (x, y, _pixel) in Pixels::new(self, bounds) {
                let kernel_bounds = IRect {
                    x0: x as i32 - target.0,
                    y0: y as i32 - target.1,
                    x1: x as i32 - target.0 + kernel.cols() as i32,
                    y1: y as i32 - target.1 + kernel.rows() as i32,
                };

                let mut r = 0.0;
                let mut g = 0.0;
                let mut b = 0.0;
                let mut a = 0.0;

                for (x, y, pixel) in PixelRectangle::new(self, bounds, kernel_bounds, edge_mode) {
                    let kernel_x = (kernel_bounds.x1 - x - 1) as usize;
                    let kernel_y = (kernel_bounds.y1 - y - 1) as usize;
                    let factor = kernel[[kernel_y, kernel_x]];

                    r += f64::from(pixel.r) * factor;
                    g += f64::from(pixel.g) * factor;
                    b += f64::from(pixel.b) * factor;
                    a += f64::from(pixel.a) * factor;
                }

                let convert = |x: f64| clamp(x, 0.0, 255.0).round() as u8;

                let output_pixel = Pixel {
                    r: convert(r),
                    g: convert(g),
                    b: convert(b),
                    a: convert(a),
                };

                output_data.set_pixel(output_stride, output_pixel, x, y);
            }
        }

        SharedImageSurface::new(output_surface)
    }

    /// Returns a raw pointer to the underlying surface.
    ///
    /// # Safety
    /// The returned pointer must not be used to modify the surface.
    #[inline]
    pub unsafe fn to_glib_none(&self) -> Stash<*mut cairo_sys::cairo_surface_t, ImageSurface> {
        self.surface.to_glib_none()
    }
}
<commit_msg>Propagate alpha_only through scale()<commit_after>//! Shared access to Cairo image surfaces.
use std::ptr::NonNull;

use cairo::prelude::SurfaceExt;
use cairo::{self, ImageSurface};
use cairo_sys;
use glib::translate::{Stash, ToGlibPtr};
use rulinalg::matrix::{BaseMatrix, Matrix};

use filters::context::IRect;
use util::clamp;

use super::{
    iterators::{PixelRectangle, Pixels},
    EdgeMode,
    ImageSurfaceDataExt,
    Pixel,
};

/// Wrapper for a Cairo image surface that allows shared access.
///
/// There doesn't seem to be any good way of making safe shared access to `ImageSurface` pixel
/// data, since a read-only borrowed reference can still be cloned and then modified (for example,
/// via a `Context`). We can't simply use `ImageSurface::get_data()` because in the filter code we
/// have surfaces referenced from multiple places and it would probably add more complexity to
/// remove that and start passing around references.
///
/// This wrapper asserts the uniqueness of its image surface and doesn't permit modifying it.
///
/// Note: originally I had an idea of using `Rc<RefCell<ImageSurface>>` here which allows to create
/// both read-only and unique read-write accessors safely, however then I realized a read-write
/// accessor isn't of much use if it can't expose a Cairo context interface. Cairo contexts have
/// the very same issue that they can be cloned from a read-only reference and break all safety
/// constraints in this way. Thus the only safe way of exposing a Cairo context seemed to be to
/// manually add all Cairo context methods on the accessor forwarding to the underlying Cairo
/// context (without exposing the context itself to prevent cloning), which would result in too
/// much code. Unless it's absolutely required, I'd like to avoid that.
///
/// Having just read-only access simplifies things further dropping the need for `Rc<RefCell<>>`
/// altogether.
#[derive(Debug, Clone)]
pub struct SharedImageSurface {
    surface: ImageSurface,

    data_ptr: NonNull<u8>, // *const.
    width: i32,
    height: i32,
    stride: isize,

    /// Whether this surface contains meaningful data only in the alpha channel.
    ///
    /// This is used for optimizations, particularly in `convolve()` to skip processing other
    /// channels.
    alpha_only: bool,
}

impl SharedImageSurface {
    /// Creates a `SharedImageSurface` from a unique `ImageSurface`.
    ///
    /// # Panics
    /// Panics if the surface format isn't `ARgb32` and if the surface is not unique, that is, its
    /// reference count isn't 1.
    #[inline]
    pub fn new(surface: ImageSurface) -> Result<Self, cairo::Status> {
        // get_pixel() assumes ARgb32.
        assert_eq!(surface.get_format(), cairo::Format::ARgb32);

        let reference_count =
            unsafe { cairo_sys::cairo_surface_get_reference_count(surface.to_raw_none()) };
        assert_eq!(reference_count, 1);

        surface.flush();
        if surface.status() != cairo::Status::Success {
            return Err(surface.status());
        }

        let data_ptr = NonNull::new(unsafe {
            cairo_sys::cairo_image_surface_get_data(surface.to_raw_none())
        }).unwrap();

        let width = surface.get_width();
        let height = surface.get_height();
        let stride = surface.get_stride() as isize;

        Ok(Self {
            surface,
            data_ptr,
            width,
            height,
            stride,
            alpha_only: false,
        })
    }

    /// Creates a `SharedImageSurface` from a unique `ImageSurface` with meaningful data only in
    /// the alpha channel.
    ///
    /// # Panics
    /// Panics if the surface format isn't `ARgb32` and if the surface is not unique, that is, its
    /// reference count isn't 1.
    #[inline]
    pub fn new_alpha_only(surface: ImageSurface) -> Result<Self, cairo::Status> {
        let mut rv = Self::new(surface)?;
        rv.alpha_only = true;
        Ok(rv)
    }

    /// Converts this `SharedImageSurface` back into a Cairo image surface.
    #[inline]
    pub fn into_image_surface(self) -> Result<ImageSurface, cairo::Status> {
        let reference_count =
            unsafe { cairo_sys::cairo_surface_get_reference_count(self.surface.to_raw_none()) };

        if reference_count == 1 {
            Ok(self.surface)
        } else {
            // If there are any other references, copy the underlying surface.
            let bounds = IRect {
                x0: 0,
                y0: 0,
                x1: self.width,
                y1: self.height,
            };

            self.copy_surface(bounds)
        }
    }

    /// Returns the surface width.
    #[inline]
    pub fn width(&self) -> i32 {
        self.width
    }

    /// Returns the surface height.
    #[inline]
    pub fn height(&self) -> i32 {
        self.height
    }

    /// Returns `true` if the surface contains meaningful data only in the alpha channel.
    #[inline]
    pub fn is_alpha_only(&self) -> bool {
        self.alpha_only
    }

    /// Retrieves the pixel value at the given coordinates.
    #[inline]
    pub fn get_pixel(&self, x: u32, y: u32) -> Pixel {
        assert!(x < self.width as u32);
        assert!(y < self.height as u32);

        let value = unsafe {
            *(self
                .data_ptr
                .as_ptr()
                .offset(y as isize * self.stride + x as isize * 4) as *const u32)
        };

        Pixel {
            r: ((value >> 16) & 0xFF) as u8,
            g: ((value >> 8) & 0xFF) as u8,
            b: (value & 0xFF) as u8,
            a: ((value >> 24) & 0xFF) as u8,
        }
    }

    /// Calls `set_source_surface()` on the given Cairo context.
    #[inline]
    pub fn set_as_source_surface(&self, cr: &cairo::Context, x: f64, y: f64) {
        cr.set_source_surface(&self.surface, x, y);
    }

    /// Returns a new `ImageSurface` with the same contents as the one stored in this
    /// `SharedImageSurface` within the given bounds.
    pub fn copy_surface(&self, bounds: IRect) -> Result<ImageSurface, cairo::Status> {
        let output_surface = ImageSurface::create(cairo::Format::ARgb32, self.width, self.height)?;

        let cr = cairo::Context::new(&output_surface);
        cr.rectangle(
            bounds.x0 as f64,
            bounds.y0 as f64,
            (bounds.x1 - bounds.x0) as f64,
            (bounds.y1 - bounds.y0) as f64,
        );
        cr.clip();

        cr.set_source_surface(&self.surface, 0f64, 0f64);
        cr.paint();

        Ok(output_surface)
    }

    /// Scales the given surface by `x` and `y` into a surface `width`×`height` in size, clipped by
    /// `bounds`.
    pub fn scale_to(
        &self,
        width: i32,
        height: i32,
        bounds: IRect,
        x: f64,
        y: f64,
    ) -> Result<SharedImageSurface, cairo::Status> {
        let output_surface = ImageSurface::create(cairo::Format::ARgb32, width, height)?;

        {
            let cr = cairo::Context::new(&output_surface);
            cr.rectangle(
                bounds.x0 as f64,
                bounds.y0 as f64,
                (bounds.x1 - bounds.x0) as f64,
                (bounds.y1 - bounds.y0) as f64,
            );
            cr.clip();

            cr.scale(x, y);
            self.set_as_source_surface(&cr, 0.0, 0.0);
            cr.paint();
        }

        if self.alpha_only {
            SharedImageSurface::new_alpha_only(output_surface)
        } else {
            SharedImageSurface::new(output_surface)
        }
    }

    /// Returns a scaled version of a surface and bounds.
    #[inline]
    pub fn scale(
        &self,
        bounds: IRect,
        x: f64,
        y: f64,
    ) -> Result<(SharedImageSurface, IRect), cairo::Status> {
        let new_width = (f64::from(self.width) * x).ceil() as i32;
        let new_height = (f64::from(self.height) * y).ceil() as i32;
        let new_bounds = bounds.scale(x, y);

        Ok((
            self.scale_to(new_width, new_height, new_bounds, x, y)?,
            new_bounds,
        ))
    }

    /// Returns a surface with black background and alpha channel matching this surface.
    pub fn extract_alpha(&self, bounds: IRect) -> Result<SharedImageSurface, cairo::Status> {
        let mut output_surface =
            ImageSurface::create(cairo::Format::ARgb32, self.width, self.height)?;

        let output_stride = output_surface.get_stride() as usize;
        {
            let mut output_data = output_surface.get_data().unwrap();

            for (x, y, Pixel { a, .. }) in Pixels::new(self, bounds) {
                let output_pixel = Pixel {
                    r: 0,
                    g: 0,
                    b: 0,
                    a,
                };
                output_data.set_pixel(output_stride, output_pixel, x, y);
            }
        }

        SharedImageSurface::new_alpha_only(output_surface)
    }

    /// Returns a surface with pre-multiplication of color values undone.
    ///
    /// HACK: this is storing unpremultiplied pixels in an ARGB32 image surface (which is supposed
    /// to be premultiplied pixels).
    pub fn unpremultiply(&self, bounds: IRect) -> Result<SharedImageSurface, cairo::Status> {
        // Unpremultiplication doesn't affect the alpha channel.
        if self.alpha_only {
            return Ok(self.clone());
        }

        let mut output_surface =
            ImageSurface::create(cairo::Format::ARgb32, self.width, self.height)?;

        let stride = output_surface.get_stride() as usize;
        {
            let mut data = output_surface.get_data().unwrap();

            for (x, y, pixel) in Pixels::new(self, bounds) {
                data.set_pixel(stride, pixel.unpremultiply(), x, y);
            }
        }

        SharedImageSurface::new(output_surface)
    }

    /// Performs a convolution.
    ///
    /// Note that `kernel` is rotated 180 degrees.
    ///
    /// The `target` parameter determines the position of the kernel relative to each pixel of the
    /// image. The value of `(0, 0)` indicates that the top left pixel of the (180-degrees-rotated)
    /// kernel corresponds to the current pixel, and the rest of the kernel is to the right and
    /// bottom of the pixel. The value of `(cols / 2, rows / 2)` centers a kernel with an odd
    /// number of rows and columns.
    ///
    /// # Panics
    /// Panics if `kernel` has zero rows or columns.
    pub fn convolve(
        &self,
        bounds: IRect,
        target: (i32, i32),
        kernel: &Matrix<f64>,
        edge_mode: EdgeMode,
    ) -> Result<SharedImageSurface, cairo::Status> {
        assert!(kernel.rows() >= 1);
        assert!(kernel.cols() >= 1);

        let mut output_surface =
            ImageSurface::create(cairo::Format::ARgb32, self.width, self.height)?;

        let output_stride = output_surface.get_stride() as usize;
        {
            let mut output_data = output_surface.get_data().unwrap();

            for (x, y, _pixel) in Pixels::new(self, bounds) {
                let kernel_bounds = IRect {
                    x0: x as i32 - target.0,
                    y0: y as i32 - target.1,
                    x1: x as i32 - target.0 + kernel.cols() as i32,
                    y1: y as i32 - target.1 + kernel.rows() as i32,
                };

                let mut r = 0.0;
                let mut g = 0.0;
                let mut b = 0.0;
                let mut a = 0.0;

                for (x, y, pixel) in PixelRectangle::new(self, bounds, kernel_bounds, edge_mode) {
                    let kernel_x = (kernel_bounds.x1 - x - 1) as usize;
                    let kernel_y = (kernel_bounds.y1 - y - 1) as usize;
                    let factor = kernel[[kernel_y, kernel_x]];

                    r += f64::from(pixel.r) * factor;
                    g += f64::from(pixel.g) * factor;
                    b += f64::from(pixel.b) * factor;
                    a += f64::from(pixel.a) * factor;
                }

                let convert = |x: f64| clamp(x, 0.0, 255.0).round() as u8;

                let output_pixel = Pixel {
                    r: convert(r),
                    g: convert(g),
                    b: convert(b),
                    a: convert(a),
                };

                output_data.set_pixel(output_stride, output_pixel, x, y);
            }
        }

        SharedImageSurface::new(output_surface)
    }

    /// Returns a raw pointer to the underlying surface.
    ///
    /// # Safety
    /// The returned pointer must not be used to modify the surface.
    #[inline]
    pub unsafe fn to_glib_none(&self) -> Stash<*mut cairo_sys::cairo_surface_t, ImageSurface> {
        self.surface.to_glib_none()
    }
}
<|endoftext|>


<commit_before>//! Character conversions.

use crate::convert::TryFrom;
use crate::fmt;
use crate::mem::transmute;
use crate::str::FromStr;

use super::MAX;

/// Converts a `u32` to a `char`.
///
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
/// `as`:
///
/// ```
/// let c = '💯';
/// let i = c as u32;
///
/// assert_eq!(128175, i);
/// ```
///
/// However, the reverse is not true: not all valid [`u32`]s are valid
/// [`char`]s. `from_u32()` will return `None` if the input is not a valid value
/// for a [`char`].
///
/// [`char`]: ../../std/primitive.char.html
/// [`u32`]: ../../std/primitive.u32.html
///
/// For an unsafe version of this function which ignores these checks, see
/// [`from_u32_unchecked`].
///
/// [`from_u32_unchecked`]: fn.from_u32_unchecked.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = char::from_u32(0x2764);
///
/// assert_eq!(Some('❤'), c);
/// ```
///
/// Returning `None` when the input is not a valid [`char`]:
///
/// ```
/// use std::char;
///
/// let c = char::from_u32(0x110000);
///
/// assert_eq!(None, c);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_u32(i: u32) -> Option<char> {
    char::try_from(i).ok()
}

/// Converts a `u32` to a `char`, ignoring validity.
///
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
/// `as`:
///
/// ```
/// let c = '💯';
/// let i = c as u32;
///
/// assert_eq!(128175, i);
/// ```
///
/// However, the reverse is not true: not all valid [`u32`]s are valid
/// [`char`]s. `from_u32_unchecked()` will ignore this, and blindly cast to
/// [`char`], possibly creating an invalid one.
///
/// [`char`]: ../../std/primitive.char.html
/// [`u32`]: ../../std/primitive.u32.html
///
/// # Safety
///
/// This function is unsafe, as it may construct invalid `char` values.
///
/// For a safe version of this function, see the [`from_u32`] function.
///
/// [`from_u32`]: fn.from_u32.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = unsafe { char::from_u32_unchecked(0x2764) };
///
/// assert_eq!('❤', c);
/// ```
#[inline]
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
pub unsafe fn from_u32_unchecked(i: u32) -> char {
    transmute(i)
}

#[stable(feature = "char_convert", since = "1.13.0")]
impl From<char> for u32 {
    /// Converts a [`char`] into a [`u32`].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::mem;
    ///
    /// let c = 'c';
    /// let u = u32::from(c);
    /// assert!(4 == mem::size_of_val(&u))
    /// ```
    #[inline]
    fn from(c: char) -> Self {
        c as u32
    }
}

/// Maps a byte in 0x00..=0xFF to a `char` whose code point has the same value, in U+0000..=U+00FF.
///
/// Unicode is designed such that this effectively decodes bytes
/// with the character encoding that IANA calls ISO-8859-1.
/// This encoding is compatible with ASCII.
///
/// Note that this is different from ISO/IEC 8859-1 a.k.a. ISO 8859-1 (with one less hyphen),
/// which leaves some "blanks", byte values that are not assigned to any character.
/// ISO-8859-1 (the IANA one) assigns them to the C0 and C1 control codes.
///
/// Note that this is *also* different from Windows-1252 a.k.a. code page 1252,
/// which is a superset ISO/IEC 8859-1 that assigns some (not all!) blanks
/// to punctuation and various Latin characters.
///
/// To confuse things further, [on the Web](https://encoding.spec.whatwg.org/)
/// `ascii`, `iso-8859-1`, and `windows-1252` are all aliases
/// for a superset of Windows-1252 that fills the remaining blanks with corresponding
/// C0 and C1 control codes.
#[stable(feature = "char_convert", since = "1.13.0")]
impl From<u8> for char {
    /// Converts a [`u8`] into a [`char`].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::mem;
    ///
    /// let u = 32 as u8;
    /// let c = char::from(u);
    /// assert!(4 == mem::size_of_val(&c))
    /// ```
    #[inline]
    fn from(i: u8) -> Self {
        i as char
    }
}

/// An error which can be returned when parsing a char.
#[stable(feature = "char_from_str", since = "1.20.0")]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseCharError {
    kind: CharErrorKind,
}

impl ParseCharError {
    #[unstable(
        feature = "char_error_internals",
        reason = "this method should not be available publicly",
        issue = "none"
    )]
    #[doc(hidden)]
    pub fn __description(&self) -> &str {
        match self.kind {
            CharErrorKind::EmptyString => "cannot parse char from empty string",
            CharErrorKind::TooManyChars => "too many characters in string",
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum CharErrorKind {
    EmptyString,
    TooManyChars,
}

#[stable(feature = "char_from_str", since = "1.20.0")]
impl fmt::Display for ParseCharError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.__description().fmt(f)
    }
}

#[stable(feature = "char_from_str", since = "1.20.0")]
impl FromStr for char {
    type Err = ParseCharError;

    #[inline]
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut chars = s.chars();
        match (chars.next(), chars.next()) {
            (None, _) => Err(ParseCharError { kind: CharErrorKind::EmptyString }),
            (Some(c), None) => Ok(c),
            _ => Err(ParseCharError { kind: CharErrorKind::TooManyChars }),
        }
    }
}

#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<u32> for char {
    type Error = CharTryFromError;

    #[inline]
    fn try_from(i: u32) -> Result<Self, Self::Error> {
        if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
            Err(CharTryFromError(()))
        } else {
            // SAFETY: checked that it's a legal unicode value
            Ok(unsafe { from_u32_unchecked(i) })
        }
    }
}

/// The error type returned when a conversion from u32 to char fails.
#[stable(feature = "try_from", since = "1.34.0")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct CharTryFromError(());

#[stable(feature = "try_from", since = "1.34.0")]
impl fmt::Display for CharTryFromError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        "converted integer out of range for `char`".fmt(f)
    }
}

/// Converts a digit in the given radix to a `char`.
///
/// A 'radix' here is sometimes also called a 'base'. A radix of two
/// indicates a binary number, a radix of ten, decimal, and a radix of
/// sixteen, hexadecimal, to give some common values. Arbitrary
/// radices are supported.
///
/// `from_digit()` will return `None` if the input is not a digit in
/// the given radix.
///
/// # Panics
///
/// Panics if given a radix larger than 36.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = char::from_digit(4, 10);
///
/// assert_eq!(Some('4'), c);
///
/// // Decimal 11 is a single digit in base 16
/// let c = char::from_digit(11, 16);
///
/// assert_eq!(Some('b'), c);
/// ```
///
/// Returning `None` when the input is not a digit:
///
/// ```
/// use std::char;
///
/// let c = char::from_digit(20, 10);
///
/// assert_eq!(None, c);
/// ```
///
/// Passing a large radix, causing a panic:
///
/// ```
/// use std::thread;
/// use std::char;
///
/// let result = thread::spawn(|| {
///     // this panics
///     let c = char::from_digit(1, 37);
/// }).join();
///
/// assert!(result.is_err());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_digit(num: u32, radix: u32) -> Option<char> {
    if radix > 36 {
        panic!("from_digit: radix is too high (maximum 36)");
    }
    if num < radix {
        let num = num as u8;
        if num < 10 { Some((b'0' + num) as char) } else { Some((b'a' + num - 10) as char) }
    } else {
        None
    }
}
<commit_msg>from_u32_unchecked: check validity when debug assertions are enabled<commit_after>//! Character conversions.

use crate::convert::TryFrom;
use crate::fmt;
use crate::mem::transmute;
use crate::str::FromStr;

use super::MAX;

/// Converts a `u32` to a `char`.
///
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
/// `as`:
///
/// ```
/// let c = '💯';
/// let i = c as u32;
///
/// assert_eq!(128175, i);
/// ```
///
/// However, the reverse is not true: not all valid [`u32`]s are valid
/// [`char`]s. `from_u32()` will return `None` if the input is not a valid value
/// for a [`char`].
///
/// [`char`]: ../../std/primitive.char.html
/// [`u32`]: ../../std/primitive.u32.html
///
/// For an unsafe version of this function which ignores these checks, see
/// [`from_u32_unchecked`].
///
/// [`from_u32_unchecked`]: fn.from_u32_unchecked.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = char::from_u32(0x2764);
///
/// assert_eq!(Some('❤'), c);
/// ```
///
/// Returning `None` when the input is not a valid [`char`]:
///
/// ```
/// use std::char;
///
/// let c = char::from_u32(0x110000);
///
/// assert_eq!(None, c);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_u32(i: u32) -> Option<char> {
    char::try_from(i).ok()
}

/// Converts a `u32` to a `char`, ignoring validity.
///
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
/// `as`:
///
/// ```
/// let c = '💯';
/// let i = c as u32;
///
/// assert_eq!(128175, i);
/// ```
///
/// However, the reverse is not true: not all valid [`u32`]s are valid
/// [`char`]s. `from_u32_unchecked()` will ignore this, and blindly cast to
/// [`char`], possibly creating an invalid one.
///
/// [`char`]: ../../std/primitive.char.html
/// [`u32`]: ../../std/primitive.u32.html
///
/// # Safety
///
/// This function is unsafe, as it may construct invalid `char` values.
///
/// For a safe version of this function, see the [`from_u32`] function.
///
/// [`from_u32`]: fn.from_u32.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = unsafe { char::from_u32_unchecked(0x2764) };
///
/// assert_eq!('❤', c);
/// ```
#[inline]
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
pub unsafe fn from_u32_unchecked(i: u32) -> char {
    if cfg!(debug_assertions) { char::from_u32(i).unwrap() } else { transmute(i) }
}

#[stable(feature = "char_convert", since = "1.13.0")]
impl From<char> for u32 {
    /// Converts a [`char`] into a [`u32`].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::mem;
    ///
    /// let c = 'c';
    /// let u = u32::from(c);
    /// assert!(4 == mem::size_of_val(&u))
    /// ```
    #[inline]
    fn from(c: char) -> Self {
        c as u32
    }
}

/// Maps a byte in 0x00..=0xFF to a `char` whose code point has the same value, in U+0000..=U+00FF.
///
/// Unicode is designed such that this effectively decodes bytes
/// with the character encoding that IANA calls ISO-8859-1.
/// This encoding is compatible with ASCII.
///
/// Note that this is different from ISO/IEC 8859-1 a.k.a. ISO 8859-1 (with one less hyphen),
/// which leaves some "blanks", byte values that are not assigned to any character.
/// ISO-8859-1 (the IANA one) assigns them to the C0 and C1 control codes.
///
/// Note that this is *also* different from Windows-1252 a.k.a. code page 1252,
/// which is a superset ISO/IEC 8859-1 that assigns some (not all!) blanks
/// to punctuation and various Latin characters.
///
/// To confuse things further, [on the Web](https://encoding.spec.whatwg.org/)
/// `ascii`, `iso-8859-1`, and `windows-1252` are all aliases
/// for a superset of Windows-1252 that fills the remaining blanks with corresponding
/// C0 and C1 control codes.
#[stable(feature = "char_convert", since = "1.13.0")]
impl From<u8> for char {
    /// Converts a [`u8`] into a [`char`].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::mem;
    ///
    /// let u = 32 as u8;
    /// let c = char::from(u);
    /// assert!(4 == mem::size_of_val(&c))
    /// ```
    #[inline]
    fn from(i: u8) -> Self {
        i as char
    }
}

/// An error which can be returned when parsing a char.
#[stable(feature = "char_from_str", since = "1.20.0")]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseCharError {
    kind: CharErrorKind,
}

impl ParseCharError {
    #[unstable(
        feature = "char_error_internals",
        reason = "this method should not be available publicly",
        issue = "none"
    )]
    #[doc(hidden)]
    pub fn __description(&self) -> &str {
        match self.kind {
            CharErrorKind::EmptyString => "cannot parse char from empty string",
            CharErrorKind::TooManyChars => "too many characters in string",
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum CharErrorKind {
    EmptyString,
    TooManyChars,
}

#[stable(feature = "char_from_str", since = "1.20.0")]
impl fmt::Display for ParseCharError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.__description().fmt(f)
    }
}

#[stable(feature = "char_from_str", since = "1.20.0")]
impl FromStr for char {
    type Err = ParseCharError;

    #[inline]
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut chars = s.chars();
        match (chars.next(), chars.next()) {
            (None, _) => Err(ParseCharError { kind: CharErrorKind::EmptyString }),
            (Some(c), None) => Ok(c),
            _ => Err(ParseCharError { kind: CharErrorKind::TooManyChars }),
        }
    }
}

#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<u32> for char {
    type Error = CharTryFromError;

    #[inline]
    fn try_from(i: u32) -> Result<Self, Self::Error> {
        if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
            Err(CharTryFromError(()))
        } else {
            // SAFETY: checked that it's a legal unicode value
            Ok(unsafe { transmute(i) })
        }
    }
}

/// The error type returned when a conversion from u32 to char fails.
#[stable(feature = "try_from", since = "1.34.0")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct CharTryFromError(());

#[stable(feature = "try_from", since = "1.34.0")]
impl fmt::Display for CharTryFromError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        "converted integer out of range for `char`".fmt(f)
    }
}

/// Converts a digit in the given radix to a `char`.
///
/// A 'radix' here is sometimes also called a 'base'. A radix of two
/// indicates a binary number, a radix of ten, decimal, and a radix of
/// sixteen, hexadecimal, to give some common values. Arbitrary
/// radices are supported.
///
/// `from_digit()` will return `None` if the input is not a digit in
/// the given radix.
///
/// # Panics
///
/// Panics if given a radix larger than 36.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char;
///
/// let c = char::from_digit(4, 10);
///
/// assert_eq!(Some('4'), c);
///
/// // Decimal 11 is a single digit in base 16
/// let c = char::from_digit(11, 16);
///
/// assert_eq!(Some('b'), c);
/// ```
///
/// Returning `None` when the input is not a digit:
///
/// ```
/// use std::char;
///
/// let c = char::from_digit(20, 10);
///
/// assert_eq!(None, c);
/// ```
///
/// Passing a large radix, causing a panic:
///
/// ```
/// use std::thread;
/// use std::char;
///
/// let result = thread::spawn(|| {
///     // this panics
///     let c = char::from_digit(1, 37);
/// }).join();
///
/// assert!(result.is_err());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_digit(num: u32, radix: u32) -> Option<char> {
    if radix > 36 {
        panic!("from_digit: radix is too high (maximum 36)");
    }
    if num < radix {
        let num = num as u8;
        if num < 10 { Some((b'0' + num) as char) } else { Some((b'a' + num - 10) as char) }
    } else {
        None
    }
}
<|endoftext|>


<commit_before>use super::*;
use redox::*;

impl Editor {
    pub fn exec(&mut self, Inst(n, cmd): Inst) {
        use super::Mode::*;
        use super::PrimitiveMode::*;
        use super::CommandMode::*;
        match self.cursor().mode {
            Command(Normal) => match cmd {
                'i' => {
                    self.cursor_mut().mode = Mode::Primitive(PrimitiveMode::Insert(
                        InsertOptions {
                            mode: InsertMode::Insert,
                        }));

                },
                'h' => self.left(n as usize),
                'j' => self.down(n as usize),
                'k' => self.up(n as usize),
                'l' => self.right(n as usize),
                'J' => self.down(15),
                'K' => self.up(15),
                'x' => self.delete(),
                'X' => {
                    self.previous();
                    self.delete();
                },
                '$' => self.cursor_mut().x = self.text[self.y()].len(),
                '0' => self.cursor_mut().x = 0,
                'r' => {
                    if let EventOption::Key(k) = self.window.poll()
                                                 .unwrap_or(Event::new())
                                                 .to_option() {
                        let x = self.x();
                        let y = self.y();
                        self.text[y][x] = k.character;
                    }
                },
                ' ' => self.next(),
                _ => {},
            },
            Primitive(Insert(_)) => {
                self.insert(cmd);
            },
        }
    }
}
<commit_msg>Fix r command<commit_after>use super::*;
use redox::*;

impl Editor {
    pub fn exec(&mut self, Inst(n, cmd): Inst) {
        use super::Mode::*;
        use super::PrimitiveMode::*;
        use super::CommandMode::*;
        match self.cursor().mode {
            Command(Normal) => match cmd {
                'i' => {
                    self.cursor_mut().mode = Mode::Primitive(PrimitiveMode::Insert(
                        InsertOptions {
                            mode: InsertMode::Insert,
                        }));

                },
                'h' => self.left(n as usize),
                'j' => self.down(n as usize),
                'k' => self.up(n as usize),
                'l' => self.right(n as usize),
                'J' => self.down(15),
                'K' => self.up(15),
                'x' => self.delete(),
                'X' => {
                    self.previous();
                    self.delete();
                },
                '$' => self.cursor_mut().x = self.text[self.y()].len(),
                '0' => self.cursor_mut().x = 0,
                'r' => {
                    loop {
                        if let EventOption::Key(k) = self.window.poll()
                                                     .unwrap_or(Event::new())
                                                     .to_option() {
                            if k.pressed {
                                let x = self.x();
                                let y = self.y();
                                self.text[y][x] = k.character;
                                break;
                            }
                        }
                    }
                },
                ' ' => self.next(),
                _ => {},
            },
            Primitive(Insert(_)) => {
                self.insert(cmd);
            },
        }
    }
}
<|endoftext|>


<commit_before>use super::*;
use redox::*;

pub struct InstructionIterator<'a, I: 'a> {
    pub editor: &'a Editor,
    pub iter: &'a mut I,
}

impl<'a, I: Iterator<Item = EventOption>> Iterator for InstructionIterator<'a, I> {
    type Item = Inst;

    fn next(&mut self) -> Option<Inst> {
        let mut n = 0;

        let mut last = '\0';
        for c in self.iter {
            match self.editor.cursors[self.editor.current_cursor as usize].mode {
                Mode::Primitive(_) => {
                    Inst(0, c);
                },
                Mode::Command(_) => {
                    n = match c {
                        '0' if n != 0 => n * 10,
                        '1'           => n * 10 + 1,
                        '2'           => n * 10 + 2,
                        '3'           => n * 10 + 3,
                        '4'           => n * 10 + 4,
                        '5'           => n * 10 + 5,
                        '6'           => n * 10 + 6,
                        '7'           => n * 10 + 7,
                        '8'           => n * 10 + 8,
                        '9'           => n * 10 + 9,
                        _             => {
                            last = c;
                            break;
                        },
                    }

                }
            }
        }

        Some(Inst(if n == 0 { 1 } else { n }, last))
    }
}

trait ToInstructionIterator {
    fn inst_iter<'a>(&'a mut self, editor: &'a Editor) -> InstructionIterator<'a, Self>;
}

impl ToInstructionIterator for Iterator<Item = EventOption> {
    fn inst_iter<'a>(&'a mut self, editor: &'a Editor) -> InstructionIterator<'a, Self> {
        InstructionIterator {
            editor: self,
            iter: self,
        }
    }
}
impl Editor {
    /// Execute a instruction
    pub fn exec(&mut self, inst: Inst) {

    }

}
<commit_msg>Fix some type errors<commit_after>use super::*;
use redox::*;

pub struct InstructionIterator<'a, I: 'a> {
    pub editor: &'a Editor,
    pub iter: &'a mut I,
}

impl<'a, I: Iterator<Item = EventOption>> Iterator for InstructionIterator<'a, I> {
    type Item = Inst;

    fn next(&mut self) -> Option<Inst> {
        let mut n = 0;

        let mut last = '\0';
        for e in self.iter {
            match e {
                EventOption::Key(k) if k.pressed => {
                    let c = k.character;
                    match self.editor.cursors[self.editor.current_cursor as usize].mode {
                        Mode::Primitive(_) => {
                            Inst(0, c);
                        },
                        Mode::Command(_) => {
                            n = match c {
                                '0' if n != 0 => n * 10,
                                '1'           => n * 10 + 1,
                                '2'           => n * 10 + 2,
                                '3'           => n * 10 + 3,
                                '4'           => n * 10 + 4,
                                '5'           => n * 10 + 5,
                                '6'           => n * 10 + 6,
                                '7'           => n * 10 + 7,
                                '8'           => n * 10 + 8,
                                '9'           => n * 10 + 9,
                                _             => {
                                    last = c;
                                    break;
                                },
                            }

                        }
                    }
        }

        Some(Inst(if n == 0 { 1 } else { n }, last))
    }
}

trait ToInstructionIterator {
    fn inst_iter<'a>(&'a mut self, editor: &'a Editor) -> InstructionIterator<'a, Self>;
}

impl ToInstructionIterator for Iterator<Item = EventOption> {
    fn inst_iter<'a>(&'a mut self, editor: &'a Editor) -> InstructionIterator<'a, Self> {
        InstructionIterator {
            editor: self,
            iter: self,
        }
    }
}
impl Editor {
    /// Execute a instruction
    pub fn exec(&mut self, inst: Inst) {

    }

}
<|endoftext|>


<commit_before>#![cfg(feature = "json5")]

use serde_derive::Deserialize;

use config::{Config, File, FileFormat, Map, Value};
use float_cmp::ApproxEqUlps;
use std::path::PathBuf;

#[derive(Debug, Deserialize)]
struct Place {
    name: String,
    longitude: f64,
    latitude: f64,
    favorite: bool,
    telephone: Option<String>,
    reviews: u64,
    creator: Map<String, Value>,
    rating: Option<f32>,
}

#[derive(Debug, Deserialize)]
struct Settings {
    debug: f64,
    production: Option<String>,
    place: Place,
    #[serde(rename = "arr")]
    elements: Vec<String>,
}

fn make() -> Config {
    Config::builder()
        .add_source(File::new("tests/Settings", FileFormat::Json5))
        .build()
        .unwrap()
}

#[test]
fn test_file() {
    let c = make();

    // Deserialize the entire file as single struct
    let s: Settings = c.try_deserialize().unwrap();

    assert!(s.debug.approx_eq_ulps(&1.0, 2));
    assert_eq!(s.production, Some("false".to_string()));
    assert_eq!(s.place.name, "Torre di Pisa");
    assert!(s.place.longitude.approx_eq_ulps(&43.722_498_5, 2));
    assert!(s.place.latitude.approx_eq_ulps(&10.397_052_2, 2));
    assert!(!s.place.favorite);
    assert_eq!(s.place.reviews, 3866);
    assert_eq!(s.place.rating, Some(4.5));
    assert_eq!(s.place.telephone, None);
    assert_eq!(s.elements.len(), 10);
    assert_eq!(s.elements[3], "4".to_string());
    if cfg!(feature = "preserve_order") {
        assert_eq!(
            s.place
                .creator
                .into_iter()
                .collect::<Vec<(String, config::Value)>>(),
            vec![
                ("name".to_string(), "John Smith".into()),
                ("username".into(), "jsmith".into()),
                ("email".into(), "jsmith@localhost".into()),
            ]
        );
    } else {
        assert_eq!(
            s.place.creator["name"].clone().into_string().unwrap(),
            "John Smith".to_string()
        );
    }
}

#[test]
fn test_error_parse() {
    let res = Config::builder()
        .add_source(File::new("tests/Settings-invalid", FileFormat::Json5))
        .build();

    let path_with_extension: PathBuf = ["tests", "Settings-invalid.json5"].iter().collect();

    assert!(res.is_err());
    assert_eq!(
        res.unwrap_err().to_string(),
        format!(
            " --> 2:7\n  |\n2 |   ok: true␊\n  |       ^---\n  |\n  = expected null in {}",
            path_with_extension.display()
        )
    );
}
<commit_msg>Fix json5 test: Remove artifact character<commit_after>#![cfg(feature = "json5")]

use serde_derive::Deserialize;

use config::{Config, File, FileFormat, Map, Value};
use float_cmp::ApproxEqUlps;
use std::path::PathBuf;

#[derive(Debug, Deserialize)]
struct Place {
    name: String,
    longitude: f64,
    latitude: f64,
    favorite: bool,
    telephone: Option<String>,
    reviews: u64,
    creator: Map<String, Value>,
    rating: Option<f32>,
}

#[derive(Debug, Deserialize)]
struct Settings {
    debug: f64,
    production: Option<String>,
    place: Place,
    #[serde(rename = "arr")]
    elements: Vec<String>,
}

fn make() -> Config {
    Config::builder()
        .add_source(File::new("tests/Settings", FileFormat::Json5))
        .build()
        .unwrap()
}

#[test]
fn test_file() {
    let c = make();

    // Deserialize the entire file as single struct
    let s: Settings = c.try_deserialize().unwrap();

    assert!(s.debug.approx_eq_ulps(&1.0, 2));
    assert_eq!(s.production, Some("false".to_string()));
    assert_eq!(s.place.name, "Torre di Pisa");
    assert!(s.place.longitude.approx_eq_ulps(&43.722_498_5, 2));
    assert!(s.place.latitude.approx_eq_ulps(&10.397_052_2, 2));
    assert!(!s.place.favorite);
    assert_eq!(s.place.reviews, 3866);
    assert_eq!(s.place.rating, Some(4.5));
    assert_eq!(s.place.telephone, None);
    assert_eq!(s.elements.len(), 10);
    assert_eq!(s.elements[3], "4".to_string());
    if cfg!(feature = "preserve_order") {
        assert_eq!(
            s.place
                .creator
                .into_iter()
                .collect::<Vec<(String, config::Value)>>(),
            vec![
                ("name".to_string(), "John Smith".into()),
                ("username".into(), "jsmith".into()),
                ("email".into(), "jsmith@localhost".into()),
            ]
        );
    } else {
        assert_eq!(
            s.place.creator["name"].clone().into_string().unwrap(),
            "John Smith".to_string()
        );
    }
}

#[test]
fn test_error_parse() {
    let res = Config::builder()
        .add_source(File::new("tests/Settings-invalid", FileFormat::Json5))
        .build();

    let path_with_extension: PathBuf = ["tests", "Settings-invalid.json5"].iter().collect();

    assert!(res.is_err());
    assert_eq!(
        res.unwrap_err().to_string(),
        format!(
            " --> 2:7\n  |\n2 |   ok: true\n  |       ^---\n  |\n  = expected null in {}",
            path_with_extension.display()
        )
    );
}
<|endoftext|>


<commit_before>use unicode_width::{UnicodeWidthStr,UnicodeWidthChar};
use super::Renderer;
use std::mem;
use std::fmt::Debug;

/// A wrapper around a String with extra metadata.
#[derive(Debug)]
struct TaggedString<T:Debug> {
    s: String,
    tag: T,
}

/// A type to build up wrapped text, allowing extra metadata for
/// spans.
#[derive(Debug)]
struct WrappedBlock<T:Clone+Eq+Debug> {
    width: usize,
    text: Vec<Vec<TaggedString<T>>>,
    textlen: usize,
    line: Vec<TaggedString<T>>,
    linelen: usize,
    spacetag: Option<T>,         // Tag for the whitespace before the current word
    word: Vec<TaggedString<T>>,  // The current word (with no whitespace).
    wordlen: usize,
}

impl<T:Clone+Eq+Debug> WrappedBlock<T> {
    pub fn new(width: usize) -> WrappedBlock<T> {
        WrappedBlock {
            width: width,
            text: Vec::new(),
            textlen: 0,
            line: Vec::new(),
            linelen: 0,
            spacetag: None,
            word: Vec::new(),
            wordlen: 0,
        }
    }

    fn flush_word(&mut self) {
        /* Finish the word. */
        if self.word.len() > 0 {
            let space_in_line = self.width - self.linelen
                        - if self.linelen > 0 { 1 } else { 0 }; // space
            if self.wordlen <= space_in_line {
                if self.linelen > 0 {
                    self.line.push(TaggedString{s: " ".into(), tag: self.spacetag.take().unwrap()});
                    self.linelen += 1;
                }
                self.line.extend(self.word.drain(..));
                self.linelen += self.wordlen;
                self.wordlen = 0;
            } else {
                unimplemented!()
            }
        }
    }

    fn flush(&mut self) {
        self.flush_word();
        if self.line.len() > 0 {
            let mut tmp_line = Vec::new();
            mem::swap(&mut tmp_line, &mut self.line);
            self.text.push(tmp_line);
        }
    }

    /// Consume self and return a vector of lines.
    pub fn into_untagged_lines(mut self) -> Vec<String> {
        self.flush();

        let mut result = Vec::new();
        for line in self.text.into_iter() {
            let mut line_s = String::new();
            for TaggedString{ s, .. } in line.into_iter() {
                line_s.push_str(&s);
            }
            result.push(line_s);
        }
        result
    }

    pub fn add_text(&mut self, text: &str, tag: T) {
        for c in text.chars() {
            if c.is_whitespace() {
                /* Whitespace is mostly ignored, except to terminate words. */
                self.flush_word();
                self.spacetag = Some(tag.clone());
            } else {
                /* Not whitespace; add to the current word. */
                if self.word.len() > 0 && self.word[self.word.len()-1].tag == tag {
                    /* Just add a character to the last piece */
                    let last_idx = self.word.len() - 1;
                    self.word[last_idx].s.push(c);
                } else {
                    /* Starting a new word; easy. */
                    let mut s = String::new();
                    s.push(c);
                    self.word.push(TaggedString{ s: s, tag: tag.clone()});
                }
                self.wordlen += UnicodeWidthChar::width(c).unwrap();
            }
        }
    }

    pub fn text_len(&self) -> usize {
        self.textlen + self.linelen + self.wordlen
    }
}

/// A renderer which just outputs plain text.
pub struct TextRenderer {
    width: usize,
    lines: Vec<String>,
    /// True at the end of a block, meaning we should add
    /// a blank line if any other text is added.
    at_block_end: bool,
    links: Vec<String>,
    wrapping: Option<WrappedBlock<()>>,
}

impl TextRenderer {
    /// Construct a new empty TextRenderer.
    pub fn new(width: usize) -> TextRenderer {
        html_trace!("new({})", width);
        TextRenderer {
            width: width,
            lines: Vec::new(),
            at_block_end: false,
            links: Vec::new(),
            wrapping: None,
        }
    }

    /// Get the current line wrapping context (and create if
    /// needed).
    fn current_text(&mut self) -> &mut WrappedBlock<()> {
        if self.wrapping.is_none() {
            self.wrapping = Some(WrappedBlock::new(self.width));
        }
        self.wrapping.as_mut().unwrap()
    }

    pub fn add_subblock(&mut self, s: &str) {
        html_trace!("add_subblock({}, {})", self.width, s);
        self.lines.extend(s.lines().map(|l| l.into()));
    }

    fn flush_wrapping(&mut self) {
        if let Some(w) = self.wrapping.take() {
            self.lines.extend(w.into_untagged_lines())
        }
    }

    pub fn into_string(self) -> String {
        let mut result = String::new();
        for s in self.into_lines() {
            result.push_str(&s);
            result.push('\n');
        }
        html_trace!("into_string({}, {:?})", self.width, result);
        result
    }

    fn into_lines(mut self) -> Vec<String> {
        self.flush_wrapping();
        // And add the links
        if self.links.len() > 0 {
            self.start_block();
            for (idx, target) in self.links.drain((0..)).enumerate() {
                /* Hard wrap */
                let mut output = String::new();
                let mut pos = 0;
                for c in format!("[{}] {}", idx+1, target).chars() {
                    let c_width = UnicodeWidthChar::width(c).unwrap();
                    if pos + c_width > self.width {
                        let mut tmp_s = String::new();
                        mem::swap(&mut output, &mut tmp_s);
                        self.lines.push(tmp_s);
                        output.push(c);
                        pos = c_width;
                    } else {
                        output.push(c);
                        pos += c_width;
                    }
                }
                self.lines.push(output);
            }
        }
        self.lines
    }
}

impl Renderer for TextRenderer {
    type Sub = TextRenderer;

    fn add_empty_line(&mut self) {
        html_trace!("add_empty_line()");
        self.flush_wrapping();
        self.lines.push("".into());
        html_trace_quiet!("add_empty_line: at_block_end <- false");
        self.at_block_end = false;
        html_trace_quiet!("add_empty_line: new lines: {:?}", self.lines);
    }

    fn new_sub_renderer(&self, width: usize) -> Self::Sub {
        TextRenderer::new(width)
    }

    fn start_block(&mut self) {
        html_trace!("start_block({})", self.width);
        self.flush_wrapping();
        if self.lines.len() > 0 {
            self.add_empty_line();
        }
        html_trace_quiet!("start_block; at_block_end <- false");
        self.at_block_end = false;
    }

    fn add_preformatted_block(&mut self, text: &str) {
        html_trace!("add_block({}, {})", self.width, text);
        self.start_block();
        self.add_subblock(text);
        html_trace_quiet!("add_block: at_block_end <- true");
        self.at_block_end = true;
    }

    fn end_block(&mut self) {
        self.at_block_end = true;
    }

    fn add_inline_text(&mut self, text: &str) {
        html_trace!("add_inline_text({}, {})", self.width, text);
        let mut partial = self.current_text();
        partial.add_text(text, ());
    }

    fn width(&self) -> usize {
        self.width
    }

    fn add_block_line(&mut self, line: &str)
    {
        self.add_subblock(line);
    }

    fn append_subrender<'a, I>(&mut self, other: Self::Sub,
                               prefixes: I)
                           where I:Iterator<Item=&'a str>
    {
        self.flush_wrapping();
        self.lines.extend(other.into_lines()
                               .into_iter()
                               .zip(prefixes)
                               .map(|(line, prefix)| prefix.to_string() + &line));
    }

    fn append_columns<I>(&mut self, cols: I, separator: char)
                           where I:IntoIterator<Item=Self::Sub> {
        self.flush_wrapping();

        let line_sets = cols.into_iter()
                            .map(|sub_r| {
                                let width = sub_r.width;
                                (width, sub_r.into_lines()
                                             .into_iter()
                                             .map(|line| format!("{: <width$}", line, width=width))
                                             .collect())
                                 })
                            .collect::<Vec<(usize, Vec<String>)>>();

        let cell_height = line_sets.iter()
                                   .map(|&(_, ref v)| v.len())
                                   .max().unwrap_or(0);
        let spaces:String = (0..self.width).map(|_| ' ').collect();
        for i in 0..cell_height {
            let mut line = String::new();
            for (cellno, &(width, ref ls)) in line_sets.iter().enumerate() {
                let piece = ls.get(i).map(|s| s.as_str()).unwrap_or(&spaces[0..width]);
                line.push_str(piece);
                if cellno != line_sets.len()-1 {
                    line.push(separator)
                }
            }
            self.add_block_line(&line);
        }
    }

    fn empty(&self) -> bool {
        self.lines.len() == 0 && self.wrapping.is_none()
    }

    fn text_len(&self) -> usize {
        let mut result = 0;
        for line in &self.lines {
            result += UnicodeWidthStr::width(line.as_str());
        }
        if let Some(ref w) = self.wrapping {
            result += w.text_len();
        }
        result
    }

    fn start_link(&mut self, target: &str)
    {
        self.links.push(target.to_string());
        self.add_inline_text("[");
    }
    fn end_link(&mut self)
    {
        let idx = self.links.len();
        self.add_inline_text(&format!("][{}]", idx));
    }
}<commit_msg>Implement the actual wrapping (except for overly-long words).<commit_after>use unicode_width::{UnicodeWidthStr,UnicodeWidthChar};
use super::Renderer;
use std::mem;
use std::fmt::Debug;

/// A wrapper around a String with extra metadata.
#[derive(Debug)]
struct TaggedString<T:Debug> {
    s: String,
    tag: T,
}

/// A type to build up wrapped text, allowing extra metadata for
/// spans.
#[derive(Debug)]
struct WrappedBlock<T:Clone+Eq+Debug> {
    width: usize,
    text: Vec<Vec<TaggedString<T>>>,
    textlen: usize,
    line: Vec<TaggedString<T>>,
    linelen: usize,
    spacetag: Option<T>,         // Tag for the whitespace before the current word
    word: Vec<TaggedString<T>>,  // The current word (with no whitespace).
    wordlen: usize,
}

impl<T:Clone+Eq+Debug> WrappedBlock<T> {
    pub fn new(width: usize) -> WrappedBlock<T> {
        WrappedBlock {
            width: width,
            text: Vec::new(),
            textlen: 0,
            line: Vec::new(),
            linelen: 0,
            spacetag: None,
            word: Vec::new(),
            wordlen: 0,
        }
    }

    fn flush_word(&mut self) {
        /* Finish the word. */
        if self.word.len() > 0 {
            let space_in_line = self.width - self.linelen
                        - if self.linelen > 0 { 1 } else { 0 }; // space
            if self.wordlen <= space_in_line {
                if self.linelen > 0 {
                    self.line.push(TaggedString{s: " ".into(), tag: self.spacetag.take().unwrap()});
                    self.linelen += 1;
                }
                self.line.extend(self.word.drain(..));
                self.linelen += self.wordlen;
                self.wordlen = 0;
            } else {
                /* Start a new line */
                self.flush_line();
                if self.wordlen <= self.width {
                    let mut new_word = Vec::new();
                    mem::swap(&mut new_word, &mut self.word);
                    mem::swap(&mut self.line, &mut new_word);
                } else {
                    unimplemented!()
                }
            }
        }
    }

    fn flush_line(&mut self) {
        if self.line.len() > 0 {
            let mut tmp_line = Vec::new();
            mem::swap(&mut tmp_line, &mut self.line);
            self.text.push(tmp_line);
            self.linelen = 0;
        }
    }

    fn flush(&mut self) {
        self.flush_word();
        self.flush_line();
    }

    /// Consume self and return a vector of lines.
    pub fn into_untagged_lines(mut self) -> Vec<String> {
        self.flush();

        let mut result = Vec::new();
        for line in self.text.into_iter() {
            let mut line_s = String::new();
            for TaggedString{ s, .. } in line.into_iter() {
                line_s.push_str(&s);
            }
            result.push(line_s);
        }
        result
    }

    pub fn add_text(&mut self, text: &str, tag: T) {
        for c in text.chars() {
            if c.is_whitespace() {
                /* Whitespace is mostly ignored, except to terminate words. */
                self.flush_word();
                self.spacetag = Some(tag.clone());
            } else {
                /* Not whitespace; add to the current word. */
                if self.word.len() > 0 && self.word[self.word.len()-1].tag == tag {
                    /* Just add a character to the last piece */
                    let last_idx = self.word.len() - 1;
                    self.word[last_idx].s.push(c);
                } else {
                    /* Starting a new word; easy. */
                    let mut s = String::new();
                    s.push(c);
                    self.word.push(TaggedString{ s: s, tag: tag.clone()});
                }
                self.wordlen += UnicodeWidthChar::width(c).unwrap();
            }
        }
    }

    pub fn text_len(&self) -> usize {
        self.textlen + self.linelen + self.wordlen
    }
}

/// A renderer which just outputs plain text.
pub struct TextRenderer {
    width: usize,
    lines: Vec<String>,
    /// True at the end of a block, meaning we should add
    /// a blank line if any other text is added.
    at_block_end: bool,
    links: Vec<String>,
    wrapping: Option<WrappedBlock<()>>,
}

impl TextRenderer {
    /// Construct a new empty TextRenderer.
    pub fn new(width: usize) -> TextRenderer {
        html_trace!("new({})", width);
        TextRenderer {
            width: width,
            lines: Vec::new(),
            at_block_end: false,
            links: Vec::new(),
            wrapping: None,
        }
    }

    /// Get the current line wrapping context (and create if
    /// needed).
    fn current_text(&mut self) -> &mut WrappedBlock<()> {
        if self.wrapping.is_none() {
            self.wrapping = Some(WrappedBlock::new(self.width));
        }
        self.wrapping.as_mut().unwrap()
    }

    pub fn add_subblock(&mut self, s: &str) {
        html_trace!("add_subblock({}, {})", self.width, s);
        self.lines.extend(s.lines().map(|l| l.into()));
    }

    fn flush_wrapping(&mut self) {
        if let Some(w) = self.wrapping.take() {
            self.lines.extend(w.into_untagged_lines())
        }
    }

    pub fn into_string(self) -> String {
        let mut result = String::new();
        for s in self.into_lines() {
            result.push_str(&s);
            result.push('\n');
        }
        html_trace!("into_string({}, {:?})", self.width, result);
        result
    }

    fn into_lines(mut self) -> Vec<String> {
        self.flush_wrapping();
        // And add the links
        if self.links.len() > 0 {
            self.start_block();
            for (idx, target) in self.links.drain((0..)).enumerate() {
                /* Hard wrap */
                let mut output = String::new();
                let mut pos = 0;
                for c in format!("[{}] {}", idx+1, target).chars() {
                    let c_width = UnicodeWidthChar::width(c).unwrap();
                    if pos + c_width > self.width {
                        let mut tmp_s = String::new();
                        mem::swap(&mut output, &mut tmp_s);
                        self.lines.push(tmp_s);
                        output.push(c);
                        pos = c_width;
                    } else {
                        output.push(c);
                        pos += c_width;
                    }
                }
                self.lines.push(output);
            }
        }
        self.lines
    }
}

impl Renderer for TextRenderer {
    type Sub = TextRenderer;

    fn add_empty_line(&mut self) {
        html_trace!("add_empty_line()");
        self.flush_wrapping();
        self.lines.push("".into());
        html_trace_quiet!("add_empty_line: at_block_end <- false");
        self.at_block_end = false;
        html_trace_quiet!("add_empty_line: new lines: {:?}", self.lines);
    }

    fn new_sub_renderer(&self, width: usize) -> Self::Sub {
        TextRenderer::new(width)
    }

    fn start_block(&mut self) {
        html_trace!("start_block({})", self.width);
        self.flush_wrapping();
        if self.lines.len() > 0 {
            self.add_empty_line();
        }
        html_trace_quiet!("start_block; at_block_end <- false");
        self.at_block_end = false;
    }

    fn add_preformatted_block(&mut self, text: &str) {
        html_trace!("add_block({}, {})", self.width, text);
        self.start_block();
        self.add_subblock(text);
        html_trace_quiet!("add_block: at_block_end <- true");
        self.at_block_end = true;
    }

    fn end_block(&mut self) {
        self.at_block_end = true;
    }

    fn add_inline_text(&mut self, text: &str) {
        html_trace!("add_inline_text({}, {})", self.width, text);
        let mut partial = self.current_text();
        partial.add_text(text, ());
    }

    fn width(&self) -> usize {
        self.width
    }

    fn add_block_line(&mut self, line: &str)
    {
        self.add_subblock(line);
    }

    fn append_subrender<'a, I>(&mut self, other: Self::Sub,
                               prefixes: I)
                           where I:Iterator<Item=&'a str>
    {
        self.flush_wrapping();
        self.lines.extend(other.into_lines()
                               .into_iter()
                               .zip(prefixes)
                               .map(|(line, prefix)| prefix.to_string() + &line));
    }

    fn append_columns<I>(&mut self, cols: I, separator: char)
                           where I:IntoIterator<Item=Self::Sub> {
        self.flush_wrapping();

        let line_sets = cols.into_iter()
                            .map(|sub_r| {
                                let width = sub_r.width;
                                (width, sub_r.into_lines()
                                             .into_iter()
                                             .map(|line| format!("{: <width$}", line, width=width))
                                             .collect())
                                 })
                            .collect::<Vec<(usize, Vec<String>)>>();

        let cell_height = line_sets.iter()
                                   .map(|&(_, ref v)| v.len())
                                   .max().unwrap_or(0);
        let spaces:String = (0..self.width).map(|_| ' ').collect();
        for i in 0..cell_height {
            let mut line = String::new();
            for (cellno, &(width, ref ls)) in line_sets.iter().enumerate() {
                let piece = ls.get(i).map(|s| s.as_str()).unwrap_or(&spaces[0..width]);
                line.push_str(piece);
                if cellno != line_sets.len()-1 {
                    line.push(separator)
                }
            }
            self.add_block_line(&line);
        }
    }

    fn empty(&self) -> bool {
        self.lines.len() == 0 && self.wrapping.is_none()
    }

    fn text_len(&self) -> usize {
        let mut result = 0;
        for line in &self.lines {
            result += UnicodeWidthStr::width(line.as_str());
        }
        if let Some(ref w) = self.wrapping {
            result += w.text_len();
        }
        result
    }

    fn start_link(&mut self, target: &str)
    {
        self.links.push(target.to_string());
        self.add_inline_text("[");
    }
    fn end_link(&mut self)
    {
        let idx = self.links.len();
        self.add_inline_text(&format!("][{}]", idx));
    }
}<|endoftext|>


<commit_before>use crate::{
    interrupt::stack_trace,
    syscall,
    syscall::flag::*,

    with_exception_stack,
    exception_stack,
};

exception_stack!(synchronous_exception_at_el1_with_sp0, |stack| {
    println!("Synchronous exception at EL1 with SP0");
    stack.dump();
    stack_trace();
    loop {}
});

exception_stack!(synchronous_exception_at_el1_with_spx, |stack| {
    println!("Synchronous exception at EL1 with SPx");
    stack.dump();
    stack_trace();
    loop {}
});

exception_stack!(synchronous_exception_at_el0, |stack| {
    with_exception_stack!(|stack| {
        let fp;
        asm!("mov {}, fp", out(reg) fp);

        let exception_code = (stack.iret.esr_el1 & (0x3f << 26)) >> 26;
        if exception_code != 0b010101 {
            println!("FATAL: Not an SVC induced synchronous exception");
            stack.dump();
            stack_trace();
            loop {}
        }

        let scratch = &stack.scratch;
        syscall::syscall(scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, fp, stack)
    });
});

exception_stack!(unhandled_exception, |stack| {
    println!("Unhandled exception");
    stack.dump();
    stack_trace();
    loop {}
});
<commit_msg>Print CPU and PID when exception occurs<commit_after>use crate::{
    context,
    cpu_id,
    interrupt::stack_trace,
    syscall,
    syscall::flag::*,

    with_exception_stack,
    exception_stack,
};

exception_stack!(synchronous_exception_at_el1_with_sp0, |stack| {
    println!("Synchronous exception at EL1 with SP0");
    stack.dump();
    stack_trace();
    loop {}
});

exception_stack!(synchronous_exception_at_el1_with_spx, |stack| {
    println!("Synchronous exception at EL1 with SPx");
    stack.dump();
    stack_trace();
    loop {}
});

exception_stack!(synchronous_exception_at_el0, |stack| {
    with_exception_stack!(|stack| {
        let fp;
        asm!("mov {}, fp", out(reg) fp);

        let exception_code = (stack.iret.esr_el1 & (0x3f << 26)) >> 26;
        if exception_code != 0b010101 {
            println!("FATAL: Not an SVC induced synchronous exception");
            stack.dump();
            stack_trace();
            println!("CPU {}, PID {:?}", cpu_id(), context::context_id());
            loop {}
        }

        let scratch = &stack.scratch;
        syscall::syscall(scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, fp, stack)
    });
});

exception_stack!(unhandled_exception, |stack| {
    println!("Unhandled exception");
    stack.dump();
    stack_trace();
    loop {}
});
<|endoftext|>


<commit_before>#![warn(clippy::random_state)]

use std::collections::hash_map::RandomState;
use std::collections::hash_map::{DefaultHasher, HashMap};
use std::hash::{BuildHasherDefault};

fn main() {
    // Should warn
    let mut map = HashMap::new();
    map.insert(3, 4);
    let mut map = HashMap::with_hasher(RandomState::new());
    map.insert(true, false);
    let _map: HashMap<_, _> = vec![(2, 3)].into_iter().collect();
    let _vec: Vec<HashMap<i32, i32>>;
    // Shouldn't warn
    let _map: HashMap<i32, i32, BuildHasherDefault<DefaultHasher>> = HashMap::default();
    let mut map = HashMap::with_hasher(BuildHasherDefault::<DefaultHasher>::default());
    map.insert("a", "b");
}
<commit_msg>Reformat random_state tests<commit_after>#![warn(clippy::random_state)]

use std::collections::hash_map::RandomState;
use std::collections::hash_map::{DefaultHasher, HashMap};
use std::hash::BuildHasherDefault;

fn main() {
    // Should warn
    let mut map = HashMap::new();
    map.insert(3, 4);
    let mut map = HashMap::with_hasher(RandomState::new());
    map.insert(true, false);
    let _map: HashMap<_, _> = vec![(2, 3)].into_iter().collect();
    let _vec: Vec<HashMap<i32, i32>>;
    // Shouldn't warn
    let _map: HashMap<i32, i32, BuildHasherDefault<DefaultHasher>> = HashMap::default();
    let mut map = HashMap::with_hasher(BuildHasherDefault::<DefaultHasher>::default());
    map.insert("a", "b");
}
<|endoftext|>


<commit_before>use futures::Async;
use futures::Poll;
use futures::future::Future;
use futures::stream::Stream;
use futures::sync::mpsc::UnboundedSender;

use void::Void;

use solicit::StreamId;

use rc_mut::RcMut;

use stream_part::HttpPartStream;
use stream_part::HttpStreamPartContent;

use error::ErrorCode;

use super::*;

/// Poll the stream and enqueues frames
pub struct PumpStreamToWriteLoop<T : Types> {
    // TODO: this is not thread-safe
    pub conn_rc: RcMut<ConnData<T>>,
    pub to_write_tx: UnboundedSender<T::ToWriteMessage>,
    pub stream_id: StreamId,
    pub out_window: window_size::StreamOutWindowReceiver,
    pub stream: HttpPartStream,
}

//unsafe impl <T : Types> Send for PumpStreamToWriteLoop<T> {}
//unsafe impl <T : Types> Sync for PumpStreamToWriteLoop<T> {}

impl<T : Types> Future for PumpStreamToWriteLoop<T> {
    type Item = ();
    type Error = Void;

    fn poll(&mut self) -> Poll<(), Void> {
        loop {
            match self.out_window.poll() {
                Ok(Async::NotReady) => return Ok(Async::NotReady),
                Ok(Async::Ready(())) => {}
                Err(window_size::StreamDead::Conn) => {
                    warn!("conn dead");
                    return Ok(Async::Ready(()));
                }
                Err(window_size::StreamDead::Stream) => {
                    warn!("stream {} dead", self.stream_id);
                    return Ok(Async::Ready(()));
                }
            }

            let part_opt = match self.stream.poll() {
                Ok(Async::NotReady) => return Ok(Async::NotReady),
                Ok(Async::Ready(r)) => r,
                Err(e) => {
                    warn!("stream error: {:?}", e);
                    let stream_end = CommonToWriteMessage::StreamEnd(self.stream_id, ErrorCode::InternalError);
                    if let Err(e) = self.to_write_tx.send(stream_end.into()) {
                        warn!("failed to write to channel, probably connection is closed: {:?}", e);
                    }
                    break;
                },
            };

            let mut conn = self.conn_rc.borrow_mut();
            let conn: &mut ConnData<T> = &mut conn;

            if let Some(mut stream) = conn.streams.get_mut(self.stream_id) {
                if stream.stream().state.is_closed_local() {
                    break;
                }

                match part_opt {
                    Some(part) => {
                        match &part.content {
                            &HttpStreamPartContent::Data(ref d) => {
                                self.out_window.decrease(d.len());
                            }
                            &HttpStreamPartContent::Headers(_) => {
                            }
                        }

                        stream.stream().outgoing.push_back_part(part);

                        let flush_stream = CommonToWriteMessage::TryFlushStream(Some(self.stream_id));
                        if let Err(e) = self.to_write_tx.send(flush_stream.into()) {
                            warn!("failed to write to channel, probably connection is closed: {:?}", e);
                        }

                        continue;
                    }
                    None => {
                        let msg = CommonToWriteMessage::StreamEnd(self.stream_id, ErrorCode::NoError);
                        if let Err(e) = self.to_write_tx.send(msg.into()) {
                            warn!("failed to write to channel, probably connection is closed: {:?}", e);
                        }

                        break;
                    }
                }
            } else {
                break;
            }
        }

        Ok(Async::Ready(()))
    }
}
<commit_msg>Unnecessary check<commit_after>use futures::Async;
use futures::Poll;
use futures::future::Future;
use futures::stream::Stream;
use futures::sync::mpsc::UnboundedSender;

use void::Void;

use solicit::StreamId;

use rc_mut::RcMut;

use stream_part::HttpPartStream;
use stream_part::HttpStreamPartContent;

use error::ErrorCode;

use super::*;

/// Poll the stream and enqueues frames
pub struct PumpStreamToWriteLoop<T : Types> {
    // TODO: this is not thread-safe
    pub conn_rc: RcMut<ConnData<T>>,
    pub to_write_tx: UnboundedSender<T::ToWriteMessage>,
    pub stream_id: StreamId,
    pub out_window: window_size::StreamOutWindowReceiver,
    pub stream: HttpPartStream,
}

//unsafe impl <T : Types> Send for PumpStreamToWriteLoop<T> {}
//unsafe impl <T : Types> Sync for PumpStreamToWriteLoop<T> {}

impl<T : Types> Future for PumpStreamToWriteLoop<T> {
    type Item = ();
    type Error = Void;

    fn poll(&mut self) -> Poll<(), Void> {
        loop {
            match self.out_window.poll() {
                Ok(Async::NotReady) => return Ok(Async::NotReady),
                Ok(Async::Ready(())) => {}
                Err(window_size::StreamDead::Conn) => {
                    warn!("conn dead");
                    return Ok(Async::Ready(()));
                }
                Err(window_size::StreamDead::Stream) => {
                    warn!("stream {} dead", self.stream_id);
                    return Ok(Async::Ready(()));
                }
            }

            let part_opt = match self.stream.poll() {
                Ok(Async::NotReady) => return Ok(Async::NotReady),
                Ok(Async::Ready(r)) => r,
                Err(e) => {
                    warn!("stream error: {:?}", e);
                    let stream_end = CommonToWriteMessage::StreamEnd(self.stream_id, ErrorCode::InternalError);
                    if let Err(e) = self.to_write_tx.send(stream_end.into()) {
                        warn!("failed to write to channel, probably connection is closed: {:?}", e);
                    }
                    break;
                },
            };

            let mut conn = self.conn_rc.borrow_mut();
            let conn: &mut ConnData<T> = &mut conn;

            if let Some(mut stream) = conn.streams.get_mut(self.stream_id) {
                match part_opt {
                    Some(part) => {
                        match &part.content {
                            &HttpStreamPartContent::Data(ref d) => {
                                self.out_window.decrease(d.len());
                            }
                            &HttpStreamPartContent::Headers(_) => {
                            }
                        }

                        stream.stream().outgoing.push_back_part(part);

                        let flush_stream = CommonToWriteMessage::TryFlushStream(Some(self.stream_id));
                        if let Err(e) = self.to_write_tx.send(flush_stream.into()) {
                            warn!("failed to write to channel, probably connection is closed: {:?}", e);
                        }

                        continue;
                    }
                    None => {
                        let msg = CommonToWriteMessage::StreamEnd(self.stream_id, ErrorCode::NoError);
                        if let Err(e) = self.to_write_tx.send(msg.into()) {
                            warn!("failed to write to channel, probably connection is closed: {:?}", e);
                        }

                        break;
                    }
                }
            } else {
                break;
            }
        }

        Ok(Async::Ready(()))
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate proc_macro2;
extern crate syn;

use proc_macro2::{Span, TokenStream};
use std::str::FromStr;
use syn::synom::ParseError;
use syn::Ident;

fn parse(s: &str) -> Result<Ident, ParseError> {
    syn::parse2(TokenStream::from_str(s).unwrap())
}

fn new(s: &str) -> Ident {
    Ident::new(s, Span::call_site())
}

#[test]
fn ident_parse() {
    parse("String").unwrap();
}

#[test]
fn ident_parse_keyword() {
    parse("abstract").unwrap_err();
}

#[test]
fn ident_parse_empty() {
    parse("").unwrap_err();
}

#[test]
fn ident_parse_lifetime() {
    parse("'static").unwrap_err();
}

#[test]
fn ident_parse_underscore() {
    parse("_").unwrap_err();
}

#[test]
fn ident_parse_number() {
    parse("255").unwrap_err();
}

#[test]
fn ident_parse_invalid() {
    parse("a#").unwrap_err();
}

#[test]
fn ident_new() {
    new("String");
}

#[test]
fn ident_new_keyword() {
    new("abstract");
}

#[test]
#[should_panic(expected = "ident is not allowed to be empty; use Option<Ident>")]
fn ident_new_empty() {
    new("");
}

#[test]
#[should_panic(expected = "ident is not allowed to be a lifetime; use syn::Lifetime")]
fn ident_new_lifetime() {
    new("'static");
}

#[test]
fn ident_new_underscore() {
    new("_");
}

#[test]
#[should_panic(expected = "ident cannot be a number, use syn::Index instead")]
fn ident_new_number() {
    new("255");
}

#[test]
#[should_panic(expected = "\"a#\" is not a valid ident")]
fn ident_new_invalid() {
    new("a#");
}
<commit_msg>Fix test_ident<commit_after>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate proc_macro2;
extern crate syn;

use proc_macro2::{Span, TokenStream, Ident};
use std::str::FromStr;
use syn::synom::ParseError;

fn parse(s: &str) -> Result<Ident, ParseError> {
    syn::parse2(TokenStream::from_str(s).unwrap())
}

fn new(s: &str) -> Ident {
    Ident::new(s, Span::call_site())
}

#[test]
fn ident_parse() {
    parse("String").unwrap();
}

#[test]
fn ident_parse_keyword() {
    parse("abstract").unwrap();
}

#[test]
fn ident_parse_empty() {
    parse("").unwrap_err();
}

#[test]
fn ident_parse_lifetime() {
    parse("'static").unwrap_err();
}

#[test]
fn ident_parse_underscore() {
    parse("_").unwrap();
}

#[test]
fn ident_parse_number() {
    parse("255").unwrap_err();
}

#[test]
fn ident_parse_invalid() {
    parse("a#").unwrap_err();
}

#[test]
fn ident_new() {
    new("String");
}

#[test]
fn ident_new_keyword() {
    new("abstract");
}

#[test]
#[should_panic(expected = "use Option<Ident>")]
fn ident_new_empty() {
    new("");
}

#[test]
#[should_panic(expected = "not a valid Ident")]
fn ident_new_lifetime() {
    new("'static");
}

#[test]
fn ident_new_underscore() {
    new("_");
}

#[test]
#[should_panic(expected = "use Literal instead")]
fn ident_new_number() {
    new("255");
}

#[test]
#[should_panic(expected = "\"a#\" is not a valid Ident")]
fn ident_new_invalid() {
    new("a#");
}
<|endoftext|>


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

<%namespace name="helpers" file="/helpers.mako.rs" />

<% data.new_style_struct("Pointing", inherited=True, gecko_name="UserInterface") %>

${helpers.predefined_type("cursor",
                          "Cursor",
                          "computed::Cursor::auto()",
                          initial_specified_value="specified::Cursor::auto()",
                          animation_value_type="discrete",
                          spec="https://drafts.csswg.org/css-ui/#cursor")}

// NB: `pointer-events: auto` (and use of `pointer-events` in anything that isn't SVG, in fact)
// is nonstandard, slated for CSS4-UI.
// TODO(pcwalton): SVG-only values.
${helpers.single_keyword("pointer-events", "auto none", animation_value_type="discrete",
                         extra_gecko_values="visiblepainted visiblefill visiblestroke visible painted fill stroke all",
                         flags="APPLIES_TO_PLACEHOLDER",
                         spec="https://www.w3.org/TR/SVG11/interact.html#PointerEventsProperty")}

${helpers.single_keyword("-moz-user-input", "auto none enabled",
                         products="gecko", gecko_ffi_name="mUserInput",
                         gecko_enum_prefix="StyleUserInput",
                         animation_value_type="discrete",
                         spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-user-input)")}

${helpers.single_keyword("-moz-user-modify", "read-only read-write write-only",
                         products="gecko", gecko_ffi_name="mUserModify",
                         gecko_enum_prefix="StyleUserModify",
                         needs_conversion=True,
                         animation_value_type="discrete",
                         spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-user-modify)")}

${helpers.single_keyword("-moz-user-focus",
                         "none ignore normal select-after select-before select-menu select-same select-all",
                         products="gecko", gecko_ffi_name="mUserFocus",
                         gecko_enum_prefix="StyleUserFocus",
                         animation_value_type="discrete",
                         spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-user-focus)")}

${helpers.predefined_type(
    "caret-color",
    "ColorOrAuto",
    "Either::Second(Auto)",
    spec="https://drafts.csswg.org/css-ui/#caret-color",
    animation_value_type="Either<AnimatedColor, Auto>",
    boxed=not RUSTC_HAS_PR45225,
    ignored_when_colors_disabled=True,
    products="gecko",
)}
<commit_msg>style: Also nix -moz-user-input: enabled.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />

<% data.new_style_struct("Pointing", inherited=True, gecko_name="UserInterface") %>

${helpers.predefined_type("cursor",
                          "Cursor",
                          "computed::Cursor::auto()",
                          initial_specified_value="specified::Cursor::auto()",
                          animation_value_type="discrete",
                          spec="https://drafts.csswg.org/css-ui/#cursor")}

// NB: `pointer-events: auto` (and use of `pointer-events` in anything that isn't SVG, in fact)
// is nonstandard, slated for CSS4-UI.
// TODO(pcwalton): SVG-only values.
${helpers.single_keyword("pointer-events", "auto none", animation_value_type="discrete",
                         extra_gecko_values="visiblepainted visiblefill visiblestroke visible painted fill stroke all",
                         flags="APPLIES_TO_PLACEHOLDER",
                         spec="https://www.w3.org/TR/SVG11/interact.html#PointerEventsProperty")}

${helpers.single_keyword("-moz-user-input", "auto none",
                         products="gecko", gecko_ffi_name="mUserInput",
                         gecko_enum_prefix="StyleUserInput",
                         animation_value_type="discrete",
                         spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-user-input)")}

${helpers.single_keyword("-moz-user-modify", "read-only read-write write-only",
                         products="gecko", gecko_ffi_name="mUserModify",
                         gecko_enum_prefix="StyleUserModify",
                         needs_conversion=True,
                         animation_value_type="discrete",
                         spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-user-modify)")}

${helpers.single_keyword("-moz-user-focus",
                         "none ignore normal select-after select-before select-menu select-same select-all",
                         products="gecko", gecko_ffi_name="mUserFocus",
                         gecko_enum_prefix="StyleUserFocus",
                         animation_value_type="discrete",
                         spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-user-focus)")}

${helpers.predefined_type(
    "caret-color",
    "ColorOrAuto",
    "Either::Second(Auto)",
    spec="https://drafts.csswg.org/css-ui/#caret-color",
    animation_value_type="Either<AnimatedColor, Auto>",
    boxed=not RUSTC_HAS_PR45225,
    ignored_when_colors_disabled=True,
    products="gecko",
)}
<|endoftext|>