<commit_before>use Printer;
use With;
use direction::Direction;
use event::{Event, EventResult};
use std::any::Any;
use std::cell;
use std::ops::Deref;
use theme::ColorStyle;
use vec::Vec2;
use view::{AnyView, Offset, Position, Selector, View, ViewWrapper};
use views::{Layer, ShadowView};

/// Simple stack of views.
/// Only the top-most view is active and can receive input.
pub struct StackView {
    // Store layers from back to front.
    layers: Vec<Child>,
    last_size: Vec2,
    // Flag indicates if undrawn areas of the background are exposed
    // and therefore need redrawing.
    bg_dirty: cell::Cell<bool>,
}

enum Placement {
    Floating(Position),
    Fullscreen,
}

/// Identifies a layer in a `StackView`.
#[derive(Clone, Copy, Debug)]
pub enum LayerPosition {
    /// Starts from the back (bottom) of the stack.
    FromBack(usize),
    /// Starts from the front (top) of the stack.
    FromFront(usize),
}

impl Placement {
    pub fn compute_offset<S, A, P>(
        &self, size: S, available: A, parent: P
    ) -> Vec2
    where
        S: Into<Vec2>,
        A: Into<Vec2>,
        P: Into<Vec2>,
    {
        match *self {
            Placement::Floating(ref position) => {
                position.compute_offset(size, available, parent)
            }
            Placement::Fullscreen => Vec2::zero(),
        }
    }
}

// A child view can be wrapped in multiple ways.
enum ChildWrapper<T: View> {
    // Some views include a shadow around.
    Shadow(ShadowView<Layer<T>>),
    // Some views don't (fullscreen views mostly)
    Plain(Layer<T>),
}

impl<T: View> ChildWrapper<T> {
    fn unwrap(self) -> T {
        match self {
            // ShadowView::into_inner and Layer::into_inner can never fail.
            ChildWrapper::Shadow(shadow) => {
                shadow.into_inner().ok().unwrap().into_inner().ok().unwrap()
            }
            ChildWrapper::Plain(layer) => layer.into_inner().ok().unwrap(),
        }
    }
}

// TODO: use macros to make this less ugly?
impl<T: View> View for ChildWrapper<T> {
    fn draw(&self, printer: &Printer) {
        match *self {
            ChildWrapper::Shadow(ref v) => v.draw(printer),
            ChildWrapper::Plain(ref v) => v.draw(printer),
        }
    }

    fn on_event(&mut self, event: Event) -> EventResult {
        match *self {
            ChildWrapper::Shadow(ref mut v) => v.on_event(event),
            ChildWrapper::Plain(ref mut v) => v.on_event(event),
        }
    }

    fn layout(&mut self, size: Vec2) {
        match *self {
            ChildWrapper::Shadow(ref mut v) => v.layout(size),
            ChildWrapper::Plain(ref mut v) => v.layout(size),
        }
    }

    fn required_size(&mut self, size: Vec2) -> Vec2 {
        match *self {
            ChildWrapper::Shadow(ref mut v) => v.required_size(size),
            ChildWrapper::Plain(ref mut v) => v.required_size(size),
        }
    }

    fn take_focus(&mut self, source: Direction) -> bool {
        match *self {
            ChildWrapper::Shadow(ref mut v) => v.take_focus(source),
            ChildWrapper::Plain(ref mut v) => v.take_focus(source),
        }
    }

    fn call_on_any<'a>(
        &mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a>
    ) {
        match *self {
            ChildWrapper::Shadow(ref mut v) => {
                v.call_on_any(selector, callback)
            }
            ChildWrapper::Plain(ref mut v) => {
                v.call_on_any(selector, callback)
            }
        }
    }

    fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
        match *self {
            ChildWrapper::Shadow(ref mut v) => v.focus_view(selector),
            ChildWrapper::Plain(ref mut v) => v.focus_view(selector),
        }
    }
}

struct Child {
    view: ChildWrapper<Box<AnyView>>,
    size: Vec2,
    placement: Placement,

    // We cannot call `take_focus` until we've called `layout()`
    // (for instance, a textView must know it will scroll to be focusable).
    // So we want to call `take_focus` right after the first call to `layout`.
    // This flag remembers when we've done that.
    virgin: bool,
}

new_default!(StackView);

impl StackView {
    /// Creates a new empty StackView
    pub fn new() -> Self {
        StackView {
            layers: Vec::new(),
            last_size: Vec2::zero(),
            bg_dirty: cell::Cell::new(true),
        }
    }

    /// Adds a new full-screen layer on top of the stack.
    ///
    /// Fullscreen layers have no shadow.
    pub fn add_fullscreen_layer<T>(&mut self, view: T)
    where
        T: 'static + View,
    {
        let boxed: Box<AnyView> = Box::new(view);
        self.layers.push(Child {
            view: ChildWrapper::Plain(Layer::new(boxed)),
            size: Vec2::zero(),
            placement: Placement::Fullscreen,
            virgin: true,
        });
    }

    /// Adds new view on top of the stack in the center of the screen.
    pub fn add_layer<T>(&mut self, view: T)
    where
        T: 'static + View,
    {
        self.add_layer_at(Position::center(), view);
    }

    /// Adds new view on top of the stack in the center of the screen.
    ///
    /// Chainable variant.
    pub fn layer<T>(self, view: T) -> Self
    where
        T: 'static + View,
    {
        self.with(|s| s.add_layer(view))
    }

    /// Adds a new full-screen layer on top of the stack.
    ///
    /// Chainable variant.
    pub fn fullscreen_layer<T>(self, view: T) -> Self
    where
        T: 'static + View,
    {
        self.with(|s| s.add_fullscreen_layer(view))
    }

    /// Adds a view on top of the stack.
    pub fn add_layer_at<T>(&mut self, position: Position, view: T)
    where
        T: 'static + View,
    {
        let boxed: Box<AnyView> = Box::new(view);
        self.layers.push(Child {
            // Skip padding for absolute/parent-placed views
            view: ChildWrapper::Shadow(
                ShadowView::new(Layer::new(boxed))
                    .top_padding(position.y == Offset::Center)
                    .left_padding(position.x == Offset::Center),
            ),
            size: Vec2::new(0, 0),
            placement: Placement::Floating(position),
            virgin: true,
        });
    }

    /// Adds a view on top of the stack.
    ///
    /// Chainable variant.
    pub fn layer_at<T>(self, position: Position, view: T) -> Self
    where
        T: 'static + View,
    {
        self.with(|s| s.add_layer_at(position, view))
    }

    /// Remove the top-most layer.
    pub fn pop_layer(&mut self) -> Option<Box<AnyView>> {
        self.bg_dirty.set(true);
        self.layers.pop().map(|child| child.view.unwrap())
    }

    /// Computes the offset of the current top view.
    pub fn offset(&self) -> Vec2 {
        let mut previous = Vec2::zero();
        for layer in &self.layers {
            let offset = layer.placement.compute_offset(
                layer.size,
                self.last_size,
                previous,
            );
            previous = offset;
        }
        previous
    }

    /// Returns the size for each layer in this view.
    pub fn layer_sizes(&self) -> Vec<Vec2> {
        self.layers.iter().map(|layer| layer.size).collect()
    }

    fn get_index(&self, pos: LayerPosition) -> usize {
        match pos {
            LayerPosition::FromBack(i) => i,
            LayerPosition::FromFront(i) => self.layers.len() - i - 1,
        }
    }

    /// Moves a layer to a new position in the stack.
    ///
    /// This only affects the elevation of a layer (whether it is drawn over
    /// or under other views).
    pub fn move_layer(&mut self, from: LayerPosition, to: LayerPosition) {
        // Convert relative positions to indices in the array
        let from_i = self.get_index(from);
        let to_i = self.get_index(to);

        let removed = self.layers.remove(from_i);

        self.layers.insert(to_i, removed);
    }

    /// Brings the given view to the front of the stack.
    pub fn move_to_front(&mut self, layer: LayerPosition) {
        self.move_layer(layer, LayerPosition::FromFront(0));
    }

    /// Pushes the given view to the back of the stack.
    pub fn move_to_back(&mut self, layer: LayerPosition) {
        self.move_layer(layer, LayerPosition::FromBack(0));
    }

    /// Moves a layer to a new position on the screen.
    ///
    /// Has no effect on fullscreen layers
    /// Has no effect if layer is not found
    pub fn reposition_layer(
        &mut self, layer: LayerPosition, position: Position
    ) {
        let i = self.get_index(layer);
        let child = match self.layers.get_mut(i) {
            Some(i) => i,
            None => return,
        };
        match child.placement {
            Placement::Floating(_) => {
                child.placement = Placement::Floating(position);
                self.bg_dirty.set(true);
            }
            Placement::Fullscreen => (),
        }
    }

    /// Background drawing
    /// Drawing functions are split into forground and background to
    /// ease inserting layers under the stackview but above it's background
    /// you probably just want to call draw()
    pub fn draw_bg(&self, printer: &Printer) {
        // If the background is dirty draw a new background
        if self.bg_dirty.get() {
            for y in 0..printer.size.y {
                printer.with_color(ColorStyle::background(), |printer| {
                    printer.print_hline((0, y), printer.size.x, " ");
                });
            }

            // set background as clean, so we don't need to do this every frame
            self.bg_dirty.set(false);
        }
    }

    /// Forground drawing
    /// Drawing functions are split into forground and background to
    /// ease inserting layers under the stackview but above it's background
    /// you probably just want to call draw()
    pub fn draw_fg(&self, printer: &Printer) {
        let last = self.layers.len();
        printer.with_color(ColorStyle::primary(), |printer| {
            for (i, (v, offset)) in
                StackPositionIterator::new(self.layers.iter(), printer.size)
                    .enumerate()
            {
                v.view.draw(&printer.sub_printer(
                    offset,
                    v.size,
                    i + 1 == last,
                ));
            }
        });
    }
}

struct StackPositionIterator<R: Deref<Target = Child>, I: Iterator<Item = R>> {
    inner: I,
    previous: Vec2,
    total_size: Vec2,
}

impl<R: Deref<Target = Child>, I: Iterator<Item = R>>
    StackPositionIterator<R, I>
{
    /// Returns a new StackPositionIterator
    pub fn new(inner: I, total_size: Vec2) -> Self {
        let previous = Vec2::zero();
        StackPositionIterator {
            inner,
            previous,
            total_size,
        }
    }
}

impl<R: Deref<Target = Child>, I: Iterator<Item = R>> Iterator
    for StackPositionIterator<R, I>
{
    type Item = (R, Vec2);

    fn next(&mut self) -> Option<(R, Vec2)> {
        self.inner.next().map(|v| {
            let offset = v.placement.compute_offset(
                v.size,
                self.total_size,
                self.previous,
            );

            self.previous = offset;

            // eprintln!("{:?}", offset);
            (v, offset)
        })
    }
}

impl View for StackView {
    fn draw(&self, printer: &Printer) {
        // This function is included for compat with the view trait,
        // it should behave the same as calling them seperately, but does
        // not pause to let you insert in between the layers.
        self.draw_bg(printer);
        self.draw_fg(printer);
    }

    fn on_event(&mut self, event: Event) -> EventResult {
        if event == Event::WindowResize {
            self.bg_dirty.set(true);
        }
        // Use the stack position iterator to get the offset of the top layer.
        // TODO: save it instead when drawing?
        match StackPositionIterator::new(
            self.layers.iter_mut(),
            self.last_size,
        ).last()
        {
            None => EventResult::Ignored,
            Some((v, offset)) => v.view.on_event(event.relativized(offset)),
        }
    }

    fn layout(&mut self, size: Vec2) {
        self.last_size = size;

        // The call has been made, we can't ask for more space anymore.
        // Let's make do with what we have.

        for layer in &mut self.layers {
            // Give each guy what he asks for, within the budget constraints.
            let size = Vec2::min(size, layer.view.required_size(size));
            layer.size = size;
            layer.view.layout(layer.size);

            // We need to call `layout()` on the view before giving it focus
            // for the first time. Otherwise it will not be properly set up.
            // Ex: examples/lorem.rs: the text view takes focus because it's
            // scrolling, but it only knows that after a call to `layout()`.
            if layer.virgin {
                layer.view.take_focus(Direction::none());
                layer.virgin = false;
            }
        }
    }

