<commit_before>//! Layout handling

// remove
#![allow(unused)]

use rustwlc::handle::{WlcView, WlcOutput};
use rustwlc::types::VIEW_MAXIMIZED;
use std::rc::{Rc, Weak};
use std::fmt::{Debug, Formatter};
use std::fmt::Result as FmtResult;
use std::cell::RefCell;

pub type Node = Rc<RefCell<Container>>;

#[derive(Debug, Clone)]
pub enum Handle {
    View(WlcView),
    Output(WlcOutput)
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ContainerType {
    /// Root container, only one exists
    Root,
    /// WlcOutput/Monitor
    Output,
    /// A workspace
    Workspace,
    /// A Container, houses views and other containers
    Container,
    /// A view (window)
    View
}

/// Layout mode for a container
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Layout {
    None,
    Horizontal,
    Vertical,
    Stacked,
    Tabbed,
    Floating
}

#[derive(Clone)]
pub struct Container {
    handle: Option<Handle>,
    parent: Option<Weak<RefCell<Container>>>,
    children: Vec<Node>,
    container_type: ContainerType,
    layout: Layout,
    visible: bool,
    is_focused: bool,
    is_floating: bool,
}

/// Like i3, everything (workspaces, containers, views) are containable.
impl Container {

    /// Makes the root container. There should be only one of these
    /// Does not ensure that this is the only root container
    // NOTE Need to find a way to ensure there is only one of these things
    // Perhaps set a static global variable
    pub fn new_root() -> Node {
        trace!("Root created");
        Rc::new(RefCell::new(Container {
            handle: None,
            parent: None,
            children: vec!(),
            container_type: ContainerType::Root,
            layout: Layout::None,
            visible: false,
            is_focused: false,
            is_floating: false
        }))
    }

    /// Makes a new output. These can only be children of the root node. They
    /// contain information about which monitor (output) its children are being
    /// displayed on.
    pub fn new_output(root: &mut Node, wlc_output: WlcOutput) -> Node {
        if ! root.borrow().is_root() {
            panic!("Output containers can only be children of the root, not {:?}", root.borrow().get_type());
        }

        let size = wlc_output.get_resolution();
        let output = Rc::new(RefCell::new(Container {
            handle: Some(Handle::Output(wlc_output.clone())),
            parent: Some(Rc::downgrade(&root)),
            children: vec!(),
            container_type: ContainerType::Output,
            // NOTE Should be initialized to some default here, so the children
            // know which output they are on
            layout: Layout::None,
            visible: false,
            is_focused: false,
            is_floating: false
        }));
        // NOTE Should automatically add a new workspace here, there are edge
        // cases to worry about though so leaving that out for now
        root.borrow_mut().add_child(output.clone());
        output
    }

    /// Makes a new workspace container. These can only be attached to output
    /// containers. They will inherit the output of the parent container.
    pub fn new_workspace(parent_: &mut Node) -> Node {
        let parent = parent_.borrow();
        if parent.get_type() != ContainerType::Output {
            panic!("Workspaces can only be children of an output container, not {:?}", parent.get_type());
        }
        let workspace: Node =
            Rc::new(RefCell::new(Container {
                handle: Some(parent.get_handle().unwrap()),
                parent: Some(Rc::downgrade(&parent_)),
                children: vec!(),
                container_type: ContainerType::Workspace,
                // NOTE Change this to some other default
                layout: Layout::None,
                visible: false,
                is_focused: false,
                is_floating: false,
                }));
        drop(parent);
        parent_.borrow_mut().add_child(workspace.clone());
        trace!("Workspace created");
        workspace
    }

    /// Makes a new container. These hold views and other containers.
    /// Container hold information about specific parts of the tree in some
    /// workspace and the layout of the views within.
    pub fn new_container(parent_: &mut Node) -> Node {
        let mut parent = parent_.borrow_mut();
        if ! (parent.get_type() == ContainerType::Container
            || parent.get_type() == ContainerType::Workspace) {
            panic!("Container can only be child of container or workspace, not {:?}", parent.get_type());
        }
        let output = parent.get_handle().unwrap();
        let container = Rc::new(RefCell::new(Container {
            handle: Some(output),
            parent: Some(Rc::downgrade(&parent_)),
            children: vec!(),
            container_type: ContainerType::Container,
            // NOTE Get default, either from config or from workspace
            layout: Layout::None,
            visible: false,
            is_focused: false,
            is_floating: false,
        }));
        parent.add_child(container.clone());
        trace!("Container created");
        container
    }

    /// Makes a new view. A view holds either a Wayland or an X Wayland window.
    pub fn new_view(parent_: &mut Node, wlc_view: WlcView) -> Node {
        let mut parent = parent_.borrow_mut();
        if parent.is_root() {
            panic!("View cannot be a direct child of root, not {:?}", parent.get_type());
        }
        let view = Rc::new(RefCell::new(Container {
            handle: Some(Handle::View(wlc_view.clone())),
            parent: Some(Rc::downgrade(&parent_)),
            children: vec!(),
            container_type: ContainerType::View,
            layout: Layout::None,
            visible: false,
            is_focused: false,
            is_floating: false
        }));
        if parent.get_type() == ContainerType::Workspace {
            // Case of focused workspace, just create a child of it
            parent.add_child(view.clone());
        } else {
            // Regular case, create as sibling of current container
            parent.add_sibling(view.clone());
        }
        trace!("View created");
        view
    }

    /// Gets the parent that this container sits in.
    ///
    /// If the container is the root, it returns None
    pub fn get_parent(&self) -> Option<Node> {
        if self.is_root() {
            None
        } else {
            // NOTE Clone has to be done here because we have to store the
            // parent as an option since the `Weak::new` is unstable
            if let Some(parent) = self.parent.clone() {
                parent.upgrade()
            } else {
                None
            }
        }
    }

    pub fn add_child(&mut self, container: Node) -> Result<(), &'static str> {
        if self.get_type() == ContainerType::Workspace
            && container.borrow().get_type() == ContainerType::Workspace {
            return Err("Only containers can be children of a workspace");
        } else if self.get_type() == ContainerType::View {
            return Err("Cannot add child to a view");
        }
        // NOTE check to make sure we are not adding a duplicate
        self.children.push(container);
        Ok(())
    }

    pub fn add_sibling(&mut self, container: Node) -> Result<(), &'static str> {
        if self.is_root() {
            return Err("Root has no sibling, cannot add sibling to root");
        }
        let parent = self.get_parent().unwrap();
        trace!("Borrowing container {:?} (parent of {:?}) as mutable", parent, self);
        parent.borrow_mut().add_child(container);
        Ok(())
    }

    /// Removes this container and all of its children.
    /// You MUST call this function while `borrow`ing, a mutable borrow will
    /// cause it to panic at run time
    pub fn remove_container(&self) -> Result<(), &'static str> {
        if self.is_root() {
            return Err("Cannot remove root container");
        } else if self.get_type() == ContainerType::Workspace  {
            return Err("Cannot remove workspace container");
        }
        if let Some(parent) = self.get_parent() {
            // NOTE Add check here to ensure we can borrow mutably once that
            // feature stabilizes
            trace!("Borrowing container {:?} (parent of {:?}) as mutable", parent, self);
            parent.borrow_mut().remove_child(self);
        }
        Ok(())
    }

    /// Gets the children of this container.
    ///
    /// Views never have children
    pub fn get_children(&self) -> Option<&[Node]> {
        if self.get_type() == ContainerType::View {
            None
        }
        else {
            Some(self.children.as_slice())
        }
    }

    /// Gets the type of the container
    pub fn get_type(&self) -> ContainerType {
        self.container_type
    }

    /// Gets the handle of the container. This could either be an output (a
    /// monitor), or a view (a Wayland or X Wayland Window)
    pub fn get_handle(&self) -> Option<Handle> {
        self.handle.clone()
    }

    /// Returns true if this container is focused.
    pub fn is_focused(&self) -> bool {
        self.is_focused
    }

    /// Removes the child at the specified index
    pub fn remove_child_at(&mut self, index: usize) -> Result<Node, &'static str> {
        // NOTE Add check here to ensure we can borrow once that
        // feature stabilizes
        if self.children[index].borrow().get_type() == ContainerType::Workspace {
            return Err("Cannot remove workspace")
        }
        Ok(self.children.remove(index))
    }

    /// Removes the given child from this container's children.
    /// If the child is not present, then an error is returned
    pub fn remove_child(&mut self, node: &Container) -> Result<Node, &'static str> {
        for (index, child) in self.children.clone().iter().enumerate() {
            // NOTE Add check here to ensure we can borrow once that
            // feature stabilizes
            if *child.borrow() == *node {
                if child.borrow().get_type() == ContainerType::Workspace {
                    return Err("Can not remove workspace");
                }
                return Ok(self.children.remove(index));
            }
        }
        return Err("Could not find child in container");//format!("Could not find child {:?} in {:?}", node, self));
    }

    /// Sets this container (and everything in it) to given visibility
    pub fn set_visibility(&mut self, visibility: bool) {
        self.visible = visibility
    }

    /// Gets the visibility of the container
    pub fn get_visibility(&self) -> bool {
        self.visible
    }

    /// Gets the X and Y dimensions of the container. Width is the first
    /// value, height is the second.
    pub fn get_dimensions(&self) -> Option<(u32, u32)> {
        if let Some(ref handle) = self.handle {
            match handle {
                &Handle::Output(ref output) => {
                    let size = output.get_resolution();
                    Some((size.w, size.h))
                }
                &Handle::View(ref view) => {
                    let ref size = view.get_geometry().unwrap().size;
                    Some((size.w, size.h))
                }
            }
        } else {
            None
        }
    }

    /// Gets the position of this container on the screen.
    pub fn get_position(&self) -> Option<(i32, i32)> {
        if let Some(ref handle) = self.handle {
            match handle {
                &Handle::Output(ref output) => None,
                &Handle::View(ref view) => {
                    let ref origin = view.get_geometry().unwrap().origin;
                    Some((origin.x, origin.y))
                }
            }
        } else {
            None
        }
    }

    /// Returns true if this container is a parent of the child
    pub fn is_parent_of(&self, child: Node) -> bool {
        if self.is_root() {
            true
        } else {
            while ! child.borrow().is_root() {
                let parent = child.borrow().get_parent().unwrap();
                if child == parent {
                    return true
                }
            }
            return false;
        }
    }

    /// Returns true if this container is a child is an decedent of the parent
    pub fn is_child_of(&self, parent: Node) -> bool {
        parent.borrow().is_parent_of(Rc::new(RefCell::new(self.clone())))
    }

    pub fn is_root(&self) -> bool {
        self.get_type() == ContainerType::Root
    }

    /// Finds a parent container with the given type, if there is any
    pub fn get_parent_by_type(&self, container_type: ContainerType) -> Option<Node> {
        let mut container = self.get_parent();
        loop {
            if let Some(parent) = container {
                if parent.borrow().get_type() == container_type {
                    return Some(parent);
                }
                container = parent.borrow().get_parent();
            } else {
                return None;
            }
        }
    }
}

