<commit_before>//! The module exposes the `H2Client` struct, which implements a futures-based API for performing
//! HTTP/2 requests, based on Tokio.

use super::{HttpRequestHeaders, HttpRequestBody, HttpResponseHeaders, HttpResponseBody};
use client::tokio_layer::{H2ClientTokioProto};

use std::io::{self};
use std::net::SocketAddr;
use std::iter::{self, IntoIterator};

use futures::{Async, Future, Poll};
use futures::future::{self, BoxFuture};
use futures::stream::{self, Stream};

use tokio_core::reactor::{Handle};
use tokio_proto::{Connect, TcpClient};
use tokio_proto::streaming::{Message, Body};
use tokio_proto::streaming::multiplex::{StreamingMultiplex};
use tokio_proto::util::client_proxy::ClientProxy;

use tokio_service::{Service};

use solicit::http::{Header, StaticHeader};

/// A type alias for the request body stream. For now, we assume that all requests are a
/// single-chunk stream.
type RequestBodyStream = stream::Once<HttpRequestBody, io::Error>;

/// A type alias for the `ClientProxy` that we end up building after an `Io` is bound to a
/// `H2ClientTokioTransport` by `H2ClientTokioProto`.
type TokioClient =
    ClientProxy<
        Message<HttpRequestHeaders, RequestBodyStream>,
        Message<HttpResponseHeaders, Body<HttpResponseBody, io::Error>>,
        io::Error>;

/// A `futures::Stream` impl that represents the body of the response. The `Future` returned
/// by various `H2Client` methods returns an instance of this type, along with the response
/// headers.
pub struct ResponseBodyStream {
    /// The type simply hides away the Tokio `Body`, which will be returned by Tokio client
    /// Service.
    inner: Body<HttpResponseBody, io::Error>,
}

impl ResponseBodyStream {
    fn new(inner: Body<HttpResponseBody, io::Error>) -> ResponseBodyStream {
        ResponseBodyStream {
            inner: inner,
        }
    }
}

impl Stream for ResponseBodyStream {
    type Item = HttpResponseBody;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        self.inner.poll()
    }
}

/// A `Future` produced by the `H2Client`'s various `request` methods.
/// (`request`, `get`, `post`, ...)
pub struct FutureH2Response {
    /// Simply wraps a boxed future
    inner: BoxFuture<(HttpResponseHeaders, ResponseBodyStream), io::Error>,
}

impl Future for FutureH2Response {
    type Item = (HttpResponseHeaders, ResponseBodyStream);
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        self.inner.poll()
    }
}

impl FutureH2Response {
    /// Creates a new `FutureH2Response` wrapping the given boxed future.
    fn new(inner: BoxFuture<(HttpResponseHeaders, ResponseBodyStream), io::Error>)
            -> FutureH2Response {
        FutureH2Response {
            inner: inner,
        }
    }

    /// Consumes the `FutureH2Response` and returns a new `Future` that will resolve once the full
    /// body of the response has become available, with both the response headers and all the body
    /// bytes in a `Vec<u8>`.
    pub fn into_full_body_response(self) -> BoxFuture<(HttpResponseHeaders, Vec<u8>), io::Error> {
        let body_response = self.and_then(|(headers, body_stream)| {
            body_stream
                .fold(Vec::<u8>::new(), |mut vec, chunk| {
                    vec.extend(chunk.body.into_iter());
                    future::ok::<_, io::Error>(vec)
                })
                .map(|body| {
                    (headers, body)
                })
        });

        body_response.boxed()
    }
}

/// A struct that implements a futures-based API for an HTTP/2 client.
pub struct H2Client {
    /// The inner ClientProxy that hooks into the whole Tokio infrastructure.
    inner: TokioClient,
    /// The authority header (nee Host). Specifies the host name that the HTTP requests will
    /// be directed at. This is distinct from the socket address.
    authority: Vec<u8>,
}

impl H2Client {
    /// Creates a new `H2Client` from the given `TokioClient`.
    fn new(inner: TokioClient, authority: Vec<u8>) -> H2Client {
        H2Client {
            inner: inner,
            authority: authority,
        }
    }

    /// Connect to the given socket and yield a new `H2Client` that can be used to send HTTP/2
    /// requests to this socket.
    ///
    /// Returns a future that will resolve to the `H2Client`.
    pub fn connect(authority: &str, socket_addr: &SocketAddr, handle: &Handle) -> H2ClientNew {
        let proto = H2ClientTokioProto;

        let client = TcpClient::<StreamingMultiplex<RequestBodyStream>, _>::new(proto);
        let connect = client.connect(&socket_addr, &handle);

        H2ClientNew::new(connect, authority.as_bytes().to_vec())
    }

    /// Issues a GET request to the server.
    ///
    /// Yields a future that resolves to an `HttpRequestHeaders` struct. This struct will carry
    /// both the response headers, as well as the response body.
    pub fn get(&mut self, path: &[u8]) -> FutureH2Response {
        self.request(b"GET", path, iter::empty(), None)
    }

    /// Issues a POST request, carrying the given body.
    pub fn post(&mut self, path: &[u8], body: Vec<u8>) -> FutureH2Response {
        self.request(b"POST", path, iter::empty(), Some(body))
    }

    /// Perform a request, providing manually the request method, headers, and body.
    pub fn request<I>(&mut self,
                      method: &[u8],
                      path: &[u8],
                      user_headers: I,
                      body: Option<Vec<u8>>)
                      -> FutureH2Response
                      where I: IntoIterator<Item=StaticHeader> {
        let mut headers = Vec::new();
        headers.extend(vec![
            Header::new(b":method", method.to_vec()),
            Header::new(b":path", path.to_vec()),
            Header::new(b":authority", self.authority.clone()),
            Header::new(b":scheme", b"http"),
        ].into_iter());
        headers.extend(user_headers.into_iter());

        self.request_with_vec(headers, body)
    }

    /// Actually performs the full request. Avoids monomorphizing the entire code, but rather only
    /// the bit that requires the use of the IntoIterator trait, before passing off to this.
    fn request_with_vec(&mut self,
                        headers: Vec<StaticHeader>,
                        body: Option<Vec<u8>>)
                        -> FutureH2Response {

        let request_headers = HttpRequestHeaders::with_headers(headers);
        let tokio_req = match body {
            None => Message::WithoutBody(request_headers),
            Some(body) => {
                let body_stream = stream::once::<_, io::Error>(Ok(HttpRequestBody::new(body)));
                Message::WithBody(request_headers, body_stream)
            },
        };

        let response_future = Service::call(&self.inner, tokio_req).map(|response| {
            debug!("resolved response message");

            match response {
                Message::WithoutBody(resp @ HttpResponseHeaders { .. }) => {
                    // If there's no body, just yield an empty body stream.
                    (resp, ResponseBodyStream::new(Body::empty()))
                },
                Message::WithBody(resp @ HttpResponseHeaders { .. }, body) => {
                    (resp, ResponseBodyStream::new(body))
                },
            }
        });

        FutureH2Response::new(response_future.boxed())
    }
}

/// A simple `Future` implementation that resolves once the HTTP/2 client connection is
/// established.
pub struct H2ClientNew {
    /// The future that resolves to a new Tokio ClientProxy.
    inner: Connect<StreamingMultiplex<RequestBodyStream>, H2ClientTokioProto>,
    /// The authority that the new client will send requests to.
    authority: Option<Vec<u8>>,
}

impl H2ClientNew {
    fn new(connect: Connect<StreamingMultiplex<RequestBodyStream>, H2ClientTokioProto>,
           authority: Vec<u8>)
           -> H2ClientNew {
        H2ClientNew {
            inner: connect,
            authority: Some(authority),
        }
    }
}

impl Future for H2ClientNew {
    type Item = H2Client;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        trace!("waiting for client connection...");

        match self.inner.poll() {
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Ok(Async::Ready(client_proxy)) => {
                trace!("client connected");
                let authority = self.authority.take().expect("H2ClientNew future polled again");
                Ok(Async::Ready(H2Client::new(client_proxy, authority)))
            },
            Err(e) => Err(e),
        }
    }
}
<commit_msg>client: Refactor RequestBodyStream to use Tokio Body<commit_after>//! The module exposes the `H2Client` struct, which implements a futures-based API for performing
//! HTTP/2 requests, based on Tokio.

use super::{HttpRequestHeaders, HttpRequestBody, HttpResponseHeaders, HttpResponseBody};
use client::tokio_layer::{H2ClientTokioProto};

use std::io::{self};
use std::net::SocketAddr;
use std::iter::{self, IntoIterator};

use futures::{Async, Future, Poll};
use futures::future::{self, BoxFuture};
use futures::stream::{Stream};

use tokio_core::reactor::{Handle};
use tokio_proto::{Connect, TcpClient};
use tokio_proto::streaming::{Message, Body};
use tokio_proto::streaming::multiplex::{StreamingMultiplex};
use tokio_proto::util::client_proxy::ClientProxy;

use tokio_service::{Service};

use solicit::http::{Header, StaticHeader};

/// A type alias for the request body stream.
type RequestBodyStream = Body<HttpRequestBody, io::Error>;

/// A type alias for the `ClientProxy` that we end up building after an `Io` is bound to a
/// `H2ClientTokioTransport` by `H2ClientTokioProto`.
type TokioClient =
    ClientProxy<
        Message<HttpRequestHeaders, RequestBodyStream>,
        Message<HttpResponseHeaders, Body<HttpResponseBody, io::Error>>,
        io::Error>;

/// A `futures::Stream` impl that represents the body of the response. The `Future` returned
/// by various `H2Client` methods returns an instance of this type, along with the response
/// headers.
pub struct ResponseBodyStream {
    /// The type simply hides away the Tokio `Body`, which will be returned by Tokio client
    /// Service.
    inner: Body<HttpResponseBody, io::Error>,
}

impl ResponseBodyStream {
    fn new(inner: Body<HttpResponseBody, io::Error>) -> ResponseBodyStream {
        ResponseBodyStream {
            inner: inner,
        }
    }
}

impl Stream for ResponseBodyStream {
    type Item = HttpResponseBody;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        self.inner.poll()
    }
}

/// A `Future` produced by the `H2Client`'s various `request` methods.
/// (`request`, `get`, `post`, ...)
pub struct FutureH2Response {
    /// Simply wraps a boxed future
    inner: BoxFuture<(HttpResponseHeaders, ResponseBodyStream), io::Error>,
}

impl Future for FutureH2Response {
    type Item = (HttpResponseHeaders, ResponseBodyStream);
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        self.inner.poll()
    }
}