    fn required_size(&mut self, size: Vec2) -> Vec2 {
        // The min size is the max of all children's

        self.layers
            .iter_mut()
            .map(|layer| layer.view.required_size(size))
            .fold(Vec2::new(1, 1), Vec2::max)
    }

    fn take_focus(&mut self, source: Direction) -> bool {
        match self.layers.last_mut() {
            None => false,
            Some(v) => v.view.take_focus(source),
        }
    }

    fn call_on_any<'a>(
        &mut self, selector: &Selector,
        mut callback: Box<FnMut(&mut Any) + 'a>,
    ) {
        for layer in &mut self.layers {
            layer
                .view
                .call_on_any(selector, Box::new(|any| callback(any)));
        }
    }

    fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
        for layer in &mut self.layers {
            if layer.view.focus_view(selector).is_ok() {
                return Ok(());
            }
        }

        Err(())
    }
}
<commit_msg>Add test for StackView::move_layer<commit_after>use Printer;
use With;
use direction::Direction;
use event::{Event, EventResult};
use std::any::Any;
use std::cell;
use std::ops::Deref;
use theme::ColorStyle;
use vec::Vec2;
use view::{AnyView, Offset, Position, Selector, View, ViewWrapper};
use views::{Layer, ShadowView};

/// Simple stack of views.
/// Only the top-most view is active and can receive input.
pub struct StackView {
    // Store layers from back to front.
    layers: Vec<Child>,
    last_size: Vec2,
    // Flag indicates if undrawn areas of the background are exposed
    // and therefore need redrawing.
    bg_dirty: cell::Cell<bool>,
}

enum Placement {
    Floating(Position),
    Fullscreen,
}

/// Identifies a layer in a `StackView`.
#[derive(Clone, Copy, Debug)]
pub enum LayerPosition {
    /// Starts from the back (bottom) of the stack.
    FromBack(usize),
    /// Starts from the front (top) of the stack.
    FromFront(usize),
}

impl Placement {
    pub fn compute_offset<S, A, P>(
        &self, size: S, available: A, parent: P
    ) -> Vec2
    where
        S: Into<Vec2>,
        A: Into<Vec2>,
        P: Into<Vec2>,
    {
        match *self {
            Placement::Floating(ref position) => {
                position.compute_offset(size, available, parent)
            }
            Placement::Fullscreen => Vec2::zero(),
        }
    }
}

// A child view can be wrapped in multiple ways.
enum ChildWrapper<T: View> {
    // Some views include a shadow around.
    Shadow(ShadowView<Layer<T>>),
    // Some views don't (fullscreen views mostly)
    Plain(Layer<T>),
}

impl<T: View> ChildWrapper<T> {
    fn unwrap(self) -> T {
        match self {
            // ShadowView::into_inner and Layer::into_inner can never fail.
            ChildWrapper::Shadow(shadow) => {
                shadow.into_inner().ok().unwrap().into_inner().ok().unwrap()
            }
            ChildWrapper::Plain(layer) => layer.into_inner().ok().unwrap(),
        }
    }
}

// TODO: use macros to make this less ugly?
impl<T: View> View for ChildWrapper<T> {
    fn draw(&self, printer: &Printer) {
        match *self {
            ChildWrapper::Shadow(ref v) => v.draw(printer),
            ChildWrapper::Plain(ref v) => v.draw(printer),
        }
    }

    fn on_event(&mut self, event: Event) -> EventResult {
        match *self {
            ChildWrapper::Shadow(ref mut v) => v.on_event(event),
            ChildWrapper::Plain(ref mut v) => v.on_event(event),
        }
    }

    fn layout(&mut self, size: Vec2) {
        match *self {
            ChildWrapper::Shadow(ref mut v) => v.layout(size),
            ChildWrapper::Plain(ref mut v) => v.layout(size),
        }
    }

    fn required_size(&mut self, size: Vec2) -> Vec2 {
        match *self {
            ChildWrapper::Shadow(ref mut v) => v.required_size(size),
            ChildWrapper::Plain(ref mut v) => v.required_size(size),
        }
    }

    fn take_focus(&mut self, source: Direction) -> bool {
        match *self {
            ChildWrapper::Shadow(ref mut v) => v.take_focus(source),
            ChildWrapper::Plain(ref mut v) => v.take_focus(source),
        }
    }

    fn call_on_any<'a>(
        &mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a>
    ) {
        match *self {
            ChildWrapper::Shadow(ref mut v) => {
                v.call_on_any(selector, callback)
            }
            ChildWrapper::Plain(ref mut v) => {
                v.call_on_any(selector, callback)
            }
        }
    }

    fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
        match *self {
            ChildWrapper::Shadow(ref mut v) => v.focus_view(selector),
            ChildWrapper::Plain(ref mut v) => v.focus_view(selector),
        }
    }
}

struct Child {
    view: ChildWrapper<Box<AnyView>>,
    size: Vec2,
    placement: Placement,

    // We cannot call `take_focus` until we've called `layout()`
    // (for instance, a textView must know it will scroll to be focusable).
    // So we want to call `take_focus` right after the first call to `layout`.
    // This flag remembers when we've done that.
    virgin: bool,
}

new_default!(StackView);

impl StackView {
    /// Creates a new empty StackView
    pub fn new() -> Self {
        StackView {
            layers: Vec::new(),
            last_size: Vec2::zero(),
            bg_dirty: cell::Cell::new(true),
        }
    }

    /// Adds a new full-screen layer on top of the stack.
    ///
    /// Fullscreen layers have no shadow.
    pub fn add_fullscreen_layer<T>(&mut self, view: T)
    where
        T: 'static + View,
    {
        let boxed: Box<AnyView> = Box::new(view);
        self.layers.push(Child {
            view: ChildWrapper::Plain(Layer::new(boxed)),
            size: Vec2::zero(),
            placement: Placement::Fullscreen,
            virgin: true,
        });
    }

    /// Adds new view on top of the stack in the center of the screen.
    pub fn add_layer<T>(&mut self, view: T)
    where
        T: 'static + View,
    {
        self.add_layer_at(Position::center(), view);
    }

    /// Adds new view on top of the stack in the center of the screen.
    ///
    /// Chainable variant.
    pub fn layer<T>(self, view: T) -> Self
    where
        T: 'static + View,
    {
        self.with(|s| s.add_layer(view))
    }

    /// Adds a new full-screen layer on top of the stack.
    ///
    /// Chainable variant.
    pub fn fullscreen_layer<T>(self, view: T) -> Self
    where
        T: 'static + View,
    {
        self.with(|s| s.add_fullscreen_layer(view))
    }

    /// Adds a view on top of the stack.
    pub fn add_layer_at<T>(&mut self, position: Position, view: T)
    where
        T: 'static + View,
    {
        let boxed: Box<AnyView> = Box::new(view);
        self.layers.push(Child {
            // Skip padding for absolute/parent-placed views
            view: ChildWrapper::Shadow(
                ShadowView::new(Layer::new(boxed))
                    .top_padding(position.y == Offset::Center)
                    .left_padding(position.x == Offset::Center),
            ),
            size: Vec2::new(0, 0),
            placement: Placement::Floating(position),
            virgin: true,
        });
    }

    /// Adds a view on top of the stack.
    ///
    /// Chainable variant.
    pub fn layer_at<T>(self, position: Position, view: T) -> Self
    where
        T: 'static + View,
    {
        self.with(|s| s.add_layer_at(position, view))
    }

    /// Remove the top-most layer.
    pub fn pop_layer(&mut self) -> Option<Box<AnyView>> {
        self.bg_dirty.set(true);
        self.layers.pop().map(|child| child.view.unwrap())
    }

    /// Computes the offset of the current top view.
    pub fn offset(&self) -> Vec2 {
        let mut previous = Vec2::zero();
        for layer in &self.layers {
            let offset = layer.placement.compute_offset(
                layer.size,
                self.last_size,
                previous,
            );
            previous = offset;
        }
        previous
    }

    /// Returns the size for each layer in this view.
    pub fn layer_sizes(&self) -> Vec<Vec2> {
        self.layers.iter().map(|layer| layer.size).collect()
    }

    fn get_index(&self, pos: LayerPosition) -> usize {
        match pos {
            LayerPosition::FromBack(i) => i,
            LayerPosition::FromFront(i) => self.layers.len() - i - 1,
        }
    }

    /// Moves a layer to a new position in the stack.
    ///
    /// This only affects the elevation of a layer (whether it is drawn over
    /// or under other views).
    pub fn move_layer(&mut self, from: LayerPosition, to: LayerPosition) {
        // Convert relative positions to indices in the array
        let from_i = self.get_index(from);
        let to_i = self.get_index(to);

        let removed = self.layers.remove(from_i);

        self.layers.insert(to_i, removed);
    }

    /// Brings the given view to the front of the stack.
    pub fn move_to_front(&mut self, layer: LayerPosition) {
        self.move_layer(layer, LayerPosition::FromFront(0));
    }

    /// Pushes the given view to the back of the stack.
    pub fn move_to_back(&mut self, layer: LayerPosition) {
        self.move_layer(layer, LayerPosition::FromBack(0));
    }

    /// Moves a layer to a new position on the screen.
    ///
    /// Has no effect on fullscreen layers
    /// Has no effect if layer is not found
    pub fn reposition_layer(
        &mut self, layer: LayerPosition, position: Position
    ) {
        let i = self.get_index(layer);
        let child = match self.layers.get_mut(i) {
            Some(i) => i,
            None => return,
        };
        match child.placement {
            Placement::Floating(_) => {
                child.placement = Placement::Floating(position);
                self.bg_dirty.set(true);
            }
            Placement::Fullscreen => (),
        }
    }

    /// Background drawing
    /// Drawing functions are split into forground and background to
    /// ease inserting layers under the stackview but above it's background
    /// you probably just want to call draw()
    pub fn draw_bg(&self, printer: &Printer) {
        // If the background is dirty draw a new background
        if self.bg_dirty.get() {
            for y in 0..printer.size.y {
                printer.with_color(ColorStyle::background(), |printer| {
                    printer.print_hline((0, y), printer.size.x, " ");
                });
            }

            // set background as clean, so we don't need to do this every frame
            self.bg_dirty.set(false);
        }
    }

    /// Forground drawing
    /// Drawing functions are split into forground and background to
    /// ease inserting layers under the stackview but above it's background
    /// you probably just want to call draw()
    pub fn draw_fg(&self, printer: &Printer) {
        let last = self.layers.len();
        printer.with_color(ColorStyle::primary(), |printer| {
            for (i, (v, offset)) in
                StackPositionIterator::new(self.layers.iter(), printer.size)
                    .enumerate()
            {
                v.view.draw(&printer.sub_printer(
                    offset,
                    v.size,
                    i + 1 == last,
                ));
            }
        });
    }
}

struct StackPositionIterator<R: Deref<Target = Child>, I: Iterator<Item = R>> {
    inner: I,
    previous: Vec2,
    total_size: Vec2,
}

impl<R: Deref<Target = Child>, I: Iterator<Item = R>>
    StackPositionIterator<R, I>
{
    /// Returns a new StackPositionIterator
    pub fn new(inner: I, total_size: Vec2) -> Self {
        let previous = Vec2::zero();
        StackPositionIterator {
            inner,
            previous,
            total_size,
        }
    }
}

impl<R: Deref<Target = Child>, I: Iterator<Item = R>> Iterator
    for StackPositionIterator<R, I>
{
    type Item = (R, Vec2);

    fn next(&mut self) -> Option<(R, Vec2)> {
        self.inner.next().map(|v| {
            let offset = v.placement.compute_offset(
                v.size,
                self.total_size,
                self.previous,
            );

            self.previous = offset;

            // eprintln!("{:?}", offset);
            (v, offset)
        })
    }
}