impl PartialEq for Container {
    fn eq(&self, other: &Container) -> bool {
        self.get_type() == other.get_type()
    }
}

impl Eq for Container { }

impl Debug for Container {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        f.debug_struct("Containable")
            .field("type", &self.get_type())
            //.field("parent", &self.get_parent())
            .field("children", &self.get_children())
            .field("focused", &self.is_focused())
            .finish()
    }
}
<commit_msg>add_sibling takes non-mutable borrow now, which could cause too many mutable borrows if not checked<commit_after>//! Layout handling

// remove
#![allow(unused)]

use rustwlc::handle::{WlcView, WlcOutput};
use rustwlc::types::VIEW_MAXIMIZED;
use std::rc::{Rc, Weak};
use std::fmt::{Debug, Formatter};
use std::fmt::Result as FmtResult;
use std::cell::RefCell;

pub type Node = Rc<RefCell<Container>>;

#[derive(Debug, Clone)]
pub enum Handle {
    View(WlcView),
    Output(WlcOutput)
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ContainerType {
    /// Root container, only one exists
    Root,
    /// WlcOutput/Monitor
    Output,
    /// A workspace
    Workspace,
    /// A Container, houses views and other containers
    Container,
    /// A view (window)
    View
}

/// Layout mode for a container
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Layout {
    None,
    Horizontal,
    Vertical,
    Stacked,
    Tabbed,
    Floating
}

#[derive(Clone)]
pub struct Container {
    handle: Option<Handle>,
    parent: Option<Weak<RefCell<Container>>>,
    children: Vec<Node>,
    container_type: ContainerType,
    layout: Layout,
    visible: bool,
    is_focused: bool,
    is_floating: bool,
}

/// Like i3, everything (workspaces, containers, views) are containable.
impl Container {

    /// Makes the root container. There should be only one of these
    /// Does not ensure that this is the only root container
    // NOTE Need to find a way to ensure there is only one of these things
    // Perhaps set a static global variable
    pub fn new_root() -> Node {
        trace!("Root created");
        Rc::new(RefCell::new(Container {
            handle: None,
            parent: None,
            children: vec!(),
            container_type: ContainerType::Root,
            layout: Layout::None,
            visible: false,
            is_focused: false,
            is_floating: false
        }))
    }

    /// Makes a new output. These can only be children of the root node. They
    /// contain information about which monitor (output) its children are being
    /// displayed on.
    pub fn new_output(root: &mut Node, wlc_output: WlcOutput) -> Node {
        if ! root.borrow().is_root() {
            panic!("Output containers can only be children of the root, not {:?}", root.borrow().get_type());
        }

        let size = wlc_output.get_resolution();
        let output = Rc::new(RefCell::new(Container {
            handle: Some(Handle::Output(wlc_output.clone())),
            parent: Some(Rc::downgrade(&root)),
            children: vec!(),
            container_type: ContainerType::Output,
            // NOTE Should be initialized to some default here, so the children
            // know which output they are on
            layout: Layout::None,
            visible: false,
            is_focused: false,
            is_floating: false
        }));
        // NOTE Should automatically add a new workspace here, there are edge
        // cases to worry about though so leaving that out for now
        root.borrow_mut().add_child(output.clone());
        output
    }

    /// Makes a new workspace container. These can only be attached to output
    /// containers. They will inherit the output of the parent container.
    pub fn new_workspace(parent_: &mut Node) -> Node {
        let parent = parent_.borrow();
        if parent.get_type() != ContainerType::Output {
            panic!("Workspaces can only be children of an output container, not {:?}", parent.get_type());
        }
        let workspace: Node =
            Rc::new(RefCell::new(Container {
                handle: Some(parent.get_handle().unwrap()),
                parent: Some(Rc::downgrade(&parent_)),
                children: vec!(),
                container_type: ContainerType::Workspace,
                // NOTE Change this to some other default
                layout: Layout::None,
                visible: false,
                is_focused: false,
                is_floating: false,
                }));
        drop(parent);
        parent_.borrow_mut().add_child(workspace.clone());
        trace!("Workspace created");
        workspace
    }

    /// Makes a new container. These hold views and other containers.
    /// Container hold information about specific parts of the tree in some
    /// workspace and the layout of the views within.
    pub fn new_container(parent_: &mut Node) -> Node {
        let mut parent = parent_.borrow_mut();
        if ! (parent.get_type() == ContainerType::Container
            || parent.get_type() == ContainerType::Workspace) {
            panic!("Container can only be child of container or workspace, not {:?}", parent.get_type());
        }
        let output = parent.get_handle().unwrap();
        let container = Rc::new(RefCell::new(Container {
            handle: Some(output),
            parent: Some(Rc::downgrade(&parent_)),
            children: vec!(),
            container_type: ContainerType::Container,
            // NOTE Get default, either from config or from workspace
            layout: Layout::None,
            visible: false,
            is_focused: false,
            is_floating: false,
        }));
        parent.add_child(container.clone());
        trace!("Container created");
        container
    }

    /// Makes a new view. A view holds either a Wayland or an X Wayland window.
    pub fn new_view(parent_: &mut Node, wlc_view: WlcView) -> Node {
        let parent = parent_.borrow();
        if parent.is_root() {
            panic!("View cannot be a direct child of root, not {:?}", parent.get_type());
        }
        let view = Rc::new(RefCell::new(Container {
            handle: Some(Handle::View(wlc_view.clone())),
            parent: Some(Rc::downgrade(&parent_)),
            children: vec!(),
            container_type: ContainerType::View,
            layout: Layout::None,
            visible: false,
            is_focused: false,
            is_floating: false
        }));
        if parent.get_type() == ContainerType::Workspace {
            // Case of focused workspace, just create a child of it
            drop(parent);
            let mut parent = parent_.borrow_mut();
            parent.add_child(view.clone());
        } else {
            // Regular case, create as sibling of current container
            parent.add_sibling(view.clone());
        }
        trace!("View created");
        view
    }

    /// Gets the parent that this container sits in.
    ///
    /// If the container is the root, it returns None
    pub fn get_parent(&self) -> Option<Node> {
        if self.is_root() {
            None
        } else {
            // NOTE Clone has to be done here because we have to store the
            // parent as an option since the `Weak::new` is unstable
            if let Some(parent) = self.parent.clone() {
                parent.upgrade()
            } else {
                None
            }
        }
    }

    pub fn add_child(&mut self, container: Node) -> Result<(), &'static str> {
        if self.get_type() == ContainerType::Workspace
            && container.borrow().get_type() == ContainerType::Workspace {
            return Err("Only containers can be children of a workspace");
        } else if self.get_type() == ContainerType::View {
            return Err("Cannot add child to a view");
        }
        // NOTE check to make sure we are not adding a duplicate
        self.children.push(container);
        Ok(())
    }