impl FutureH2Response {
    /// Creates a new `FutureH2Response` wrapping the given boxed future.
    fn new(inner: BoxFuture<(HttpResponseHeaders, ResponseBodyStream), io::Error>)
            -> FutureH2Response {
        FutureH2Response {
            inner: inner,
        }
    }

    /// Consumes the `FutureH2Response` and returns a new `Future` that will resolve once the full
    /// body of the response has become available, with both the response headers and all the body
    /// bytes in a `Vec<u8>`.
    pub fn into_full_body_response(self) -> BoxFuture<(HttpResponseHeaders, Vec<u8>), io::Error> {
        let body_response = self.and_then(|(headers, body_stream)| {
            body_stream
                .fold(Vec::<u8>::new(), |mut vec, chunk| {
                    vec.extend(chunk.body.into_iter());
                    future::ok::<_, io::Error>(vec)
                })
                .map(|body| {
                    (headers, body)
                })
        });

        body_response.boxed()
    }
}

/// A struct that implements a futures-based API for an HTTP/2 client.
pub struct H2Client {
    /// The inner ClientProxy that hooks into the whole Tokio infrastructure.
    inner: TokioClient,
    /// The authority header (nee Host). Specifies the host name that the HTTP requests will
    /// be directed at. This is distinct from the socket address.
    authority: Vec<u8>,
}

impl H2Client {
    /// Creates a new `H2Client` from the given `TokioClient`.
    fn new(inner: TokioClient, authority: Vec<u8>) -> H2Client {
        H2Client {
            inner: inner,
            authority: authority,
        }
    }

    /// Connect to the given socket and yield a new `H2Client` that can be used to send HTTP/2
    /// requests to this socket.
    ///
    /// Returns a future that will resolve to the `H2Client`.
    pub fn connect(authority: &str, socket_addr: &SocketAddr, handle: &Handle) -> H2ClientNew {
        let proto = H2ClientTokioProto;

        let client = TcpClient::<StreamingMultiplex<RequestBodyStream>, _>::new(proto);
        let connect = client.connect(&socket_addr, &handle);

        H2ClientNew::new(connect, authority.as_bytes().to_vec())
    }

    /// Issues a GET request to the server.
    ///
    /// Yields a future that resolves to an `HttpRequestHeaders` struct. This struct will carry
    /// both the response headers, as well as the response body.
    pub fn get(&mut self, path: &[u8]) -> FutureH2Response {
        self.request(b"GET", path, iter::empty(), None)
    }

    /// Issues a POST request, carrying the given body.
    pub fn post(&mut self, path: &[u8], body: Vec<u8>) -> FutureH2Response {
        self.request(b"POST", path, iter::empty(), Some(body))
    }

    /// Perform a request, providing manually the request method, headers, and body.
    pub fn request<I>(&mut self,
                      method: &[u8],
                      path: &[u8],
                      user_headers: I,
                      body: Option<Vec<u8>>)
                      -> FutureH2Response
                      where I: IntoIterator<Item=StaticHeader> {
        let mut headers = Vec::new();
        headers.extend(vec![
            Header::new(b":method", method.to_vec()),
            Header::new(b":path", path.to_vec()),
            Header::new(b":authority", self.authority.clone()),
            Header::new(b":scheme", b"http"),
        ].into_iter());
        headers.extend(user_headers.into_iter());

        self.request_with_vec(headers, body)
    }

    /// Actually performs the full request. Avoids monomorphizing the entire code, but rather only
    /// the bit that requires the use of the IntoIterator trait, before passing off to this.
    fn request_with_vec(&mut self,
                        headers: Vec<StaticHeader>,
                        body: Option<Vec<u8>>)
                        -> FutureH2Response {

        let request_headers = HttpRequestHeaders::with_headers(headers);
        let tokio_req = match body {
            None => Message::WithoutBody(request_headers),
            Some(body) => {
                let body_stream = Body::from(HttpRequestBody::new(body));
                Message::WithBody(request_headers, body_stream)
            },
        };

        let response_future = Service::call(&self.inner, tokio_req).map(|response| {
            debug!("resolved response message");

            match response {
                Message::WithoutBody(resp @ HttpResponseHeaders { .. }) => {
                    // If there's no body, just yield an empty body stream.
                    (resp, ResponseBodyStream::new(Body::empty()))
                },
                Message::WithBody(resp @ HttpResponseHeaders { .. }, body) => {
                    (resp, ResponseBodyStream::new(body))
                },
            }
        });

        FutureH2Response::new(response_future.boxed())
    }
}

/// A simple `Future` implementation that resolves once the HTTP/2 client connection is
/// established.
pub struct H2ClientNew {
    /// The future that resolves to a new Tokio ClientProxy.
    inner: Connect<StreamingMultiplex<RequestBodyStream>, H2ClientTokioProto>,
    /// The authority that the new client will send requests to.
    authority: Option<Vec<u8>>,
}

impl H2ClientNew {
    fn new(connect: Connect<StreamingMultiplex<RequestBodyStream>, H2ClientTokioProto>,
           authority: Vec<u8>)
           -> H2ClientNew {
        H2ClientNew {
            inner: connect,
            authority: Some(authority),
        }
    }
}

impl Future for H2ClientNew {
    type Item = H2Client;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        trace!("waiting for client connection...");

        match self.inner.poll() {
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Ok(Async::Ready(client_proxy)) => {
                trace!("client connected");
                let authority = self.authority.take().expect("H2ClientNew future polled again");
                Ok(Async::Ready(H2Client::new(client_proxy, authority)))
            },
            Err(e) => Err(e),
        }
    }
}
<|endoftext|>


<commit_before>use petgraph::graph::NodeIndex;

use rustwlc::WlcView;

use super::super::LayoutTree;
use super::super::core::Direction;
use super::super::core::container::{Container, ContainerType, Handle, Layout};

impl LayoutTree {
    pub fn move_focus_recurse(&mut self, node_ix: NodeIndex, direction: Direction) -> Result<NodeIndex, ()> {
        match self.tree[node_ix].get_type() {
            ContainerType::View | ContainerType::Container => { /* continue */ },
            _ => return Err(())
        }
        let parent_ix = self.tree.parent_of(node_ix)
            .expect("Active ix had no parent");
        match self.tree[parent_ix] {
            Container::Container { layout, .. } => {
                match (layout, direction) {
                    (Layout::Horizontal, Direction::Left) |
                    (Layout::Horizontal, Direction::Right) |
                    (Layout::Vertical, Direction::Up) |
                    (Layout::Vertical, Direction::Down) => {
                        let siblings = self.tree.children_of(parent_ix);
                        let cur_index = siblings.iter().position(|node| {
                            *node == node_ix
                        }).expect("Could not find self in parent");
                        let maybe_new_index = match direction {
                            Direction::Right | Direction::Down => {
                                cur_index.checked_add(1)
                            }
                            Direction::Left  | Direction::Up => {
                                cur_index.checked_sub(1)
                            }
                        };
                        if maybe_new_index.is_some() &&
                            maybe_new_index.unwrap() < siblings.len() {
                                // There is a sibling to move to.
                                let new_index = maybe_new_index.unwrap();
                                let new_active_ix = siblings[new_index];
                                match self.tree[new_active_ix].get_type() {
                                    ContainerType::Container => {
                                        let path_ix = self.tree.follow_path(new_active_ix);
                                        // If the pat wasn't complete, find the first view and focus on that
                                        let node_ix = (self.tree.descendant_of_type(path_ix, ContainerType::View)).unwrap();
                                        let parent_ix = (self.tree.parent_of(node_ix)).unwrap();
                                        match self.tree[node_ix].get_type() {
                                            ContainerType::View | ContainerType::Container => {},
                                            _ => panic!("Following path did not lead to a container or a view!")
                                        }
                                        trace!("Moving to different view {:?} in container {:?}",
                                                self.tree[node_ix], self.tree[parent_ix]);
                                        return Ok(node_ix);
                                    },
                                    ContainerType::View => {
                                        trace!("Moving to other view {:?}", self.tree[new_active_ix]);
                                        return Ok(new_active_ix)
                                    },
                                    _ => unreachable!()
                                };
                            }
                    },
                    _ => { /* We are moving out of siblings, recurse */ }
                }
            }
            Container::Workspace { .. } => {
                return Err(());
            }
            _ => unreachable!()
        }
        let parent_ix = self.tree.parent_of(node_ix)
            .expect("Node had no parent");
        return self.move_focus_recurse(parent_ix, direction);
    }

    /// Updates the current active container to be the next container or view
    /// to focus on after the previous view/container was moved/removed.
    ///
    /// A new view will tried to be set, starting with the children of the
    /// parent node. If a view cannot be found there, it starts climbing the
    /// tree until either a view is found or the workspace is (in which case
    /// it set the active container to the root container of the workspace)
    pub fn focus_on_next_container(&mut self, mut parent_ix: NodeIndex) {
        while self.tree.node_type(parent_ix)
            .expect("Node not part of the tree") != ContainerType::Workspace {
            if let Some(view_ix) = self.tree.descendant_of_type_right(parent_ix,
                                                            ContainerType::View) {
                match self.tree[view_ix]
                                    .get_handle().expect("view had no handle") {
                    Handle::View(view) => view.focus(),
                    _ => panic!("View had an output handle")
                }
                trace!("Active container set to view at {:?}", view_ix);
                let id = self.tree[view_ix].get_id();
                self.set_active_container(id)
                    .expect("Could not set active container");
                return;
            }
            parent_ix = self.tree.ancestor_of_type(parent_ix,
                                                    ContainerType::Container)
                .unwrap_or_else(|| {
                    self.tree.ancestor_of_type(parent_ix, ContainerType::Workspace)
                        .expect("Container was not part of a workspace")
                });
        }
        // If this is reached, parent is workspace
        let container_ix = self.tree.children_of(parent_ix)[0];
        // set the workspace to be active
        match self.tree[parent_ix] {
            Container::Workspace {ref mut focused, .. }=> {
                *focused = true;
            },
            _ => unreachable!()
        }
        let root_c_children = self.tree.children_of(container_ix);
        if root_c_children.len() > 0 {
            let new_active_ix = self.tree.descendant_of_type(root_c_children[0],
                                                                ContainerType::View)
                .unwrap_or(root_c_children[0]);
            let id = self.tree[new_active_ix].get_id();
            self.set_active_container(id)
                .expect("Could not set active container");
            match self.tree[new_active_ix] {
                Container::View { ref handle, .. } => handle.focus(),
                _ => {}
            };
            return;
        }
        trace!("Active container set to container {:?}", container_ix);
        let id = self.tree[container_ix].get_id();
        self.set_active_container(id)
            .expect("Could not set active container");

        // Update focus to new container
        self.get_active_container().map(|con| match *con {
            Container::View { ref handle, .. } => handle.focus(),
            Container::Container { .. } => WlcView::root().focus(),
            _ => panic!("Active container not view or container!")
        });
    }
}
<commit_msg>Type fixed<commit_after>use petgraph::graph::NodeIndex;