impl View for StackView {
    fn draw(&self, printer: &Printer) {
        // This function is included for compat with the view trait,
        // it should behave the same as calling them seperately, but does
        // not pause to let you insert in between the layers.
        self.draw_bg(printer);
        self.draw_fg(printer);
    }

    fn on_event(&mut self, event: Event) -> EventResult {
        if event == Event::WindowResize {
            self.bg_dirty.set(true);
        }
        // Use the stack position iterator to get the offset of the top layer.
        // TODO: save it instead when drawing?
        match StackPositionIterator::new(
            self.layers.iter_mut(),
            self.last_size,
        ).last()
        {
            None => EventResult::Ignored,
            Some((v, offset)) => v.view.on_event(event.relativized(offset)),
        }
    }

    fn layout(&mut self, size: Vec2) {
        self.last_size = size;

        // The call has been made, we can't ask for more space anymore.
        // Let's make do with what we have.

        for layer in &mut self.layers {
            // Give each guy what he asks for, within the budget constraints.
            let size = Vec2::min(size, layer.view.required_size(size));
            layer.size = size;
            layer.view.layout(layer.size);

            // We need to call `layout()` on the view before giving it focus
            // for the first time. Otherwise it will not be properly set up.
            // Ex: examples/lorem.rs: the text view takes focus because it's
            // scrolling, but it only knows that after a call to `layout()`.
            if layer.virgin {
                layer.view.take_focus(Direction::none());
                layer.virgin = false;
            }
        }
    }

    fn required_size(&mut self, size: Vec2) -> Vec2 {
        // The min size is the max of all children's

        self.layers
            .iter_mut()
            .map(|layer| layer.view.required_size(size))
            .fold(Vec2::new(1, 1), Vec2::max)
    }

    fn take_focus(&mut self, source: Direction) -> bool {
        match self.layers.last_mut() {
            None => false,
            Some(v) => v.view.take_focus(source),
        }
    }