    pub fn add_sibling(&self, container: Node) -> Result<(), &'static str> {
        if self.is_root() {
            return Err("Root has no sibling, cannot add sibling to root");
        }
        let parent = self.get_parent().unwrap();
        trace!("Borrowing container {:?} (parent of {:?}) as mutable", parent, self);
        parent.borrow_mut().add_child(container);
        Ok(())
    }

    /// Removes this container and all of its children.
    /// You MUST call this function while `borrow`ing, a mutable borrow will
    /// cause it to panic at run time
    pub fn remove_container(&self) -> Result<(), &'static str> {
        if self.is_root() {
            return Err("Cannot remove root container");
        } else if self.get_type() == ContainerType::Workspace  {
            return Err("Cannot remove workspace container");
        }
        if let Some(parent) = self.get_parent() {
            // NOTE Add check here to ensure we can borrow mutably once that
            // feature stabilizes
            trace!("Borrowing container {:?} (parent of {:?}) as mutable", parent, self);
            parent.borrow_mut().remove_child(self);
        }
        Ok(())
    }

    /// Gets the children of this container.
    ///
    /// Views never have children
    pub fn get_children(&self) -> Option<&[Node]> {
        if self.get_type() == ContainerType::View {
            None
        }
        else {
            Some(self.children.as_slice())
        }
    }

    /// Gets the type of the container
    pub fn get_type(&self) -> ContainerType {
        self.container_type
    }

    /// Gets the handle of the container. This could either be an output (a
    /// monitor), or a view (a Wayland or X Wayland Window)
    pub fn get_handle(&self) -> Option<Handle> {
        self.handle.clone()
    }

    /// Returns true if this container is focused.
    pub fn is_focused(&self) -> bool {
        self.is_focused
    }

    /// Removes the child at the specified index
    pub fn remove_child_at(&mut self, index: usize) -> Result<Node, &'static str> {
        // NOTE Add check here to ensure we can borrow once that
        // feature stabilizes
        if self.children[index].borrow().get_type() == ContainerType::Workspace {
            return Err("Cannot remove workspace")
        }
        Ok(self.children.remove(index))
    }

    /// Removes the given child from this container's children.
    /// If the child is not present, then an error is returned
    pub fn remove_child(&mut self, node: &Container) -> Result<Node, &'static str> {
        for (index, child) in self.children.clone().iter().enumerate() {
            // NOTE Add check here to ensure we can borrow once that
            // feature stabilizes
            if *child.borrow() == *node {
                if child.borrow().get_type() == ContainerType::Workspace {
                    return Err("Can not remove workspace");
                }
                return Ok(self.children.remove(index));
            }
        }
        return Err("Could not find child in container");//format!("Could not find child {:?} in {:?}", node, self));
    }

    /// Sets this container (and everything in it) to given visibility
    pub fn set_visibility(&mut self, visibility: bool) {
        self.visible = visibility
    }

    /// Gets the visibility of the container
    pub fn get_visibility(&self) -> bool {
        self.visible
    }

    /// Gets the X and Y dimensions of the container. Width is the first
    /// value, height is the second.
    pub fn get_dimensions(&self) -> Option<(u32, u32)> {
        if let Some(ref handle) = self.handle {
            match handle {
                &Handle::Output(ref output) => {
                    let size = output.get_resolution();
                    Some((size.w, size.h))
                }
                &Handle::View(ref view) => {
                    let ref size = view.get_geometry().unwrap().size;
                    Some((size.w, size.h))
                }
            }
        } else {
            None
        }
    }

    /// Gets the position of this container on the screen.
    pub fn get_position(&self) -> Option<(i32, i32)> {
        if let Some(ref handle) = self.handle {
            match handle {
                &Handle::Output(ref output) => None,
                &Handle::View(ref view) => {
                    let ref origin = view.get_geometry().unwrap().origin;
                    Some((origin.x, origin.y))
                }
            }
        } else {
            None
        }
    }

    /// Returns true if this container is a parent of the child
    pub fn is_parent_of(&self, child: Node) -> bool {
        if self.is_root() {
            true
        } else {
            while ! child.borrow().is_root() {
                let parent = child.borrow().get_parent().unwrap();
                if child == parent {
                    return true
                }
            }
            return false;
        }
    }

    /// Returns true if this container is a child is an decedent of the parent
    pub fn is_child_of(&self, parent: Node) -> bool {
        parent.borrow().is_parent_of(Rc::new(RefCell::new(self.clone())))
    }

    pub fn is_root(&self) -> bool {
        self.get_type() == ContainerType::Root
    }

    /// Finds a parent container with the given type, if there is any
    pub fn get_parent_by_type(&self, container_type: ContainerType) -> Option<Node> {
        let mut container = self.get_parent();
        loop {
            if let Some(parent) = container {
                if parent.borrow().get_type() == container_type {
                    return Some(parent);
                }
                container = parent.borrow().get_parent();
            } else {
                return None;
            }
        }
    }
}

impl PartialEq for Container {
    fn eq(&self, other: &Container) -> bool {
        self.get_type() == other.get_type()
    }
}

impl Eq for Container { }

impl Debug for Container {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        f.debug_struct("Containable")
            .field("type", &self.get_type())
            //.field("parent", &self.get_parent())
            .field("children", &self.get_children())
            .field("focused", &self.is_focused())
            .finish()
    }
}
<|endoftext|>


<commit_before>use std::sync::atomic::Ordering;

use crate::{
    utils::Serial,
    wayland::{compositor, shell::xdg::XdgToplevelSurfaceData},
};

use wayland_protocols::xdg::shell::server::xdg_toplevel::{self, XdgToplevel};

use wayland_server::{
    backend::{ClientId, ObjectId},
    protocol::wl_surface,
    DataInit, Dispatch, DisplayHandle, Resource, WEnum,
};

use super::{
    SurfaceCachedState, ToplevelConfigure, XdgShellHandler, XdgShellState, XdgShellSurfaceUserData,
    XdgSurfaceUserData, XdgToplevelSurfaceRoleAttributes,
};

impl<D> Dispatch<XdgToplevel, XdgShellSurfaceUserData, D> for XdgShellState
where
    D: Dispatch<XdgToplevel, XdgShellSurfaceUserData>,
    D: XdgShellHandler,
    D: 'static,
{
    fn request(
        state: &mut D,
        _client: &wayland_server::Client,
        toplevel: &XdgToplevel,
        request: xdg_toplevel::Request,
        data: &XdgShellSurfaceUserData,
        _dh: &DisplayHandle,
        _data_init: &mut DataInit<'_, D>,
    ) {
        match request {
            xdg_toplevel::Request::Destroy => {
                if let Some(surface_data) = data.xdg_surface.data::<XdgSurfaceUserData>() {
                    surface_data.has_active_role.store(false, Ordering::Release);
                }
            }
            xdg_toplevel::Request::SetParent { parent } => {
                let parent_surface = parent.map(|toplevel_surface_parent| {
                    toplevel_surface_parent
                        .data::<XdgShellSurfaceUserData>()
                        .unwrap()
                        .wl_surface
                        .clone()
                });

                // Parent is not double buffered, we can set it directly
                set_parent(toplevel, parent_surface);
            }
            xdg_toplevel::Request::SetTitle { title } => {
                // Title is not double buffered, we can set it directly
                with_surface_toplevel_role_data(toplevel, |data| {
                    data.title = Some(title);
                });
            }
            xdg_toplevel::Request::SetAppId { app_id } => {
                // AppId is not double buffered, we can set it directly
                with_surface_toplevel_role_data(toplevel, |role| {
                    role.app_id = Some(app_id);
                });
            }
            xdg_toplevel::Request::ShowWindowMenu { seat, serial, x, y } => {
                // This has to be handled by the compositor
                let handle = make_toplevel_handle(toplevel);
                let serial = Serial::from(serial);

                XdgShellHandler::show_window_menu(state, handle, seat, serial, (x, y).into());
            }
            xdg_toplevel::Request::Move { seat, serial } => {
                // This has to be handled by the compositor
                let handle = make_toplevel_handle(toplevel);
                let serial = Serial::from(serial);

                XdgShellHandler::move_request(state, handle, seat, serial);
            }
            xdg_toplevel::Request::Resize { seat, serial, edges } => {
                if let WEnum::Value(edges) = edges {
                    // This has to be handled by the compositor
                    let handle = make_toplevel_handle(toplevel);
                    let serial = Serial::from(serial);

                    XdgShellHandler::resize_request(state, handle, seat, serial, edges);
                }
            }
            xdg_toplevel::Request::SetMaxSize { width, height } => {
                with_toplevel_pending_state(data, |toplevel_data| {
                    toplevel_data.max_size = (width, height).into();
                });
            }
            xdg_toplevel::Request::SetMinSize { width, height } => {
                with_toplevel_pending_state(data, |toplevel_data| {
                    toplevel_data.min_size = (width, height).into();
                });
            }
            xdg_toplevel::Request::SetMaximized => {
                let handle = make_toplevel_handle(toplevel);
                XdgShellHandler::maximize_request(state, handle);
            }
            xdg_toplevel::Request::UnsetMaximized => {
                let handle = make_toplevel_handle(toplevel);
                XdgShellHandler::unmaximize_request(state, handle);
            }
            xdg_toplevel::Request::SetFullscreen { output } => {
                let handle = make_toplevel_handle(toplevel);
                XdgShellHandler::fullscreen_request(state, handle, output);
            }
            xdg_toplevel::Request::UnsetFullscreen => {
                let handle = make_toplevel_handle(toplevel);
                XdgShellHandler::unfullscreen_request(state, handle);
            }
            xdg_toplevel::Request::SetMinimized => {
                // This has to be handled by the compositor, may not be
                // supported and just ignored
                let handle = make_toplevel_handle(toplevel);
                XdgShellHandler::minimize_request(state, handle);
            }
            _ => unreachable!(),
        }
    }

    fn destroyed(_state: &mut D, _client_id: ClientId, object_id: ObjectId, data: &XdgShellSurfaceUserData) {
        data.alive_tracker.destroy_notify();

        // remove this surface from the known ones (as well as any leftover dead surface)
        data.shell_data
            .lock()
            .unwrap()
            .known_toplevels
            .retain(|other| other.shell_surface.id() != object_id);
    }
}

// Utility functions allowing to factor out a lot of the upcoming logic
fn with_surface_toplevel_role_data<F, T>(toplevel: &xdg_toplevel::XdgToplevel, f: F) -> T
where
    F: FnOnce(&mut XdgToplevelSurfaceRoleAttributes) -> T,
{
    let data = toplevel.data::<XdgShellSurfaceUserData>().unwrap();
    compositor::with_states(&data.wl_surface, |states| {
        f(&mut *states
            .data_map
            .get::<XdgToplevelSurfaceData>()
            .unwrap()
            .lock()
            .unwrap())
    })
}

pub(super) fn make_toplevel_handle(
    resource: &xdg_toplevel::XdgToplevel,
) -> crate::wayland::shell::xdg::ToplevelSurface {
    let data = resource.data::<XdgShellSurfaceUserData>().unwrap();
    crate::wayland::shell::xdg::ToplevelSurface {
        wl_surface: data.wl_surface.clone(),
        shell_surface: resource.clone(),
    }
}

pub fn get_parent(toplevel: &xdg_toplevel::XdgToplevel) -> Option<wl_surface::WlSurface> {
    with_surface_toplevel_role_data(toplevel, |data| data.parent.clone())
}