use rustwlc::WlcView;

use super::super::LayoutTree;
use super::super::core::Direction;
use super::super::core::container::{Container, ContainerType, Handle, Layout};

impl LayoutTree {
    pub fn move_focus_recurse(&mut self, node_ix: NodeIndex, direction: Direction) -> Result<NodeIndex, ()> {
        match self.tree[node_ix].get_type() {
            ContainerType::View | ContainerType::Container => { /* continue */ },
            _ => return Err(())
        }
        let parent_ix = self.tree.parent_of(node_ix)
            .expect("Active ix had no parent");
        match self.tree[parent_ix] {
            Container::Container { layout, .. } => {
                match (layout, direction) {
                    (Layout::Horizontal, Direction::Left) |
                    (Layout::Horizontal, Direction::Right) |
                    (Layout::Vertical, Direction::Up) |
                    (Layout::Vertical, Direction::Down) => {
                        let siblings = self.tree.children_of(parent_ix);
                        let cur_index = siblings.iter().position(|node| {
                            *node == node_ix
                        }).expect("Could not find self in parent");
                        let maybe_new_index = match direction {
                            Direction::Right | Direction::Down => {
                                cur_index.checked_add(1)
                            }
                            Direction::Left  | Direction::Up => {
                                cur_index.checked_sub(1)
                            }
                        };
                        if maybe_new_index.is_some() &&
                            maybe_new_index.unwrap() < siblings.len() {
                                // There is a sibling to move to.
                                let new_index = maybe_new_index.unwrap();
                                let new_active_ix = siblings[new_index];
                                match self.tree[new_active_ix].get_type() {
                                    ContainerType::Container => {
                                        let path_ix = self.tree.follow_path(new_active_ix);
                                        // If the path wasn't complete, find the first view and focus on that
                                        let node_ix = (self.tree.descendant_of_type(path_ix, ContainerType::View)).unwrap();
                                        let parent_ix = (self.tree.parent_of(node_ix)).unwrap();
                                        match self.tree[node_ix].get_type() {
                                            ContainerType::View | ContainerType::Container => {},
                                            _ => panic!("Following path did not lead to a container or a view!")
                                        }
                                        trace!("Moving to different view {:?} in container {:?}",
                                                self.tree[node_ix], self.tree[parent_ix]);
                                        return Ok(node_ix);
                                    },
                                    ContainerType::View => {
                                        trace!("Moving to other view {:?}", self.tree[new_active_ix]);
                                        return Ok(new_active_ix)
                                    },
                                    _ => unreachable!()
                                };
                            }
                    },
                    _ => { /* We are moving out of siblings, recurse */ }
                }
            }
            Container::Workspace { .. } => {
                return Err(());
            }
            _ => unreachable!()
        }
        let parent_ix = self.tree.parent_of(node_ix)
            .expect("Node had no parent");
        return self.move_focus_recurse(parent_ix, direction);
    }

    /// Updates the current active container to be the next container or view
    /// to focus on after the previous view/container was moved/removed.
    ///
    /// A new view will tried to be set, starting with the children of the
    /// parent node. If a view cannot be found there, it starts climbing the
    /// tree until either a view is found or the workspace is (in which case
    /// it set the active container to the root container of the workspace)
    pub fn focus_on_next_container(&mut self, mut parent_ix: NodeIndex) {
        while self.tree.node_type(parent_ix)
            .expect("Node not part of the tree") != ContainerType::Workspace {
            if let Some(view_ix) = self.tree.descendant_of_type_right(parent_ix,
                                                            ContainerType::View) {
                match self.tree[view_ix]
                                    .get_handle().expect("view had no handle") {
                    Handle::View(view) => view.focus(),
                    _ => panic!("View had an output handle")
                }
                trace!("Active container set to view at {:?}", view_ix);
                let id = self.tree[view_ix].get_id();
                self.set_active_container(id)
                    .expect("Could not set active container");
                return;
            }
            parent_ix = self.tree.ancestor_of_type(parent_ix,
                                                    ContainerType::Container)
                .unwrap_or_else(|| {
                    self.tree.ancestor_of_type(parent_ix, ContainerType::Workspace)
                        .expect("Container was not part of a workspace")
                });
        }
        // If this is reached, parent is workspace
        let container_ix = self.tree.children_of(parent_ix)[0];
        // set the workspace to be active
        match self.tree[parent_ix] {
            Container::Workspace {ref mut focused, .. }=> {
                *focused = true;
            },
            _ => unreachable!()
        }
        let root_c_children = self.tree.children_of(container_ix);
        if root_c_children.len() > 0 {
            let new_active_ix = self.tree.descendant_of_type(root_c_children[0],
                                                                ContainerType::View)
                .unwrap_or(root_c_children[0]);
            let id = self.tree[new_active_ix].get_id();
            self.set_active_container(id)
                .expect("Could not set active container");
            match self.tree[new_active_ix] {
                Container::View { ref handle, .. } => handle.focus(),
                _ => {}
            };
            return;
        }
        trace!("Active container set to container {:?}", container_ix);
        let id = self.tree[container_ix].get_id();
        self.set_active_container(id)
            .expect("Could not set active container");

        // Update focus to new container
        self.get_active_container().map(|con| match *con {
            Container::View { ref handle, .. } => handle.focus(),
            Container::Container { .. } => WlcView::root().focus(),
            _ => panic!("Active container not view or container!")
        });
    }
}
<|endoftext|>


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

//! Complex numbers.

use core::prelude::*;

use core::num::{Zero,One,ToStrRadix};

// FIXME #1284: handle complex NaN & infinity etc. This
// probably doesn't map to C's _Complex correctly.

// FIXME #5734:: Need generic sin/cos for .to/from_polar().
// FIXME #5735: Need generic sqrt to implement .norm().

/// A complex number in Cartesian form.
#[deriving(Eq,Clone)]
pub struct Cmplx<T> {
    /// Real portion of the complex number
    re: T,
    /// Imaginary portion of the complex number
    im: T
}

pub type Complex = Cmplx<float>;
pub type Complex32 = Cmplx<f32>;
pub type Complex64 = Cmplx<f64>;

impl<T: Clone + Num> Cmplx<T> {
    /// Create a new Cmplx
    #[inline]
    pub fn new(re: T, im: T) -> Cmplx<T> {
        Cmplx { re: re, im: im }
    }

    /**
    Returns the square of the norm (since `T` doesn't necessarily
    have a sqrt function), i.e. `re^2 + im^2`.
    */
    #[inline]
    pub fn norm_sqr(&self) -> T {
        self.re * self.re + self.im * self.im
    }

    /// Returns the complex conjugate. i.e. `re - i im`
    #[inline]
    pub fn conj(&self) -> Cmplx<T> {
        Cmplx::new(self.re.clone(), -self.im)
    }

    /// Multiplies `self` by the scalar `t`.
    #[inline]
    pub fn scale(&self, t: T) -> Cmplx<T> {
        Cmplx::new(self.re * t, self.im * t)
    }

    /// Divides `self` by the scalar `t`.
    #[inline]
    pub fn unscale(&self, t: T) -> Cmplx<T> {
        Cmplx::new(self.re / t, self.im / t)
    }

    /// Returns `1/self`
    #[inline]
    pub fn inv(&self) -> Cmplx<T> {
        let norm_sqr = self.norm_sqr();
        Cmplx::new(self.re / norm_sqr,
                    -self.im / norm_sqr)
    }
}

#[cfg(not(stage0))] // Fixed by #4228
impl<T: Clone + Algebraic + Num> Cmplx<T> {
    /// Calculate |self|
    #[inline]
    pub fn norm(&self) -> T {
        self.re.hypot(&self.im)
    }
}

#[cfg(not(stage0))] // Fixed by #4228
impl<T: Clone + Trigonometric + Algebraic + Num> Cmplx<T> {
    /// Calculate the principal Arg of self.
    #[inline]
    pub fn arg(&self) -> T {
        self.im.atan2(&self.re)
    }
    /// Convert to polar form (r, theta), such that `self = r * exp(i
    /// * theta)`
    #[inline]
    pub fn to_polar(&self) -> (T, T) {
        (self.norm(), self.arg())
    }
    /// Convert a polar representation into a complex number.
    #[inline]
    pub fn from_polar(r: &T, theta: &T) -> Cmplx<T> {
        Cmplx::new(r * theta.cos(), r * theta.sin())
    }
}

/* arithmetic */
// (a + i b) + (c + i d) == (a + c) + i (b + d)
impl<T: Clone + Num> Add<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn add(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re + other.re, self.im + other.im)
    }
}
// (a + i b) - (c + i d) == (a - c) + i (b - d)
impl<T: Clone + Num> Sub<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn sub(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re - other.re, self.im - other.im)
    }
}
// (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
impl<T: Clone + Num> Mul<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn mul(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re*other.re - self.im*other.im,
                   self.re*other.im + self.im*other.re)
    }
}

// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
//   == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
impl<T: Clone + Num> Div<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn div(&self, other: &Cmplx<T>) -> Cmplx<T> {
        let norm_sqr = other.norm_sqr();
        Cmplx::new((self.re*other.re + self.im*other.im) / norm_sqr,
                   (self.im*other.re - self.re*other.im) / norm_sqr)
    }
}

impl<T: Clone + Num> Neg<Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn neg(&self) -> Cmplx<T> {
        Cmplx::new(-self.re, -self.im)
    }
}

/* constants */
impl<T: Clone + Num> Zero for Cmplx<T> {
    #[inline]
    fn zero() -> Cmplx<T> {
        Cmplx::new(Zero::zero(), Zero::zero())
    }

    #[inline]
    fn is_zero(&self) -> bool {
        self.re.is_zero() && self.im.is_zero()
    }
}

impl<T: Clone + Num> One for Cmplx<T> {
    #[inline]
    fn one() -> Cmplx<T> {
        Cmplx::new(One::one(), Zero::zero())
    }
}