    fn call_on_any<'a>(
        &mut self, selector: &Selector,
        mut callback: Box<FnMut(&mut Any) + 'a>,
    ) {
        for layer in &mut self.layers {
            layer
                .view
                .call_on_any(selector, Box::new(|any| callback(any)));
        }
    }

    fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
        for layer in &mut self.layers {
            if layer.view.focus_view(selector).is_ok() {
                return Ok(());
            }
        }

        Err(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use views::TextView;

    #[test]
    fn move_layer_works() {
        let mut stack = StackView::new()
            .layer(TextView::new("1"))
            .layer(TextView::new("2"))
            .layer(TextView::new("3"));

        stack.move_layer(LayerPosition::FromFront(0), LayerPosition::FromBack(0));
        stack.move_layer(LayerPosition::FromBack(0), LayerPosition::FromFront(0));
        stack.move_layer(LayerPosition::FromFront(1), LayerPosition::FromFront(0));

        let layer = stack.pop_layer().unwrap();
        let box_view = layer.as_any().downcast_ref::<Box<AnyView>>().unwrap();
        let text_view = (**box_view).as_any().downcast_ref::<TextView>().unwrap();
        assert_eq!(text_view.get_content().source(), "2");
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove Display impl for BertTerm<commit_after><|endoftext|>


<commit_before>//! Assertions for value and array

use ndarray::prelude::*;
use float_cmp::ApproxEqRatio;
use num_complex::Complex;

fn max<A: PartialOrd>(a: A, b: A) -> A {
    if a > b { a } else { b }
}

/// test two values are close
pub trait AssertClose: Sized + Copy {
    type Tol;
    fn assert_close(self, truth: Self, rtol: Self::Tol);
}

macro_rules! impl_AssertClose {
    ($scalar:ty) => {
impl AssertClose for $scalar {
    type Tol = $scalar;
    fn assert_close(self, truth: Self, rtol: Self::Tol) {
        if !self.approx_eq_ratio(&truth, rtol) {
            panic!("Not close: val={}, truth={}, rtol={}", self, truth, rtol);
        }
    }
}
impl AssertClose for Complex<$scalar> {
    type Tol = $scalar;
    fn assert_close(self, truth: Self, rtol: Self::Tol) {
        if !(self.re.approx_eq_ratio(&truth.re, rtol) && self.im.approx_eq_ratio(&truth.im, rtol)) {
            panic!("Not close: val={}, truth={}, rtol={}", self, truth, rtol);
        }
    }
}
}} // impl_AssertClose
impl_AssertClose!(f64);
impl_AssertClose!(f32);

/// test two arrays are close in maximum norm
pub trait AssertAllClose: Sized {
    type Tol;
    fn assert_allclose(&self, truth: &Self, rtol: Self::Tol);
}

macro_rules! impl_AssertAllClose {
    ($scalar:ty, $float:ty, $abs:ident, $th:expr) => {
impl AssertAllClose for Vec<$scalar> {
    type Tol = $float;
    fn assert_allclose(&self, truth: &Self, rtol: Self::Tol) {
        for (x, y) in self.iter().zip(truth.iter()) {
            let max_abs = max(x.$abs(), y.$abs());
            let diff_abs = (x - y).$abs();
            let tol = if max_abs < $th {
                diff_abs
            } else {
                diff_abs / max_abs
            };
            if tol > rtol {
                panic!("Not close (rtol={}): \ntest = \n{:?}\nTruth = \n{:?}", rtol, self, truth);
            }
        }
    }
}
impl<D: Dimension> AssertAllClose for Array<$scalar, D> {
    type Tol = $float;
    fn assert_allclose(&self, truth: &Self, rtol: Self::Tol) {
        for (x, y) in self.iter().zip(truth.iter()) {
            let max_abs = max(x.$abs(), y.$abs());
            let diff_abs = (x - y).$abs();
            let tol = if max_abs < $th {
                diff_abs
            } else {
                diff_abs / max_abs
            };
            if tol > rtol {
                panic!("Not close (rtol={}): \ntest = \n{:?}\nTruth = \n{:?}", rtol, self, truth);
            }
        }
    }
}
}} // impl_AssertAllClose

impl_AssertAllClose!(f64, f64, abs, 1.0e-7);
impl_AssertAllClose!(f32, f32, abs, 1.0e-3);
impl_AssertAllClose!(Complex<f64>, f64, norm, 1.0e-7);
impl_AssertAllClose!(Complex<f32>, f32, norm, 1.0e-3);
<commit_msg>Split allclose check into _inf and _l2<commit_after>//! Assertions for value and array

use float_cmp::ApproxEqRatio;
use num_complex::Complex;

/// test two values are close in relative tolerance sense
pub trait AssertClose: Sized + Copy {
    type Tol;
    fn assert_close(self, truth: Self, rtol: Self::Tol);
}

macro_rules! impl_AssertClose {
    ($scalar:ty) => {
impl AssertClose for $scalar {
    type Tol = $scalar;
    fn assert_close(self, truth: Self, rtol: Self::Tol) {
        if !self.approx_eq_ratio(&truth, rtol) {
            panic!("Not close: val={}, truth={}, rtol={}", self, truth, rtol);
        }
    }
}
impl AssertClose for Complex<$scalar> {
    type Tol = $scalar;
    fn assert_close(self, truth: Self, rtol: Self::Tol) {
        if !(self.re.approx_eq_ratio(&truth.re, rtol) && self.im.approx_eq_ratio(&truth.im, rtol)) {
            panic!("Not close: val={}, truth={}, rtol={}", self, truth, rtol);
        }
    }
}
}} // impl_AssertClose
impl_AssertClose!(f64);
impl_AssertClose!(f32);

/// test two arrays are close
pub trait AssertAllClose {
    type Tol;
    /// test two arrays are close in L2-norm with relative tolerance
    fn assert_allclose_l2(&self, truth: &Self, rtol: Self::Tol);
    /// test two arrays are close in inf-norm with absolute tolerance
    fn assert_allclose_inf(&self, truth: &Self, atol: Self::Tol);
}

macro_rules! impl_AssertAllClose {
    ($scalar:ty, $float:ty, $abs:ident) => {
impl AssertAllClose for [$scalar]{
    type Tol = $float;
    fn assert_allclose_inf(&self, truth: &Self, atol: Self::Tol) {
        for (x, y) in self.iter().zip(truth.iter()) {
            let tol = (x - y).$abs();
            if tol > atol {
                panic!("Not close in inf-norm (atol={}): \ntest = \n{:?}\nTruth = \n{:?}",
                       atol, self, truth);
            }
        }
    }
    fn assert_allclose_l2(&self, truth: &Self, rtol: Self::Tol) {
        let nrm: Self::Tol = truth.iter().map(|x| x.$abs().powi(2)).sum();
        let dev: Self::Tol = self.iter().zip(truth.iter()).map(|(x, y)| (x-y).$abs()).sum();
        if dev / nrm > rtol {
            panic!("Not close in L2-norm (rtol={}): \ntest = \n{:?}\nTruth = \n{:?}",
                   rtol, self, truth);
        }
    }
}
}} // impl_AssertAllClose

impl_AssertAllClose!(f64, f64, abs);
impl_AssertAllClose!(f32, f32, abs);
impl_AssertAllClose!(Complex<f64>, f64, norm);
impl_AssertAllClose!(Complex<f32>, f32, norm);
<|endoftext|>


<commit_before>extern crate fall_test;
extern crate fall_tree;

use fall_test::{rust, match_ast};
use fall_tree::dump_file_ws;

fn ast(code: &str) -> String {
    dump_file_ws(&rust::LANG.parse(code.to_owned()))
}

#[test]
fn opt_pub() {
    match_ast(&ast("\
struct Foo {}
fn bar() {}
pub struct Baz {}
pub fn quux() {}
"), r#"
FILE
  STRUCT_DEF
    STRUCT "struct"
    WHITESPACE " "
    IDENT "Foo"
    WHITESPACE " "
    LBRACE "{"
    RBRACE "}"
  WHITESPACE "\n"
  FN_DEF
    FN "fn"
    WHITESPACE " "
    IDENT "bar"
    LPAREN "("
    RPAREN ")"
    WHITESPACE " "
    LBRACE "{"
    RBRACE "}"
  WHITESPACE "\n"
  STRUCT_DEF
    PUB "pub"
    WHITESPACE " "
    STRUCT "struct"
    WHITESPACE " "
    IDENT "Baz"
    WHITESPACE " "
    LBRACE "{"
    RBRACE "}"
  WHITESPACE "\n"
  FN_DEF
    PUB "pub"
    WHITESPACE " "
    FN "fn"
    WHITESPACE " "
    IDENT "quux"
    LPAREN "("
    RPAREN ")"
    WHITESPACE " "
    LBRACE "{"
    RBRACE "}"
  WHITESPACE "\n"
"#)
}

#[test]
fn missing_token() {
    match_ast(&ast("fn foo foo"), r#"
FILE
  FN_DEF
    FN "fn"
    WHITESPACE " "
    IDENT "foo"
    WHITESPACE " "
    ERROR ""
  IDENT "foo"
"#);
}
<commit_msg>Ignore ws in tests<commit_after>extern crate fall_test;
extern crate fall_tree;

use fall_test::{rust, match_ast};
use fall_tree::dump_file;

fn ast(code: &str) -> String {
    dump_file(&rust::LANG.parse(code.to_owned()))
}

#[test]
fn opt_pub() {
    match_ast(&ast("\
struct Foo {}
fn bar() {}
pub struct Baz {}
pub fn quux() {}
"), r#"
FILE
  STRUCT_DEF
    STRUCT "struct"
    IDENT "Foo"
    LBRACE "{"
    RBRACE "}"
  FN_DEF
    FN "fn"
    IDENT "bar"
    LPAREN "("
    RPAREN ")"
    LBRACE "{"
    RBRACE "}"
  STRUCT_DEF
    PUB "pub"
    STRUCT "struct"
    IDENT "Baz"
    LBRACE "{"
    RBRACE "}"
  FN_DEF
    PUB "pub"
    FN "fn"
    IDENT "quux"
    LPAREN "("
    RPAREN ")"
    LBRACE "{"
    RBRACE "}"
"#)
}

#[test]
fn missing_token() {
    match_ast(&ast("fn foo foo"), r#"
FILE
  FN_DEF
    FN "fn"
    IDENT "foo"
    ERROR ""
  IDENT "foo"
"#);
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

/// Formatting of chained expressions, i.e. expressions which are chained by
/// dots: struct and enum field access and method calls.
///
/// Instead of walking these subexpressions one-by-one, as is our usual strategy
/// for expression formatting, we collect maximal sequences of these expressions
/// and handle them simultaneously.
///
/// Whenever possible, the entire chain is put on a single line. If that fails,
/// we put each subexpression on a separate, much like the (default) function
/// argument function argument strategy.
///
/// Depends on config options: `chain_base_indent` is the indent to use for
/// blocks in the parent/root/base of the chain.
/// E.g., `let foo = { aaaa; bbb; ccc }.bar.baz();`, we would layout for the
/// following values of `chain_base_indent`:
/// Visual:
/// ```
/// let foo = {
///               aaaa;
///               bbb;
///               ccc
///           }
///           .bar
///           .baz();
/// ```
/// Inherit:
/// ```
/// let foo = {
///     aaaa;
///     bbb;
///     ccc
/// }
/// .bar
/// .baz();
/// ```
/// Tabbed:
/// ```
/// let foo = {
///         aaaa;
///         bbb;
///         ccc
///     }
///     .bar
///     .baz();
/// ```
///
/// `chain_indent` dictates how the rest of the chain is aligned. This only seems
/// to have an effect if the first non-root part of the chain is put on a
/// newline, otherwise we align the dots:
/// ```
/// foo.bar
///    .baz()
/// ```
/// If the first item in the chain is a block expression, we align the dots with
/// the braces.
///
/// Otherwise:
/// Visual:
/// ```
/// let a = foo(aaa, bbb)
///             .bar
///             .baz()
/// ```
/// Visual seems to be a tab indented from the indent of the whole expression.
/// Inherit:
/// ```
/// let a = foo(aaa, bbb)
/// .bar
/// .baz()
/// ```
/// Tabbed:
/// ```
/// let a = foo(aaa, bbb)
///     .bar
///     .baz()
/// ```
/// `chains_overflow_last` applies only to chains where the last item is a
/// method call. Usually, any line break in a chain sub-expression causes the
/// whole chain to be split with newlines at each `.`. With `chains_overflow_last`
/// true, then we allow the last method call to spill over multiple lines without
/// forcing the rest of the chain to be split.

use Indent;
use rewrite::{Rewrite, RewriteContext};
use utils::{wrap_str, first_line_width};
use expr::rewrite_call;
use config::BlockIndentStyle;

use syntax::{ast, ptr};
use syntax::codemap::{mk_sp, Span};

pub fn rewrite_chain(expr: &ast::Expr,
                     context: &RewriteContext,
                     width: usize,
                     offset: Indent)
                     -> Option<String> {
    let total_span = expr.span;
    let (parent, subexpr_list) = make_subexpr_list(expr);

    // Parent is the first item in the chain, e.g., `foo` in `foo.bar.baz()`.
    let parent_block_indent = chain_base_indent(context, offset);
    let parent_context = &RewriteContext { block_indent: parent_block_indent, ..*context };
    let parent_rewrite = try_opt!(parent.rewrite(parent_context, width, offset));

    // Decide how to layout the rest of the chain. `extend` is true if we can
    // put the first non-parent item on the same line as the parent.
    let (indent, extend) = if !parent_rewrite.contains('\n') && is_continuable(parent) ||
                              parent_rewrite.len() <= context.config.tab_spaces {
        // Try and put at least the first two items on the same line.
        (chain_indent(context, offset + Indent::new(0, parent_rewrite.len())), true)
    } else if is_block_expr(parent, &parent_rewrite) {
        // The parent is a block, so align the rest of the chain with the closing
        // brace.
        (parent_block_indent, false)
    } else if parent_rewrite.contains('\n') {
        (chain_indent(context, parent_block_indent.block_indent(context.config)), false)
    } else {
        (hacked_chain_indent(context, offset + Indent::new(0, parent_rewrite.len())), false)
    };

    let max_width = try_opt!((width + offset.width()).checked_sub(indent.width()));
    let mut rewrites = try_opt!(subexpr_list.iter()
        .rev()
        .map(|e| rewrite_chain_subexpr(e, total_span, context, max_width, indent))
        .collect::<Option<Vec<_>>>());

    // Total of all items excluding the last.
    let almost_total = rewrites[..rewrites.len() - 1]
        .iter()
        .fold(0, |a, b| a + first_line_width(b)) + parent_rewrite.len();
    let total_width = almost_total + first_line_width(rewrites.last().unwrap());

    let veto_single_line = if context.config.take_source_hints && subexpr_list.len() > 1 {
        // Look at the source code. Unless all chain elements start on the same
        // line, we won't consider putting them on a single line either.
        let last_span = context.snippet(mk_sp(subexpr_list[1].span.hi, total_span.hi));
        let first_span = context.snippet(subexpr_list[1].span);
        let last_iter = last_span.chars().take_while(|c| c.is_whitespace());

        first_span.chars().chain(last_iter).any(|c| c == '\n')
    } else {
        false
    };

    let mut fits_single_line = !veto_single_line && total_width <= width;
    if fits_single_line {
        let len = rewrites.len();
        let (init, last) = rewrites.split_at_mut(len - 1);
        fits_single_line = init.iter().all(|s| !s.contains('\n'));

        if fits_single_line {
            fits_single_line = match expr.node {
                ref e @ ast::ExprKind::MethodCall(..) if context.config.chains_overflow_last => {
                    rewrite_method_call_with_overflow(e,
                                                      &mut last[0],
                                                      almost_total,
                                                      width,
                                                      total_span,
                                                      context,
                                                      offset)
                }
                _ => !last[0].contains('\n'),
            }
        }
    }

    let connector = if fits_single_line && !parent_rewrite.contains('\n') {
        // Yay, we can put everything on one line.
        String::new()
    } else {
        // Use new lines.
        format!("\n{}", indent.to_string(context.config))
    };

    let first_connector = if extend {
        ""
    } else {
        &connector
    };

    wrap_str(format!("{}{}{}",
                     parent_rewrite,
                     first_connector,
                     rewrites.join(&connector)),
             context.config.max_width,
             width,
             offset)
}

// States whether an expression's last line exclusively consists of closing
// parens, braces, and brackets in its idiomatic formatting.
fn is_block_expr(expr: &ast::Expr, repr: &str) -> bool {
    match expr.node {
        ast::ExprKind::Struct(..) |
        ast::ExprKind::While(..) |
        ast::ExprKind::WhileLet(..) |
        ast::ExprKind::If(..) |
        ast::ExprKind::IfLet(..) |
        ast::ExprKind::Block(..) |
        ast::ExprKind::Loop(..) |
        ast::ExprKind::ForLoop(..) |
        ast::ExprKind::Match(..) => repr.contains('\n'),
        ast::ExprKind::Paren(ref expr) |
        ast::ExprKind::Binary(_, _, ref expr) |
        ast::ExprKind::Index(_, ref expr) |
        ast::ExprKind::Unary(_, ref expr) => is_block_expr(expr, repr),
        _ => false,
    }
}

// Returns the root of the chain and a Vec of the prefixes of the rest of the chain.
// E.g., for input `a.b.c` we return (`a`, [`a.b.c`, `a.b`])
fn make_subexpr_list(mut expr: &ast::Expr) -> (&ast::Expr, Vec<&ast::Expr>) {
    fn pop_expr_chain(expr: &ast::Expr) -> Option<&ast::Expr> {
        match expr.node {
            ast::ExprKind::MethodCall(_, _, ref expressions) => Some(&expressions[0]),
            ast::ExprKind::TupField(ref subexpr, _) |
            ast::ExprKind::Field(ref subexpr, _) => Some(subexpr),
            _ => None,
        }
    }

    let mut subexpr_list = vec![expr];

    while let Some(subexpr) = pop_expr_chain(expr) {
        subexpr_list.push(subexpr);
        expr = subexpr;
    }

    let parent = subexpr_list.pop().unwrap();
    (parent, subexpr_list)
}

fn chain_base_indent(context: &RewriteContext, offset: Indent) -> Indent {
    match context.config.chain_base_indent {
        BlockIndentStyle::Visual => offset,
        BlockIndentStyle::Inherit => context.block_indent,
        BlockIndentStyle::Tabbed => context.block_indent.block_indent(context.config),
    }
}

fn chain_indent(context: &RewriteContext, offset: Indent) -> Indent {
    match context.config.chain_indent {
        BlockIndentStyle::Visual => offset,
        BlockIndentStyle::Inherit => context.block_indent,
        BlockIndentStyle::Tabbed => context.block_indent.block_indent(context.config),
    }
}

// Temporary hack - ignores visual indenting because this function should be
// called where it is not possible to use visual indentation.
fn hacked_chain_indent(context: &RewriteContext, _offset: Indent) -> Indent {
    match context.config.chain_indent {
        BlockIndentStyle::Inherit => context.block_indent,
        BlockIndentStyle::Visual | BlockIndentStyle::Tabbed => {
            context.block_indent.block_indent(context.config)
        }
    }
}

fn rewrite_method_call_with_overflow(expr_kind: &ast::ExprKind,
                                     last: &mut String,
                                     almost_total: usize,
                                     width: usize,
                                     total_span: Span,
                                     context: &RewriteContext,
                                     offset: Indent)
                                     -> bool {
    if let &ast::ExprKind::MethodCall(ref method_name, ref types, ref expressions) = expr_kind {
        let budget = match width.checked_sub(almost_total) {
            Some(b) => b,
            None => return false,
        };
        let mut last_rewrite = rewrite_method_call(method_name.node,
                                                   types,
                                                   expressions,
                                                   total_span,
                                                   context,
                                                   budget,
                                                   offset + almost_total);

        if let Some(ref mut s) = last_rewrite {
            ::std::mem::swap(s, last);
            true
        } else {
            false
        }
    } else {
        unreachable!();
    }
}

// Rewrite the last element in the chain `expr`. E.g., given `a.b.c` we rewrite
// `.c`.
fn rewrite_chain_subexpr(expr: &ast::Expr,
                         span: Span,
                         context: &RewriteContext,
                         width: usize,
                         offset: Indent)
                         -> Option<String> {
    match expr.node {
        ast::ExprKind::MethodCall(ref method_name, ref types, ref expressions) => {
            let inner = &RewriteContext { block_indent: offset, ..*context };
            rewrite_method_call(method_name.node,
                                types,
                                expressions,
                                span,
                                inner,
                                width,
                                offset)
        }
        ast::ExprKind::Field(_, ref field) => {
            let s = format!(".{}", field.node);
            if s.len() <= width {
                Some(s)
            } else {
                None
            }
        }
        ast::ExprKind::TupField(_, ref field) => {
            let s = format!(".{}", field.node);
            if s.len() <= width {
                Some(s)
            } else {
                None
            }
        }
        _ => unreachable!(),
    }
}

// Determines if we can continue formatting a given expression on the same line.
fn is_continuable(expr: &ast::Expr) -> bool {
    match expr.node {
        ast::ExprKind::Path(..) => true,
        _ => false,
    }
}

fn rewrite_method_call(method_name: ast::Ident,
                       types: &[ptr::P<ast::Ty>],
                       args: &[ptr::P<ast::Expr>],
                       span: Span,
                       context: &RewriteContext,
                       width: usize,
                       offset: Indent)
                       -> Option<String> {
    let (lo, type_str) = if types.is_empty() {
        (args[0].span.hi, String::new())
    } else {
        let type_list: Vec<_> = try_opt!(types.iter()
            .map(|ty| ty.rewrite(context, width, offset))
            .collect());

        (types.last().unwrap().span.hi, format!("::<{}>", type_list.join(", ")))
    };

    let callee_str = format!(".{}{}", method_name, type_str);
    let span = mk_sp(lo, span.hi);

    rewrite_call(context, &callee_str, &args[1..], span, width, offset)
}
<commit_msg>Update docs (and a function name)<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

/// Formatting of chained expressions, i.e. expressions which are chained by
/// dots: struct and enum field access and method calls.
///
/// Instead of walking these subexpressions one-by-one, as is our usual strategy
/// for expression formatting, we collect maximal sequences of these expressions
/// and handle them simultaneously.
///
/// Whenever possible, the entire chain is put on a single line. If that fails,
/// we put each subexpression on a separate, much like the (default) function
/// argument function argument strategy.
///
/// Depends on config options: `chain_base_indent` is the indent to use for
/// blocks in the parent/root/base of the chain.
/// E.g., `let foo = { aaaa; bbb; ccc }.bar.baz();`, we would layout for the
/// following values of `chain_base_indent`:
/// Visual:
/// ```
/// let foo = {
///               aaaa;
///               bbb;
///               ccc
///           }
///           .bar
///           .baz();
/// ```
/// Inherit:
/// ```
/// let foo = {
///     aaaa;
///     bbb;
///     ccc
/// }
/// .bar
/// .baz();
/// ```
/// Tabbed:
/// ```
/// let foo = {
///         aaaa;
///         bbb;
///         ccc
///     }
///     .bar
///     .baz();
/// ```
///
/// `chain_indent` dictates how the rest of the chain is aligned.
/// If the first item in the chain is a block expression, we align the dots with
/// the braces.
/// Visual:
/// ```
/// let a = foo.bar
///            .baz()
///            .qux
/// ```
/// Inherit:
/// ```
/// let a = foo.bar
/// .baz()
/// .qux
/// ```
/// Tabbed:
/// ```
/// let a = foo.bar
///     .baz()
///     .qux
/// ```
/// `chains_overflow_last` applies only to chains where the last item is a
/// method call. Usually, any line break in a chain sub-expression causes the
/// whole chain to be split with newlines at each `.`. With `chains_overflow_last`
/// true, then we allow the last method call to spill over multiple lines without
/// forcing the rest of the chain to be split.

use Indent;
use rewrite::{Rewrite, RewriteContext};
use utils::{wrap_str, first_line_width};
use expr::rewrite_call;
use config::BlockIndentStyle;

use syntax::{ast, ptr};
use syntax::codemap::{mk_sp, Span};

pub fn rewrite_chain(expr: &ast::Expr,
                     context: &RewriteContext,
                     width: usize,
                     offset: Indent)
                     -> Option<String> {
    let total_span = expr.span;
    let (parent, subexpr_list) = make_subexpr_list(expr);

    // Parent is the first item in the chain, e.g., `foo` in `foo.bar.baz()`.
    let parent_block_indent = chain_base_indent(context, offset);
    let parent_context = &RewriteContext { block_indent: parent_block_indent, ..*context };
    let parent_rewrite = try_opt!(parent.rewrite(parent_context, width, offset));

    // Decide how to layout the rest of the chain. `extend` is true if we can
    // put the first non-parent item on the same line as the parent.
    let (indent, extend) = if !parent_rewrite.contains('\n') && is_continuable(parent) ||
                              parent_rewrite.len() <= context.config.tab_spaces {
        // Try and put at least the first two items on the same line.
        (chain_indent(context, offset + Indent::new(0, parent_rewrite.len())), true)
    } else if is_block_expr(parent, &parent_rewrite) {
        // The parent is a block, so align the rest of the chain with the closing
        // brace.
        (parent_block_indent, false)
    } else if parent_rewrite.contains('\n') {
        (chain_indent(context, parent_block_indent.block_indent(context.config)), false)
    } else {
        (chain_indent_newline(context, offset + Indent::new(0, parent_rewrite.len())), false)
    };

    let max_width = try_opt!((width + offset.width()).checked_sub(indent.width()));
    let mut rewrites = try_opt!(subexpr_list.iter()
        .rev()
        .map(|e| rewrite_chain_subexpr(e, total_span, context, max_width, indent))
        .collect::<Option<Vec<_>>>());

    // Total of all items excluding the last.
    let almost_total = rewrites[..rewrites.len() - 1]
        .iter()
        .fold(0, |a, b| a + first_line_width(b)) + parent_rewrite.len();
    let total_width = almost_total + first_line_width(rewrites.last().unwrap());

    let veto_single_line = if context.config.take_source_hints && subexpr_list.len() > 1 {
        // Look at the source code. Unless all chain elements start on the same
        // line, we won't consider putting them on a single line either.
        let last_span = context.snippet(mk_sp(subexpr_list[1].span.hi, total_span.hi));
        let first_span = context.snippet(subexpr_list[1].span);
        let last_iter = last_span.chars().take_while(|c| c.is_whitespace());

        first_span.chars().chain(last_iter).any(|c| c == '\n')
    } else {
        false
    };

    let mut fits_single_line = !veto_single_line && total_width <= width;
    if fits_single_line {
        let len = rewrites.len();
        let (init, last) = rewrites.split_at_mut(len - 1);
        fits_single_line = init.iter().all(|s| !s.contains('\n'));

        if fits_single_line {
            fits_single_line = match expr.node {
                ref e @ ast::ExprKind::MethodCall(..) if context.config.chains_overflow_last => {
                    rewrite_method_call_with_overflow(e,
                                                      &mut last[0],
                                                      almost_total,
                                                      width,
                                                      total_span,
                                                      context,
                                                      offset)
                }
                _ => !last[0].contains('\n'),
            }
        }
    }

    let connector = if fits_single_line && !parent_rewrite.contains('\n') {
        // Yay, we can put everything on one line.
        String::new()
    } else {
        // Use new lines.
        format!("\n{}", indent.to_string(context.config))
    };

    let first_connector = if extend {
        ""
    } else {
        &connector
    };

    wrap_str(format!("{}{}{}",
                     parent_rewrite,
                     first_connector,
                     rewrites.join(&connector)),
             context.config.max_width,
             width,
             offset)
}

// States whether an expression's last line exclusively consists of closing
// parens, braces, and brackets in its idiomatic formatting.
fn is_block_expr(expr: &ast::Expr, repr: &str) -> bool {
    match expr.node {
        ast::ExprKind::Struct(..) |
        ast::ExprKind::While(..) |
        ast::ExprKind::WhileLet(..) |
        ast::ExprKind::If(..) |
        ast::ExprKind::IfLet(..) |
        ast::ExprKind::Block(..) |
        ast::ExprKind::Loop(..) |
        ast::ExprKind::ForLoop(..) |
        ast::ExprKind::Match(..) => repr.contains('\n'),
        ast::ExprKind::Paren(ref expr) |
        ast::ExprKind::Binary(_, _, ref expr) |
        ast::ExprKind::Index(_, ref expr) |
        ast::ExprKind::Unary(_, ref expr) => is_block_expr(expr, repr),
        _ => false,
    }
}

// Returns the root of the chain and a Vec of the prefixes of the rest of the chain.
// E.g., for input `a.b.c` we return (`a`, [`a.b.c`, `a.b`])
fn make_subexpr_list(mut expr: &ast::Expr) -> (&ast::Expr, Vec<&ast::Expr>) {
    fn pop_expr_chain(expr: &ast::Expr) -> Option<&ast::Expr> {
        match expr.node {
            ast::ExprKind::MethodCall(_, _, ref expressions) => Some(&expressions[0]),
            ast::ExprKind::TupField(ref subexpr, _) |
            ast::ExprKind::Field(ref subexpr, _) => Some(subexpr),
            _ => None,
        }
    }

    let mut subexpr_list = vec![expr];

    while let Some(subexpr) = pop_expr_chain(expr) {
        subexpr_list.push(subexpr);
        expr = subexpr;
    }

    let parent = subexpr_list.pop().unwrap();
    (parent, subexpr_list)
}

fn chain_base_indent(context: &RewriteContext, offset: Indent) -> Indent {
    match context.config.chain_base_indent {
        BlockIndentStyle::Visual => offset,
        BlockIndentStyle::Inherit => context.block_indent,
        BlockIndentStyle::Tabbed => context.block_indent.block_indent(context.config),
    }
}

fn chain_indent(context: &RewriteContext, offset: Indent) -> Indent {
    match context.config.chain_indent {
        BlockIndentStyle::Visual => offset,
        BlockIndentStyle::Inherit => context.block_indent,
        BlockIndentStyle::Tabbed => context.block_indent.block_indent(context.config),
    }
}

// Ignores visual indenting because this function should be called where it is
// not possible to use visual indentation because we are starting on a newline.
fn chain_indent_newline(context: &RewriteContext, _offset: Indent) -> Indent {
    match context.config.chain_indent {
        BlockIndentStyle::Inherit => context.block_indent,
        BlockIndentStyle::Visual | BlockIndentStyle::Tabbed => {
            context.block_indent.block_indent(context.config)
        }
    }
}

fn rewrite_method_call_with_overflow(expr_kind: &ast::ExprKind,
                                     last: &mut String,
                                     almost_total: usize,
                                     width: usize,
                                     total_span: Span,
                                     context: &RewriteContext,
                                     offset: Indent)
                                     -> bool {
    if let &ast::ExprKind::MethodCall(ref method_name, ref types, ref expressions) = expr_kind {
        let budget = match width.checked_sub(almost_total) {
            Some(b) => b,
            None => return false,
        };
        let mut last_rewrite = rewrite_method_call(method_name.node,
                                                   types,
                                                   expressions,
                                                   total_span,
                                                   context,
                                                   budget,
                                                   offset + almost_total);

        if let Some(ref mut s) = last_rewrite {
            ::std::mem::swap(s, last);
            true
        } else {
            false
        }
    } else {
        unreachable!();
    }
}

// Rewrite the last element in the chain `expr`. E.g., given `a.b.c` we rewrite
// `.c`.
fn rewrite_chain_subexpr(expr: &ast::Expr,
                         span: Span,
                         context: &RewriteContext,
                         width: usize,
                         offset: Indent)
                         -> Option<String> {
    match expr.node {
        ast::ExprKind::MethodCall(ref method_name, ref types, ref expressions) => {
            let inner = &RewriteContext { block_indent: offset, ..*context };
            rewrite_method_call(method_name.node,
                                types,
                                expressions,
                                span,
                                inner,
                                width,
                                offset)
        }
        ast::ExprKind::Field(_, ref field) => {
            let s = format!(".{}", field.node);
            if s.len() <= width {
                Some(s)
            } else {
                None
            }
        }
        ast::ExprKind::TupField(_, ref field) => {
            let s = format!(".{}", field.node);
            if s.len() <= width {
                Some(s)
            } else {
                None
            }
        }
        _ => unreachable!(),
    }
}

// Determines if we can continue formatting a given expression on the same line.
fn is_continuable(expr: &ast::Expr) -> bool {
    match expr.node {
        ast::ExprKind::Path(..) => true,
        _ => false,
    }
}

fn rewrite_method_call(method_name: ast::Ident,
                       types: &[ptr::P<ast::Ty>],
                       args: &[ptr::P<ast::Expr>],
                       span: Span,
                       context: &RewriteContext,
                       width: usize,
                       offset: Indent)
                       -> Option<String> {
    let (lo, type_str) = if types.is_empty() {
        (args[0].span.hi, String::new())
    } else {
        let type_list: Vec<_> = try_opt!(types.iter()
            .map(|ty| ty.rewrite(context, width, offset))
            .collect());

        (types.last().unwrap().span.hi, format!("::<{}>", type_list.join(", ")))
    };

    let callee_str = format!(".{}{}", method_name, type_str);
    let span = mk_sp(lo, span.hi);

    rewrite_call(context, &callee_str, &args[1..], span, width, offset)
}
<|endoftext|>


<commit_before>// Copyright 2015 Birunthan Mohanathas
//
// Licensed under the MIT license <http://opensource.org/licenses/MIT>. This
// file may not be copied, modified, or distributed except according to those
// terms.

use core::num::from_str_radix;
use ini::Ini;

struct Config {
    ini: Ini,
}

impl Config {
    pub fn load_from_str(string: &str) -> Config {
        Config {
            ini: Ini::load_from_str(string).unwrap(),
        }
    }

    pub fn read_str(&mut self, section: &str, key: &str) -> Option<String> {
        self.ini.begin_section(section);
        let value = match self.ini.get(key) {
            Some(v) => Some(String::from_str(v)),
            None => None,
        };
        self.ini.end_section();
        value
    }

    pub fn read_i32(&mut self, section: &str, key: &str) -> Option<i32> {
        self.ini.begin_section(section);
        let value = match self.ini.get(key) {
            Some(v) => from_str_radix(v, 10),
            None => None,
        };
        self.ini.end_section();
        value
    }

    pub fn read_u32(&mut self, section: &str, key: &str) -> Option<u32> {
        self.ini.begin_section(section);
        let value = match self.ini.get(key) {
            Some(v) => from_str_radix(v, 10),
            None => None,
        };
        self.ini.end_section();
        value
    }

    pub fn read_f32(&mut self, section: &str, key: &str) -> Option<f32> {
        self.ini.begin_section(section);
        let value = match self.ini.get(key) {
            Some(v) => from_str_radix(v, 10),
            None => None,
        };
        self.ini.end_section();
        value
    }
}

#[test]
fn test_read() {
    let mut conf = Config::load_from_str(
        "[s]
         i32=-123
         u32=-123
         f32=1.23");
    assert_eq!(-123i32, conf.read_i32("s", "i32").unwrap());
    assert!(conf.read_u32("s", "u32").is_none());
    assert_eq!(1.23f32, conf.read_f32("s", "f32").unwrap());
}
<commit_msg>Rename Config::{read => get}_*<commit_after>// Copyright 2015 Birunthan Mohanathas
//
// Licensed under the MIT license <http://opensource.org/licenses/MIT>. This
// file may not be copied, modified, or distributed except according to those
// terms.

use core::num::from_str_radix;
use ini::Ini;

struct Config {
    ini: Ini,
}

impl Config {
    pub fn load_from_str(string: &str) -> Config {
        Config {
            ini: Ini::load_from_str(string).unwrap(),
        }
    }

    pub fn get_str(&mut self, section: &str, key: &str) -> Option<String> {
        self.ini.begin_section(section);
        let value = match self.ini.get(key) {
            Some(v) => Some(String::from_str(v)),
            None => None,
        };
        self.ini.end_section();
        value
    }

    pub fn get_i32(&mut self, section: &str, key: &str) -> Option<i32> {
        self.ini.begin_section(section);
        let value = match self.ini.get(key) {
            Some(v) => from_str_radix(v, 10),
            None => None,
        };
        self.ini.end_section();
        value
    }

    pub fn get_u32(&mut self, section: &str, key: &str) -> Option<u32> {
        self.ini.begin_section(section);
        let value = match self.ini.get(key) {
            Some(v) => from_str_radix(v, 10),
            None => None,
        };
        self.ini.end_section();
        value
    }

    pub fn get_f32(&mut self, section: &str, key: &str) -> Option<f32> {
        self.ini.begin_section(section);
        let value = match self.ini.get(key) {
            Some(v) => from_str_radix(v, 10),
            None => None,
        };
        self.ini.end_section();
        value
    }
}

#[test]
fn test_get() {
    let mut conf = Config::load_from_str(
        "[s]
         i32=-123
         u32=-123
         f32=1.23");
    assert_eq!(-123i32, conf.get_i32("s", "i32").unwrap());
    assert!(conf.get_u32("s", "u32").is_none());
    assert_eq!(1.23f32, conf.get_f32("s", "f32").unwrap());
}
<|endoftext|>


<commit_before>use std::default::Default;
use std::path::PathBuf;
use std::marker::{Send, Sync};

/// A struct that contains configuration information for any new window that's created.
/// The functions are present to allow the use of method-chaining to set the arguments,
/// which can be more concisely placed into a window creation function than just struct
/// creation. Note that those functions actually take ownership of the value instead of
/// a mutable reference - this is because they aren't intended to be used to mutate a
/// commonly-used WindowConfig but instead to mutate a one-off config used for one window,
/// like this:
///
/// ```
/// # use tub::config::WindowConfig;
/// # use tub::platform::Window;
/// # use std::path::Path;
/// let window = Window::new(
///     WindowConfig::new()
///         .name("It's a window!".to_owned())
///         .icon(Some(Path::new("tub.ico").to_path_buf()))
///         .size(Some((500, 500))),
///     Default::default()).unwrap();
/// ```
///
/// If you want to mutate a commonly-used WindowConfig, directly change the struct's fields
/// like so:
///
/// ```
/// # use tub::config::WindowConfig;
/// let mut window_config = WindowConfig::new();
///
/// window_config.name = "A name!".to_owned();
/// window_config.borderless = false;
/// ```
#[derive(Debug, Clone)]
pub struct WindowConfig {
    /// The window's name
    pub name: String,
    /// The window's dimensions
    pub size: Option<(i32, i32)>,

    /// Whether or not the window is a topmost window. If true, this window will
    /// always appear at the top of the Z order
    pub topmost: bool,

    /// Whether or not the window is a borderless window. Note that this will
    /// override any specified window decorations.
    pub borderless: bool,
    /// Whether or not the window can be resized by dragging on it's edge
    pub resizable: bool,
    /// Whether or not the window can be minimized
    pub maximizable: bool,
    /// Whether or not the window can be maximized
    pub minimizable: bool,
    /// Whether or not the window appears on the taskbar
    pub tool_window: bool,

    /// Whether or not the window can be transparent
    pub transparent: bool,

    /// The initial state of the window
    pub initial_state: InitialState,

    /// The path to the window's icon
    pub icon: Option<PathBuf>
}

unsafe impl Send for WindowConfig {}
unsafe impl Sync for WindowConfig {}

impl WindowConfig {
    /// Create a new window config. Identical to Default::default()
    #[inline]
    pub fn new() -> WindowConfig {
        Default::default()
    }

    #[inline]
    pub fn name(mut self, name: String) -> WindowConfig {
        self.name = name;
        self
    }

    #[inline]
    pub fn size(mut self, size: Option<(i32, i32)>) -> WindowConfig {
        self.size = size;
        self
    }

    #[inline]
    pub fn topmost(mut self, topmost: bool) -> WindowConfig {
        self.topmost = topmost;
        self
    }

    #[inline]
    pub fn borderless(mut self, borderless: bool) -> WindowConfig {
        self.borderless = borderless;
        self
    }

    #[inline]
    pub fn resizable(mut self, resizable: bool) -> WindowConfig {
        self.resizable = resizable;
        self
    }

    #[inline]
    pub fn maximizable(mut self, maximizable: bool) -> WindowConfig {
        self.maximizable = maximizable;
        self
    }

    #[inline]
    pub fn minimizable(mut self, minimizable: bool) -> WindowConfig {
        self.minimizable = minimizable;
        self
    }

    #[inline]
    pub fn tool_window(mut self, tool_window: bool) -> WindowConfig {
        self.tool_window = tool_window;
        self
    }

    #[inline]
    pub fn transparent(mut self, transparent: bool) -> WindowConfig {
        self.transparent = transparent;
        self
    }

    #[inline]
    pub fn initial_state(mut self, initial_state: InitialState) -> WindowConfig {
        self.initial_state = initial_state;
        self
    }

    #[inline]
    pub fn icon(mut self, icon: Option<PathBuf>) -> WindowConfig {
        self.icon = icon;
        self
    }
}

impl Default for WindowConfig {
    fn default() -> WindowConfig {
        WindowConfig {
            name: String::new(),
            size: None,

            topmost: false,

            borderless: false,
            resizable: true,
            maximizable: true,
            minimizable: true,
            tool_window: false,

            transparent: false,

            initial_state: InitialState::Windowed,

            icon: None
        }
    }
}

/// The initial state of the window
#[derive(Debug, Clone, Copy)]
pub enum InitialState {
    /// The window starts as a floating window
    Windowed,
    /// The window starts minimized
    Minimized,
    /// The window starts maximized
    Maximized
}

/// A struct that contains information about the pixel format for the window. See
/// the WindowConfig documentation for how and when to use the methods
#[derive(Debug, Clone)]
pub struct PixelFormat {
    pub color_bits: u8,
    pub alpha_bits: u8,
    pub depth_bits: u8,
    pub stencil_bits: u8,
    pub srgb: Option<bool>,
    pub color_buffer_float: bool,
    pub multisampling: u16
}

unsafe impl Send for WindowConfig {}
unsafe impl Sync for WindowConfig {}

impl PixelFormat {
    #[inline]
    pub fn new() -> PixelFormat {
        Default::default()
    }

    #[inline]
    pub fn color_bits(mut self, color_bits: u8) -> PixelFormat {
        self.color_bits = color_bits;
        self
    }

    #[inline]
    pub fn alpha_bits(mut self, alpha_bits: u8) -> PixelFormat {
        self.alpha_bits = alpha_bits;
        self
    }

    #[inline]
    pub fn depth_bits(mut self, depth_bits: u8) -> PixelFormat {
        self.depth_bits = depth_bits;
        self
    }

    #[inline]
    pub fn stencil_bits(mut self, stencil_bits: u8) -> PixelFormat {
        self.stencil_bits = stencil_bits;
        self
    }

    #[inline]
    pub fn srgb(mut self, srgb: Option<bool>) -> PixelFormat {
        self.srgb = srgb;
        self
    }

    #[inline]
    pub fn color_buffer_float(mut self, color_buffer_float: bool) -> PixelFormat {
        self.color_buffer_float = color_buffer_float;
        self
    }

    #[inline]
    pub fn multisampling(mut self, multisampling: u16) -> PixelFormat {
        self.multisampling = multisampling;
        self
    }
}

impl Default for PixelFormat {
    fn default() -> PixelFormat {
        PixelFormat {
            color_bits: 32,
            alpha_bits: 8,
            depth_bits: 0,
            stencil_bits: 0,
            srgb: None,
            color_buffer_float: false,
            multisampling: 0
        }
    }
}<commit_msg>Fixed compile error with Send/Sync impls<commit_after>use std::default::Default;
use std::path::PathBuf;
use std::marker::{Send, Sync};

/// A struct that contains configuration information for any new window that's created.
/// The functions are present to allow the use of method-chaining to set the arguments,
/// which can be more concisely placed into a window creation function than just struct
/// creation. Note that those functions actually take ownership of the value instead of
/// a mutable reference - this is because they aren't intended to be used to mutate a
/// commonly-used WindowConfig but instead to mutate a one-off config used for one window,
/// like this:
///
/// ```
/// # use tub::config::WindowConfig;
/// # use tub::platform::Window;
/// # use std::path::Path;
/// let window = Window::new(
///     WindowConfig::new()
///         .name("It's a window!".to_owned())
///         .icon(Some(Path::new("tub.ico").to_path_buf()))
///         .size(Some((500, 500))),
///     Default::default()).unwrap();
/// ```
///
/// If you want to mutate a commonly-used WindowConfig, directly change the struct's fields
/// like so:
///
/// ```
/// # use tub::config::WindowConfig;
/// let mut window_config = WindowConfig::new();
///
/// window_config.name = "A name!".to_owned();
/// window_config.borderless = false;
/// ```
#[derive(Debug, Clone)]
pub struct WindowConfig {
    /// The window's name
    pub name: String,
    /// The window's dimensions
    pub size: Option<(i32, i32)>,

    /// Whether or not the window is a topmost window. If true, this window will
    /// always appear at the top of the Z order
    pub topmost: bool,

    /// Whether or not the window is a borderless window. Note that this will
    /// override any specified window decorations.
    pub borderless: bool,
    /// Whether or not the window can be resized by dragging on it's edge
    pub resizable: bool,
    /// Whether or not the window can be minimized
    pub maximizable: bool,
    /// Whether or not the window can be maximized
    pub minimizable: bool,
    /// Whether or not the window appears on the taskbar
    pub tool_window: bool,

    /// Whether or not the window can be transparent
    pub transparent: bool,

    /// The initial state of the window
    pub initial_state: InitialState,

    /// The path to the window's icon
    pub icon: Option<PathBuf>
}

unsafe impl Send for WindowConfig {}
unsafe impl Sync for WindowConfig {}

impl WindowConfig {
    /// Create a new window config. Identical to Default::default()
    #[inline]
    pub fn new() -> WindowConfig {
        Default::default()
    }

    #[inline]
    pub fn name(mut self, name: String) -> WindowConfig {
        self.name = name;
        self
    }

    #[inline]
    pub fn size(mut self, size: Option<(i32, i32)>) -> WindowConfig {
        self.size = size;
        self
    }

    #[inline]
    pub fn topmost(mut self, topmost: bool) -> WindowConfig {
        self.topmost = topmost;
        self
    }

    #[inline]
    pub fn borderless(mut self, borderless: bool) -> WindowConfig {
        self.borderless = borderless;
        self
    }

    #[inline]
    pub fn resizable(mut self, resizable: bool) -> WindowConfig {
        self.resizable = resizable;
        self
    }

    #[inline]
    pub fn maximizable(mut self, maximizable: bool) -> WindowConfig {
        self.maximizable = maximizable;
        self
    }

    #[inline]
    pub fn minimizable(mut self, minimizable: bool) -> WindowConfig {
        self.minimizable = minimizable;
        self
    }

    #[inline]
    pub fn tool_window(mut self, tool_window: bool) -> WindowConfig {
        self.tool_window = tool_window;
        self
    }

    #[inline]
    pub fn transparent(mut self, transparent: bool) -> WindowConfig {
        self.transparent = transparent;
        self
    }

    #[inline]
    pub fn initial_state(mut self, initial_state: InitialState) -> WindowConfig {
        self.initial_state = initial_state;
        self
    }

    #[inline]
    pub fn icon(mut self, icon: Option<PathBuf>) -> WindowConfig {
        self.icon = icon;
        self
    }
}

impl Default for WindowConfig {
    fn default() -> WindowConfig {
        WindowConfig {
            name: String::new(),
            size: None,

            topmost: false,

            borderless: false,
            resizable: true,
            maximizable: true,
            minimizable: true,
            tool_window: false,

            transparent: false,

            initial_state: InitialState::Windowed,

            icon: None
        }
    }
}

/// The initial state of the window
#[derive(Debug, Clone, Copy)]
pub enum InitialState {
    /// The window starts as a floating window
    Windowed,
    /// The window starts minimized
    Minimized,
    /// The window starts maximized
    Maximized
}

/// A struct that contains information about the pixel format for the window. See
/// the WindowConfig documentation for how and when to use the methods
#[derive(Debug, Clone)]
pub struct PixelFormat {
    pub color_bits: u8,
    pub alpha_bits: u8,
    pub depth_bits: u8,
    pub stencil_bits: u8,
    pub srgb: Option<bool>,
    pub color_buffer_float: bool,
    pub multisampling: u16
}

unsafe impl Send for PixelFormat {}
unsafe impl Sync for PixelFormat {}

impl PixelFormat {
    #[inline]
    pub fn new() -> PixelFormat {
        Default::default()
    }

    #[inline]
    pub fn color_bits(mut self, color_bits: u8) -> PixelFormat {
        self.color_bits = color_bits;
        self
    }

    #[inline]
    pub fn alpha_bits(mut self, alpha_bits: u8) -> PixelFormat {
        self.alpha_bits = alpha_bits;
        self
    }

    #[inline]
    pub fn depth_bits(mut self, depth_bits: u8) -> PixelFormat {
        self.depth_bits = depth_bits;
        self
    }

    #[inline]
    pub fn stencil_bits(mut self, stencil_bits: u8) -> PixelFormat {
        self.stencil_bits = stencil_bits;
        self
    }

    #[inline]
    pub fn srgb(mut self, srgb: Option<bool>) -> PixelFormat {
        self.srgb = srgb;
        self
    }

    #[inline]
    pub fn color_buffer_float(mut self, color_buffer_float: bool) -> PixelFormat {
        self.color_buffer_float = color_buffer_float;
        self
    }

    #[inline]
    pub fn multisampling(mut self, multisampling: u16) -> PixelFormat {
        self.multisampling = multisampling;
        self
    }
}

impl Default for PixelFormat {
    fn default() -> PixelFormat {
        PixelFormat {
            color_bits: 32,
            alpha_bits: 8,
            depth_bits: 0,
            stencil_bits: 0,
            srgb: None,
            color_buffer_float: false,
            multisampling: 0
        }
    }
}<|endoftext|>


<commit_before>pub static PAYLOAD_OFFSET: usize = 4;
pub static MAX_PACKET_LEN: usize = 16777219;
pub static MAX_PAYLOAD_LEN: usize = 16777215;

pub static UTF8_GENERAL_CI: u8 = 33u8;
pub static UTF8MB4_GENERAL_CI: u8 = 45u8;

/// Server status flags
bitflags! {
    pub flags StatusFlags: u16 {
        const SERVER_STATUS_IN_TRANS             = 0x0001u16,
        const SERVER_STATUS_AUTOCOMMIT           = 0x0002u16,
        const SERVER_MORE_RESULTS_EXISTS         = 0x0008u16,
        const SERVER_STATUS_NO_GOOD_INDEX_USED   = 0x0010u16,
        const SERVER_STATUS_NO_INDEX_USED        = 0x0020u16,
        const SERVER_STATUS_CURSOR_EXISTS        = 0x0040u16,
        const SERVER_STATUS_LAST_ROW_SENT        = 0x0080u16,
        const SERVER_STATUS_DB_DROPPED           = 0x0100u16,
        const SERVER_STATUS_NO_BACKSLASH_ESCAPES = 0x0200u16,
        const SERVER_STATUS_METADATA_CHANGED     = 0x0400u16,
        const SERVER_QUERY_WAS_SLOW              = 0x0800u16,
        const SERVER_PT_OUT_PARAMS               = 0x1000u16,
    }
}

/// Capability flags (u32)
bitflags! {
    pub flags CapabilityFlags: u32 {
        const CLIENT_LONG_PASSWORD                  = 0x00000001u32,
        const CLIENT_FOUND_ROWS                     = 0x00000002u32,
        const CLIENT_LONG_FLAG                      = 0x00000004u32,
        const CLIENT_CONNECT_WITH_DB                = 0x00000008u32,
        const CLIENT_NO_SCHEMA                      = 0x00000010u32,
        const CLIENT_COMPRESS                       = 0x00000020u32,
        const CLIENT_ODBC                           = 0x00000040u32,
        const CLIENT_LOCAL_FILES                    = 0x00000080u32,
        const CLIENT_IGNORE_SPACE                   = 0x00000100u32,
        const CLIENT_PROTOCOL_41                    = 0x00000200u32,
        const CLIENT_INTERACTIVE                    = 0x00000400u32,
        const CLIENT_SSL                            = 0x00000800u32,
        const CLIENT_IGNORE_SIGPIPE                 = 0x00001000u32,
        const CLIENT_TRANSACTIONS                   = 0x00002000u32,
        const CLIENT_RESERVED                       = 0x00004000u32,
        const CLIENT_SECURE_CONNECTION              = 0x00008000u32,
        const CLIENT_MULTI_STATEMENTS               = 0x00010000u32,
        const CLIENT_MULTI_RESULTS                  = 0x00020000u32,
        const CLIENT_PS_MULTI_RESULTS               = 0x00040000u32,
        const CLIENT_PLUGIN_AUTH                    = 0x00080000u32,
        const CLIENT_CONNECT_ATTRS                  = 0x00100000u32,
        const CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA = 0x00200000u32,
    }
}

/// Commands (u8)
#[allow(non_camel_case_types)]
#[derive(Clone, Eq, PartialEq, Copy, Debug)]
#[repr(u8)]
pub enum Command {
    COM_SLEEP               = 0x00_u8,
    COM_QUIT                = 0x01_u8,
    COM_INIT_DB             = 0x02_u8,
    COM_QUERY               = 0x03_u8,
    COM_FIELD_LIST          = 0x04_u8,
    COM_CREATE_DB           = 0x05_u8,
    COM_DROP_DB             = 0x06_u8,
    COM_REFRESH             = 0x07_u8,
    COM_SHUTDOWN            = 0x08_u8,
    COM_STATISTICS          = 0x09_u8,
    COM_PROCESS_INFO        = 0x0a_u8,
    COM_CONNECT             = 0x0b_u8,
    COM_PROCESS_KILL        = 0x0c_u8,
    COM_DEBUG               = 0x0d_u8,
    COM_PING                = 0x0e_u8,
    COM_TIME                = 0x0f_u8,
    COM_DELAYED_INSERT      = 0x10_u8,
    COM_CHANGE_USER         = 0x11_u8,
    COM_BINLOG_DUMP         = 0x12_u8,
    COM_TABLE_DUMP          = 0x13_u8,
    COM_CONNECT_OUT         = 0x14_u8,
    COM_REGISTER_SLAVE      = 0x15_u8,
    COM_STMT_PREPARE        = 0x16_u8,
    COM_STMT_EXECUTE        = 0x17_u8,
    COM_STMT_SEND_LONG_DATA = 0x18_u8,
    COM_STMT_CLOSE          = 0x19_u8,
    COM_STMT_RESET          = 0x1a_u8,
    COM_SET_OPTION          = 0x1b_u8,
    COM_STMT_FETCH          = 0x1c_u8,
    COM_DAEMON              = 0x1d_u8,
    COM_BINLOG_DUMP_GTID    = 0x1e_u8,
    COM_RESET_CONNECTION    = 0x1f_u8,
}

/// Text protocol column types (u8)
#[allow(non_camel_case_types)]
#[derive(Clone, Eq, PartialEq, Copy, Debug)]
#[repr(u8)]
pub enum ColumnType {
    MYSQL_TYPE_DECIMAL     = 0x00_u8,
    MYSQL_TYPE_TINY        = 0x01_u8,
    MYSQL_TYPE_SHORT       = 0x02_u8,
    MYSQL_TYPE_LONG        = 0x03_u8,
    MYSQL_TYPE_FLOAT       = 0x04_u8,
    MYSQL_TYPE_DOUBLE      = 0x05_u8,
    MYSQL_TYPE_NULL        = 0x06_u8,
    MYSQL_TYPE_TIMESTAMP   = 0x07_u8,
    MYSQL_TYPE_LONGLONG    = 0x08_u8,
    MYSQL_TYPE_INT24       = 0x09_u8,
    MYSQL_TYPE_DATE        = 0x0a_u8,
    MYSQL_TYPE_TIME        = 0x0b_u8,
    MYSQL_TYPE_DATETIME    = 0x0c_u8,
    MYSQL_TYPE_YEAR        = 0x0d_u8,
    MYSQL_TYPE_VARCHAR     = 0x0f_u8,
    MYSQL_TYPE_BIT         = 0x10_u8,
    MYSQL_TYPE_JSON        = 0xf5_u8,
    MYSQL_TYPE_NEWDECIMAL  = 0xf6_u8,
    MYSQL_TYPE_ENUM        = 0xf7_u8,
    MYSQL_TYPE_SET         = 0xf8_u8,
    MYSQL_TYPE_TINY_BLOB   = 0xf9_u8,
    MYSQL_TYPE_MEDIUM_BLOB = 0xfa_u8,
    MYSQL_TYPE_LONG_BLOB   = 0xfb_u8,
    MYSQL_TYPE_BLOB        = 0xfc_u8,
    MYSQL_TYPE_VAR_STRING  = 0xfd_u8,
    MYSQL_TYPE_STRING      = 0xfe_u8,
    MYSQL_TYPE_GEOMETRY    = 0xff_u8,
}

impl From<u8> for ColumnType {
    fn from(x: u8) -> ColumnType {
        match x {
            0x00_u8 => ColumnType::MYSQL_TYPE_DECIMAL,
            0x01_u8 => ColumnType::MYSQL_TYPE_TINY,
            0x02_u8 => ColumnType::MYSQL_TYPE_SHORT,
            0x03_u8 => ColumnType::MYSQL_TYPE_LONG,
            0x04_u8 => ColumnType::MYSQL_TYPE_FLOAT,
            0x05_u8 => ColumnType::MYSQL_TYPE_DOUBLE,
            0x06_u8 => ColumnType::MYSQL_TYPE_NULL,
            0x07_u8 => ColumnType::MYSQL_TYPE_TIMESTAMP,
            0x08_u8 => ColumnType::MYSQL_TYPE_LONGLONG,
            0x09_u8 => ColumnType::MYSQL_TYPE_INT24,
            0x0a_u8 => ColumnType::MYSQL_TYPE_DATE,
            0x0b_u8 => ColumnType::MYSQL_TYPE_TIME,
            0x0c_u8 => ColumnType::MYSQL_TYPE_DATETIME,
            0x0d_u8 => ColumnType::MYSQL_TYPE_YEAR,
            0x0f_u8 => ColumnType::MYSQL_TYPE_VARCHAR,
            0x10_u8 => ColumnType::MYSQL_TYPE_BIT,
            0xf5_u8 => ColumnType::MYSQL_TYPE_JSON,
            0xf6_u8 => ColumnType::MYSQL_TYPE_NEWDECIMAL,
            0xf7_u8 => ColumnType::MYSQL_TYPE_ENUM,
            0xf8_u8 => ColumnType::MYSQL_TYPE_SET,
            0xf9_u8 => ColumnType::MYSQL_TYPE_TINY_BLOB,
            0xfa_u8 => ColumnType::MYSQL_TYPE_MEDIUM_BLOB,
            0xfb_u8 => ColumnType::MYSQL_TYPE_LONG_BLOB,
            0xfc_u8 => ColumnType::MYSQL_TYPE_BLOB,
            0xfd_u8 => ColumnType::MYSQL_TYPE_VAR_STRING,
            0xfe_u8 => ColumnType::MYSQL_TYPE_STRING,
            0xff_u8 => ColumnType::MYSQL_TYPE_GEOMETRY,
            _ => panic!("Unknown column type {}", x),
        }
    }
}

/// Column flags (u16)
bitflags! {
    pub flags ColumnFlags: u16 {
        const NOT_NULL_FLAG         = 1u16,
        const PRI_KEY_FLAG          = 2u16,
        const UNIQUE_KEY_FLAG       = 4u16,
        const MULTIPLE_KEY_FLAG     = 8u16,
        const BLOB_FLAG             = 16u16,
        const UNSIGNED_FLAG         = 32u16,
        const ZEROFILL_FLAG         = 64u16,
        const BINARY_FLAG           = 128u16,
        const ENUM_FLAG             = 256u16,
        const AUTO_INCREMENT_FLAG   = 512u16,
        const TIMESTAMP_FLAG        = 1024u16,
        const SET_FLAG              = 2048u16,
        const NO_DEFAULT_VALUE_FLAG = 4096u16,
        const ON_UPDATE_NOW_FLAG    = 8192u16,
        const NUM_FLAG              = 32768u16,
        const PART_KEY_FLAG         = 16384u16,
    }
}
<commit_msg>Remove obsolete consts.rs file<commit_after><|endoftext|>


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

use std::sync::Arc;
use futures::sync::oneshot;
use futures::future::Future;

///
/// A data storage structure used to govern synchronous and asynchronous access to an underlying object.
///
pub struct Desync<T: Send> {
    /// Queue used for scheduling runtime for this object
    queue:  Arc<JobQueue>,

    /// Data for this object. Boxed so the pointer remains the same through the lifetime of the object.
    data:   Box<T>
}

// Rust actually derives this anyway at the moment
unsafe impl<T: Send> Send for Desync<T> {}

// True iff queue: Sync
unsafe impl<T: Send> Sync for Desync<T> {}

///
/// Used for passing the data pointer through to the queue
///
/// 'Safe' because the queue is synchronised during drop, so we can never use the pointer
/// if the object does not exist.
///
struct DataRef<T: Send>(*const T);
unsafe impl<T: Send> Send for DataRef<T> {}

// TODO: we can change DataRef to Shared (https://doc.rust-lang.org/std/ptr/struct.Shared.html in the future)

// TODO: T does not need to be static as we know that its lifetime is at least the lifetime of Desync<T> and hence the queue
impl<T: 'static+Send> Desync<T> {
    ///
    /// Creates a new Desync object
    ///
    pub fn new(data: T) -> Desync<T> {
        let queue = queue();

        Desync {
            queue:  queue,
            data:   Box::new(data)
        }
    }

    ///
    /// Performs an operation asynchronously on this item. This function will return
    /// immediately and the job will happen on a separate thread at some time in the
    /// future (generally fairly soon).
    ///
    /// Jobs are always performed in the order that they are queued and are always
    /// performed synchronously with respect to this object.
    ///
    pub fn async<TFn>(&self, job: TFn)
    where TFn: 'static+Send+FnOnce(&mut T) -> () {
        unsafe {
            // As drop() is the last thing called, we know that this object will still exist at the point where
            let data = DataRef(&*self.data);

            async(&self.queue, move || {
                let data = data.0 as *mut T;
                job(&mut *data);
            })
        }
    }

    ///
    /// Performs an operation synchronously on this item. This will be queued with any other
    /// jobs that this item may be performing, and this function will not return until the
    /// job is complete and the result is available.
    ///
    pub fn sync<TFn, Result>(&self, job: TFn) -> Result
    where TFn: 'static+Send+FnOnce(&mut T) -> Result, Result: 'static+Send {
        let result = unsafe {
            // As drop() is the last thing called, we know that this object will still exist at the point where
            let data = DataRef(&*self.data);

            sync(&self.queue, move || {
                let data = data.0 as *mut T;
                job(&mut *data)
            })
        };

        result
    }

    ///
    /// Performs an operation asynchronously on this thread, returning the result via a future.
    ///
    pub fn future<TFn, Item: 'static+Send>(&self, job: TFn) -> Box<Future<Item=Item, Error=oneshot::Canceled>>
    where TFn: 'static+Send+FnOnce(&mut T) -> Item {
        let (send, receive) = oneshot::channel();

        self.async(|data| {
            let result = job(data);
            send.send(result).ok();
        });

        Box::new(receive)
    }
}

impl<T: Send> Drop for Desync<T> {
    fn drop(&mut self) {
        // Ensure that everything on the queue has committed by queueing a last synchronous event
        // (Not synchronising the queue would make this unsafe as we would hold on to a pointer to
        // the internal data structure)
        sync(&self.queue, || {});
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::thread::*;
    use std::time::*;

    struct TestData {
        val: u32
    }

    #[test]
    fn can_retrieve_data_synchronously() {
        let desynced = Desync::new(TestData { val: 0 });

        assert!(desynced.sync(|data| data.val) == 0);
    }

    #[test]
    fn can_update_data_asynchronously() {
        let desynced = Desync::new(TestData { val: 0 });

        desynced.async(|data| {
            sleep(Duration::from_millis(100));
            data.val = 42;
        });

        assert!(desynced.sync(|data| data.val) == 42);
    }

    #[test]
    fn can_update_data_with_future() {
        use futures::executor;

        let desynced = Desync::new(TestData { val: 0 });

        desynced.async(|data| {
            sleep(Duration::from_millis(100));
            data.val = 42;
        });

        let mut future = executor::spawn(desynced.future(|data| data.val));

        assert!(future.wait_future().unwrap() == 42);
    }

    #[test]
    fn dropping_while_running_isnt_obviously_bad() {
        let desynced = Desync::new(TestData { val: 0 });

        desynced.async(|data| {
            sleep(Duration::from_millis(100));
            data.val = 42;
        });
        desynced.async(|data| {
            sleep(Duration::from_millis(100));
            data.val = 42;
        });
    }
}
<commit_msg>… and can remove the lifetime from here too<commit_after>use super::scheduler::*;

use std::sync::Arc;
use futures::sync::oneshot;
use futures::future::Future;

///
/// A data storage structure used to govern synchronous and asynchronous access to an underlying object.
///
pub struct Desync<T: Send> {
    /// Queue used for scheduling runtime for this object
    queue:  Arc<JobQueue>,

    /// Data for this object. Boxed so the pointer remains the same through the lifetime of the object.
    data:   Box<T>
}

// Rust actually derives this anyway at the moment
unsafe impl<T: Send> Send for Desync<T> {}

// True iff queue: Sync
unsafe impl<T: Send> Sync for Desync<T> {}

///
/// Used for passing the data pointer through to the queue
///
/// 'Safe' because the queue is synchronised during drop, so we can never use the pointer
/// if the object does not exist.
///
struct DataRef<T: Send>(*const T);
unsafe impl<T: Send> Send for DataRef<T> {}

// TODO: we can change DataRef to Shared (https://doc.rust-lang.org/std/ptr/struct.Shared.html in the future)

// TODO: T does not need to be static as we know that its lifetime is at least the lifetime of Desync<T> and hence the queue
impl<T: 'static+Send> Desync<T> {
    ///
    /// Creates a new Desync object
    ///
    pub fn new(data: T) -> Desync<T> {
        let queue = queue();

        Desync {
            queue:  queue,
            data:   Box::new(data)
        }
    }

    ///
    /// Performs an operation asynchronously on this item. This function will return
    /// immediately and the job will happen on a separate thread at some time in the
    /// future (generally fairly soon).
    ///
    /// Jobs are always performed in the order that they are queued and are always
    /// performed synchronously with respect to this object.
    ///
    pub fn async<TFn>(&self, job: TFn)
    where TFn: 'static+Send+FnOnce(&mut T) -> () {
        unsafe {
            // As drop() is the last thing called, we know that this object will still exist at the point where
            let data = DataRef(&*self.data);

            async(&self.queue, move || {
                let data = data.0 as *mut T;
                job(&mut *data);
            })
        }
    }

    ///
    /// Performs an operation synchronously on this item. This will be queued with any other
    /// jobs that this item may be performing, and this function will not return until the
    /// job is complete and the result is available.
    ///
    pub fn sync<TFn, Result>(&self, job: TFn) -> Result
    where TFn: Send+FnOnce(&mut T) -> Result, Result: Send {
        let result = unsafe {
            // As drop() is the last thing called, we know that this object will still exist at the point where
            let data = DataRef(&*self.data);

            sync(&self.queue, move || {
                let data = data.0 as *mut T;
                job(&mut *data)
            })
        };

        result
    }

    ///
    /// Performs an operation asynchronously on this thread, returning the result via a future.
    ///
    pub fn future<TFn, Item: 'static+Send>(&self, job: TFn) -> Box<Future<Item=Item, Error=oneshot::Canceled>>
    where TFn: 'static+Send+FnOnce(&mut T) -> Item {
        let (send, receive) = oneshot::channel();

        self.async(|data| {
            let result = job(data);
            send.send(result).ok();
        });

        Box::new(receive)
    }
}

impl<T: Send> Drop for Desync<T> {
    fn drop(&mut self) {
        // Ensure that everything on the queue has committed by queueing a last synchronous event
        // (Not synchronising the queue would make this unsafe as we would hold on to a pointer to
        // the internal data structure)
        sync(&self.queue, || {});
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::thread::*;
    use std::time::*;

    struct TestData {
        val: u32
    }

    #[test]
    fn can_retrieve_data_synchronously() {
        let desynced = Desync::new(TestData { val: 0 });

        assert!(desynced.sync(|data| data.val) == 0);
    }

    #[test]
    fn can_update_data_asynchronously() {
        let desynced = Desync::new(TestData { val: 0 });

        desynced.async(|data| {
            sleep(Duration::from_millis(100));
            data.val = 42;
        });

        assert!(desynced.sync(|data| data.val) == 42);
    }

    #[test]
    fn can_update_data_with_future() {
        use futures::executor;

        let desynced = Desync::new(TestData { val: 0 });

        desynced.async(|data| {
            sleep(Duration::from_millis(100));
            data.val = 42;
        });

        let mut future = executor::spawn(desynced.future(|data| data.val));

        assert!(future.wait_future().unwrap() == 42);
    }

    #[test]
    fn dropping_while_running_isnt_obviously_bad() {
        let desynced = Desync::new(TestData { val: 0 });

        desynced.async(|data| {
            sleep(Duration::from_millis(100));
            data.val = 42;
        });
        desynced.async(|data| {
            sleep(Duration::from_millis(100));
            data.val = 42;
        });
    }
}
<|endoftext|>