/// Sets the parent of the specified toplevel surface.
///
/// The parent must be a toplevel surface.
///
/// The parent of a surface is not double buffered and therefore may be set directly.
///
/// If the parent is `None`, the parent-child relationship is removed.
pub fn set_parent(toplevel: &xdg_toplevel::XdgToplevel, parent: Option<wl_surface::WlSurface>) {
    with_surface_toplevel_role_data(toplevel, |data| {
        data.parent = parent;
    });
}

fn with_toplevel_pending_state<F, T>(data: &XdgShellSurfaceUserData, f: F) -> T
where
    F: FnOnce(&mut SurfaceCachedState) -> T,
{
    compositor::with_states(&data.wl_surface, |states| {
        f(&mut *states.cached_state.pending::<SurfaceCachedState>())
    })
}

pub fn send_toplevel_configure(resource: &xdg_toplevel::XdgToplevel, configure: ToplevelConfigure) {
    let data = resource.data::<XdgShellSurfaceUserData>().unwrap();
    let (width, height) = configure.state.size.unwrap_or_default().into();
    // convert the Vec<State> (which is really a Vec<u32>) into Vec<u8>
    let states = {
        let mut states: Vec<xdg_toplevel::State> =
            configure.state.states.into_filtered_states(resource.version());
        let ptr = states.as_mut_ptr();
        let len = states.len();
        let cap = states.capacity();
        ::std::mem::forget(states);
        unsafe { Vec::from_raw_parts(ptr as *mut u8, len * 4, cap * 4) }
    };
    let serial = configure.serial;

    // Send the toplevel configure
    resource.configure(width, height, states);

    // Send the base xdg_surface configure event to mark
    // The configure as finished
    data.xdg_surface.configure(serial.into());
}
<commit_msg>xdg/decoration: Cleanup reference cycle<commit_after>use std::sync::atomic::Ordering;

use crate::{
    utils::Serial,
    wayland::{compositor, shell::xdg::XdgToplevelSurfaceData},
};

use wayland_protocols::xdg::shell::server::xdg_toplevel::{self, XdgToplevel};

use wayland_server::{
    backend::{ClientId, ObjectId},
    protocol::wl_surface,
    DataInit, Dispatch, DisplayHandle, Resource, WEnum,
};

use super::{
    SurfaceCachedState, ToplevelConfigure, XdgShellHandler, XdgShellState, XdgShellSurfaceUserData,
    XdgSurfaceUserData, XdgToplevelSurfaceRoleAttributes,
};

impl<D> Dispatch<XdgToplevel, XdgShellSurfaceUserData, D> for XdgShellState
where
    D: Dispatch<XdgToplevel, XdgShellSurfaceUserData>,
    D: XdgShellHandler,
    D: 'static,
{
    fn request(
        state: &mut D,
        _client: &wayland_server::Client,
        toplevel: &XdgToplevel,
        request: xdg_toplevel::Request,
        data: &XdgShellSurfaceUserData,
        _dh: &DisplayHandle,
        _data_init: &mut DataInit<'_, D>,
    ) {
        match request {
            xdg_toplevel::Request::Destroy => {
                if let Some(surface_data) = data.xdg_surface.data::<XdgSurfaceUserData>() {
                    surface_data.has_active_role.store(false, Ordering::Release);
                }
            }
            xdg_toplevel::Request::SetParent { parent } => {
                let parent_surface = parent.map(|toplevel_surface_parent| {
                    toplevel_surface_parent
                        .data::<XdgShellSurfaceUserData>()
                        .unwrap()
                        .wl_surface
                        .clone()
                });

                // Parent is not double buffered, we can set it directly
                set_parent(toplevel, parent_surface);
            }
            xdg_toplevel::Request::SetTitle { title } => {
                // Title is not double buffered, we can set it directly
                with_surface_toplevel_role_data(toplevel, |data| {
                    data.title = Some(title);
                });
            }
            xdg_toplevel::Request::SetAppId { app_id } => {
                // AppId is not double buffered, we can set it directly
                with_surface_toplevel_role_data(toplevel, |role| {
                    role.app_id = Some(app_id);
                });
            }
            xdg_toplevel::Request::ShowWindowMenu { seat, serial, x, y } => {
                // This has to be handled by the compositor
                let handle = make_toplevel_handle(toplevel);
                let serial = Serial::from(serial);

                XdgShellHandler::show_window_menu(state, handle, seat, serial, (x, y).into());
            }
            xdg_toplevel::Request::Move { seat, serial } => {
                // This has to be handled by the compositor
                let handle = make_toplevel_handle(toplevel);
                let serial = Serial::from(serial);

                XdgShellHandler::move_request(state, handle, seat, serial);
            }
            xdg_toplevel::Request::Resize { seat, serial, edges } => {
                if let WEnum::Value(edges) = edges {
                    // This has to be handled by the compositor
                    let handle = make_toplevel_handle(toplevel);
                    let serial = Serial::from(serial);

                    XdgShellHandler::resize_request(state, handle, seat, serial, edges);
                }
            }
            xdg_toplevel::Request::SetMaxSize { width, height } => {
                with_toplevel_pending_state(data, |toplevel_data| {
                    toplevel_data.max_size = (width, height).into();
                });
            }
            xdg_toplevel::Request::SetMinSize { width, height } => {
                with_toplevel_pending_state(data, |toplevel_data| {
                    toplevel_data.min_size = (width, height).into();
                });
            }
            xdg_toplevel::Request::SetMaximized => {
                let handle = make_toplevel_handle(toplevel);
                XdgShellHandler::maximize_request(state, handle);
            }
            xdg_toplevel::Request::UnsetMaximized => {
                let handle = make_toplevel_handle(toplevel);
                XdgShellHandler::unmaximize_request(state, handle);
            }
            xdg_toplevel::Request::SetFullscreen { output } => {
                let handle = make_toplevel_handle(toplevel);
                XdgShellHandler::fullscreen_request(state, handle, output);
            }
            xdg_toplevel::Request::UnsetFullscreen => {
                let handle = make_toplevel_handle(toplevel);
                XdgShellHandler::unfullscreen_request(state, handle);
            }
            xdg_toplevel::Request::SetMinimized => {
                // This has to be handled by the compositor, may not be
                // supported and just ignored
                let handle = make_toplevel_handle(toplevel);
                XdgShellHandler::minimize_request(state, handle);
            }
            _ => unreachable!(),
        }
    }

    fn destroyed(_state: &mut D, _client_id: ClientId, object_id: ObjectId, data: &XdgShellSurfaceUserData) {
        data.alive_tracker.destroy_notify();
        data.decoration.lock().unwrap().take();

        // remove this surface from the known ones (as well as any leftover dead surface)
        data.shell_data
            .lock()
            .unwrap()
            .known_toplevels
            .retain(|other| other.shell_surface.id() != object_id);
    }
}

// Utility functions allowing to factor out a lot of the upcoming logic
fn with_surface_toplevel_role_data<F, T>(toplevel: &xdg_toplevel::XdgToplevel, f: F) -> T
where
    F: FnOnce(&mut XdgToplevelSurfaceRoleAttributes) -> T,
{
    let data = toplevel.data::<XdgShellSurfaceUserData>().unwrap();
    compositor::with_states(&data.wl_surface, |states| {
        f(&mut *states
            .data_map
            .get::<XdgToplevelSurfaceData>()
            .unwrap()
            .lock()
            .unwrap())
    })
}

pub(super) fn make_toplevel_handle(
    resource: &xdg_toplevel::XdgToplevel,
) -> crate::wayland::shell::xdg::ToplevelSurface {
    let data = resource.data::<XdgShellSurfaceUserData>().unwrap();
    crate::wayland::shell::xdg::ToplevelSurface {
        wl_surface: data.wl_surface.clone(),
        shell_surface: resource.clone(),
    }
}

pub fn get_parent(toplevel: &xdg_toplevel::XdgToplevel) -> Option<wl_surface::WlSurface> {
    with_surface_toplevel_role_data(toplevel, |data| data.parent.clone())
}

/// Sets the parent of the specified toplevel surface.
///
/// The parent must be a toplevel surface.
///
/// The parent of a surface is not double buffered and therefore may be set directly.
///
/// If the parent is `None`, the parent-child relationship is removed.
pub fn set_parent(toplevel: &xdg_toplevel::XdgToplevel, parent: Option<wl_surface::WlSurface>) {
    with_surface_toplevel_role_data(toplevel, |data| {
        data.parent = parent;
    });
}

fn with_toplevel_pending_state<F, T>(data: &XdgShellSurfaceUserData, f: F) -> T
where
    F: FnOnce(&mut SurfaceCachedState) -> T,
{
    compositor::with_states(&data.wl_surface, |states| {
        f(&mut *states.cached_state.pending::<SurfaceCachedState>())
    })
}

pub fn send_toplevel_configure(resource: &xdg_toplevel::XdgToplevel, configure: ToplevelConfigure) {
    let data = resource.data::<XdgShellSurfaceUserData>().unwrap();
    let (width, height) = configure.state.size.unwrap_or_default().into();
    // convert the Vec<State> (which is really a Vec<u32>) into Vec<u8>
    let states = {
        let mut states: Vec<xdg_toplevel::State> =
            configure.state.states.into_filtered_states(resource.version());
        let ptr = states.as_mut_ptr();
        let len = states.len();
        let cap = states.capacity();
        ::std::mem::forget(states);
        unsafe { Vec::from_raw_parts(ptr as *mut u8, len * 4, cap * 4) }
    };
    let serial = configure.serial;

    // Send the toplevel configure
    resource.configure(width, height, states);

    // Send the base xdg_surface configure event to mark
    // The configure as finished
    data.xdg_surface.configure(serial.into());
}
<|endoftext|>


<commit_before>// TODO: Rethink this in an architecture independent fashion in due time

use xen::event::dispatcher;
use xen::arch::x86::callbacks::set_callbacks;