/* string conversions */
impl<T: ToStr + Num + Ord> ToStr for Cmplx<T> {
    fn to_str(&self) -> ~str {
        if self.im < Zero::zero() {
            fmt!("%s-%si", self.re.to_str(), (-self.im).to_str())
        } else {
            fmt!("%s+%si", self.re.to_str(), self.im.to_str())
        }
    }
}

impl<T: ToStrRadix + Num + Ord> ToStrRadix for Cmplx<T> {
    fn to_str_radix(&self, radix: uint) -> ~str {
        if self.im < Zero::zero() {
            fmt!("%s-%si", self.re.to_str_radix(radix), (-self.im).to_str_radix(radix))
        } else {
            fmt!("%s+%si", self.re.to_str_radix(radix), self.im.to_str_radix(radix))
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use core::num::{Zero,One,Real};

    pub static _0_0i : Complex = Cmplx { re: 0f, im: 0f };
    pub static _1_0i : Complex = Cmplx { re: 1f, im: 0f };
    pub static _1_1i : Complex = Cmplx { re: 1f, im: 1f };
    pub static _0_1i : Complex = Cmplx { re: 0f, im: 1f };
    pub static _neg1_1i : Complex = Cmplx { re: -1f, im: 1f };
    pub static _05_05i : Complex = Cmplx { re: 0.5f, im: 0.5f };
    pub static all_consts : [Complex, .. 5] = [_0_0i, _1_0i, _1_1i, _neg1_1i, _05_05i];

    #[test]
    fn test_consts() {
        // check our constants are what Cmplx::new creates
        fn test(c : Complex, r : float, i: float) {
            assert_eq!(c, Cmplx::new(r,i));
        }
        test(_0_0i, 0f, 0f);
        test(_1_0i, 1f, 0f);
        test(_1_1i, 1f, 1f);
        test(_neg1_1i, -1f, 1f);
        test(_05_05i, 0.5f, 0.5f);

        assert_eq!(_0_0i, Zero::zero());
        assert_eq!(_1_0i, One::one());
    }

    #[test]
    fn test_norm() {
        fn test(c: Complex, ns: float) {
            assert_eq!(c.norm_sqr(), ns);
            assert_eq!(c.norm(), ns.sqrt())
        }
        test(_0_0i, 0f);
        test(_1_0i, 1f);
        test(_1_1i, 2f);
        test(_neg1_1i, 2f);
        test(_05_05i, 0.5f);
    }

    #[test]
    fn test_scale_unscale() {
        assert_eq!(_05_05i.scale(2f), _1_1i);
        assert_eq!(_1_1i.unscale(2f), _05_05i);
        for all_consts.each |&c| {
            assert_eq!(c.scale(2f).unscale(2f), c);
        }
    }

    #[test]
    fn test_conj() {
        for all_consts.each |&c| {
            assert_eq!(c.conj(), Cmplx::new(c.re, -c.im));
            assert_eq!(c.conj().conj(), c);
        }
    }

    #[test]
    fn test_inv() {
        assert_eq!(_1_1i.inv(), _05_05i.conj());
        assert_eq!(_1_0i.inv(), _1_0i.inv());
    }

    #[test]
    #[should_fail]
    #[ignore]
    fn test_inv_zero() {
        // FIXME #5736: should this really fail, or just NaN?
        _0_0i.inv();
    }

    #[test]
    fn test_arg() {
        fn test(c: Complex, arg: float) {
            assert!(c.arg().approx_eq(&arg))
        }
        test(_1_0i, 0f);
        test(_1_1i, 0.25f * Real::pi());
        test(_neg1_1i, 0.75f * Real::pi());
        test(_05_05i, 0.25f * Real::pi());
    }

    #[test]
    fn test_polar_conv() {
        fn test(c: Complex) {
            let (r, theta) = c.to_polar();
            assert!((c - Cmplx::from_polar(&r, &theta)).norm() < 1e-6);
        }
        for all_consts.each |&c| { test(c); }
    }

    mod arith {
        use super::*;
        use core::num::Zero;

        #[test]
        fn test_add() {
            assert_eq!(_05_05i + _05_05i, _1_1i);
            assert_eq!(_0_1i + _1_0i, _1_1i);
            assert_eq!(_1_0i + _neg1_1i, _0_1i);

            for all_consts.each |&c| {
                assert_eq!(_0_0i + c, c);
                assert_eq!(c + _0_0i, c);
            }
        }

        #[test]
        fn test_sub() {
            assert_eq!(_05_05i - _05_05i, _0_0i);
            assert_eq!(_0_1i - _1_0i, _neg1_1i);
            assert_eq!(_0_1i - _neg1_1i, _1_0i);

            for all_consts.each |&c| {
                assert_eq!(c - _0_0i, c);
                assert_eq!(c - c, _0_0i);
            }
        }

        #[test]
        fn test_mul() {
            assert_eq!(_05_05i * _05_05i, _0_1i.unscale(2f));
            assert_eq!(_1_1i * _0_1i, _neg1_1i);

            // i^2 & i^4
            assert_eq!(_0_1i * _0_1i, -_1_0i);
            assert_eq!(_0_1i * _0_1i * _0_1i * _0_1i, _1_0i);

            for all_consts.each |&c| {
                assert_eq!(c * _1_0i, c);
                assert_eq!(_1_0i * c, c);
            }
        }
        #[test]
        fn test_div() {
            assert_eq!(_neg1_1i / _0_1i, _1_1i);
            for all_consts.each |&c| {
                if c != Zero::zero() {
                    assert_eq!(c / c, _1_0i);
                }
            }
        }
        #[test]
        fn test_neg() {
            assert_eq!(-_1_0i + _0_1i, _neg1_1i);
            assert_eq!((-_0_1i) * _0_1i, _1_0i);
            for all_consts.each |&c| {
                assert_eq!(-(-c), c);
            }
        }
    }

    #[test]
    fn test_to_str() {
        fn test(c : Complex, s: ~str) {
            assert_eq!(c.to_str(), s);
        }
        test(_0_0i, ~"0+0i");
        test(_1_0i, ~"1+0i");
        test(_0_1i, ~"0+1i");
        test(_1_1i, ~"1+1i");
        test(_neg1_1i, ~"-1+1i");
        test(-_neg1_1i, ~"1-1i");
        test(_05_05i, ~"0.5+0.5i");
    }
}
<commit_msg>xfail std::num::complex::test_norm on x86, r=burningtree.<commit_after>// Copyright 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.

//! Complex numbers.

use core::prelude::*;

use core::num::{Zero,One,ToStrRadix};

// FIXME #1284: handle complex NaN & infinity etc. This
// probably doesn't map to C's _Complex correctly.

// FIXME #5734:: Need generic sin/cos for .to/from_polar().
// FIXME #5735: Need generic sqrt to implement .norm().

/// A complex number in Cartesian form.
#[deriving(Eq,Clone)]
pub struct Cmplx<T> {
    /// Real portion of the complex number
    re: T,
    /// Imaginary portion of the complex number
    im: T
}

pub type Complex = Cmplx<float>;
pub type Complex32 = Cmplx<f32>;
pub type Complex64 = Cmplx<f64>;

impl<T: Clone + Num> Cmplx<T> {
    /// Create a new Cmplx
    #[inline]
    pub fn new(re: T, im: T) -> Cmplx<T> {
        Cmplx { re: re, im: im }
    }

    /**
    Returns the square of the norm (since `T` doesn't necessarily
    have a sqrt function), i.e. `re^2 + im^2`.
    */
    #[inline]
    pub fn norm_sqr(&self) -> T {
        self.re * self.re + self.im * self.im
    }

    /// Returns the complex conjugate. i.e. `re - i im`
    #[inline]
    pub fn conj(&self) -> Cmplx<T> {
        Cmplx::new(self.re.clone(), -self.im)
    }

    /// Multiplies `self` by the scalar `t`.
    #[inline]
    pub fn scale(&self, t: T) -> Cmplx<T> {
        Cmplx::new(self.re * t, self.im * t)
    }

    /// Divides `self` by the scalar `t`.
    #[inline]
    pub fn unscale(&self, t: T) -> Cmplx<T> {
        Cmplx::new(self.re / t, self.im / t)
    }

    /// Returns `1/self`
    #[inline]
    pub fn inv(&self) -> Cmplx<T> {
        let norm_sqr = self.norm_sqr();
        Cmplx::new(self.re / norm_sqr,
                    -self.im / norm_sqr)
    }
}

#[cfg(not(stage0))] // Fixed by #4228
impl<T: Clone + Algebraic + Num> Cmplx<T> {
    /// Calculate |self|
    #[inline]
    pub fn norm(&self) -> T {
        self.re.hypot(&self.im)
    }
}

#[cfg(not(stage0))] // Fixed by #4228
impl<T: Clone + Trigonometric + Algebraic + Num> Cmplx<T> {
    /// Calculate the principal Arg of self.
    #[inline]
    pub fn arg(&self) -> T {
        self.im.atan2(&self.re)
    }
    /// Convert to polar form (r, theta), such that `self = r * exp(i
    /// * theta)`
    #[inline]
    pub fn to_polar(&self) -> (T, T) {
        (self.norm(), self.arg())
    }
    /// Convert a polar representation into a complex number.
    #[inline]
    pub fn from_polar(r: &T, theta: &T) -> Cmplx<T> {
        Cmplx::new(r * theta.cos(), r * theta.sin())
    }
}

/* arithmetic */
// (a + i b) + (c + i d) == (a + c) + i (b + d)
impl<T: Clone + Num> Add<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn add(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re + other.re, self.im + other.im)
    }
}
// (a + i b) - (c + i d) == (a - c) + i (b - d)
impl<T: Clone + Num> Sub<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn sub(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re - other.re, self.im - other.im)
    }
}
// (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
impl<T: Clone + Num> Mul<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn mul(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re*other.re - self.im*other.im,
                   self.re*other.im + self.im*other.re)
    }
}

// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
//   == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
impl<T: Clone + Num> Div<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn div(&self, other: &Cmplx<T>) -> Cmplx<T> {
        let norm_sqr = other.norm_sqr();
        Cmplx::new((self.re*other.re + self.im*other.im) / norm_sqr,
                   (self.im*other.re - self.re*other.im) / norm_sqr)
    }
}

impl<T: Clone + Num> Neg<Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn neg(&self) -> Cmplx<T> {
        Cmplx::new(-self.re, -self.im)
    }
}

/* constants */
impl<T: Clone + Num> Zero for Cmplx<T> {
    #[inline]
    fn zero() -> Cmplx<T> {
        Cmplx::new(Zero::zero(), Zero::zero())
    }