extern "C" {
    fn hypervisor_callback();
    fn failsafe_callback();
}

#[cfg(target_arch = "x86")]
fn init_callbacks() {
    unsafe {
        use xen::defs::FLAT_KERNEL_CS;

        set_callbacks(FLAT_KERNEL_CS, hypervisor_callback,
                      FLAT_KERNEL_CS, failsafe_callback);
    }
}

#[cfg(target_arch = "x86_64")]
fn init_callbacks() {
    unsafe {
        set_callbacks(hypervisor_callback, failsafe_callback, None);
    }
}

#[no_mangle]
pub unsafe extern "C" fn do_hypervisor_callback() {
    panic!("Hypercall callback");
}

pub fn init() {
    init_callbacks();

    dispatcher().mask_all();

    println!("Event subsystem initialized");
}
<commit_msg>libboot: Use serve_event() as hypervisor callback<commit_after>// TODO: Rethink this in an architecture independent fashion in due time

use xen::event::dispatcher;
use xen::arch::x86::callbacks::set_callbacks;

extern "C" {
    fn hypervisor_callback();
    fn failsafe_callback();
}

#[cfg(target_arch = "x86")]
fn init_callbacks() {
    unsafe {
        use xen::defs::FLAT_KERNEL_CS;

        set_callbacks(FLAT_KERNEL_CS, hypervisor_callback,
                      FLAT_KERNEL_CS, failsafe_callback);
    }
}

#[cfg(target_arch = "x86_64")]
fn init_callbacks() {
    unsafe {
        set_callbacks(hypervisor_callback, failsafe_callback, None);
    }
}

#[no_mangle]
pub unsafe extern "C" fn do_hypervisor_callback() {
    dispatcher().serve_event();
}

pub fn init() {
    init_callbacks();

    dispatcher().mask_all();

    println!("Event subsystem initialized");
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 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.

/*! Composable internal iterators

Internal iterators are functions implementing the protocol used by the `for` loop.

An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal
breaking out of iteration. The adaptors in the module work with any such iterator, not just ones
tied to specific traits. For example:

~~~~
println(iter::to_vec(|f| uint::range(0, 20, f)).to_str());
~~~~

An external iterator object implementing the interface in the `iterator` module can be used as an
internal iterator by calling the `advance` method. For example:

~~~~
use core::iterator::*;

let xs = [0u, 1, 2, 3, 4, 5];
let ys = [30, 40, 50, 60];
let mut it = xs.iter().chain(ys.iter());
for it.advance |&x: &uint| {
    println(x.to_str());
}
~~~~

Internal iterators provide a subset of the functionality of an external iterator. It's not possible
to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often
much easier to implement.

*/

#[cfg(not(stage0))] use cmp::Ord;
#[cfg(not(stage0))] use option::{Option, Some, None};
#[cfg(not(stage0))] use vec::OwnedVector;

#[cfg(stage0)]
pub trait Times {
    fn times(&self, it: &fn() -> bool);
}
#[cfg(not(stage0))]
pub trait Times {
    fn times(&self, it: &fn() -> bool) -> bool;
}

/**
 * Transform an internal iterator into an owned vector.
 *
 * # Example:
 *
 * ~~~
 * let xs = ~[1, 2, 3];
 * let ys = do iter::to_vec |f| { xs.each(|x| f(*x)) };
 * assert_eq!(xs, ys);
 * ~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn to_vec<T>(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
    let mut v = ~[];
    for iter |x| { v.push(x) }
    v
}

/**
 * Return true if `predicate` is true for any values yielded by an internal iterator.
 *
 * Example:
 *
 * ~~~~
 * let xs = ~[1u, 2, 3, 4, 5];
 * assert!(any(|&x: &uint| x > 2, |f| xs.each(f)));
 * assert!(!any(|&x: &uint| x > 5, |f| xs.each(f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn any<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
    for iter |x| {
        if predicate(x) {
            return true;
        }
    }
    return false;
}

/**
 * Return true if `predicate` is true for all values yielded by an internal iterator.
 *
 * # Example:
 *
 * ~~~~
 * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
 * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(stage0)]
pub fn all<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool)) -> bool {
    for iter |x| {
        if !predicate(x) {
            return false;
        }
    }
    return true;
}

/**
 * Return true if `predicate` is true for all values yielded by an internal iterator.
 *
 * # Example:
 *
 * ~~~~
 * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
 * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn all<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
    // If we ever break, iter will return false, so this will only return true
    // if predicate returns true for everything.
    iter(|x| predicate(x))
}

/**
 * Return the first element where `predicate` returns `true`. Return `None` if no element is found.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[1u, 2, 3, 4, 5, 6];
 * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn find<T>(predicate: &fn(&T) -> bool,
               iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    for iter |x| {
        if predicate(&x) {
            return Some(x);
        }
    }
    None
}

/**
 * Return the largest item yielded by an iterator. Return `None` if the iterator is empty.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
 * assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
 * ~~~~
 */
#[inline]
#[cfg(not(stage0))]
pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    let mut result = None;
    for iter |x| {
        match result {
            Some(ref mut y) => {
                if x > *y {
                    *y = x;
                }
            }
            None => result = Some(x)
        }
    }
    result
}

/**
 * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
 * assert_eq!(max(|f| xs.each(f)).unwrap(), &-5);
 * ~~~~
 */
#[inline]
#[cfg(not(stage0))]
pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    let mut result = None;
    for iter |x| {
        match result {
            Some(ref mut y) => {
                if x < *y {
                    *y = x;
                }
            }
            None => result = Some(x)
        }
    }
    result
}

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

    #[test]
    fn test_to_vec() {
        let xs = ~[1, 2, 3];
        let ys = do to_vec |f| { xs.each(|x| f(*x)) };
        assert_eq!(xs, ys);
    }

    #[test]
    fn test_any() {
        let xs = ~[1u, 2, 3, 4, 5];
        assert!(any(|&x: &uint| x > 2, |f| xs.each(f)));
        assert!(!any(|&x: &uint| x > 5, |f| xs.each(f)));
    }

    #[test]
    fn test_all() {
        assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f)));
        assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f)));
    }

    #[test]
    fn test_find() {
        let xs = ~[1u, 2, 3, 4, 5, 6];
        assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
    }

    #[test]
    fn test_max() {
        let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
        assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
    }

    #[test]
    fn test_min() {
        let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
        assert_eq!(min(|f| xs.each(f)).unwrap(), &-5);
    }
}
<commit_msg>auto merge of #6544 : thestinger/rust/new_iter, r=nikomatsakis<commit_after>// Copyright 2012-2013 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.

/*! Composable internal iterators

Internal iterators are functions implementing the protocol used by the `for` loop.

An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal
breaking out of iteration. The adaptors in the module work with any such iterator, not just ones
tied to specific traits. For example:

~~~~
println(iter::to_vec(|f| uint::range(0, 20, f)).to_str());
~~~~

An external iterator object implementing the interface in the `iterator` module can be used as an
internal iterator by calling the `advance` method. For example:

~~~~
use core::iterator::*;

let xs = [0u, 1, 2, 3, 4, 5];
let ys = [30, 40, 50, 60];
let mut it = xs.iter().chain(ys.iter());
for it.advance |&x: &uint| {
    println(x.to_str());
}
~~~~

Internal iterators provide a subset of the functionality of an external iterator. It's not possible
to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often
much easier to implement.

*/

#[cfg(not(stage0))] use cmp::Ord;
#[cfg(not(stage0))] use option::{Option, Some, None};
#[cfg(not(stage0))] use vec::OwnedVector;
#[cfg(not(stage0))] use num::{One, Zero};
#[cfg(not(stage0))] use ops::{Add, Mul};

#[cfg(stage0)]
pub trait Times {
    fn times(&self, it: &fn() -> bool);
}
#[cfg(not(stage0))]
pub trait Times {
    fn times(&self, it: &fn() -> bool) -> bool;
}

/**
 * Transform an internal iterator into an owned vector.
 *
 * # Example:
 *
 * ~~~
 * let xs = ~[1, 2, 3];
 * let ys = do iter::to_vec |f| { xs.each(|x| f(*x)) };
 * assert_eq!(xs, ys);
 * ~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn to_vec<T>(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
    let mut v = ~[];
    for iter |x| { v.push(x) }
    v
}

/**
 * Return true if `predicate` is true for any values yielded by an internal iterator.
 *
 * Example:
 *
 * ~~~~
 * let xs = ~[1u, 2, 3, 4, 5];
 * assert!(any(|&x: &uint| x > 2, |f| xs.each(f)));
 * assert!(!any(|&x: &uint| x > 5, |f| xs.each(f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn any<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
    for iter |x| {
        if predicate(x) {
            return true;
        }
    }
    return false;
}

/**
 * Return true if `predicate` is true for all values yielded by an internal iterator.
 *
 * # Example:
 *
 * ~~~~
 * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
 * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(stage0)]
pub fn all<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool)) -> bool {
    for iter |x| {
        if !predicate(x) {
            return false;
        }
    }
    return true;
}

/**
 * Return true if `predicate` is true for all values yielded by an internal iterator.
 *
 * # Example:
 *
 * ~~~~
 * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
 * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn all<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
    // If we ever break, iter will return false, so this will only return true
    // if predicate returns true for everything.
    iter(|x| predicate(x))
}

/**
 * Return the first element where `predicate` returns `true`. Return `None` if no element is found.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[1u, 2, 3, 4, 5, 6];
 * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn find<T>(predicate: &fn(&T) -> bool,
               iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    for iter |x| {
        if predicate(&x) {
            return Some(x);
        }
    }
    None
}

/**
 * Return the largest item yielded by an iterator. Return `None` if the iterator is empty.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
 * assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
 * ~~~~
 */