    #[inline]
    fn is_zero(&self) -> bool {
        self.re.is_zero() && self.im.is_zero()
    }
}

impl<T: Clone + Num> One for Cmplx<T> {
    #[inline]
    fn one() -> Cmplx<T> {
        Cmplx::new(One::one(), Zero::zero())
    }
}

/* string conversions */
impl<T: ToStr + Num + Ord> ToStr for Cmplx<T> {
    fn to_str(&self) -> ~str {
        if self.im < Zero::zero() {
            fmt!("%s-%si", self.re.to_str(), (-self.im).to_str())
        } else {
            fmt!("%s+%si", self.re.to_str(), self.im.to_str())
        }
    }
}

impl<T: ToStrRadix + Num + Ord> ToStrRadix for Cmplx<T> {
    fn to_str_radix(&self, radix: uint) -> ~str {
        if self.im < Zero::zero() {
            fmt!("%s-%si", self.re.to_str_radix(radix), (-self.im).to_str_radix(radix))
        } else {
            fmt!("%s+%si", self.re.to_str_radix(radix), self.im.to_str_radix(radix))
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use core::num::{Zero,One,Real};

    pub static _0_0i : Complex = Cmplx { re: 0f, im: 0f };
    pub static _1_0i : Complex = Cmplx { re: 1f, im: 0f };
    pub static _1_1i : Complex = Cmplx { re: 1f, im: 1f };
    pub static _0_1i : Complex = Cmplx { re: 0f, im: 1f };
    pub static _neg1_1i : Complex = Cmplx { re: -1f, im: 1f };
    pub static _05_05i : Complex = Cmplx { re: 0.5f, im: 0.5f };
    pub static all_consts : [Complex, .. 5] = [_0_0i, _1_0i, _1_1i, _neg1_1i, _05_05i];

    #[test]
    fn test_consts() {
        // check our constants are what Cmplx::new creates
        fn test(c : Complex, r : float, i: float) {
            assert_eq!(c, Cmplx::new(r,i));
        }
        test(_0_0i, 0f, 0f);
        test(_1_0i, 1f, 0f);
        test(_1_1i, 1f, 1f);
        test(_neg1_1i, -1f, 1f);
        test(_05_05i, 0.5f, 0.5f);

        assert_eq!(_0_0i, Zero::zero());
        assert_eq!(_1_0i, One::one());
    }

    #[test]
    #[ignore(cfg(target_arch = "x86"))]
    // FIXME #7158: (maybe?) currently failing on x86.
    fn test_norm() {
        fn test(c: Complex, ns: float) {
            assert_eq!(c.norm_sqr(), ns);
            assert_eq!(c.norm(), ns.sqrt())
        }
        test(_0_0i, 0f);
        test(_1_0i, 1f);
        test(_1_1i, 2f);
        test(_neg1_1i, 2f);
        test(_05_05i, 0.5f);
    }

    #[test]
    fn test_scale_unscale() {
        assert_eq!(_05_05i.scale(2f), _1_1i);
        assert_eq!(_1_1i.unscale(2f), _05_05i);
        for all_consts.each |&c| {
            assert_eq!(c.scale(2f).unscale(2f), c);
        }
    }

    #[test]
    fn test_conj() {
        for all_consts.each |&c| {
            assert_eq!(c.conj(), Cmplx::new(c.re, -c.im));
            assert_eq!(c.conj().conj(), c);
        }
    }

    #[test]
    fn test_inv() {
        assert_eq!(_1_1i.inv(), _05_05i.conj());
        assert_eq!(_1_0i.inv(), _1_0i.inv());
    }

    #[test]
    #[should_fail]
    #[ignore]
    fn test_inv_zero() {
        // FIXME #5736: should this really fail, or just NaN?
        _0_0i.inv();
    }

    #[test]
    fn test_arg() {
        fn test(c: Complex, arg: float) {
            assert!(c.arg().approx_eq(&arg))
        }
        test(_1_0i, 0f);
        test(_1_1i, 0.25f * Real::pi());
        test(_neg1_1i, 0.75f * Real::pi());
        test(_05_05i, 0.25f * Real::pi());
    }

    #[test]
    fn test_polar_conv() {
        fn test(c: Complex) {
            let (r, theta) = c.to_polar();
            assert!((c - Cmplx::from_polar(&r, &theta)).norm() < 1e-6);
        }
        for all_consts.each |&c| { test(c); }
    }

    mod arith {
        use super::*;
        use core::num::Zero;

        #[test]
        fn test_add() {
            assert_eq!(_05_05i + _05_05i, _1_1i);
            assert_eq!(_0_1i + _1_0i, _1_1i);
            assert_eq!(_1_0i + _neg1_1i, _0_1i);

            for all_consts.each |&c| {
                assert_eq!(_0_0i + c, c);
                assert_eq!(c + _0_0i, c);
            }
        }

        #[test]
        fn test_sub() {
            assert_eq!(_05_05i - _05_05i, _0_0i);
            assert_eq!(_0_1i - _1_0i, _neg1_1i);
            assert_eq!(_0_1i - _neg1_1i, _1_0i);

            for all_consts.each |&c| {
                assert_eq!(c - _0_0i, c);
                assert_eq!(c - c, _0_0i);
            }
        }

        #[test]
        fn test_mul() {
            assert_eq!(_05_05i * _05_05i, _0_1i.unscale(2f));
            assert_eq!(_1_1i * _0_1i, _neg1_1i);

            // i^2 & i^4
            assert_eq!(_0_1i * _0_1i, -_1_0i);
            assert_eq!(_0_1i * _0_1i * _0_1i * _0_1i, _1_0i);

            for all_consts.each |&c| {
                assert_eq!(c * _1_0i, c);
                assert_eq!(_1_0i * c, c);
            }
        }
        #[test]
        fn test_div() {
            assert_eq!(_neg1_1i / _0_1i, _1_1i);
            for all_consts.each |&c| {
                if c != Zero::zero() {
                    assert_eq!(c / c, _1_0i);
                }
            }
        }
        #[test]
        fn test_neg() {
            assert_eq!(-_1_0i + _0_1i, _neg1_1i);
            assert_eq!((-_0_1i) * _0_1i, _1_0i);
            for all_consts.each |&c| {
                assert_eq!(-(-c), c);
            }
        }
    }

    #[test]
    fn test_to_str() {
        fn test(c : Complex, s: ~str) {
            assert_eq!(c.to_str(), s);
        }
        test(_0_0i, ~"0+0i");
        test(_1_0i, ~"1+0i");
        test(_0_1i, ~"0+1i");
        test(_1_1i, ~"1+1i");
        test(_neg1_1i, ~"-1+1i");
        test(-_neg1_1i, ~"1-1i");
        test(_05_05i, ~"0.5+0.5i");
    }
}
<|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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being
matched, one of the preceding patterns will match.

This means that perhaps some of the preceding patterns are too general, this one
is too specific or the ordering is incorrect.
"##,

E0002: r##"
This error indicates that an empty match expression is illegal because the type
it is matching on is non-empty (there exist values of this type). In safe code
it is impossible to create an instance of an empty type, so empty match
expressions are almost never desired.  This error is typically fixed by adding
one or more cases to the match expression.

An example of an empty type is `enum Empty { }`.
"##,

E0003: r##"
Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. To match against NaN values, you should
instead use the `is_nan` method in a guard, as in: x if x.is_nan() => ...
"##,

E0004: r##"
This error indicates that the compiler cannot guarantee a matching pattern for
one or more possible inputs to a match expression. Guaranteed matches are
required in order to assign values to match expressions, or alternatively,
determine the flow of execution.

If you encounter this error you must alter your patterns so that every possible
value of the input type is matched. For types with a small number of variants
(like enums) you should probably cover all cases explicitly. Alternatively, the
underscore `_` wildcard pattern can be added after all other patterns to match
"anything else".
"##,

// FIXME: Remove duplication here?
E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0006: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0007: r##"
This error indicates that the bindings in a match arm would require a value to
be moved into more than one location, thus violating unique ownership. Code like
the following is invalid as it requires the entire Option<String> to be moved
into a variable called `op_string` while simultaneously requiring the inner
String to be moved into a variable called `s`.

let x = Some("s".to_string());
match x {
    op_string @ Some(s) => ...
    None => ...
}

See also Error 303.
"##,

E0008: r##"
Names bound in match arms retain their type in pattern guards. As such, if a
name is bound by move in a pattern, it should also be moved to wherever it is
referenced in the pattern guard code. Doing so however would prevent the name
from being available in the body of the match arm. Consider the following:

match Some("hi".to_string()) {
    Some(s) if s.len() == 0 => // use s.
    ...
}

The variable `s` has type String, and its use in the guard is as a variable of
type String. The guard code effectively executes in a separate scope to the body
of the arm, so the value would be moved into this anonymous scope and therefore
become unavailable in the body of the arm. Although this example seems
innocuous, the problem is most clear when considering functions that take their
argument by value.

match Some("hi".to_string()) {
    Some(s) if { drop(s); false } => (),
    Some(s) => // use s.
    ...
}

The value would be dropped in the guard then become unavailable not only in the
body of that arm but also in all subsequent arms! The solution is to bind by
reference when using guards or refactor the entire expression, perhaps by
putting the condition inside the body of the arm.
"##,

E0152: r##"
Lang items are already implemented in the standard library. Unless you are
writing a free-standing application (e.g. a kernel), you do not need to provide
them yourself.

You can build a free-standing crate by adding `#![no_std]` to the crate
attributes:

#![feature(no_std)]
#![no_std]

See also https://doc.rust-lang.org/book/no-stdlib.html
"##,

E0158: r##"
`const` and `static` mean different things. A `const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.

The `static` keyword, on the other hand, guarantees a fixed location in memory.
This does not always mean that the value is constant. For example, a global
mutex can be declared `static` as well.

If you want to match against a `static`, consider using a guard instead:

static FORTY_TWO: i32 = 42;
match Some(42) {
    Some(x) if x == FORTY_TWO => ...
    ...
}
"##,

E0161: r##"
In Rust, you can only move a value when its size is known at compile time.

To work around this restriction, consider "hiding" the value behind a reference:
either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
it around as usual.
"##,

E0162: r##"
An if-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
if let Irrefutable(x) = irr {
    // This body will always be executed.
    foo(x);
}

// Try this instead:
let Irrefutable(x) = irr;
foo(x);
"##,

E0165: r##"
A while-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding inside a `loop` instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
while let Irrefutable(x) = irr {
    ...
}

// Try this instead:
loop {
    let Irrefutable(x) = irr;
    ...
}
"##,

E0170: r##"
Enum variants are qualified by default. For example, given this type:

enum Method {
    GET,
    POST
}

you would match it using:

match m {
    Method::GET => ...
    Method::POST => ...
}

If you don't qualify the names, the code will bind new variables named "GET" and
"POST" instead. This behavior is likely not what you want, so rustc warns when
that happens.

Qualified names are good practice, and most code works well with them. But if
you prefer them unqualified, you can import the variants into scope:

use Method::*;
enum Method { GET, POST }
"##,

E0297: r##"
Patterns used to bind names must be irrefutable. That is, they must guarantee
that a name will be extracted in all cases. Instead of pattern matching the
loop variable, consider using a `match` or `if let` inside the loop body. For
instance:

// This fails because `None` is not covered.
for Some(x) in xs {
    ...
}

// Match inside the loop instead:
for item in xs {
    match item {
        Some(x) => ...
        None => ...
    }
}

// Or use `if let`:
for item in xs {
    if let Some(x) = item {
        ...
    }
}
"##,

E0301: r##"
Mutable borrows are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if mutable
borrows were allowed:

match Some(()) {
    None => { },
    option if option.take().is_none() => { /* impossible, option is `Some` */ },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0302: r##"
Assignments are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if assignments
were allowed:

match Some(()) {
    None => { },
    option if { option = None; false } { },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0303: r##"
In certain cases it is possible for sub-bindings to violate memory safety.
Updates to the borrow checker in a future version of Rust may remove this
restriction, but for now patterns must be rewritten without sub-bindings.

// Code like this...
match Some(5) {
    ref op_num @ Some(num) => ...
    None => ...
}

// ... should be updated to code like this.
match Some(5) {
    Some(num) => {
        let op_num = &Some(num);
        ...
    }
    None => ...
}

See also https://github.com/rust-lang/rust/issues/14587
"##,

E0306: r##"
In an array literal `[x; N]`, `N` is the number of elements in the array. This
number cannot be negative.
"##,

E0307: r##"
The length of an array is part of its type. For this reason, this length must be
a compile-time constant.
"##,

E0308: r##"
This error occurs when the compiler was unable to infer the concrete type of a
variable. This error can occur for several cases, the most common of which is
that there is a mismatch in the expected type that the compiler inferred, and
the actual type that the user defined a variable as.

let a: char = 7;    // An integral type can't be contained in a character, so
                    // there is a mismatch.

let b: u32 = 7;     // Either use the right type...
let c = 7;          // ...or let the compiler infer it.

let d: char = c;    // This also causes a mismatch because c is some sort
                    // of number whereas d is definitely a character.
"##,

E0309: r##"
Types in type definitions have lifetimes associated with them that represent
how long the data stored within them is guaranteed to be live. This lifetime
must be as long as the data needs to be alive, and missing the constraint that
denotes this will cause this error.

// This won't compile because T is not constrained, meaning the data
// stored in it is not guaranteed to last as long as the reference
struct Foo<'a, T> {
    foo: &'a T
}

// This will compile, because it has the constraint on the type parameter
struct Foo<'a, T: 'a> {
    foo: &'a T
}
"##,

E0310: r##"
Types in type definitions have lifetimes associated with them that represent
how long the data stored within them is guaranteed to be live. This lifetime
must be as long as the data needs to be alive, and missing the constraint that
denotes this will cause this error.

// This won't compile because T is not constrained to the static lifetime
// the reference needs
struct Foo<T> {
    foo: &'static T
}

// This will compile, because it has the constraint on the type parameter
struct Foo<T: 'static> {
    foo: &'static T
}
"##

}

register_diagnostics! {
    E0009,
    E0010,
    E0011,
    E0012,
    E0013,
    E0014,
    E0015,
    E0016,
    E0017,
    E0018,
    E0019,
    E0020,
    E0022,
    E0079, // enum variant: expected signed integer constant
    E0080, // enum variant: constant evaluation error
    E0109,
    E0110,
    E0133,
    E0134,
    E0135,
    E0136,
    E0137,
    E0138,
    E0139,
    E0261, // use of undeclared lifetime name
    E0262, // illegal lifetime parameter name
    E0263, // lifetime name declared twice in same scope
    E0264, // unknown external lang item
    E0265, // recursive constant
    E0266, // expected item
    E0267, // thing inside of a closure
    E0268, // thing outside of a loop
    E0269, // not all control paths return a value
    E0270, // computation may converge in a function marked as diverging
    E0271, // type mismatch resolving
    E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
    E0273, // rustc_on_unimplemented must have named format arguments
    E0274, // rustc_on_unimplemented must have a value
    E0275, // overflow evaluating requirement
    E0276, // requirement appears on impl method but not on corresponding trait method
    E0277, // trait is not implemented for type
    E0278, // requirement is not satisfied
    E0279, // requirement is not satisfied
    E0280, // requirement is not satisfied
    E0281, // type implements trait but other trait is required
    E0282, // unable to infer enough type information about
    E0283, // cannot resolve type
    E0284, // cannot resolve type
    E0285, // overflow evaluation builtin bounds
    E0296, // malformed recursion limit attribute
    E0298, // mismatched types between arms
    E0299, // mismatched types between arms
    E0300, // unexpanded macro
    E0304, // expected signed integer constant
    E0305, // expected constant
    E0311, // thing may not live long enough
    E0312, // lifetime of reference outlives lifetime of borrowed content
    E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
    E0314, // closure outlives stack frame
    E0315, // cannot invoke closure outside of its lifetime
    E0316, // nested quantification of lifetimes
    E0370  // discriminant overflow
}

__build_diagnostic_array! { DIAGNOSTICS }
<commit_msg>Reword with pnkfelix's suggestion<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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being
matched, one of the preceding patterns will match.

This means that perhaps some of the preceding patterns are too general, this one
is too specific or the ordering is incorrect.
"##,

E0002: r##"
This error indicates that an empty match expression is illegal because the type
it is matching on is non-empty (there exist values of this type). In safe code
it is impossible to create an instance of an empty type, so empty match
expressions are almost never desired.  This error is typically fixed by adding
one or more cases to the match expression.

An example of an empty type is `enum Empty { }`.
"##,

E0003: r##"
Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. To match against NaN values, you should
instead use the `is_nan` method in a guard, as in: x if x.is_nan() => ...
"##,

E0004: r##"
This error indicates that the compiler cannot guarantee a matching pattern for
one or more possible inputs to a match expression. Guaranteed matches are
required in order to assign values to match expressions, or alternatively,
determine the flow of execution.

If you encounter this error you must alter your patterns so that every possible
value of the input type is matched. For types with a small number of variants
(like enums) you should probably cover all cases explicitly. Alternatively, the
underscore `_` wildcard pattern can be added after all other patterns to match
"anything else".
"##,

// FIXME: Remove duplication here?
E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0006: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0007: r##"
This error indicates that the bindings in a match arm would require a value to
be moved into more than one location, thus violating unique ownership. Code like
the following is invalid as it requires the entire Option<String> to be moved
into a variable called `op_string` while simultaneously requiring the inner
String to be moved into a variable called `s`.

let x = Some("s".to_string());
match x {
    op_string @ Some(s) => ...
    None => ...
}

See also Error 303.
"##,

E0008: r##"
Names bound in match arms retain their type in pattern guards. As such, if a
name is bound by move in a pattern, it should also be moved to wherever it is
referenced in the pattern guard code. Doing so however would prevent the name
from being available in the body of the match arm. Consider the following:

match Some("hi".to_string()) {
    Some(s) if s.len() == 0 => // use s.
    ...
}

The variable `s` has type String, and its use in the guard is as a variable of
type String. The guard code effectively executes in a separate scope to the body
of the arm, so the value would be moved into this anonymous scope and therefore
become unavailable in the body of the arm. Although this example seems
innocuous, the problem is most clear when considering functions that take their
argument by value.

match Some("hi".to_string()) {
    Some(s) if { drop(s); false } => (),
    Some(s) => // use s.
    ...
}

The value would be dropped in the guard then become unavailable not only in the
body of that arm but also in all subsequent arms! The solution is to bind by
reference when using guards or refactor the entire expression, perhaps by
putting the condition inside the body of the arm.
"##,

E0152: r##"
Lang items are already implemented in the standard library. Unless you are
writing a free-standing application (e.g. a kernel), you do not need to provide
them yourself.

You can build a free-standing crate by adding `#![no_std]` to the crate
attributes:

#![feature(no_std)]
#![no_std]

See also https://doc.rust-lang.org/book/no-stdlib.html
"##,

E0158: r##"
`const` and `static` mean different things. A `const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.

The `static` keyword, on the other hand, guarantees a fixed location in memory.
This does not always mean that the value is constant. For example, a global
mutex can be declared `static` as well.

If you want to match against a `static`, consider using a guard instead:

static FORTY_TWO: i32 = 42;
match Some(42) {
    Some(x) if x == FORTY_TWO => ...
    ...
}
"##,

E0161: r##"
In Rust, you can only move a value when its size is known at compile time.

To work around this restriction, consider "hiding" the value behind a reference:
either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
it around as usual.
"##,

E0162: r##"
An if-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
if let Irrefutable(x) = irr {
    // This body will always be executed.
    foo(x);
}

// Try this instead:
let Irrefutable(x) = irr;
foo(x);
"##,

E0165: r##"
A while-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding inside a `loop` instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
while let Irrefutable(x) = irr {
    ...
}

// Try this instead:
loop {
    let Irrefutable(x) = irr;
    ...
}
"##,

E0170: r##"
Enum variants are qualified by default. For example, given this type:

enum Method {
    GET,
    POST
}

you would match it using:

match m {
    Method::GET => ...
    Method::POST => ...
}

If you don't qualify the names, the code will bind new variables named "GET" and
"POST" instead. This behavior is likely not what you want, so rustc warns when
that happens.

Qualified names are good practice, and most code works well with them. But if
you prefer them unqualified, you can import the variants into scope:

use Method::*;
enum Method { GET, POST }
"##,

E0297: r##"
Patterns used to bind names must be irrefutable. That is, they must guarantee
that a name will be extracted in all cases. Instead of pattern matching the
loop variable, consider using a `match` or `if let` inside the loop body. For
instance:

// This fails because `None` is not covered.
for Some(x) in xs {
    ...
}

// Match inside the loop instead:
for item in xs {
    match item {
        Some(x) => ...
        None => ...
    }
}

// Or use `if let`:
for item in xs {
    if let Some(x) = item {
        ...
    }
}
"##,

E0301: r##"
Mutable borrows are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if mutable
borrows were allowed:

match Some(()) {
    None => { },
    option if option.take().is_none() => { /* impossible, option is `Some` */ },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0302: r##"
Assignments are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if assignments
were allowed:

match Some(()) {
    None => { },
    option if { option = None; false } { },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0303: r##"
In certain cases it is possible for sub-bindings to violate memory safety.
Updates to the borrow checker in a future version of Rust may remove this
restriction, but for now patterns must be rewritten without sub-bindings.

// Code like this...
match Some(5) {
    ref op_num @ Some(num) => ...
    None => ...
}

// ... should be updated to code like this.
match Some(5) {
    Some(num) => {
        let op_num = &Some(num);
        ...
    }
    None => ...
}

See also https://github.com/rust-lang/rust/issues/14587
"##,

E0306: r##"
In an array literal `[x; N]`, `N` is the number of elements in the array. This
number cannot be negative.
"##,

E0307: r##"
The length of an array is part of its type. For this reason, this length must be
a compile-time constant.
"##,

E0308: r##"
This error occurs when the compiler was unable to infer the concrete type of a
variable. This error can occur for several cases, the most common of which is a
mismatch in the expected type that the compiler inferred for a variable's
initializing expression, and the actual type explicitly assigned to the
variable.

For example:

let x: i32 = "I am not a number!";
//     ~~~   ~~~~~~~~~~~~~~~~~~~~
//      |             |
//      |    initializing expression;
//      |    compiler infers type `&str`
//      |
//    type `i32` assigned to variable `x`
"##,

E0309: r##"
Types in type definitions have lifetimes associated with them that represent
how long the data stored within them is guaranteed to be live. This lifetime
must be as long as the data needs to be alive, and missing the constraint that
denotes this will cause this error.

// This won't compile because T is not constrained, meaning the data
// stored in it is not guaranteed to last as long as the reference
struct Foo<'a, T> {
    foo: &'a T
}

// This will compile, because it has the constraint on the type parameter
struct Foo<'a, T: 'a> {
    foo: &'a T
}
"##,

E0310: r##"
Types in type definitions have lifetimes associated with them that represent
how long the data stored within them is guaranteed to be live. This lifetime
must be as long as the data needs to be alive, and missing the constraint that
denotes this will cause this error.

// This won't compile because T is not constrained to the static lifetime
// the reference needs
struct Foo<T> {
    foo: &'static T
}

// This will compile, because it has the constraint on the type parameter
struct Foo<T: 'static> {
    foo: &'static T
}
"##

}

register_diagnostics! {
    E0009,
    E0010,
    E0011,
    E0012,
    E0013,
    E0014,
    E0015,
    E0016,
    E0017,
    E0018,
    E0019,
    E0020,
    E0022,
    E0079, // enum variant: expected signed integer constant
    E0080, // enum variant: constant evaluation error
    E0109,
    E0110,
    E0133,
    E0134,
    E0135,
    E0136,
    E0137,
    E0138,
    E0139,
    E0261, // use of undeclared lifetime name
    E0262, // illegal lifetime parameter name
    E0263, // lifetime name declared twice in same scope
    E0264, // unknown external lang item
    E0265, // recursive constant
    E0266, // expected item
    E0267, // thing inside of a closure
    E0268, // thing outside of a loop
    E0269, // not all control paths return a value
    E0270, // computation may converge in a function marked as diverging
    E0271, // type mismatch resolving
    E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
    E0273, // rustc_on_unimplemented must have named format arguments
    E0274, // rustc_on_unimplemented must have a value
    E0275, // overflow evaluating requirement
    E0276, // requirement appears on impl method but not on corresponding trait method
    E0277, // trait is not implemented for type
    E0278, // requirement is not satisfied
    E0279, // requirement is not satisfied
    E0280, // requirement is not satisfied
    E0281, // type implements trait but other trait is required
    E0282, // unable to infer enough type information about
    E0283, // cannot resolve type
    E0284, // cannot resolve type
    E0285, // overflow evaluation builtin bounds
    E0296, // malformed recursion limit attribute
    E0298, // mismatched types between arms
    E0299, // mismatched types between arms
    E0300, // unexpanded macro
    E0304, // expected signed integer constant
    E0305, // expected constant
    E0311, // thing may not live long enough
    E0312, // lifetime of reference outlives lifetime of borrowed content
    E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
    E0314, // closure outlives stack frame
    E0315, // cannot invoke closure outside of its lifetime
    E0316, // nested quantification of lifetimes
    E0370  // discriminant overflow
}

__build_diagnostic_array! { DIAGNOSTICS }
<|endoftext|>


<commit_before>//! Manager for wl_shell clients.

use libc;
use wayland_sys::server::signal::wl_signal_add;
use wlroots_sys::wlr_wl_shell_surface;

use super::wl_shell_handler::WlShell;
use {Surface, WlShellHandler, WlShellSurface};
use compositor::{Compositor, COMPOSITOR_PTR};

/// Handles making new Wayland shells as reported by clients.
pub trait WlShellManagerHandler {
    fn new_surface(&mut self, &mut Compositor, &mut WlShellSurface) -> Option<Box<WlShellHandler>>;
}

wayland_listener!(WlShellManager, Box<WlShellManagerHandler>, [
    add_listener => add_notify: |this: &mut WlShellManager, data: *mut libc::c_void,| unsafe {
        let manager = &mut this.data;
        let data = data as *mut wlr_wl_shell_surface;
        wlr_log!(L_DEBUG, "New wl_shell_surface request {:p}", data);
        let compositor = &mut *COMPOSITOR_PTR;
        let mut shell_surface = WlShellSurface::new(data);
        let new_surface_res = manager.new_surface(compositor, &mut shell_surface);
        if let Some(shell_surface_handler) = new_surface_res {
            let surface = Surface::from_ptr((*data).surface);
            let mut shell_surface = WlShell::new((shell_surface, surface, shell_surface_handler));
            // Add the destroy event to this handler.
            wl_signal_add(&mut (*data).events.destroy as *mut _ as _,
                          shell_surface.destroy_listener() as _);

            // Add the ping timeout event to this handler.
            wl_signal_add(&mut (*data).events.ping_timeout as *mut _ as _,
                          shell_surface.ping_timeout_listener() as _);

            // Add the move request event to this handler.
            wl_signal_add(&mut (*data).events.request_move as *mut _ as _,
                          shell_surface.request_move_listener() as _);

            // Add the resize request event to this handler.
            wl_signal_add(&mut (*data).events.request_resize as *mut _ as _,
                          shell_surface.request_resize_listener() as _);

            // Add the fullscreen request event to this handler.
            wl_signal_add(&mut (*data).events.request_fullscreen as *mut _ as _,
                          shell_surface.request_fullscreen_listener() as _);

            // Add the maximize request event to this handler.
            wl_signal_add(&mut (*data).events.request_maximize as *mut _ as _,
                          shell_surface.request_maximize_listener() as _);

            // Add the set state request event to this handler.
            wl_signal_add(&mut (*data).events.set_state as *mut _ as _,
                          shell_surface.set_state_listener() as _);

            // Add the set title request event to this handler.
            wl_signal_add(&mut (*data).events.set_title as *mut _ as _,
                          shell_surface.set_title_listener() as _);

            // Add the set class request event to this handler.
            wl_signal_add(&mut (*data).events.set_class as *mut _ as _,
                          shell_surface.set_class_listener() as _);

            // NOTE This is cleaned up in the wl_shell_handler::destroy signal.
            ::std::mem::forget(shell_surface);
        }
    };
]);
<commit_msg>Init surface _before_ we do the wlshell create cb<commit_after>//! Manager for wl_shell clients.

use libc;
use wayland_sys::server::signal::wl_signal_add;
use wlroots_sys::wlr_wl_shell_surface;

use super::wl_shell_handler::WlShell;
use {Surface, WlShellHandler, WlShellSurface};
use compositor::{Compositor, COMPOSITOR_PTR};

/// Handles making new Wayland shells as reported by clients.
pub trait WlShellManagerHandler {
    fn new_surface(&mut self, &mut Compositor, &mut WlShellSurface) -> Option<Box<WlShellHandler>>;
}

wayland_listener!(WlShellManager, Box<WlShellManagerHandler>, [
    add_listener => add_notify: |this: &mut WlShellManager, data: *mut libc::c_void,| unsafe {
        let manager = &mut this.data;
        let data = data as *mut wlr_wl_shell_surface;
        wlr_log!(L_DEBUG, "New wl_shell_surface request {:p}", data);
        let compositor = &mut *COMPOSITOR_PTR;
        let surface = Surface::from_ptr((*data).surface);
        let mut shell_surface = WlShellSurface::new(data);
        let new_surface_res = manager.new_surface(compositor, &mut shell_surface);
        if let Some(shell_surface_handler) = new_surface_res {
            let mut shell_surface = WlShell::new((shell_surface, surface, shell_surface_handler));
            // Add the destroy event to this handler.
            wl_signal_add(&mut (*data).events.destroy as *mut _ as _,
                          shell_surface.destroy_listener() as _);

            // Add the ping timeout event to this handler.
            wl_signal_add(&mut (*data).events.ping_timeout as *mut _ as _,
                          shell_surface.ping_timeout_listener() as _);

            // Add the move request event to this handler.
            wl_signal_add(&mut (*data).events.request_move as *mut _ as _,
                          shell_surface.request_move_listener() as _);

            // Add the resize request event to this handler.
            wl_signal_add(&mut (*data).events.request_resize as *mut _ as _,
                          shell_surface.request_resize_listener() as _);

            // Add the fullscreen request event to this handler.
            wl_signal_add(&mut (*data).events.request_fullscreen as *mut _ as _,
                          shell_surface.request_fullscreen_listener() as _);

            // Add the maximize request event to this handler.
            wl_signal_add(&mut (*data).events.request_maximize as *mut _ as _,
                          shell_surface.request_maximize_listener() as _);

            // Add the set state request event to this handler.
            wl_signal_add(&mut (*data).events.set_state as *mut _ as _,
                          shell_surface.set_state_listener() as _);

            // Add the set title request event to this handler.
            wl_signal_add(&mut (*data).events.set_title as *mut _ as _,
                          shell_surface.set_title_listener() as _);

            // Add the set class request event to this handler.
            wl_signal_add(&mut (*data).events.set_class as *mut _ as _,
                          shell_surface.set_class_listener() as _);

            // NOTE This is cleaned up in the wl_shell_handler::destroy signal.
            ::std::mem::forget(shell_surface);
        }
    };
]);
<|endoftext|>


<commit_before>// Copyright (c) 2017-2018 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// gpio_status.rs
//
// Retrieves the mode and logic level for each of the pins on the standard
// 40-pin GPIO header, and displays the results in an ASCII table.

use std::fmt;
use std::process::exit;

use rppal::gpio::Gpio;
use rppal::system::{DeviceInfo, Model};

enum PinType {
    Gpio(u8),
    Ground,
    Power3v3,
    Power5v,
}

impl fmt::Display for PinType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            PinType::Gpio(pin) => write!(f, "GPIO{}", pin),
            PinType::Ground => write!(f, "{:<5}", "GND"),
            PinType::Power3v3 => write!(f, "{:<5}", "3.3 V"),
            PinType::Power5v => write!(f, "{:<5}", "5 V"),
        }
    }
}

const HEADER_40: [PinType; 40] = [
    PinType::Power3v3, // Physical pin 1
    PinType::Power5v,  // Physical pin 2
    PinType::Gpio(2),  // Physical pin 3
    PinType::Power5v,  // Physical pin 4
    PinType::Gpio(3),  // Physical pin 5
    PinType::Ground,   // Physical pin 6
    PinType::Gpio(4),  // Physical pin 7
    PinType::Gpio(14), // Physical pin 8
    PinType::Ground,   // Physical pin 9
    PinType::Gpio(15), // Physical pin 10
    PinType::Gpio(17), // Physical pin 11
    PinType::Gpio(18), // Physical pin 12
    PinType::Gpio(27), // Physical pin 13
    PinType::Ground,   // Physical pin 14
    PinType::Gpio(22), // Physical pin 15
    PinType::Gpio(23), // Physical pin 16
    PinType::Power3v3, // Physical pin 17
    PinType::Gpio(24), // Physical pin 18
    PinType::Gpio(10), // Physical pin 19
    PinType::Ground,   // Physical pin 20
    PinType::Gpio(9),  // Physical pin 21
    PinType::Gpio(25), // Physical pin 22
    PinType::Gpio(11), // Physical pin 23
    PinType::Gpio(8),  // Physical pin 24
    PinType::Ground,   // Physical pin 25
    PinType::Gpio(7),  // Physical pin 26
    PinType::Gpio(0),  // Physical pin 27
    PinType::Gpio(1),  // Physical pin 28
    PinType::Gpio(5),  // Physical pin 29
    PinType::Ground,   // Physical pin 30
    PinType::Gpio(6),  // Physical pin 31
    PinType::Gpio(12), // Physical pin 32
    PinType::Gpio(13), // Physical pin 33
    PinType::Ground,   // Physical pin 34
    PinType::Gpio(19), // Physical pin 35
    PinType::Gpio(16), // Physical pin 36
    PinType::Gpio(26), // Physical pin 37
    PinType::Gpio(20), // Physical pin 38
    PinType::Ground,   // Physical pin 39
    PinType::Gpio(21), // Physical pin 40
];

fn print_gpio_status() {
    let gpio = Gpio::new().unwrap_or_else(|e| {
        println!("Error: Can't access GPIO peripheral ({})", e);
        exit(1);
    });

    println!("+------+-------+-------+-----------+-------+-------+------+");
    println!("| GPIO | Mode  | Level |    Pin    | Level | Mode  | GPIO |");
    println!("+------+-------+-------+-----+-----+-------+-------+------+");

    for (idx, pin_type) in HEADER_40.iter().enumerate() {
        match pin_type {
            PinType::Gpio(bcm) => {
                let pin = gpio.get(*bcm).unwrap_or_else(|| {
                    println!("\nError: Can't access GPIO pin {}", *bcm);;
                    exit(1);
                });

                if idx % 2 == 0 {
                    print!(
                        "| {:>4} | {:<5} | {:<5} | {:>3} |",
                        bcm,
                        format!("{}", pin.mode()).to_uppercase(),
                        format!("{}", pin.read()),
                        idx + 1
                    );
                } else {
                    println!(
                        " {:>3} | {:<5} | {:<5} | {:>4} |",
                        idx + 1,
                        format!("{:?}", pin.read()),
                        format!("{}", pin.mode()).to_uppercase(),
                        bcm,
                    );
                }
            }
            _ => {
                if idx % 2 == 0 {
                    print!("|      | {} |       | {:>3} |", pin_type, idx + 1);
                } else {
                    println!(" {:>3} |       | {} |      |", idx + 1, pin_type);
                }
            }
        };
    }

    println!("+------+-------+-------+-----+-----+-------+-------+------+");
}

fn main() {
    match DeviceInfo::new()
        .unwrap_or_else(|e| {
            println!("Error: Can't identify Raspberry Pi model ({})", e);
            exit(1);
        })
        .model()
    {
        Model::RaspberryPiAPlus
        | Model::RaspberryPiBPlus
        | Model::RaspberryPi2B
        | Model::RaspberryPi3APlus
        | Model::RaspberryPi3B
        | Model::RaspberryPi3BPlus
        | Model::RaspberryPiZero
        | Model::RaspberryPiZeroW => print_gpio_status(),
        model => {
            println!("No GPIO header information available for the {}.", model);
        }
    }
}
<commit_msg>Remove debug formatting<commit_after>// Copyright (c) 2017-2018 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// gpio_status.rs
//
// Retrieves the mode and logic level for each of the pins on the standard
// 40-pin GPIO header, and displays the results in an ASCII table.

use std::fmt;
use std::process::exit;

use rppal::gpio::Gpio;
use rppal::system::{DeviceInfo, Model};

enum PinType {
    Gpio(u8),
    Ground,
    Power3v3,
    Power5v,
}

impl fmt::Display for PinType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            PinType::Gpio(pin) => write!(f, "GPIO{}", pin),
            PinType::Ground => write!(f, "{:<5}", "GND"),
            PinType::Power3v3 => write!(f, "{:<5}", "3.3 V"),
            PinType::Power5v => write!(f, "{:<5}", "5 V"),
        }
    }
}

const HEADER_40: [PinType; 40] = [
    PinType::Power3v3, // Physical pin 1
    PinType::Power5v,  // Physical pin 2
    PinType::Gpio(2),  // Physical pin 3
    PinType::Power5v,  // Physical pin 4
    PinType::Gpio(3),  // Physical pin 5
    PinType::Ground,   // Physical pin 6
    PinType::Gpio(4),  // Physical pin 7
    PinType::Gpio(14), // Physical pin 8
    PinType::Ground,   // Physical pin 9
    PinType::Gpio(15), // Physical pin 10
    PinType::Gpio(17), // Physical pin 11
    PinType::Gpio(18), // Physical pin 12
    PinType::Gpio(27), // Physical pin 13
    PinType::Ground,   // Physical pin 14
    PinType::Gpio(22), // Physical pin 15
    PinType::Gpio(23), // Physical pin 16
    PinType::Power3v3, // Physical pin 17
    PinType::Gpio(24), // Physical pin 18
    PinType::Gpio(10), // Physical pin 19
    PinType::Ground,   // Physical pin 20
    PinType::Gpio(9),  // Physical pin 21
    PinType::Gpio(25), // Physical pin 22
    PinType::Gpio(11), // Physical pin 23
    PinType::Gpio(8),  // Physical pin 24
    PinType::Ground,   // Physical pin 25
    PinType::Gpio(7),  // Physical pin 26
    PinType::Gpio(0),  // Physical pin 27
    PinType::Gpio(1),  // Physical pin 28
    PinType::Gpio(5),  // Physical pin 29
    PinType::Ground,   // Physical pin 30
    PinType::Gpio(6),  // Physical pin 31
    PinType::Gpio(12), // Physical pin 32
    PinType::Gpio(13), // Physical pin 33
    PinType::Ground,   // Physical pin 34
    PinType::Gpio(19), // Physical pin 35
    PinType::Gpio(16), // Physical pin 36
    PinType::Gpio(26), // Physical pin 37
    PinType::Gpio(20), // Physical pin 38
    PinType::Ground,   // Physical pin 39
    PinType::Gpio(21), // Physical pin 40
];

fn print_gpio_status() {
    let gpio = Gpio::new().unwrap_or_else(|e| {
        println!("Error: Can't access GPIO peripheral ({})", e);
        exit(1);
    });

    println!("+------+-------+-------+-----------+-------+-------+------+");
    println!("| GPIO | Mode  | Level |    Pin    | Level | Mode  | GPIO |");
    println!("+------+-------+-------+-----+-----+-------+-------+------+");

    for (idx, pin_type) in HEADER_40.iter().enumerate() {
        match pin_type {
            PinType::Gpio(bcm) => {
                let pin = gpio.get(*bcm).unwrap_or_else(|| {
                    println!("\nError: Can't access GPIO pin {}", *bcm);;
                    exit(1);
                });

                if idx % 2 == 0 {
                    print!(
                        "| {:>4} | {:<5} | {:<5} | {:>3} |",
                        bcm,
                        format!("{}", pin.mode()).to_uppercase(),
                        format!("{}", pin.read()),
                        idx + 1
                    );
                } else {
                    println!(
                        " {:>3} | {:<5} | {:<5} | {:>4} |",
                        idx + 1,
                        format!("{}", pin.read()),
                        format!("{}", pin.mode()).to_uppercase(),
                        bcm,
                    );
                }
            }
            _ => {
                if idx % 2 == 0 {
                    print!("|      | {} |       | {:>3} |", pin_type, idx + 1);
                } else {
                    println!(" {:>3} |       | {} |      |", idx + 1, pin_type);
                }
            }
        };
    }

    println!("+------+-------+-------+-----+-----+-------+-------+------+");
}

fn main() {
    match DeviceInfo::new()
        .unwrap_or_else(|e| {
            println!("Error: Can't identify Raspberry Pi model ({})", e);
            exit(1);
        })
        .model()
    {
        Model::RaspberryPiAPlus
        | Model::RaspberryPiBPlus
        | Model::RaspberryPi2B
        | Model::RaspberryPi3APlus
        | Model::RaspberryPi3B
        | Model::RaspberryPi3BPlus
        | Model::RaspberryPiZero
        | Model::RaspberryPiZeroW => print_gpio_status(),
        model => {
            println!("No GPIO header information available for the {}.", model);
        }
    }
}
<|endoftext|>