#[inline]
#[cfg(not(stage0))]
pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    let mut result = None;
    for iter |x| {
        match result {
            Some(ref mut y) => {
                if x > *y {
                    *y = x;
                }
            }
            None => result = Some(x)
        }
    }
    result
}

/**
 * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
 * assert_eq!(max(|f| xs.each(f)).unwrap(), &-5);
 * ~~~~
 */
#[inline]
#[cfg(not(stage0))]
pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    let mut result = None;
    for iter |x| {
        match result {
            Some(ref mut y) => {
                if x < *y {
                    *y = x;
                }
            }
            None => result = Some(x)
        }
    }
    result
}

/**
 * Reduce an iterator to an accumulated value.
 *
 * # Example:
 *
 * ~~~~
 * assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
 * ~~~~
 */
#[cfg(not(stage0))]
#[inline]
pub fn fold<T, U>(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T {
    let mut result = start;
    for iter |x| {
        f(&mut result, x);
    }
    result
}

/**
 * Reduce an iterator to an accumulated value.
 *
 * `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it
 * forces the iterator to yield borrowed pointers.
 *
 * # Example:
 *
 * ~~~~
 * fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
 *     fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
 * }
 * ~~~~
 */
#[cfg(not(stage0))]
#[inline]
pub fn fold_ref<T, U>(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T {
    let mut result = start;
    for iter |x| {
        f(&mut result, x);
    }
    result
}

/**
 * Return the sum of the items yielding by an iterator.
 *
 * # Example:
 *
 * ~~~~
 * let xs: ~[int] = ~[1, 2, 3, 4];
 * assert_eq!(do sum |f| { xs.each(f) }, 10);
 * ~~~~
 */
#[cfg(not(stage0))]
#[inline(always)]
pub fn sum<T: Zero + Add<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
    fold_ref(Zero::zero::<T>(), iter, |a, x| *a = a.add(x))
}

/**
 * Return the product of the items yielded by an iterator.
 *
 * # Example:
 *
 * ~~~~
 * let xs: ~[int] = ~[1, 2, 3, 4];
 * assert_eq!(do product |f| { xs.each(f) }, 24);
 * ~~~~
 */
#[cfg(not(stage0))]
#[inline(always)]
pub fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
    fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
}

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

    #[test]
    fn test_to_vec() {
        let xs = ~[1, 2, 3];
        let ys = do to_vec |f| { xs.each(|x| f(*x)) };
        assert_eq!(xs, ys);
    }

    #[test]
    fn test_any() {
        let xs = ~[1u, 2, 3, 4, 5];
        assert!(any(|&x: &uint| x > 2, |f| xs.each(f)));
        assert!(!any(|&x: &uint| x > 5, |f| xs.each(f)));
    }

    #[test]
    fn test_all() {
        assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f)));
        assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f)));
    }

    #[test]
    fn test_find() {
        let xs = ~[1u, 2, 3, 4, 5, 6];
        assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
    }

    #[test]
    fn test_max() {
        let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
        assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
    }

    #[test]
    fn test_min() {
        let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
        assert_eq!(min(|f| xs.each(f)).unwrap(), &-5);
    }

    #[test]
    fn test_fold() {
        assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
    }

    #[test]
    fn test_sum() {
        let xs: ~[int] = ~[1, 2, 3, 4];
        assert_eq!(do sum |f| { xs.each(f) }, 10);
    }

    #[test]
    fn test_empty_sum() {
        let xs: ~[int] = ~[];
        assert_eq!(do sum |f| { xs.each(f) }, 0);
    }

    #[test]
    fn test_product() {
        let xs: ~[int] = ~[1, 2, 3, 4];
        assert_eq!(do product |f| { xs.each(f) }, 24);
    }

    #[test]
    fn test_empty_product() {
        let xs: ~[int] = ~[];
        assert_eq!(do product |f| { xs.each(f) }, 1);
    }
}
<|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.

//! A type that can represent all platform-native strings, but is cheaply
//! interconvertable with Rust strings.
//!
//! The need for this type arises from the fact that:
//!
//! * On Unix systems, strings are often arbitrary sequences of non-zero
//!   bytes, in many cases interpreted as UTF-8.
//!
//! * On Windows, strings are often arbitrary sequences of non-zero 16-bit
//!   values, interpreted as UTF-16 when it is valid to do so.
//!
//! * In Rust, strings are always valid UTF-8, but may contain zeros.
//!
//! The types in this module bridge this gap by simultaneously representing Rust
//! and platform-native string values, and in particular allowing a Rust string
//! to be converted into an "OS" string with no cost.
//!
//! **Note**: At the moment, these types are extremely bare-bones, usable only
//! for conversion to/from various other string types. Eventually these types
//! will offer a full-fledged string API.

use borrow::{Borrow, Cow, ToOwned};
use ffi::CString;
use fmt::{self, Debug};
use mem;
use string::String;
use ops;
use cmp;
use hash::{Hash, Hasher};
use vec::Vec;

use sys::os_str::{Buf, Slice};
use sys_common::{AsInner, IntoInner, FromInner};

/// Owned, mutable OS strings.
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsString {
    inner: Buf
}

/// Slices into OS strings.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsStr {
    inner: Slice
}

impl OsString {
    /// Constructs a new empty `OsString`.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new() -> OsString {
        OsString { inner: Buf::from_string(String::new()) }
    }

    /// Constructs an `OsString` from a byte sequence.
    ///
    /// # Platform behavior
    ///
    /// On Unix systems, any byte sequence can be successfully
    /// converted into an `OsString`.
    ///
    /// On Windows system, only UTF-8 byte sequences will successfully
    /// convert; non UTF-8 data will produce `None`.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    pub fn from_bytes<B>(bytes: B) -> Option<OsString> where B: Into<Vec<u8>> {
        Self::_from_bytes(bytes.into())
    }

    #[cfg(unix)]
    fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
        use os::unix::ffi::OsStringExt;
        Some(OsString::from_vec(vec))
    }

    #[cfg(windows)]
    fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
        String::from_utf8(vec).ok().map(OsString::from)
    }

    /// Converts to an `OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn as_os_str(&self) -> &OsStr {
        self
    }

    /// Converts the `OsString` into a `String` if it contains valid Unicode data.
    ///
    /// On failure, ownership of the original `OsString` is returned.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn into_string(self) -> Result<String, OsString> {
        self.inner.into_string().map_err(|buf| OsString { inner: buf} )
    }

    /// Extends the string with the given `&OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
        self.inner.push_slice(&s.as_ref().inner)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for OsString {
    fn from(s: String) -> OsString {
        OsString { inner: Buf::from_string(s) }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString {
    fn from(s: &'a T) -> OsString {
        s.as_ref().to_os_string()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFull> for OsString {
    type Output = OsStr;

    #[inline]
    fn index(&self, _index: ops::RangeFull) -> &OsStr {
        OsStr::from_inner(self.inner.as_slice())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Deref for OsString {
    type Target = OsStr;

    #[inline]
    fn deref(&self) -> &OsStr {
        &self[..]
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsString {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Debug::fmt(&**self, formatter)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsString {
    fn eq(&self, other: &OsString) -> bool {
        &**self == &**other
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsString {
    fn eq(&self, other: &str) -> bool {
        &**self == other
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsString> for str {
    fn eq(&self, other: &OsString) -> bool {
        &**other == self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsString {}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for OsString {
    #[inline]
    fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(&**other)
    }
    #[inline]
    fn lt(&self, other: &OsString) -> bool { &**self < &**other }
    #[inline]
    fn le(&self, other: &OsString) -> bool { &**self <= &**other }
    #[inline]
    fn gt(&self, other: &OsString) -> bool { &**self > &**other }
    #[inline]
    fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd<str> for OsString {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsString {
    #[inline]
    fn cmp(&self, other: &OsString) -> cmp::Ordering {
        (&**self).cmp(&**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Hash for OsString {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        (&**self).hash(state)
    }
}

impl OsStr {
    /// Coerces into an `OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
        s.as_ref()
    }

    fn from_inner(inner: &Slice) -> &OsStr {
        unsafe { mem::transmute(inner) }
    }

    /// Yields a `&str` slice if the `OsStr` is valid unicode.
    ///
    /// This conversion may entail doing a check for UTF-8 validity.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_str(&self) -> Option<&str> {
        self.inner.to_str()
    }

    /// Converts an `OsStr` to a `Cow<str>`.
    ///
    /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_string_lossy(&self) -> Cow<str> {
        self.inner.to_string_lossy()
    }

    /// Copies the slice into an owned `OsString`.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_os_string(&self) -> OsString {
        OsString { inner: self.inner.to_owned() }
    }

    /// Yields this `OsStr` as a byte slice.
    ///
    /// # Platform behavior
    ///
    /// On Unix systems, this is a no-op.
    ///
    /// On Windows systems, this returns `None` unless the `OsStr` is
    /// valid unicode, in which case it produces UTF-8-encoded
    /// data. This may entail checking validity.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    pub fn to_bytes(&self) -> Option<&[u8]> {
        if cfg!(windows) {
            self.to_str().map(|s| s.as_bytes())
        } else {
            Some(self.bytes())
        }
    }

    /// Creates a `CString` containing this `OsStr` data.
    ///
    /// Fails if the `OsStr` contains interior nulls.
    ///
    /// This is a convenience for creating a `CString` from
    /// `self.to_bytes()`, and inherits the platform behavior of the
    /// `to_bytes` method.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    #[allow(deprecated)]
    pub fn to_cstring(&self) -> Option<CString> {
        self.to_bytes().and_then(|b| CString::new(b).ok())
    }

    /// Gets the underlying byte representation.
    ///
    /// Note: it is *crucial* that this API is private, to avoid
    /// revealing the internal, platform-specific encodings.
    fn bytes(&self) -> &[u8] {
        unsafe { mem::transmute(&self.inner) }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsStr {
    fn eq(&self, other: &OsStr) -> bool {
        self.bytes().eq(other.bytes())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsStr {
    fn eq(&self, other: &str) -> bool {
        *self == *OsStr::new(other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsStr> for str {
    fn eq(&self, other: &OsStr) -> bool {
        *other == *OsStr::new(self)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsStr {}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
        self.bytes().partial_cmp(other.bytes())
    }
    #[inline]
    fn lt(&self, other: &OsStr) -> bool { self.bytes().lt(other.bytes()) }
    #[inline]
    fn le(&self, other: &OsStr) -> bool { self.bytes().le(other.bytes()) }
    #[inline]
    fn gt(&self, other: &OsStr) -> bool { self.bytes().gt(other.bytes()) }
    #[inline]
    fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd<str> for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        self.partial_cmp(OsStr::new(other))
    }
}

// FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
// have more flexible coherence rules.

#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsStr {
    #[inline]
    fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Hash for OsStr {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.bytes().hash(state)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsStr {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.inner.fmt(formatter)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Borrow<OsStr> for OsString {
    fn borrow(&self) -> &OsStr { &self[..] }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for OsStr {
    type Owned = OsString;
    fn to_owned(&self) -> OsString { self.to_os_string() }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for OsStr {
    fn as_ref(&self) -> &OsStr {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for OsString {
    fn as_ref(&self) -> &OsStr {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for str {
    fn as_ref(&self) -> &OsStr {
        OsStr::from_inner(Slice::from_str(self))
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for String {
    fn as_ref(&self) -> &OsStr {
        (&**self).as_ref()
    }
}

impl FromInner<Buf> for OsString {
    fn from_inner(buf: Buf) -> OsString {
        OsString { inner: buf }
    }
}

impl IntoInner<Buf> for OsString {
    fn into_inner(self) -> Buf {
        self.inner
    }
}

impl AsInner<Slice> for OsStr {
    fn as_inner(&self) -> &Slice {
        &self.inner
    }
}
<commit_msg>Rollup merge of #30758 - birkenfeld:fix-30743, r=steveklabnik<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.

use borrow::{Borrow, Cow, ToOwned};
use ffi::CString;
use fmt::{self, Debug};
use mem;
use string::String;
use ops;
use cmp;
use hash::{Hash, Hasher};
use vec::Vec;

use sys::os_str::{Buf, Slice};
use sys_common::{AsInner, IntoInner, FromInner};

/// A type that can represent owned, mutable platform-native strings, but is
/// cheaply interconvertable with Rust strings.
///
/// The need for this type arises from the fact that:
///
/// * On Unix systems, strings are often arbitrary sequences of non-zero
///   bytes, in many cases interpreted as UTF-8.
///
/// * On Windows, strings are often arbitrary sequences of non-zero 16-bit
///   values, interpreted as UTF-16 when it is valid to do so.
///
/// * In Rust, strings are always valid UTF-8, but may contain zeros.
///
/// `OsString` and `OsStr` bridge this gap by simultaneously representing Rust
/// and platform-native string values, and in particular allowing a Rust string
/// to be converted into an "OS" string with no cost.
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsString {
    inner: Buf
}

/// Slices into OS strings (see `OsString`).
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsStr {
    inner: Slice
}

impl OsString {
    /// Constructs a new empty `OsString`.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new() -> OsString {
        OsString { inner: Buf::from_string(String::new()) }
    }

    /// Constructs an `OsString` from a byte sequence.
    ///
    /// # Platform behavior
    ///
    /// On Unix systems, any byte sequence can be successfully
    /// converted into an `OsString`.
    ///
    /// On Windows system, only UTF-8 byte sequences will successfully
    /// convert; non UTF-8 data will produce `None`.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    pub fn from_bytes<B>(bytes: B) -> Option<OsString> where B: Into<Vec<u8>> {
        Self::_from_bytes(bytes.into())
    }

    #[cfg(unix)]
    fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
        use os::unix::ffi::OsStringExt;
        Some(OsString::from_vec(vec))
    }

    #[cfg(windows)]
    fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
        String::from_utf8(vec).ok().map(OsString::from)
    }

    /// Converts to an `OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn as_os_str(&self) -> &OsStr {
        self
    }

    /// Converts the `OsString` into a `String` if it contains valid Unicode data.
    ///
    /// On failure, ownership of the original `OsString` is returned.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn into_string(self) -> Result<String, OsString> {
        self.inner.into_string().map_err(|buf| OsString { inner: buf} )
    }

    /// Extends the string with the given `&OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
        self.inner.push_slice(&s.as_ref().inner)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for OsString {
    fn from(s: String) -> OsString {
        OsString { inner: Buf::from_string(s) }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString {
    fn from(s: &'a T) -> OsString {
        s.as_ref().to_os_string()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFull> for OsString {
    type Output = OsStr;

    #[inline]
    fn index(&self, _index: ops::RangeFull) -> &OsStr {
        OsStr::from_inner(self.inner.as_slice())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Deref for OsString {
    type Target = OsStr;

    #[inline]
    fn deref(&self) -> &OsStr {
        &self[..]
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsString {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Debug::fmt(&**self, formatter)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsString {
    fn eq(&self, other: &OsString) -> bool {
        &**self == &**other
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsString {
    fn eq(&self, other: &str) -> bool {
        &**self == other
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsString> for str {
    fn eq(&self, other: &OsString) -> bool {
        &**other == self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsString {}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for OsString {
    #[inline]
    fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(&**other)
    }
    #[inline]
    fn lt(&self, other: &OsString) -> bool { &**self < &**other }
    #[inline]
    fn le(&self, other: &OsString) -> bool { &**self <= &**other }
    #[inline]
    fn gt(&self, other: &OsString) -> bool { &**self > &**other }
    #[inline]
    fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd<str> for OsString {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsString {
    #[inline]
    fn cmp(&self, other: &OsString) -> cmp::Ordering {
        (&**self).cmp(&**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Hash for OsString {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        (&**self).hash(state)
    }
}

impl OsStr {
    /// Coerces into an `OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
        s.as_ref()
    }

    fn from_inner(inner: &Slice) -> &OsStr {
        unsafe { mem::transmute(inner) }
    }

    /// Yields a `&str` slice if the `OsStr` is valid unicode.
    ///
    /// This conversion may entail doing a check for UTF-8 validity.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_str(&self) -> Option<&str> {
        self.inner.to_str()
    }

    /// Converts an `OsStr` to a `Cow<str>`.
    ///
    /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_string_lossy(&self) -> Cow<str> {
        self.inner.to_string_lossy()
    }

    /// Copies the slice into an owned `OsString`.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_os_string(&self) -> OsString {
        OsString { inner: self.inner.to_owned() }
    }

    /// Yields this `OsStr` as a byte slice.
    ///
    /// # Platform behavior
    ///
    /// On Unix systems, this is a no-op.
    ///
    /// On Windows systems, this returns `None` unless the `OsStr` is
    /// valid unicode, in which case it produces UTF-8-encoded
    /// data. This may entail checking validity.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    pub fn to_bytes(&self) -> Option<&[u8]> {
        if cfg!(windows) {
            self.to_str().map(|s| s.as_bytes())
        } else {
            Some(self.bytes())
        }
    }

    /// Creates a `CString` containing this `OsStr` data.
    ///
    /// Fails if the `OsStr` contains interior nulls.
    ///
    /// This is a convenience for creating a `CString` from
    /// `self.to_bytes()`, and inherits the platform behavior of the
    /// `to_bytes` method.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    #[allow(deprecated)]
    pub fn to_cstring(&self) -> Option<CString> {
        self.to_bytes().and_then(|b| CString::new(b).ok())
    }

    /// Gets the underlying byte representation.
    ///
    /// Note: it is *crucial* that this API is private, to avoid
    /// revealing the internal, platform-specific encodings.
    fn bytes(&self) -> &[u8] {
        unsafe { mem::transmute(&self.inner) }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsStr {
    fn eq(&self, other: &OsStr) -> bool {
        self.bytes().eq(other.bytes())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsStr {
    fn eq(&self, other: &str) -> bool {
        *self == *OsStr::new(other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsStr> for str {
    fn eq(&self, other: &OsStr) -> bool {
        *other == *OsStr::new(self)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsStr {}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
        self.bytes().partial_cmp(other.bytes())
    }
    #[inline]
    fn lt(&self, other: &OsStr) -> bool { self.bytes().lt(other.bytes()) }
    #[inline]
    fn le(&self, other: &OsStr) -> bool { self.bytes().le(other.bytes()) }
    #[inline]
    fn gt(&self, other: &OsStr) -> bool { self.bytes().gt(other.bytes()) }
    #[inline]
    fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd<str> for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        self.partial_cmp(OsStr::new(other))
    }
}

// FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
// have more flexible coherence rules.

#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsStr {
    #[inline]
    fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Hash for OsStr {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.bytes().hash(state)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsStr {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.inner.fmt(formatter)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Borrow<OsStr> for OsString {
    fn borrow(&self) -> &OsStr { &self[..] }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for OsStr {
    type Owned = OsString;
    fn to_owned(&self) -> OsString { self.to_os_string() }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for OsStr {
    fn as_ref(&self) -> &OsStr {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for OsString {
    fn as_ref(&self) -> &OsStr {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for str {
    fn as_ref(&self) -> &OsStr {
        OsStr::from_inner(Slice::from_str(self))
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for String {
    fn as_ref(&self) -> &OsStr {
        (&**self).as_ref()
    }
}

impl FromInner<Buf> for OsString {
    fn from_inner(buf: Buf) -> OsString {
        OsString { inner: buf }
    }
}

impl IntoInner<Buf> for OsString {
    fn into_inner(self) -> Buf {
        self.inner
    }
}

impl AsInner<Slice> for OsStr {
    fn as_inner(&self) -> &Slice {
        &self.inner
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 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.

// Because this module is temporary...
#![allow(missing_docs)]
#![unstable(feature = "thunk")]

use alloc::boxed::{Box, FnBox};
use core::marker::Send;

pub type Thunk<'a, A=(), R=()> =
    Box<FnBox<A,Output=R> + Send + 'a>;

<commit_msg>std: Deprecate the `thunk` module<commit_after>// Copyright 2014 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.

// Because this module is temporary...
#![allow(missing_docs)]
#![unstable(feature = "thunk")]
#![deprecated(since = "1.2.0", reason = "use FnBox instead")]

use alloc::boxed::{Box, FnBox};
use core::marker::Send;

pub type Thunk<'a, A=(), R=()> =
    Box<FnBox<A,Output=R> + Send + 'a>;

<|endoftext|>


<commit_before>// Copyright 2012-2013 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.

/*!

Higher level communication abstractions.

*/

#[allow(missing_doc)];

use std::comm;

/// An extension of `pipes::stream` that allows both sending and receiving.
pub struct DuplexStream<T, U> {
    priv tx: Sender<T>,
    priv rx: Receiver<U>,
}

/// Creates a bidirectional stream.
pub fn duplex<T: Send, U: Send>() -> (DuplexStream<T, U>, DuplexStream<U, T>) {
    let (tx1, rx1) = channel();
    let (tx2, rx2) = channel();
    (DuplexStream { tx: tx1, rx: rx2 },
     DuplexStream { tx: tx2, rx: rx1 })
}

// Allow these methods to be used without import:
impl<T:Send,U:Send> DuplexStream<T, U> {
    pub fn send(&self, x: T) {
        self.tx.send(x)
    }
    pub fn try_send(&self, x: T) -> bool {
        self.tx.try_send(x)
    }
    pub fn recv(&self) -> U {
        self.rx.recv()
    }
    pub fn try_recv(&self) -> comm::TryRecvResult<U> {
        self.rx.try_recv()
    }
    pub fn recv_opt(&self) -> Option<U> {
        self.rx.recv_opt()
    }
}

/// An extension of `pipes::stream` that provides synchronous message sending.
pub struct SyncSender<T> { priv duplex_stream: DuplexStream<T, ()> }
/// An extension of `pipes::stream` that acknowledges each message received.
pub struct SyncReceiver<T> { priv duplex_stream: DuplexStream<(), T> }

impl<T: Send> SyncSender<T> {
    pub fn send(&self, val: T) {
        assert!(self.try_send(val), "SyncSender.send: receiving port closed");
    }

    /// Sends a message, or report if the receiver has closed the connection
    /// before receiving.
    pub fn try_send(&self, val: T) -> bool {
        self.duplex_stream.try_send(val) && self.duplex_stream.recv_opt().is_some()
    }
}

impl<T: Send> SyncReceiver<T> {
    pub fn recv(&self) -> T {
        self.recv_opt().expect("SyncReceiver.recv: sending channel closed")
    }

    pub fn recv_opt(&self) -> Option<T> {
        self.duplex_stream.recv_opt().map(|val| {
            self.duplex_stream.try_send(());
            val
        })
    }

    pub fn try_recv(&self) -> comm::TryRecvResult<T> {
        match self.duplex_stream.try_recv() {
            comm::Data(t) => { self.duplex_stream.try_send(()); comm::Data(t) }
            state => state,
        }
    }
}

/// Creates a stream whose channel, upon sending a message, blocks until the
/// message is received.
pub fn rendezvous<T: Send>() -> (SyncReceiver<T>, SyncSender<T>) {
    let (chan_stream, port_stream) = duplex();
    (SyncReceiver { duplex_stream: port_stream },
     SyncSender { duplex_stream: chan_stream })
}

#[cfg(test)]
mod test {
    use comm::{duplex, rendezvous};

    #[test]
    pub fn DuplexStream1() {
        let (left, right) = duplex();

        left.send(~"abc");
        right.send(123);

        assert!(left.recv() == 123);
        assert!(right.recv() == ~"abc");
    }

    #[test]
    pub fn basic_rendezvous_test() {
        let (port, chan) = rendezvous();

        spawn(proc() {
            chan.send("abc");
        });

        assert!(port.recv() == "abc");
    }

    #[test]
    fn recv_a_lot() {
        // Rendezvous streams should be able to handle any number of messages being sent
        let (port, chan) = rendezvous();
        spawn(proc() {
            for _ in range(0, 10000) { chan.send(()); }
        });
        for _ in range(0, 10000) { port.recv(); }
    }

    #[test]
    fn send_and_fail_and_try_recv() {
        let (port, chan) = rendezvous();
        spawn(proc() {
            chan.duplex_stream.send(()); // Can't access this field outside this module
            fail!()
        });
        port.recv()
    }

    #[test]
    fn try_send_and_recv_then_fail_before_ack() {
        let (port, chan) = rendezvous();
        spawn(proc() {
            port.duplex_stream.recv();
            fail!()
        });
        chan.try_send(());
    }

    #[test]
    #[should_fail]
    fn send_and_recv_then_fail_before_ack() {
        let (port, chan) = rendezvous();
        spawn(proc() {
            port.duplex_stream.recv();
            fail!()
        });
        chan.send(());
    }
}
<commit_msg>Change types T,U to R (recv), S (sender) in libsync/comm.rs<commit_after>// Copyright 2012-2013 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.

/*!

Higher level communication abstractions.

*/

#[allow(missing_doc)];

use std::comm;

/// An extension of `pipes::stream` that allows both sending and receiving.
pub struct DuplexStream<S, R> {
    priv tx: Sender<S>,
    priv rx: Receiver<R>,
}

/// Creates a bidirectional stream.
pub fn duplex<S: Send, R: Send>() -> (DuplexStream<S, R>, DuplexStream<R, S>) {
    let (tx1, rx1) = channel();
    let (tx2, rx2) = channel();
    (DuplexStream { tx: tx1, rx: rx2 },
     DuplexStream { tx: tx2, rx: rx1 })
}

// Allow these methods to be used without import:
impl<S:Send,R:Send> DuplexStream<S, R> {
    pub fn send(&self, x: S) {
        self.tx.send(x)
    }
    pub fn try_send(&self, x: S) -> bool {
        self.tx.try_send(x)
    }
    pub fn recv(&self) -> R {
        self.rx.recv()
    }
    pub fn try_recv(&self) -> comm::TryRecvResult<R> {
        self.rx.try_recv()
    }
    pub fn recv_opt(&self) -> Option<R> {
        self.rx.recv_opt()
    }
}

/// An extension of `pipes::stream` that provides synchronous message sending.
pub struct SyncSender<S> { priv duplex_stream: DuplexStream<S, ()> }
/// An extension of `pipes::stream` that acknowledges each message received.
pub struct SyncReceiver<R> { priv duplex_stream: DuplexStream<(), R> }

impl<S: Send> SyncSender<S> {
    pub fn send(&self, val: S) {
        assert!(self.try_send(val), "SyncSender.send: receiving port closed");
    }

    /// Sends a message, or report if the receiver has closed the connection
    /// before receiving.
    pub fn try_send(&self, val: S) -> bool {
        self.duplex_stream.try_send(val) && self.duplex_stream.recv_opt().is_some()
    }
}

impl<R: Send> SyncReceiver<R> {
    pub fn recv(&self) -> R {
        self.recv_opt().expect("SyncReceiver.recv: sending channel closed")
    }

    pub fn recv_opt(&self) -> Option<R> {
        self.duplex_stream.recv_opt().map(|val| {
            self.duplex_stream.try_send(());
            val
        })
    }

    pub fn try_recv(&self) -> comm::TryRecvResult<R> {
        match self.duplex_stream.try_recv() {
            comm::Data(t) => { self.duplex_stream.try_send(()); comm::Data(t) }
            state => state,
        }
    }
}

/// Creates a stream whose channel, upon sending a message, blocks until the
/// message is received.
pub fn rendezvous<T: Send>() -> (SyncReceiver<T>, SyncSender<T>) {
    let (chan_stream, port_stream) = duplex();
    (SyncReceiver { duplex_stream: port_stream },
     SyncSender { duplex_stream: chan_stream })
}

#[cfg(test)]
mod test {
    use comm::{duplex, rendezvous};

    #[test]
    pub fn DuplexStream1() {
        let (left, right) = duplex();

        left.send(~"abc");
        right.send(123);

        assert!(left.recv() == 123);
        assert!(right.recv() == ~"abc");
    }

    #[test]
    pub fn basic_rendezvous_test() {
        let (port, chan) = rendezvous();

        spawn(proc() {
            chan.send("abc");
        });

        assert!(port.recv() == "abc");
    }

    #[test]
    fn recv_a_lot() {
        // Rendezvous streams should be able to handle any number of messages being sent
        let (port, chan) = rendezvous();
        spawn(proc() {
            for _ in range(0, 10000) { chan.send(()); }
        });
        for _ in range(0, 10000) { port.recv(); }
    }

    #[test]
    fn send_and_fail_and_try_recv() {
        let (port, chan) = rendezvous();
        spawn(proc() {
            chan.duplex_stream.send(()); // Can't access this field outside this module
            fail!()
        });
        port.recv()
    }

    #[test]
    fn try_send_and_recv_then_fail_before_ack() {
        let (port, chan) = rendezvous();
        spawn(proc() {
            port.duplex_stream.recv();
            fail!()
        });
        chan.try_send(());
    }

    #[test]
    #[should_fail]
    fn send_and_recv_then_fail_before_ack() {
        let (port, chan) = rendezvous();
        spawn(proc() {
            port.duplex_stream.recv();
            fail!()
        });
        chan.send(());
    }
}
<|endoftext|>