<commit_before>//! singular-value decomposition

use ndarray::*;

use super::convert::*;
use super::error::*;
use super::lapack_traits::LapackScalar;
use super::layout::*;

pub trait SVD<U, S, VT> {
    fn svd(self, calc_u: bool, calc_vt: bool) -> Result<(Option<U>, S, Option<VT>)>;
}

impl<A, S, Su, Svt, Ss> SVD<ArrayBase<Su, Ix2>, ArrayBase<Ss, Ix1>, ArrayBase<Svt, Ix2>> for ArrayBase<S, Ix2>
    where A: LapackScalar,
          S: DataMut<Elem = A>,
          Su: DataOwned<Elem = A>,
          Svt: DataOwned<Elem = A>,
          Ss: DataOwned<Elem = A::Real>
{
    fn svd(mut self,
           calc_u: bool,
           calc_vt: bool)
           -> Result<(Option<ArrayBase<Su, Ix2>>, ArrayBase<Ss, Ix1>, Option<ArrayBase<Svt, Ix2>>)> {
        (&mut self).svd(calc_u, calc_vt)
    }
}

impl<'a, A, S, Su, Svt, Ss> SVD<ArrayBase<Su, Ix2>, ArrayBase<Ss, Ix1>, ArrayBase<Svt, Ix2>> for &'a ArrayBase<S, Ix2>
    where A: LapackScalar + Clone,
          S: Data<Elem = A>,
          Su: DataOwned<Elem = A>,
          Svt: DataOwned<Elem = A>,
          Ss: DataOwned<Elem = A::Real>
{
    fn svd(self,
           calc_u: bool,
           calc_vt: bool)
           -> Result<(Option<ArrayBase<Su, Ix2>>, ArrayBase<Ss, Ix1>, Option<ArrayBase<Svt, Ix2>>)> {
        let a = self.to_owned();
        a.svd(calc_u, calc_vt)
    }
}

impl<'a, A, S, Su, Svt, Ss> SVD<ArrayBase<Su, Ix2>, ArrayBase<Ss, Ix1>, ArrayBase<Svt, Ix2>>
    for &'a mut ArrayBase<S, Ix2>
where
    A: LapackScalar,
    S: DataMut<Elem = A>,
    Su: DataOwned<Elem = A>,
    Svt: DataOwned<Elem = A>,
    Ss: DataOwned<Elem = A::Real>,
{
    fn svd(
        mut self,
        calc_u: bool,
        calc_vt: bool,
    ) -> Result<(Option<ArrayBase<Su, Ix2>>, ArrayBase<Ss, Ix1>, Option<ArrayBase<Svt, Ix2>>)> {
        let l = self.layout()?;
        let svd_res = A::svd(l, calc_u, calc_vt, self.as_allocated_mut()?)?;
        let (n, m) = l.size();
        let u = svd_res.u.map(|u| into_matrix(l.resized(n, n), u).unwrap());
        let vt = svd_res.vt.map(
            |vt| into_matrix(l.resized(m, m), vt).unwrap(),
        );
        let s = ArrayBase::from_vec(svd_res.s);
        Ok((u, s, vt))
    }
}
<commit_msg>Simplify SVD<commit_after>//! singular-value decomposition

use ndarray::*;

use super::convert::*;
use super::error::*;
use super::layout::*;
use super::types::*;

pub trait SVD {
    type U;
    type VT;
    type Sigma;
    fn svd(&self, calc_u: bool, calc_vt: bool) -> Result<(Option<Self::U>, Self::Sigma, Option<Self::VT>)>;
}

pub trait SVDInto {
    type U;
    type VT;
    type Sigma;
    fn svd_into(self, calc_u: bool, calc_vt: bool) -> Result<(Option<Self::U>, Self::Sigma, Option<Self::VT>)>;
}

pub trait SVDMut {
    type U;
    type VT;
    type Sigma;
    fn svd_mut(&mut self, calc_u: bool, calc_vt: bool) -> Result<(Option<Self::U>, Self::Sigma, Option<Self::VT>)>;
}

impl<A, S> SVDInto for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type U = Array2<A>;
    type VT = Array2<A>;
    type Sigma = Array1<A::Real>;

    fn svd_into(mut self, calc_u: bool, calc_vt: bool) -> Result<(Option<Self::U>, Self::Sigma, Option<Self::VT>)> {
        self.svd_mut(calc_u, calc_vt)
    }
}

impl<A, S> SVD for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    type U = Array2<A>;
    type VT = Array2<A>;
    type Sigma = Array1<A::Real>;

    fn svd(&self, calc_u: bool, calc_vt: bool) -> Result<(Option<Self::U>, Self::Sigma, Option<Self::VT>)> {
        let a = self.to_owned();
        a.svd_into(calc_u, calc_vt)
    }
}

impl<A, S> SVDMut for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type U = Array2<A>;
    type VT = Array2<A>;
    type Sigma = Array1<A::Real>;

    fn svd_mut(&mut self, calc_u: bool, calc_vt: bool) -> Result<(Option<Self::U>, Self::Sigma, Option<Self::VT>)> {
        let l = self.layout()?;
        let svd_res = A::svd(l, calc_u, calc_vt, self.as_allocated_mut()?)?;
        let (n, m) = l.size();
        let u = svd_res.u.map(|u| into_matrix(l.resized(n, n), u).unwrap());
        let vt = svd_res.vt.map(
            |vt| into_matrix(l.resized(m, m), vt).unwrap(),
        );
        let s = ArrayBase::from_vec(svd_res.s);
        Ok((u, s, vt))
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

use {Error, Result};
use reader::Reader;

/// A tag.
pub enum Tag {
    Empty,
    Path(Attributes),
    Unknown(String, Attributes),
}

/// The attributes of a tag.
pub type Attributes = HashMap<String, String>;

struct Parser<'s> {
    reader: Reader<'s>,
}

impl Tag {
    /// Parse the content between a pair of angle brackets.
    pub fn parse(text: &str) -> Result<Tag> {
        Parser::new(text).process()
    }
}

macro_rules! raise(
    ($parser:expr, $($arg:tt)*) => ({
        let (line, column) = $parser.reader.position();
        return Err(Error {
            line: line,
            column: column,
            message: format!($($arg)*),
        })
    });
);

impl<'s> Parser<'s> {
    #[inline]
    fn new(text: &'s str) -> Parser<'s> {
        Parser {
            reader: Reader::new(text),
        }
    }

    fn process(&mut self) -> Result<Tag> {
        use std::ascii::OwnedAsciiExt;

        self.reader.read_char('/');

        let name = try!(self.read_name());
        let attributes = try!(self.read_attributes());

        Ok(match &(name.clone().into_ascii_lowercase())[] {
            "path" => Tag::Path(attributes),
            _ => Tag::Unknown(name, attributes),
        })
    }

    #[inline]
    fn read_name(&mut self) -> Result<String> {
        match self.reader.read_name().and_then(|name| Some(String::from_str(name))) {
            Some(name) => Ok(name),
            None => raise!(self, "expected a name"),
        }
    }

    fn read_attributes(&mut self) -> Result<Attributes> {
        let mut attributes = HashMap::new();

        loop {
            match try!(self.read_attribute()) {
                Some((name, value)) => {
                    attributes.insert(name, value);
                },
                _ => break,
            }
        }

        Ok(attributes)
    }

    fn read_attribute(&mut self) -> Result<Option<(String, String)>> {
        self.reader.consume_whitespace();

        Ok(None)
    }
}
<commit_msg>A cosmetic adjustment<commit_after>use std::collections::HashMap;

use {Error, Result};
use reader::Reader;

/// A tag.
pub enum Tag {
    Empty,
    Path(Attributes),
    Unknown(String, Attributes),
}

/// The attributes of a tag.
pub type Attributes = HashMap<String, String>;

struct Parser<'s> {
    reader: Reader<'s>,
}

impl Tag {
    /// Parse the content between a pair of angle brackets.
    pub fn parse(text: &str) -> Result<Tag> {
        Parser::new(text).process()
    }
}

macro_rules! raise(
    ($parser:expr, $($arg:tt)*) => ({
        let (line, column) = $parser.reader.position();
        return Err(Error {
            line: line,
            column: column,
            message: format!($($arg)*),
        })
    });
);

impl<'s> Parser<'s> {
    #[inline]
    fn new(text: &'s str) -> Parser<'s> {
        Parser {
            reader: Reader::new(text),
        }
    }

    fn process(&mut self) -> Result<Tag> {
        use std::ascii::OwnedAsciiExt;

        self.reader.consume_char('/');

        let name = try!(self.read_name());
        let attributes = try!(self.read_attributes());

        Ok(match &(name.clone().into_ascii_lowercase())[] {
            "path" => Tag::Path(attributes),
            _ => Tag::Unknown(name, attributes),
        })
    }

    #[inline]
    fn read_name(&mut self) -> Result<String> {
        match self.reader.read_name().and_then(|name| Some(String::from_str(name))) {
            Some(name) => Ok(name),
            None => raise!(self, "expected a name"),
        }
    }

    fn read_attributes(&mut self) -> Result<Attributes> {
        let mut attributes = HashMap::new();

        loop {
            match try!(self.read_attribute()) {
                Some((name, value)) => {
                    attributes.insert(name, value);
                },
                _ => break,
            }
        }

        Ok(attributes)
    }

    fn read_attribute(&mut self) -> Result<Option<(String, String)>> {
        self.reader.consume_whitespace();

        Ok(None)
    }
}
<|endoftext|>


<commit_before>use std::ffi::{c_str_to_bytes, CString};
use std::path::Path;

use sys::tcl as ll;

#[derive(Debug)]
pub enum TclResult {
    Ok,
    Error(String),
    Return,
    Break,
    Continue
}

impl TclResult {
    pub fn from_ll(result: i32, interpreter: &Interpreter) -> TclResult {
        match result {
            0 => TclResult::Ok,
            1 => TclResult::Error(interpreter.string_result()),
            2 => TclResult::Return,
            3 => TclResult::Break,
            4 => TclResult::Continue,
            _ => TclResult::Error("Unknown result".to_string())
        }
    }

    pub fn is_ok(&self) -> bool {
        match *self {
            TclResult::Ok => true,
            _ => false
        }
    }
}

pub struct Interpreter {
    raw: *mut ll::Tcl_Interp
}

impl Drop for Interpreter {
    fn drop(&mut self) {
        unsafe { ll::Tcl_DeleteInterp(self.raw) };
    }
}

impl Interpreter {
    pub fn new() -> Interpreter {
        Interpreter {
            raw: unsafe { ll::Tcl_CreateInterp() }
        }
    }

    //TODO: Child interpreters - create, get, get parent, paths

    pub fn is_safe(&self) -> bool {
        unsafe { ll::Tcl_IsSafe(self.raw) == 1 }
    }

    pub fn make_safe(&mut self) -> TclResult {
        let result = unsafe { ll::Tcl_MakeSafe(self.raw) };
        TclResult::from_ll(result, self)
    }

    pub fn string_result(&self) -> String {
        unsafe {
            let string = ll::Tcl_GetStringResult(self.raw);
            String::from_utf8_lossy(c_str_to_bytes(&string)).to_string()
        }
    }

    pub fn eval_file(&mut self, path: &Path) -> TclResult {
        let buf = CString::from_slice(path.to_string_lossy().as_bytes()).as_ptr();
        let result = unsafe {
            ll::Tcl_EvalFile(self.raw, buf)
        };
        TclResult::from_ll(result, self)
    }

    pub fn eval(&mut self, code: &str) -> TclResult {
        let buf = CString::from_slice(code.as_bytes()).as_ptr();
        let result = unsafe {
            ll::Tcl_Eval(self.raw, buf)
        };
        TclResult::from_ll(result, self)
    }
}
<commit_msg>Started adding object methods<commit_after>use std::ffi::{c_str_to_bytes, CString};
use std::path::Path;

use sys::tcl as ll;

#[derive(Debug)]
pub enum TclResult {
    Ok,
    Error(String),
    Return,
    Break,
    Continue
}

impl TclResult {
    pub fn from_ll(result: i32, interpreter: &Interpreter) -> TclResult {
        match result {
            0 => TclResult::Ok,
            1 => TclResult::Error(interpreter.string_result()),
            2 => TclResult::Return,
            3 => TclResult::Break,
            4 => TclResult::Continue,
            _ => TclResult::Error("Unknown result".to_string())
        }
    }

    pub fn is_ok(&self) -> bool {
        match *self {
            TclResult::Ok => true,
            _ => false
        }
    }
}

pub struct Interpreter {
    raw: *mut ll::Tcl_Interp
}

impl Drop for Interpreter {
    fn drop(&mut self) {
        unsafe { ll::Tcl_DeleteInterp(self.raw) };
    }
}

impl Interpreter {
    pub fn new() -> Interpreter {
        Interpreter {
            raw: unsafe { ll::Tcl_CreateInterp() }
        }
    }

    //TODO: Child interpreters - create, get, get parent, paths

    pub fn is_safe(&self) -> bool {
        unsafe { ll::Tcl_IsSafe(self.raw) == 1 }
    }

    pub fn make_safe(&mut self) -> TclResult {
        let result = unsafe { ll::Tcl_MakeSafe(self.raw) };
        TclResult::from_ll(result, self)
    }

    pub fn string_result(&self) -> String {
        unsafe {
            let string = ll::Tcl_GetStringResult(self.raw);
            String::from_utf8_lossy(c_str_to_bytes(&string)).to_string()
        }
    }

    pub fn eval_file(&mut self, path: &Path) -> TclResult {
        let buf = CString::from_slice(path.to_string_lossy().as_bytes()).as_ptr();
        let result = unsafe {
            ll::Tcl_EvalFile(self.raw, buf)
        };
        TclResult::from_ll(result, self)
    }

    pub fn eval(&mut self, code: &str) -> TclResult {
        let buf = CString::from_slice(code.as_bytes()).as_ptr();
        let result = unsafe {
            ll::Tcl_Eval(self.raw, buf)
        };
        TclResult::from_ll(result, self)
    }
}

pub struct Object {
    raw: *mut ll::Tcl_Obj
}

impl Object {
    pub fn new() -> Object {
        Object {
            raw: unsafe {
                let raw = ll::Tcl_NewObj();
                ll::Tcl_IncrRefCount(raw);
                raw
            }
        }
    }

    pub fn new_boolean(val: bool) -> Object {
        Object {
            raw: unsafe {
                let raw = ll::Tcl_NewBooleanObj(if val { 1 } else { 0 });
                ll::Tcl_IncrRefCount(raw);
                raw
            }
        }
    }

    pub fn new_integer(val: i32) -> Object {
        Object {
            raw: unsafe {
                let raw = ll::Tcl_NewIntObj(val);
                ll::Tcl_IncrRefCount(raw);
                raw
            }
        }
    }

    pub fn new_long(val: i64) -> Object {
        Object {
            raw: unsafe {
                let raw = ll::Tcl_NewLongObj(val);
                ll::Tcl_IncrRefCount(raw);
                raw
            }
        }
    }
}

impl Drop for Object {
    fn drop(&mut self) {
        unsafe { ll::Tcl_DecrRefCount(self.raw) };
    }
}
<|endoftext|>


<commit_before>use std::io::{self, ErrorKind, Read, Write};
use std::mem;
use std::net::{self, SocketAddr};
use std::sync::Arc;

use futures::stream::{self, Stream};
use futures::{Future, IntoFuture, failed, Task, Poll};
use futures_io::{Ready, IoFuture, IoStream};
use mio;

use {ReadinessStream, LoopHandle};
use event_loop::Source;

/// An I/O object representing a TCP socket listening for incoming connections.
///
/// This object can be converted into a stream of incoming connections for
/// various forms of processing.
pub struct TcpListener {
    loop_handle: LoopHandle,
    ready: ReadinessStream,
    listener: Arc<Source<mio::tcp::TcpListener>>,
}

impl TcpListener {
    fn new(listener: mio::tcp::TcpListener,
           handle: LoopHandle) -> Box<IoFuture<TcpListener>> {
        let listener = Arc::new(Source::new(listener));
        ReadinessStream::new(handle.clone(), listener.clone()).map(|r| {
            TcpListener {
                loop_handle: handle,
                ready: r,
                listener: listener,
            }
        }).boxed()
    }

    /// Create a new TCP listener from the standard library's TCP listener.
    ///
    /// This method can be used when the `LoopHandle::tcp_listen` method isn't
    /// sufficient because perhaps some more configuration is needed in terms of
    /// before the calls to `bind` and `listen`.
    ///
    /// This API is typically paired with the `net2` crate and the `TcpBuilder`
    /// type to build up and customize a listener before it's shipped off to the
    /// backing event loop. This allows configuration of options like
    /// `SO_REUSEPORT`, binding to multiple addresses, etc.
    ///
    /// The `addr` argument here is one of the addresses that `listener` is
    /// bound to and the listener will only be guaranteed to accept connections
    /// of the same address type currently.
    ///
    /// Finally, the `handle` argument is the event loop that this listener will
    /// be bound to.
    ///
    /// The platform specific behavior of this function looks like:
    ///
    /// * On Unix, the socket is placed into nonblocking mode and connections
    ///   can be accepted as normal
    ///
    /// * On Windows, the address is stored internally and all future accepts
    ///   will only be for the same IP version as `addr` specified. That is, if
    ///   `addr` is an IPv4 address then all sockets accepted will be IPv4 as
    ///   well (same for IPv6).
    pub fn from_listener(listener: net::TcpListener,
                         addr: &SocketAddr,
                         handle: LoopHandle) -> Box<IoFuture<TcpListener>> {
        mio::tcp::TcpListener::from_listener(listener, addr)
            .into_future()
            .and_then(|l| TcpListener::new(l, handle))
            .boxed()
    }

    /// Returns the local address that this listener is bound to.
    ///
    /// This can be useful, for example, when binding to port 0 to figure out
    /// which port was actually bound.
    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.listener.io().local_addr()
    }

    /// Consumes this listener, returning a stream of the sockets this listener
    /// accepts.
    ///
    /// This method returns an implementation of the `Stream` trait which
    /// resolves to the sockets the are accepted on this listener.
    pub fn incoming(self) -> Box<IoStream<(TcpStream, SocketAddr)>> {
        let TcpListener { loop_handle, listener, ready } = self;

        ready
            .map(move |_| {
                stream::iter(NonblockingIter { source: listener.clone() }.fuse())
            })
            .flatten()
            .and_then(move |(tcp, addr)| {
                let tcp = Arc::new(Source::new(tcp));
                ReadinessStream::new(loop_handle.clone(),
                                     tcp.clone()).map(move |ready| {
                    let stream = TcpStream {
                        source: tcp,
                        ready: ready,
                    };
                    (stream, addr)
                })
            }).boxed()
    }
}

struct NonblockingIter {
    source: Arc<Source<mio::tcp::TcpListener>>,
}

impl Iterator for NonblockingIter {
    type Item = io::Result<(mio::tcp::TcpStream, SocketAddr)>;

    fn next(&mut self) -> Option<io::Result<(mio::tcp::TcpStream, SocketAddr)>> {
        match self.source.io().accept() {
            Ok(Some(e)) => {
                debug!("accepted connection");
                Some(Ok(e))
            }
            Ok(None) => {
                debug!("no connection ready");
                None
            }
            Err(e) => Some(Err(e)),
        }
    }
}

impl Stream for TcpListener {
    type Item = Ready;
    type Error = io::Error;

    fn poll(&mut self, task: &mut Task) -> Poll<Option<Ready>, io::Error> {
        self.ready.poll(task)
    }

    fn schedule(&mut self, task: &mut Task) {
        self.ready.schedule(task)
    }
}

/// An I/O object representing a TCP stream connected to a remote endpoint.
///
/// A TCP stream can either be created by connecting to an endpoint or by
/// accepting a connection from a listener. Inside the stream is access to the
/// raw underlying I/O object as well as streams for the read/write
/// notifications on the stream itself.
pub struct TcpStream {
    source: Arc<Source<mio::tcp::TcpStream>>,
    ready: ReadinessStream,
}

enum TcpStreamNew {
    Waiting(TcpStream),
    Empty,
}

impl LoopHandle {
    /// Create a new TCP listener associated with this event loop.
    ///
    /// The TCP listener will bind to the provided `addr` address, if available,
    /// and will be returned as a future. The returned future, if resolved
    /// successfully, can then be used to accept incoming connections.
    pub fn tcp_listen(self, addr: &SocketAddr) -> Box<IoFuture<TcpListener>> {
        match mio::tcp::TcpListener::bind(addr) {
            Ok(l) => TcpListener::new(l, self),
            Err(e) => failed(e).boxed(),
        }
    }

    /// Create a new TCP stream connected to the specified address.
    ///
    /// This function will create a new TCP socket and attempt to connect it to
    /// the `addr` provided. The returned future will be resolved once the
    /// stream has successfully connected. If an error happens during the
    /// connection or during the socket creation, that error will be returned to
    /// the future instead.
    pub fn tcp_connect(self, addr: &SocketAddr) -> Box<IoFuture<TcpStream>> {
        match mio::tcp::TcpStream::connect(addr) {
            Ok(tcp) => TcpStream::new(tcp, self),
            Err(e) => failed(e).boxed(),
        }
    }
}

impl TcpStream {
    fn new(connected_stream: mio::tcp::TcpStream,
           handle: LoopHandle)
           -> Box<IoFuture<TcpStream>> {
        // Once we've connected, wait for the stream to be writable as that's
        // when the actual connection has been initiated. Once we're writable we
        // check for `take_socket_error` to see if the connect actually hit an
        // error or not.
        //
        // If all that succeeded then we ship everything on up.
        let connected_stream = Arc::new(Source::new(connected_stream));
        ReadinessStream::new(handle, connected_stream.clone()).and_then(|ready| {
            TcpStreamNew::Waiting(TcpStream {
                source: connected_stream,
                ready: ready,
            })
        }).boxed()
    }

    /// Creates a new `TcpStream` from the pending socket inside the given
    /// `std::net::TcpStream`, connecting it to the address specified.
    ///
    /// This constructor allows configuring the socket before it's actually
    /// connected, and this function will transfer ownership to the returned
    /// `TcpStream` if successful. An unconnected `TcpStream` can be created
    /// with the `net2::TcpBuilder` type (and also configured via that route).
    ///
    /// The platform specific behavior of this function looks like:
    ///
    /// * On Unix, the socket is placed into nonblocking mode and then a
    ///   `connect` call is issued.
    ///
    /// * On Windows, the address is stored internally and the connect operation
    ///   is issued when the returned `TcpStream` is registered with an event
    ///   loop. Note that on Windows you must `bind` a socket before it can be
    ///   connected, so if a custom `TcpBuilder` is used it should be bound
    ///   (perhaps to `INADDR_ANY`) before this method is called.
    pub fn connect_stream(stream: net::TcpStream,
                          addr: &SocketAddr,
                          handle: LoopHandle) -> Box<IoFuture<TcpStream>> {
        match mio::tcp::TcpStream::connect_stream(stream, addr) {
            Ok(tcp) => TcpStream::new(tcp, handle),
            Err(e) => failed(e).boxed(),
        }
    }

    /// Returns the local address that this stream is bound to.
    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.source.io().local_addr()
    }

    /// Returns the remote address that this stream is connected to.
    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        self.source.io().peer_addr()
    }
}

impl Future for TcpStreamNew {
    type Item = TcpStream;
    type Error = io::Error;

    fn poll(&mut self, task: &mut Task) -> Poll<TcpStream, io::Error> {
        let mut stream = match mem::replace(self, TcpStreamNew::Empty) {
            TcpStreamNew::Waiting(s) => s,
            TcpStreamNew::Empty => panic!("can't poll TCP stream twice"),
        };
        match stream.ready.poll(task) {
            Poll::Ok(None) => panic!(),
            Poll::Ok(Some(_)) => {
                match stream.source.io().take_socket_error() {
                    Ok(()) => return Poll::Ok(stream),
                    Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
                    Err(e) => return Poll::Err(e),
                }
            }
            Poll::Err(e) => return Poll::Err(e),
            Poll::NotReady => {}
        }
        *self = TcpStreamNew::Waiting(stream);
        Poll::NotReady
    }

    fn schedule(&mut self, task: &mut Task) {
        match *self {
            TcpStreamNew::Waiting(ref mut s) => {
                s.ready.schedule(task);
            }
            TcpStreamNew::Empty => task.notify(),
        }
    }
}

impl Read for TcpStream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let r = self.source.io().read(buf);
        trace!("read[{:p}] {:?} on {:?}", self, r, self.source.io());
        return r
    }
}

impl Write for TcpStream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let r = self.source.io().write(buf);
        trace!("write[{:p}] {:?} on {:?}", self, r, self.source.io());
        return r
    }
    fn flush(&mut self) -> io::Result<()> {
        self.source.io().flush()
    }
}

impl<'a> Read for &'a TcpStream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.source.io().read(buf)
    }
}

impl<'a> Write for &'a TcpStream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.source.io().write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.source.io().flush()
    }
}

impl Stream for TcpStream {
    type Item = Ready;
    type Error = io::Error;

    fn poll(&mut self, task: &mut Task) -> Poll<Option<Ready>, io::Error> {
        self.ready.poll(task)
    }

    fn schedule(&mut self, task: &mut Task) {
        self.ready.schedule(task)
    }
}
<commit_msg>Add a few more TCP methods<commit_after>use std::io::{self, ErrorKind, Read, Write};
use std::mem;
use std::net::{self, SocketAddr, Shutdown};
use std::sync::Arc;

use futures::stream::{self, Stream};
use futures::{Future, IntoFuture, failed, Task, Poll};
use futures_io::{Ready, IoFuture, IoStream};
use mio;

use {ReadinessStream, LoopHandle};
use event_loop::Source;

/// An I/O object representing a TCP socket listening for incoming connections.
///
/// This object can be converted into a stream of incoming connections for
/// various forms of processing.
pub struct TcpListener {
    loop_handle: LoopHandle,
    ready: ReadinessStream,
    listener: Arc<Source<mio::tcp::TcpListener>>,
}

impl TcpListener {
    fn new(listener: mio::tcp::TcpListener,
           handle: LoopHandle) -> Box<IoFuture<TcpListener>> {
        let listener = Arc::new(Source::new(listener));
        ReadinessStream::new(handle.clone(), listener.clone()).map(|r| {
            TcpListener {
                loop_handle: handle,
                ready: r,
                listener: listener,
            }
        }).boxed()
    }

    /// Create a new TCP listener from the standard library's TCP listener.
    ///
    /// This method can be used when the `LoopHandle::tcp_listen` method isn't
    /// sufficient because perhaps some more configuration is needed in terms of
    /// before the calls to `bind` and `listen`.
    ///
    /// This API is typically paired with the `net2` crate and the `TcpBuilder`
    /// type to build up and customize a listener before it's shipped off to the
    /// backing event loop. This allows configuration of options like
    /// `SO_REUSEPORT`, binding to multiple addresses, etc.
    ///
    /// The `addr` argument here is one of the addresses that `listener` is
    /// bound to and the listener will only be guaranteed to accept connections
    /// of the same address type currently.
    ///
    /// Finally, the `handle` argument is the event loop that this listener will
    /// be bound to.
    ///
    /// The platform specific behavior of this function looks like:
    ///
    /// * On Unix, the socket is placed into nonblocking mode and connections
    ///   can be accepted as normal
    ///
    /// * On Windows, the address is stored internally and all future accepts
    ///   will only be for the same IP version as `addr` specified. That is, if
    ///   `addr` is an IPv4 address then all sockets accepted will be IPv4 as
    ///   well (same for IPv6).
    pub fn from_listener(listener: net::TcpListener,
                         addr: &SocketAddr,
                         handle: LoopHandle) -> Box<IoFuture<TcpListener>> {
        mio::tcp::TcpListener::from_listener(listener, addr)
            .into_future()
            .and_then(|l| TcpListener::new(l, handle))
            .boxed()
    }

    /// Returns the local address that this listener is bound to.
    ///
    /// This can be useful, for example, when binding to port 0 to figure out
    /// which port was actually bound.
    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.listener.io().local_addr()
    }

    /// Consumes this listener, returning a stream of the sockets this listener
    /// accepts.
    ///
    /// This method returns an implementation of the `Stream` trait which
    /// resolves to the sockets the are accepted on this listener.
    pub fn incoming(self) -> Box<IoStream<(TcpStream, SocketAddr)>> {
        let TcpListener { loop_handle, listener, ready } = self;

        ready
            .map(move |_| {
                stream::iter(NonblockingIter { source: listener.clone() }.fuse())
            })
            .flatten()
            .and_then(move |(tcp, addr)| {
                let tcp = Arc::new(Source::new(tcp));
                ReadinessStream::new(loop_handle.clone(),
                                     tcp.clone()).map(move |ready| {
                    let stream = TcpStream {
                        source: tcp,
                        ready: ready,
                    };
                    (stream, addr)
                })
            }).boxed()
    }
}

struct NonblockingIter {
    source: Arc<Source<mio::tcp::TcpListener>>,
}

impl Iterator for NonblockingIter {
    type Item = io::Result<(mio::tcp::TcpStream, SocketAddr)>;

    fn next(&mut self) -> Option<io::Result<(mio::tcp::TcpStream, SocketAddr)>> {
        match self.source.io().accept() {
            Ok(Some(e)) => {
                debug!("accepted connection");
                Some(Ok(e))
            }
            Ok(None) => {
                debug!("no connection ready");
                None
            }
            Err(e) => Some(Err(e)),
        }
    }
}

impl Stream for TcpListener {
    type Item = Ready;
    type Error = io::Error;

    fn poll(&mut self, task: &mut Task) -> Poll<Option<Ready>, io::Error> {
        self.ready.poll(task)
    }

    fn schedule(&mut self, task: &mut Task) {
        self.ready.schedule(task)
    }
}

/// An I/O object representing a TCP stream connected to a remote endpoint.
///
/// A TCP stream can either be created by connecting to an endpoint or by
/// accepting a connection from a listener. Inside the stream is access to the
/// raw underlying I/O object as well as streams for the read/write
/// notifications on the stream itself.
pub struct TcpStream {
    source: Arc<Source<mio::tcp::TcpStream>>,
    ready: ReadinessStream,
}

enum TcpStreamNew {
    Waiting(TcpStream),
    Empty,
}

impl LoopHandle {
    /// Create a new TCP listener associated with this event loop.
    ///
    /// The TCP listener will bind to the provided `addr` address, if available,
    /// and will be returned as a future. The returned future, if resolved
    /// successfully, can then be used to accept incoming connections.
    pub fn tcp_listen(self, addr: &SocketAddr) -> Box<IoFuture<TcpListener>> {
        match mio::tcp::TcpListener::bind(addr) {
            Ok(l) => TcpListener::new(l, self),
            Err(e) => failed(e).boxed(),
        }
    }

    /// Create a new TCP stream connected to the specified address.
    ///
    /// This function will create a new TCP socket and attempt to connect it to
    /// the `addr` provided. The returned future will be resolved once the
    /// stream has successfully connected. If an error happens during the
    /// connection or during the socket creation, that error will be returned to
    /// the future instead.
    pub fn tcp_connect(self, addr: &SocketAddr) -> Box<IoFuture<TcpStream>> {
        match mio::tcp::TcpStream::connect(addr) {
            Ok(tcp) => TcpStream::new(tcp, self),
            Err(e) => failed(e).boxed(),
        }
    }
}

impl TcpStream {
    fn new(connected_stream: mio::tcp::TcpStream,
           handle: LoopHandle)
           -> Box<IoFuture<TcpStream>> {
        // Once we've connected, wait for the stream to be writable as that's
        // when the actual connection has been initiated. Once we're writable we
        // check for `take_socket_error` to see if the connect actually hit an
        // error or not.
        //
        // If all that succeeded then we ship everything on up.
        let connected_stream = Arc::new(Source::new(connected_stream));
        ReadinessStream::new(handle, connected_stream.clone()).and_then(|ready| {
            TcpStreamNew::Waiting(TcpStream {
                source: connected_stream,
                ready: ready,
            })
        }).boxed()
    }

    /// Creates a new `TcpStream` from the pending socket inside the given
    /// `std::net::TcpStream`, connecting it to the address specified.
    ///
    /// This constructor allows configuring the socket before it's actually
    /// connected, and this function will transfer ownership to the returned
    /// `TcpStream` if successful. An unconnected `TcpStream` can be created
    /// with the `net2::TcpBuilder` type (and also configured via that route).
    ///
    /// The platform specific behavior of this function looks like:
    ///
    /// * On Unix, the socket is placed into nonblocking mode and then a
    ///   `connect` call is issued.
    ///
    /// * On Windows, the address is stored internally and the connect operation
    ///   is issued when the returned `TcpStream` is registered with an event
    ///   loop. Note that on Windows you must `bind` a socket before it can be
    ///   connected, so if a custom `TcpBuilder` is used it should be bound
    ///   (perhaps to `INADDR_ANY`) before this method is called.
    pub fn connect_stream(stream: net::TcpStream,
                          addr: &SocketAddr,
                          handle: LoopHandle) -> Box<IoFuture<TcpStream>> {
        match mio::tcp::TcpStream::connect_stream(stream, addr) {
            Ok(tcp) => TcpStream::new(tcp, handle),
            Err(e) => failed(e).boxed(),
        }
    }

    /// Returns the local address that this stream is bound to.
    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.source.io().local_addr()
    }

    /// Returns the remote address that this stream is connected to.
    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        self.source.io().peer_addr()
    }

    /// Shuts down the read, write, or both halves of this connection.
    ///
    /// This function will cause all pending and future I/O on the specified
    /// portions to return immediately with an appropriate value (see the
    /// documentation of `Shutdown`).
    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
        self.source.io().shutdown(how)
    }

    /// Sets the value of the `TCP_NODELAY` option on this socket.
    ///
    /// If set, this option disables the Nagle algorithm. This means that
    /// segments are always sent as soon as possible, even if there is only a
    /// small amount of data. When not set, data is buffered until there is a
    /// sufficient amount to send out, thereby avoiding the frequent sending of
    /// small packets.
    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
        self.source.io().set_nodelay(nodelay)
    }

    /// Sets the keepalive time in seconds for this socket.
    pub fn set_keepalive_s(&self, seconds: Option<u32>) -> io::Result<()> {
        self.source.io().set_keepalive(seconds)
    }
}

impl Future for TcpStreamNew {
    type Item = TcpStream;
    type Error = io::Error;

    fn poll(&mut self, task: &mut Task) -> Poll<TcpStream, io::Error> {
        let mut stream = match mem::replace(self, TcpStreamNew::Empty) {
            TcpStreamNew::Waiting(s) => s,
            TcpStreamNew::Empty => panic!("can't poll TCP stream twice"),
        };
        match stream.ready.poll(task) {
            Poll::Ok(None) => panic!(),
            Poll::Ok(Some(_)) => {
                match stream.source.io().take_socket_error() {
                    Ok(()) => return Poll::Ok(stream),
                    Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
                    Err(e) => return Poll::Err(e),
                }
            }
            Poll::Err(e) => return Poll::Err(e),
            Poll::NotReady => {}
        }
        *self = TcpStreamNew::Waiting(stream);
        Poll::NotReady
    }

    fn schedule(&mut self, task: &mut Task) {
        match *self {
            TcpStreamNew::Waiting(ref mut s) => {
                s.ready.schedule(task);
            }
            TcpStreamNew::Empty => task.notify(),
        }
    }
}

impl Read for TcpStream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let r = self.source.io().read(buf);
        trace!("read[{:p}] {:?} on {:?}", self, r, self.source.io());
        return r
    }
}

impl Write for TcpStream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let r = self.source.io().write(buf);
        trace!("write[{:p}] {:?} on {:?}", self, r, self.source.io());
        return r
    }
    fn flush(&mut self) -> io::Result<()> {
        self.source.io().flush()
    }
}

impl<'a> Read for &'a TcpStream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.source.io().read(buf)
    }
}

impl<'a> Write for &'a TcpStream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.source.io().write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.source.io().flush()
    }
}

impl Stream for TcpStream {
    type Item = Ready;
    type Error = io::Error;

    fn poll(&mut self, task: &mut Task) -> Poll<Option<Ready>, io::Error> {
        self.ready.poll(task)
    }

    fn schedule(&mut self, task: &mut Task) {
        self.ready.schedule(task)
    }
}
<|endoftext|>


<commit_before>use std::fs;
use std::io;

use tempfile::tempfile;

// magic
use std::io::Seek;

pub trait Tee: io::BufRead {
    fn reset(&mut self) -> io::Result<()>;
    fn len_and_reset(&mut self) -> io::Result<u64>;
    fn as_seekable(&mut self) -> Option<&mut Seeker>;
}

pub struct TempFileTee {
    inner: io::BufReader<fs::File>,
}

impl TempFileTee {
    pub fn new<U: io::Read>(from: U) -> io::Result<Box<Tee>> {
        // TODO: take a size hint, and consider using memory, or shm,
        // TODO: or take a temp file path, or..
        let mut tmp = tempfile()?;

        {
            let mut reader = io::BufReader::new(from);
            let mut writer = io::BufWriter::new(&tmp);
            io::copy(&mut reader, &mut writer)?;
        }

        tmp.seek(BEGINNING)?;

        Ok(Box::new(TempFileTee {
            inner: io::BufReader::new(tmp),
        }))
    }
}

const BEGINNING: io::SeekFrom = io::SeekFrom::Start(0);
const END: io::SeekFrom = io::SeekFrom::End(0);

impl Tee for TempFileTee {
    fn reset(&mut self) -> io::Result<()> {
        self.inner.seek(BEGINNING).map(|_| ())
    }

    fn len_and_reset(&mut self) -> io::Result<u64> {
        let len = self.inner.seek(END)?;
        self.reset()?;
        Ok(len)
    }

    fn as_seekable(&mut self) -> Option<&mut Seeker> {
        Some(&mut self.inner)
    }
}

// Look, I didn't want to implement these. I wanted to return the implementation.
// But I couldn't make it compile, and I might care enough eventually.
impl io::Read for TempFileTee {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl io::BufRead for TempFileTee {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.inner.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.inner.consume(amt)
    }
}

pub struct BufReaderTee<R: io::Read> {
    inner: Box<io::BufReader<R>>,
}

impl<R: io::Read> BufReaderTee<R> {
    pub fn new(from: R) -> Self {
        BufReaderTee {
            inner: Box::new(io::BufReader::new(from))
        }
    }
}

impl<R: io::Read> Tee for BufReaderTee<R>
    where R: io::Seek + 'static
{
    fn reset(&mut self) -> io::Result<()> {
        self.inner.seek(io::SeekFrom::Start(0)).map(|_| ())
    }

    fn len_and_reset(&mut self) -> io::Result<u64> {
        let len = self.inner.seek(END)?;
        self.reset()?;
        Ok(len)
    }

    fn as_seekable(&mut self) -> Option<&mut Seeker> {
        Some(&mut *self.inner)
    }
}

impl<R: io::Read> io::Read for BufReaderTee<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl<R: io::Read> io::BufRead for BufReaderTee<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.inner.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.inner.consume(amt)
    }
}

pub struct FailingTee<T> {
    inner: Box<T>,
}

impl<U: io::Read> FailingTee<io::BufReader<U>> {
    pub fn new(from: U) -> Self {
        FailingTee {
            inner: Box::new(io::BufReader::new(from))
        }
    }
}

impl<T> Tee for FailingTee<T>
    where T: io::BufRead
{
    fn reset(&mut self) -> io::Result<()> {
        unreachable!();
    }

    fn len_and_reset(&mut self) -> io::Result<u64> {
        unreachable!();
    }

    fn as_seekable(&mut self) -> Option<&mut Seeker> {
        None
    }
}

impl<T> io::Read for FailingTee<T>
    where T: io::Read {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl<T> io::BufRead for FailingTee<T>
    where T: io::BufRead {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.inner.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.inner.consume(amt)
    }
}

pub trait Seeker: io::Seek + io::Read {
}

impl<R: io::Read> Seeker for io::BufReader<R>
    where R: io::Seek {
}
<commit_msg>TempFileTee uses memory (maybe a bit badly) if the input is short<commit_after>use std::fs;
use std::io;

use tempfile::tempfile;

// magic
use std::io::Seek;
use std::io::Write;

pub trait Tee: io::BufRead {
    fn reset(&mut self) -> io::Result<()>;
    fn len_and_reset(&mut self) -> io::Result<u64>;
    fn as_seekable(&mut self) -> Option<&mut Seeker>;
}

pub struct TempFileTee {
    inner: io::BufReader<fs::File>,
}

pub fn read_all<R: io::Read>(mut reader: &mut R, mut buf: &mut [u8]) -> io::Result<usize> {
    let mut pos = 0;
    loop {
        match reader.read(&mut buf[pos..]) {
            Ok(0) => return Ok(pos),
            Ok(n) => {
                pos += n;
                if pos == buf.len() {
                    return Ok(pos);
                }
            }
            Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
            Err(e) => return Err(e),
        }
    }
}

impl TempFileTee {
    pub fn new<U: io::Read>(mut from: U) -> io::Result<Box<Tee>> {
        const MEM_LIMIT: usize = 32 * 1024;
        let mut buf = [0u8; MEM_LIMIT];
        let read = read_all(&mut from, &mut buf)?;
        if read < MEM_LIMIT {
            return Ok(Box::new(BufReaderTee::new(io::Cursor::new(buf[..read].to_vec()))));
        }

        let mut tmp = tempfile()?;

        {
            let mut writer = io::BufWriter::new(&tmp);
            writer.write_all(&buf)?;
            let written = io::copy(&mut from, &mut writer)?;
            println!("temp file: {}", written);
        }

        tmp.seek(BEGINNING)?;

        Ok(Box::new(TempFileTee {
            inner: io::BufReader::new(tmp),
        }))
    }
}

const BEGINNING: io::SeekFrom = io::SeekFrom::Start(0);
const END: io::SeekFrom = io::SeekFrom::End(0);

impl Tee for TempFileTee {
    fn reset(&mut self) -> io::Result<()> {
        self.inner.seek(BEGINNING).map(|_| ())
    }

    fn len_and_reset(&mut self) -> io::Result<u64> {
        let len = self.inner.seek(END)?;
        self.reset()?;
        Ok(len)
    }

    fn as_seekable(&mut self) -> Option<&mut Seeker> {
        Some(&mut self.inner)
    }
}

// Look, I didn't want to implement these. I wanted to return the implementation.
// But I couldn't make it compile, and I might care enough eventually.
impl io::Read for TempFileTee {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl io::BufRead for TempFileTee {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.inner.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.inner.consume(amt)
    }
}

pub struct BufReaderTee<R: io::Read> {
    inner: Box<io::BufReader<R>>,
}

impl<R: io::Read> BufReaderTee<R> {
    pub fn new(from: R) -> Self {
        BufReaderTee {
            inner: Box::new(io::BufReader::new(from))
        }
    }
}

impl<R: io::Read> Tee for BufReaderTee<R>
    where R: io::Seek + 'static
{
    fn reset(&mut self) -> io::Result<()> {
        self.inner.seek(io::SeekFrom::Start(0)).map(|_| ())
    }

    fn len_and_reset(&mut self) -> io::Result<u64> {
        let len = self.inner.seek(END)?;
        self.reset()?;
        Ok(len)
    }

    fn as_seekable(&mut self) -> Option<&mut Seeker> {
        Some(&mut *self.inner)
    }
}

impl<R: io::Read> io::Read for BufReaderTee<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl<R: io::Read> io::BufRead for BufReaderTee<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.inner.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.inner.consume(amt)
    }
}

pub struct FailingTee<T> {
    inner: Box<T>,
}

impl<U: io::Read> FailingTee<io::BufReader<U>> {
    pub fn new(from: U) -> Self {
        FailingTee {
            inner: Box::new(io::BufReader::new(from))
        }
    }
}

impl<T> Tee for FailingTee<T>
    where T: io::BufRead
{
    fn reset(&mut self) -> io::Result<()> {
        unreachable!();
    }

    fn len_and_reset(&mut self) -> io::Result<u64> {
        unreachable!();
    }

    fn as_seekable(&mut self) -> Option<&mut Seeker> {
        None
    }
}

impl<T> io::Read for FailingTee<T>
    where T: io::Read {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl<T> io::BufRead for FailingTee<T>
    where T: io::BufRead {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.inner.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.inner.consume(amt)
    }
}

pub trait Seeker: io::Seek + io::Read {
}

impl<R: io::Read> Seeker for io::BufReader<R>
    where R: io::Seek {
}

#[cfg(test)]
mod tests {
    use tee;

    use std::cmp::min;
    use std::io;

    struct Readie {
        limit: usize,
        len: usize,
    }

    impl io::Read for Readie {
        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
            let to_take = min(buf.len(), min(self.limit, self.len));

            for i in 0..to_take {
                buf[i] = (i + 1) as u8;
            }

            self.len -= to_take;
            Ok(to_take)
        }
    }

    #[test]
    fn repeated_read_short() {
        let mut r = Readie {
            limit: 1,
            len: 5,
        };
        let mut a = [0u8; 8];
        assert_eq!(5, tee::read_all(&mut r, &mut a).expect("read"));
        assert_eq!([1, 1, 1, 1, 1, 0, 0, 0], a);
    }

    #[test]
    fn repeated_read_over() {
        let mut r = Readie {
            limit: 2,
            len: 12,
        };
        let mut a = [0u8; 8];
        assert_eq!(8, tee::read_all(&mut r, &mut a).expect("read"));
        assert_eq!([1, 2, 1, 2, 1, 2, 1, 2], a);
    }

    #[test]
    fn repeated_read_whole() {
        let mut r = Readie {
            limit: 12,
            len: 8,
        };
        let mut a = [0u8; 8];
        assert_eq!(8, tee::read_all(&mut r, &mut a).expect("read"));
        assert_eq!([1, 2, 3, 4, 5, 6, 7, 8], a);
    }

}<|endoftext|>


<commit_before>extern crate winapi;
extern crate kernel32;

use self::super::Size;

/// Gets the current terminal size
pub fn get() -> Option<Size> {
    //http://rosettacode.org/wiki/Terminal_control/Dimensions#Windows
    use self::winapi::HANDLE;
    use self::kernel32::{self, GetStdHandle, GetConsoleScreenBufferInfo, GetLastError};
    use self::winapi::{
        self,
        CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT,
        STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE
    };
    let name = b"CONOUT$\0";
    let handle: HANDLE = unsafe {
        kernel32::CreateFileA(
            name.as_ptr() as *const i8,
            winapi::GENERIC_READ | winapi::GENERIC_WRITE,
            winapi::FILE_SHARE_WRITE,
            ptr::null_mut(),
            winapi::OPEN_EXISTING,
            0,
            ptr::null_mut(),
        )
    };
    println!("handle {:?}", handle);
    if handle == INVALID_HANDLE_VALUE {
        println!("handle was invalid");
        return None
    }
    let zc = COORD { X: 0, Y: 0 };
    // screen buffer info is a container of console display information
    // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx
    let mut info = ::std::mem::uninitialized();/*CONSOLE_SCREEN_BUFFER_INFO {
        dwSize: zc.clone(),
        dwCursorPosition: zc.clone(),
        wAttributes: 0,
        srWindow: SMALL_RECT { Left:0, Top: 0, Right: 0, Bottom: 0 },
        dwMaximumWindowSize: zc
    };*/
    let success: bool = unsafe {
        // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx
        let result = GetConsoleScreenBufferInfo(handle, &mut info);
        println!("result was {}", result);
        if result == 0 {
            println!("last error was {:?}", GetLastError());
        }
        result != 0
    };
    println!("info {:?}", info);
    if success {
        Some(
            Size {
                rows: (info.srWindow.Bottom - info.srWindow.Top + 1) as u16,
                cols: (info.srWindow.Right - info.srWindow.Left + 1) as u16
            }
        )
    } else {
        None
    }
}
<commit_msg>use ptr<commit_after>extern crate winapi;
extern crate kernel32;

use self::super::Size;
use std::ptr;

/// Gets the current terminal size
pub fn get() -> Option<Size> {
    //http://rosettacode.org/wiki/Terminal_control/Dimensions#Windows
    use self::winapi::HANDLE;
    use self::kernel32::{self, GetStdHandle, GetConsoleScreenBufferInfo, GetLastError};
    use self::winapi::{
        self,
        CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT,
        STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE
    };
    let name = b"CONOUT$\0";
    let handle: HANDLE = unsafe {
        kernel32::CreateFileA(
            name.as_ptr() as *const i8,
            winapi::GENERIC_READ | winapi::GENERIC_WRITE,
            winapi::FILE_SHARE_WRITE,
            ptr::null_mut(),
            winapi::OPEN_EXISTING,
            0,
            ptr::null_mut(),
        )
    };
    println!("handle {:?}", handle);
    if handle == INVALID_HANDLE_VALUE {
        println!("handle was invalid");
        return None
    }
    let zc = COORD { X: 0, Y: 0 };
    // screen buffer info is a container of console display information
    // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx
    let mut info = ::std::mem::uninitialized();/*CONSOLE_SCREEN_BUFFER_INFO {
        dwSize: zc.clone(),
        dwCursorPosition: zc.clone(),
        wAttributes: 0,
        srWindow: SMALL_RECT { Left:0, Top: 0, Right: 0, Bottom: 0 },
        dwMaximumWindowSize: zc
    };*/
    let success: bool = unsafe {
        // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx
        let result = GetConsoleScreenBufferInfo(handle, &mut info);
        println!("result was {}", result);
        if result == 0 {
            println!("last error was {:?}", GetLastError());
        }
        result != 0
    };
    println!("info {:?}", info);
    if success {
        Some(
            Size {
                rows: (info.srWindow.Bottom - info.srWindow.Top + 1) as u16,
                cols: (info.srWindow.Right - info.srWindow.Left + 1) as u16
            }
        )
    } else {
        None
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Buffer that is written once then read for as long as it is alive.
//!
//! Use this buffer when you have data that you never modify.
//!
//! Only the first ever command buffer that uses this buffer can write to it (for example by
//! copying from another buffer). Any subsequent command buffer **must** only read from the buffer,
//! or a panic will happen.
//!
//! The buffer will be stored in device-local memory if possible
//!

use std::marker::PhantomData;
use std::mem;
use std::ops::Range;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::Weak;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use smallvec::SmallVec;

use buffer::sys::UnsafeBuffer;
use buffer::sys::Usage;
use buffer::traits::AccessRange;
use buffer::traits::Buffer;
use buffer::traits::GpuAccessResult;
use buffer::traits::TypedBuffer;
use command_buffer::Submission;
use device::Device;
use instance::QueueFamily;
use memory::DeviceMemory;
use sync::Sharing;

use OomError;

/// Buffer that is written once then read for as long as it is alive.
pub struct ImmutableBuffer<T: ?Sized> {
    // Inner content.
    inner: UnsafeBuffer,

    memory: DeviceMemory,

    // Queue families allowed to access this buffer.
    queue_families: SmallVec<[u32; 4]>,

    latest_write_submission: Mutex<Option<Weak<Submission>>>,        // TODO: can use `Weak::new()` once it's stabilized

    started_reading: AtomicBool,

    marker: PhantomData<Box<T>>,
}

impl<T> ImmutableBuffer<T> {
    /// Builds a new buffer. Only allowed for sized data.
    #[inline]
    pub fn new<'a, I>(device: &Arc<Device>, usage: &Usage, queue_families: I)
                      -> Result<Arc<ImmutableBuffer<T>>, OomError>
        where I: IntoIterator<Item = QueueFamily<'a>>
    {
        unsafe {
            ImmutableBuffer::raw(device, mem::size_of::<T>(), usage, queue_families)
        }
    }
}

impl<T> ImmutableBuffer<[T]> {
    /// Builds a new buffer. Can be used for arrays.
    #[inline]
    pub fn array<'a, I>(device: &Arc<Device>, len: usize, usage: &Usage, queue_families: I)
                      -> Result<Arc<ImmutableBuffer<T>>, OomError>
        where I: IntoIterator<Item = QueueFamily<'a>>
    {
        unsafe {
            ImmutableBuffer::raw(device, len * mem::size_of::<T>(), usage, queue_families)
        }
    }
}

impl<T: ?Sized> ImmutableBuffer<T> {
    /// Builds a new buffer without checking the size.
    ///
    /// # Safety
    ///
    /// You must ensure that the size that you pass is correct for `T`.
    ///
    pub unsafe fn raw<'a, I>(device: &Arc<Device>, size: usize, usage: &Usage, queue_families: I)
                             -> Result<Arc<ImmutableBuffer<T>>, OomError>
        where I: IntoIterator<Item = QueueFamily<'a>>
    {
        let queue_families = queue_families.into_iter().map(|f| f.id())
                                           .collect::<SmallVec<[u32; 4]>>();

        let (buffer, mem_reqs) = {
            let sharing = if queue_families.len() >= 2 {
                Sharing::Concurrent(queue_families.iter().cloned())
            } else {
                Sharing::Exclusive
            };

            try!(UnsafeBuffer::new(device, size, &usage, sharing))
        };

        let mem_ty = {
            let device_local = device.physical_device().memory_types()
                                     .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0)
                                     .filter(|t| t.is_device_local());
            let any = device.physical_device().memory_types()
                            .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0);
            device_local.chain(any).next().unwrap()
        };

        // note: alignment doesn't need to be checked because allocating memory is guaranteed to
        //       fulfill any alignment requirement

        let mem = try!(DeviceMemory::alloc(device, &mem_ty, mem_reqs.size));
        try!(buffer.bind_memory(&mem, 0));

        Ok(Arc::new(ImmutableBuffer {
            inner: buffer,
            memory: mem,
            queue_families: queue_families,
            latest_write_submission: Mutex::new(None),
            started_reading: AtomicBool::new(false),
            marker: PhantomData,
        }))
    }

    /// Returns the device used to create this buffer.
    #[inline]
    pub fn device(&self) -> &Arc<Device> {
        self.inner.device()
    }

    /// Returns the queue families this buffer can be used on.
    // TODO: use a custom iterator
    #[inline]
    pub fn queue_families(&self) -> Vec<QueueFamily> {
        self.queue_families.iter().map(|&num| {
            self.device().physical_device().queue_family_by_id(num).unwrap()
        }).collect()
    }
}

unsafe impl<T: ?Sized> Buffer for ImmutableBuffer<T> where T: 'static + Send + Sync {
    #[inline]
    fn inner_buffer(&self) -> &UnsafeBuffer {
        &self.inner
    }

    #[inline]
    fn blocks(&self, _: Range<usize>) -> Vec<usize> {
        vec![0]
    }

    #[inline]
    fn block_memory_range(&self, _: usize) -> Range<usize> {
        0 .. self.size()
    }

    fn needs_fence(&self, _: bool, _: Range<usize>) -> Option<bool> {
        Some(true)
    }

    #[inline]
    fn host_accesses(&self, _: usize) -> bool {
        false
    }

    unsafe fn gpu_access(&self, ranges: &mut Iterator<Item = AccessRange>,
                         submission: &Arc<Submission>) -> GpuAccessResult
    {
        let queue_id = submission.queue().family().id();
        if self.queue_families.iter().find(|&&id| id == queue_id).is_none() {
            panic!()
        }

        let write = {
            let mut write = false;
            while let Some(range) = ranges.next() {
                if range.write { write = true; break; }
            }
            write
        };

        if write {
            assert!(self.started_reading.load(Ordering::AcqRel) == false);
        }

        let dependency = {
            let mut latest_submission = self.latest_write_submission.lock().unwrap();

            if write {
                mem::replace(&mut *latest_submission, Some(Arc::downgrade(submission)))
            } else {
                latest_submission.clone()
            }
        };
        let dependency = dependency.and_then(|d| d.upgrade());

        if write {
            assert!(self.started_reading.load(Ordering::AcqRel) == false);
        } else {
            self.started_reading.store(true, Ordering::AcqRel);
        }

        GpuAccessResult {
            dependencies: if let Some(dependency) = dependency {
                vec![dependency]
            } else {
                vec![]
            },
            additional_wait_semaphore: None,
            additional_signal_semaphore: None,
        }
    }
}

unsafe impl<T: ?Sized> TypedBuffer for ImmutableBuffer<T> where T: 'static + Send + Sync {
    type Content = T;
}
<commit_msg>Bugfix in ImmutableBuffer::array<commit_after>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Buffer that is written once then read for as long as it is alive.
//!
//! Use this buffer when you have data that you never modify.
//!
//! Only the first ever command buffer that uses this buffer can write to it (for example by
//! copying from another buffer). Any subsequent command buffer **must** only read from the buffer,
//! or a panic will happen.
//!
//! The buffer will be stored in device-local memory if possible
//!

use std::marker::PhantomData;
use std::mem;
use std::ops::Range;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::Weak;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use smallvec::SmallVec;

use buffer::sys::UnsafeBuffer;
use buffer::sys::Usage;
use buffer::traits::AccessRange;
use buffer::traits::Buffer;
use buffer::traits::GpuAccessResult;
use buffer::traits::TypedBuffer;
use command_buffer::Submission;
use device::Device;
use instance::QueueFamily;
use memory::DeviceMemory;
use sync::Sharing;

use OomError;

/// Buffer that is written once then read for as long as it is alive.
pub struct ImmutableBuffer<T: ?Sized> {
    // Inner content.
    inner: UnsafeBuffer,

    memory: DeviceMemory,

    // Queue families allowed to access this buffer.
    queue_families: SmallVec<[u32; 4]>,

    latest_write_submission: Mutex<Option<Weak<Submission>>>,        // TODO: can use `Weak::new()` once it's stabilized

    started_reading: AtomicBool,

    marker: PhantomData<Box<T>>,
}

impl<T> ImmutableBuffer<T> {
    /// Builds a new buffer. Only allowed for sized data.
    #[inline]
    pub fn new<'a, I>(device: &Arc<Device>, usage: &Usage, queue_families: I)
                      -> Result<Arc<ImmutableBuffer<T>>, OomError>
        where I: IntoIterator<Item = QueueFamily<'a>>
    {
        unsafe {
            ImmutableBuffer::raw(device, mem::size_of::<T>(), usage, queue_families)
        }
    }
}

impl<T> ImmutableBuffer<[T]> {
    /// Builds a new buffer. Can be used for arrays.
    #[inline]
    pub fn array<'a, I>(device: &Arc<Device>, len: usize, usage: &Usage, queue_families: I)
                      -> Result<Arc<ImmutableBuffer<[T]>>, OomError>
        where I: IntoIterator<Item = QueueFamily<'a>>
    {
        unsafe {
            ImmutableBuffer::raw(device, len * mem::size_of::<T>(), usage, queue_families)
        }
    }
}

impl<T: ?Sized> ImmutableBuffer<T> {
    /// Builds a new buffer without checking the size.
    ///
    /// # Safety
    ///
    /// You must ensure that the size that you pass is correct for `T`.
    ///
    pub unsafe fn raw<'a, I>(device: &Arc<Device>, size: usize, usage: &Usage, queue_families: I)
                             -> Result<Arc<ImmutableBuffer<T>>, OomError>
        where I: IntoIterator<Item = QueueFamily<'a>>
    {
        let queue_families = queue_families.into_iter().map(|f| f.id())
                                           .collect::<SmallVec<[u32; 4]>>();

        let (buffer, mem_reqs) = {
            let sharing = if queue_families.len() >= 2 {
                Sharing::Concurrent(queue_families.iter().cloned())
            } else {
                Sharing::Exclusive
            };

            try!(UnsafeBuffer::new(device, size, &usage, sharing))
        };

        let mem_ty = {
            let device_local = device.physical_device().memory_types()
                                     .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0)
                                     .filter(|t| t.is_device_local());
            let any = device.physical_device().memory_types()
                            .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0);
            device_local.chain(any).next().unwrap()
        };

        // note: alignment doesn't need to be checked because allocating memory is guaranteed to
        //       fulfill any alignment requirement

        let mem = try!(DeviceMemory::alloc(device, &mem_ty, mem_reqs.size));
        try!(buffer.bind_memory(&mem, 0));

        Ok(Arc::new(ImmutableBuffer {
            inner: buffer,
            memory: mem,
            queue_families: queue_families,
            latest_write_submission: Mutex::new(None),
            started_reading: AtomicBool::new(false),
            marker: PhantomData,
        }))
    }

    /// Returns the device used to create this buffer.
    #[inline]
    pub fn device(&self) -> &Arc<Device> {
        self.inner.device()
    }

    /// Returns the queue families this buffer can be used on.
    // TODO: use a custom iterator
    #[inline]
    pub fn queue_families(&self) -> Vec<QueueFamily> {
        self.queue_families.iter().map(|&num| {
            self.device().physical_device().queue_family_by_id(num).unwrap()
        }).collect()
    }
}

unsafe impl<T: ?Sized> Buffer for ImmutableBuffer<T> where T: 'static + Send + Sync {
    #[inline]
    fn inner_buffer(&self) -> &UnsafeBuffer {
        &self.inner
    }

    #[inline]
    fn blocks(&self, _: Range<usize>) -> Vec<usize> {
        vec![0]
    }

    #[inline]
    fn block_memory_range(&self, _: usize) -> Range<usize> {
        0 .. self.size()
    }

    fn needs_fence(&self, _: bool, _: Range<usize>) -> Option<bool> {
        Some(true)
    }

    #[inline]
    fn host_accesses(&self, _: usize) -> bool {
        false
    }

    unsafe fn gpu_access(&self, ranges: &mut Iterator<Item = AccessRange>,
                         submission: &Arc<Submission>) -> GpuAccessResult
    {
        let queue_id = submission.queue().family().id();
        if self.queue_families.iter().find(|&&id| id == queue_id).is_none() {
            panic!()
        }

        let write = {
            let mut write = false;
            while let Some(range) = ranges.next() {
                if range.write { write = true; break; }
            }
            write
        };

        if write {
            assert!(self.started_reading.load(Ordering::AcqRel) == false);
        }

        let dependency = {
            let mut latest_submission = self.latest_write_submission.lock().unwrap();

            if write {
                mem::replace(&mut *latest_submission, Some(Arc::downgrade(submission)))
            } else {
                latest_submission.clone()
            }
        };
        let dependency = dependency.and_then(|d| d.upgrade());

        if write {
            assert!(self.started_reading.load(Ordering::AcqRel) == false);
        } else {
            self.started_reading.store(true, Ordering::AcqRel);
        }

        GpuAccessResult {
            dependencies: if let Some(dependency) = dependency {
                vec![dependency]
            } else {
                vec![]
            },
            additional_wait_semaphore: None,
            additional_signal_semaphore: None,
        }
    }
}

unsafe impl<T: ?Sized> TypedBuffer for ImmutableBuffer<T> where T: 'static + Send + Sync {
    type Content = T;
}
<|endoftext|>


<commit_before>//! Name resolution algorithm. The end result of the algorithm is an `ItemMap`:
//! a map which maps each module to its scope: the set of items visible in the
//! module. That is, we only resolve imports here, name resolution of item
//! bodies will be done in a separate step.
//!
//! Like Rustc, we use an interactive per-crate algorithm: we start with scopes
//! containing only directly defined items, and then iteratively resolve
//! imports.
//!
//! To make this work nicely in the IDE scenario, we place `InputModuleItems`
//! in between raw syntax and name resolution. `InputModuleItems` are computed
//! using only the module's syntax, and it is all directly defined items plus
//! imports. The plan is to make `InputModuleItems` independent of local
//! modifications (that is, typing inside a function should not change IMIs),
//! so that the results of name resolution can be preserved unless the module
//! structure itself is modified.
pub(crate) mod lower;

use std::{time, sync::Arc};

use ra_arena::map::ArenaMap;
use test_utils::tested_by;
use rustc_hash::{FxHashMap, FxHashSet};

use crate::{
    Module, ModuleDef,
    Path, PathKind, PersistentHirDatabase,
    Crate, Name,
    module_tree::{ModuleId, ModuleTree},
    nameres::lower::{ImportId, LoweredModule, ImportData},
};

/// `ItemMap` is the result of module name resolution. It contains, for each
/// module, the set of visible items.
#[derive(Default, Debug, PartialEq, Eq)]
pub struct ItemMap {
    per_module: ArenaMap<ModuleId, ModuleScope>,
}

impl std::ops::Index<ModuleId> for ItemMap {
    type Output = ModuleScope;
    fn index(&self, id: ModuleId) -> &ModuleScope {
        &self.per_module[id]
    }
}

#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct ModuleScope {
    pub(crate) items: FxHashMap<Name, Resolution>,
}

impl ModuleScope {
    pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a {
        self.items.iter()
    }
    pub fn get(&self, name: &Name) -> Option<&Resolution> {
        self.items.get(name)
    }
}

/// `Resolution` is basically `DefId` atm, but it should account for stuff like
/// multiple namespaces, ambiguity and errors.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Resolution {
    /// None for unresolved
    pub def: PerNs<ModuleDef>,
    /// ident by which this is imported into local scope.
    pub import: Option<ImportId>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Namespace {
    Types,
    Values,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct PerNs<T> {
    pub types: Option<T>,
    pub values: Option<T>,
}

impl<T> Default for PerNs<T> {
    fn default() -> Self {
        PerNs {
            types: None,
            values: None,
        }
    }
}

impl<T> PerNs<T> {
    pub fn none() -> PerNs<T> {
        PerNs {
            types: None,
            values: None,
        }
    }

    pub fn values(t: T) -> PerNs<T> {
        PerNs {
            types: None,
            values: Some(t),
        }
    }

    pub fn types(t: T) -> PerNs<T> {
        PerNs {
            types: Some(t),
            values: None,
        }
    }

    pub fn both(types: T, values: T) -> PerNs<T> {
        PerNs {
            types: Some(types),
            values: Some(values),
        }
    }

    pub fn is_none(&self) -> bool {
        self.types.is_none() && self.values.is_none()
    }

    pub fn is_both(&self) -> bool {
        self.types.is_some() && self.values.is_some()
    }

    pub fn take(self, namespace: Namespace) -> Option<T> {
        match namespace {
            Namespace::Types => self.types,
            Namespace::Values => self.values,
        }
    }

    pub fn take_types(self) -> Option<T> {
        self.take(Namespace::Types)
    }

    pub fn take_values(self) -> Option<T> {
        self.take(Namespace::Values)
    }

    pub fn get(&self, namespace: Namespace) -> Option<&T> {
        self.as_ref().take(namespace)
    }

    pub fn as_ref(&self) -> PerNs<&T> {
        PerNs {
            types: self.types.as_ref(),
            values: self.values.as_ref(),
        }
    }

    pub fn combine(self, other: PerNs<T>) -> PerNs<T> {
        PerNs {
            types: self.types.or(other.types),
            values: self.values.or(other.values),
        }
    }

    pub fn and_then<U>(self, f: impl Fn(T) -> Option<U>) -> PerNs<U> {
        PerNs {
            types: self.types.and_then(&f),
            values: self.values.and_then(&f),
        }
    }

    pub fn map<U>(self, f: impl Fn(T) -> U) -> PerNs<U> {
        PerNs {
            types: self.types.map(&f),
            values: self.values.map(&f),
        }
    }
}

struct Resolver<'a, DB> {
    db: &'a DB,
    input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
    krate: Crate,
    module_tree: Arc<ModuleTree>,
    processed_imports: FxHashSet<(ModuleId, ImportId)>,
    result: ItemMap,
}

impl<'a, DB> Resolver<'a, DB>
where
    DB: PersistentHirDatabase,
{
    fn new(
        db: &'a DB,
        input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
        krate: Crate,
    ) -> Resolver<'a, DB> {
        let module_tree = db.module_tree(krate);
        Resolver {
            db,
            input,
            krate,
            module_tree,
            processed_imports: FxHashSet::default(),
            result: ItemMap::default(),
        }
    }

    pub(crate) fn resolve(mut self) -> ItemMap {
        for (&module_id, items) in self.input.iter() {
            self.populate_module(module_id, Arc::clone(items));
        }

        let mut iter = 0;
        loop {
            iter += 1;
            if iter > 1000 {
                panic!("failed to reach fixedpoint after 1000 iters")
            }
            let processed_imports_count = self.processed_imports.len();
            for &module_id in self.input.keys() {
                self.db.check_canceled();
                self.resolve_imports(module_id);
            }
            if processed_imports_count == self.processed_imports.len() {
                // no new imports resolved
                break;
            }
        }
        self.result
    }

    fn populate_module(&mut self, module_id: ModuleId, input: Arc<LoweredModule>) {
        let mut module_items = ModuleScope::default();

        // Populate extern crates prelude
        {
            let root_id = module_id.crate_root(&self.module_tree);
            let file_id = root_id.file_id(&self.module_tree);
            let crate_graph = self.db.crate_graph();
            if let Some(crate_id) = crate_graph.crate_id_for_crate_root(file_id.as_original_file())
            {
                let krate = Crate { crate_id };
                for dep in krate.dependencies(self.db) {
                    if let Some(module) = dep.krate.root_module(self.db) {
                        let def = module.into();
                        self.add_module_item(
                            &mut module_items,
                            dep.name.clone(),
                            PerNs::types(def),
                        );
                    }
                }
            };
        }
        for (import_id, import_data) in input.imports.iter() {
            if let Some(segment) = import_data.path.segments.iter().last() {
                if !import_data.is_glob {
                    module_items.items.insert(
                        segment.name.clone(),
                        Resolution {
                            def: PerNs::none(),
                            import: Some(import_id),
                        },
                    );
                }
            }
        }
        // Populate explicitly declared items, except modules
        for (name, &def) in input.declarations.iter() {
            let resolution = Resolution { def, import: None };
            module_items.items.insert(name.clone(), resolution);
        }

        // Populate modules
        for (name, module_id) in module_id.children(&self.module_tree) {
            let module = Module {
                module_id,
                krate: self.krate,
            };
            self.add_module_item(&mut module_items, name, PerNs::types(module.into()));
        }

        self.result.per_module.insert(module_id, module_items);
    }

    fn add_module_item(&self, module_items: &mut ModuleScope, name: Name, def: PerNs<ModuleDef>) {
        let resolution = Resolution { def, import: None };
        module_items.items.insert(name, resolution);
    }

    fn resolve_imports(&mut self, module_id: ModuleId) {
        for (import_id, import_data) in self.input[&module_id].imports.iter() {
            if self.processed_imports.contains(&(module_id, import_id)) {
                // already done
                continue;
            }
            if self.resolve_import(module_id, import_id, import_data) == ReachedFixedPoint::Yes {
                log::debug!("import {:?} resolved (or definite error)", import_id);
                self.processed_imports.insert((module_id, import_id));
            }
        }
    }

    fn resolve_import(
        &mut self,
        module_id: ModuleId,
        import_id: ImportId,
        import: &ImportData,
    ) -> ReachedFixedPoint {
        log::debug!("resolving import: {:?}", import);
        if import.is_glob {
            return ReachedFixedPoint::Yes;
        };
        let original_module = Module {
            krate: self.krate,
            module_id,
        };
        let (def, reached_fixedpoint) =
            self.result
                .resolve_path_fp(self.db, original_module, &import.path);

        if reached_fixedpoint == ReachedFixedPoint::Yes {
            let last_segment = import.path.segments.last().unwrap();
            self.update(module_id, |items| {
                let res = Resolution {
                    def,
                    import: Some(import_id),
                };
                items.items.insert(last_segment.name.clone(), res);
            });
            log::debug!(
                "resolved import {:?} ({:?}) cross-source root to {:?}",
                last_segment.name,
                import,
                def,
            );
        }
        reached_fixedpoint
    }

    fn update(&mut self, module_id: ModuleId, f: impl FnOnce(&mut ModuleScope)) {
        let module_items = self.result.per_module.get_mut(module_id).unwrap();
        f(module_items)
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ReachedFixedPoint {
    Yes,
    No,
}

impl ItemMap {
    pub(crate) fn item_map_query(db: &impl PersistentHirDatabase, krate: Crate) -> Arc<ItemMap> {
        let start = time::Instant::now();
        let module_tree = db.module_tree(krate);
        let input = module_tree
            .modules()
            .map(|module_id| {
                (
                    module_id,
                    db.lower_module_module(Module { krate, module_id }),
                )
            })
            .collect::<FxHashMap<_, _>>();

        let resolver = Resolver::new(db, &input, krate);
        let res = resolver.resolve();
        let elapsed = start.elapsed();
        log::info!("item_map: {:?}", elapsed);
        Arc::new(res)
    }

    pub(crate) fn resolve_path(
        &self,
        db: &impl PersistentHirDatabase,
        original_module: Module,
        path: &Path,
    ) -> PerNs<ModuleDef> {
        self.resolve_path_fp(db, original_module, path).0
    }

    // Returns Yes if we are sure that additions to `ItemMap` wouldn't change
    // the result.
    fn resolve_path_fp(
        &self,
        db: &impl PersistentHirDatabase,
        original_module: Module,
        path: &Path,
    ) -> (PerNs<ModuleDef>, ReachedFixedPoint) {
        let mut curr_per_ns: PerNs<ModuleDef> = PerNs::types(match path.kind {
            PathKind::Crate => original_module.crate_root(db).into(),
            PathKind::Self_ | PathKind::Plain => original_module.into(),
            PathKind::Super => {
                if let Some(p) = original_module.parent(db) {
                    p.into()
                } else {
                    log::debug!("super path in root module");
                    return (PerNs::none(), ReachedFixedPoint::Yes);
                }
            }
            PathKind::Abs => {
                // TODO: absolute use is not supported
                return (PerNs::none(), ReachedFixedPoint::Yes);
            }
        });

        for (i, segment) in path.segments.iter().enumerate() {
            let curr = match curr_per_ns.as_ref().take_types() {
                Some(r) => r,
                None => {
                    // we still have path segments left, but the path so far
                    // didn't resolve in the types namespace => no resolution
                    // (don't break here because curr_per_ns might contain
                    // something in the value namespace, and it would be wrong
                    // to return that)
                    return (PerNs::none(), ReachedFixedPoint::No);
                }
            };
            // resolve segment in curr

            curr_per_ns = match curr {
                ModuleDef::Module(module) => {
                    if module.krate != original_module.krate {
                        let path = Path {
                            segments: path.segments[i..].iter().cloned().collect(),
                            kind: PathKind::Self_,
                        };
                        log::debug!("resolving {:?} in other crate", path);
                        let item_map = db.item_map(module.krate);
                        let def = item_map.resolve_path(db, *module, &path);
                        return (def, ReachedFixedPoint::Yes);
                    }

                    match self[module.module_id].items.get(&segment.name) {
                        Some(res) if !res.def.is_none() => res.def,
                        _ => {
                            log::debug!("path segment {:?} not found", segment.name);
                            return (PerNs::none(), ReachedFixedPoint::No);
                        }
                    }
                }
                ModuleDef::Enum(e) => {
                    // enum variant
                    tested_by!(item_map_enum_importing);
                    match e.variant(db, &segment.name) {
                        Some(variant) => PerNs::both(variant.into(), (*e).into()),
                        None => PerNs::none(),
                    }
                }
                _ => {
                    // could be an inherent method call in UFCS form
                    // (`Struct::method`), or some other kind of associated
                    // item... Which we currently don't handle (TODO)
                    log::debug!(
                        "path segment {:?} resolved to non-module {:?}, but is not last",
                        segment.name,
                        curr,
                    );
                    return (PerNs::none(), ReachedFixedPoint::Yes);
                }
            };
        }
        (curr_per_ns, ReachedFixedPoint::Yes)
    }
}

#[cfg(test)]
mod tests;
<commit_msg>Use aliases in import resolution<commit_after>//! Name resolution algorithm. The end result of the algorithm is an `ItemMap`:
//! a map which maps each module to its scope: the set of items visible in the
//! module. That is, we only resolve imports here, name resolution of item
//! bodies will be done in a separate step.
//!
//! Like Rustc, we use an interactive per-crate algorithm: we start with scopes
//! containing only directly defined items, and then iteratively resolve
//! imports.
//!
//! To make this work nicely in the IDE scenario, we place `InputModuleItems`
//! in between raw syntax and name resolution. `InputModuleItems` are computed
//! using only the module's syntax, and it is all directly defined items plus
//! imports. The plan is to make `InputModuleItems` independent of local
//! modifications (that is, typing inside a function should not change IMIs),
//! so that the results of name resolution can be preserved unless the module
//! structure itself is modified.
pub(crate) mod lower;

use std::{time, sync::Arc};

use ra_arena::map::ArenaMap;
use test_utils::tested_by;
use rustc_hash::{FxHashMap, FxHashSet};

use crate::{
    Module, ModuleDef,
    Path, PathKind, PersistentHirDatabase,
    Crate, Name,
    module_tree::{ModuleId, ModuleTree},
    nameres::lower::{ImportId, LoweredModule, ImportData},
};

/// `ItemMap` is the result of module name resolution. It contains, for each
/// module, the set of visible items.
#[derive(Default, Debug, PartialEq, Eq)]
pub struct ItemMap {
    per_module: ArenaMap<ModuleId, ModuleScope>,
}

impl std::ops::Index<ModuleId> for ItemMap {
    type Output = ModuleScope;
    fn index(&self, id: ModuleId) -> &ModuleScope {
        &self.per_module[id]
    }
}

#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct ModuleScope {
    pub(crate) items: FxHashMap<Name, Resolution>,
}

impl ModuleScope {
    pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a {
        self.items.iter()
    }
    pub fn get(&self, name: &Name) -> Option<&Resolution> {
        self.items.get(name)
    }
}

/// `Resolution` is basically `DefId` atm, but it should account for stuff like
/// multiple namespaces, ambiguity and errors.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Resolution {
    /// None for unresolved
    pub def: PerNs<ModuleDef>,
    /// ident by which this is imported into local scope.
    pub import: Option<ImportId>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Namespace {
    Types,
    Values,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct PerNs<T> {
    pub types: Option<T>,
    pub values: Option<T>,
}

impl<T> Default for PerNs<T> {
    fn default() -> Self {
        PerNs {
            types: None,
            values: None,
        }
    }
}

impl<T> PerNs<T> {
    pub fn none() -> PerNs<T> {
        PerNs {
            types: None,
            values: None,
        }
    }

    pub fn values(t: T) -> PerNs<T> {
        PerNs {
            types: None,
            values: Some(t),
        }
    }

    pub fn types(t: T) -> PerNs<T> {
        PerNs {
            types: Some(t),
            values: None,
        }
    }

    pub fn both(types: T, values: T) -> PerNs<T> {
        PerNs {
            types: Some(types),
            values: Some(values),
        }
    }

    pub fn is_none(&self) -> bool {
        self.types.is_none() && self.values.is_none()
    }

    pub fn is_both(&self) -> bool {
        self.types.is_some() && self.values.is_some()
    }

    pub fn take(self, namespace: Namespace) -> Option<T> {
        match namespace {
            Namespace::Types => self.types,
            Namespace::Values => self.values,
        }
    }

    pub fn take_types(self) -> Option<T> {
        self.take(Namespace::Types)
    }

    pub fn take_values(self) -> Option<T> {
        self.take(Namespace::Values)
    }

    pub fn get(&self, namespace: Namespace) -> Option<&T> {
        self.as_ref().take(namespace)
    }

    pub fn as_ref(&self) -> PerNs<&T> {
        PerNs {
            types: self.types.as_ref(),
            values: self.values.as_ref(),
        }
    }

    pub fn combine(self, other: PerNs<T>) -> PerNs<T> {
        PerNs {
            types: self.types.or(other.types),
            values: self.values.or(other.values),
        }
    }

    pub fn and_then<U>(self, f: impl Fn(T) -> Option<U>) -> PerNs<U> {
        PerNs {
            types: self.types.and_then(&f),
            values: self.values.and_then(&f),
        }
    }

    pub fn map<U>(self, f: impl Fn(T) -> U) -> PerNs<U> {
        PerNs {
            types: self.types.map(&f),
            values: self.values.map(&f),
        }
    }
}

struct Resolver<'a, DB> {
    db: &'a DB,
    input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
    krate: Crate,
    module_tree: Arc<ModuleTree>,
    processed_imports: FxHashSet<(ModuleId, ImportId)>,
    result: ItemMap,
}

impl<'a, DB> Resolver<'a, DB>
where
    DB: PersistentHirDatabase,
{
    fn new(
        db: &'a DB,
        input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
        krate: Crate,
    ) -> Resolver<'a, DB> {
        let module_tree = db.module_tree(krate);
        Resolver {
            db,
            input,
            krate,
            module_tree,
            processed_imports: FxHashSet::default(),
            result: ItemMap::default(),
        }
    }

    pub(crate) fn resolve(mut self) -> ItemMap {
        for (&module_id, items) in self.input.iter() {
            self.populate_module(module_id, Arc::clone(items));
        }

        let mut iter = 0;
        loop {
            iter += 1;
            if iter > 1000 {
                panic!("failed to reach fixedpoint after 1000 iters")
            }
            let processed_imports_count = self.processed_imports.len();
            for &module_id in self.input.keys() {
                self.db.check_canceled();
                self.resolve_imports(module_id);
            }
            if processed_imports_count == self.processed_imports.len() {
                // no new imports resolved
                break;
            }
        }
        self.result
    }

    fn populate_module(&mut self, module_id: ModuleId, input: Arc<LoweredModule>) {
        let mut module_items = ModuleScope::default();

        // Populate extern crates prelude
        {
            let root_id = module_id.crate_root(&self.module_tree);
            let file_id = root_id.file_id(&self.module_tree);
            let crate_graph = self.db.crate_graph();
            if let Some(crate_id) = crate_graph.crate_id_for_crate_root(file_id.as_original_file())
            {
                let krate = Crate { crate_id };
                for dep in krate.dependencies(self.db) {
                    if let Some(module) = dep.krate.root_module(self.db) {
                        let def = module.into();
                        self.add_module_item(
                            &mut module_items,
                            dep.name.clone(),
                            PerNs::types(def),
                        );
                    }
                }
            };
        }
        for (import_id, import_data) in input.imports.iter() {
            if let Some(last_segment) = import_data.path.segments.iter().last() {
                if !import_data.is_glob {
                    let name = import_data
                        .alias
                        .clone()
                        .unwrap_or_else(|| last_segment.name.clone());
                    module_items.items.insert(
                        name,
                        Resolution {
                            def: PerNs::none(),
                            import: Some(import_id),
                        },
                    );
                }
            }
        }
        // Populate explicitly declared items, except modules
        for (name, &def) in input.declarations.iter() {
            let resolution = Resolution { def, import: None };
            module_items.items.insert(name.clone(), resolution);
        }

        // Populate modules
        for (name, module_id) in module_id.children(&self.module_tree) {
            let module = Module {
                module_id,
                krate: self.krate,
            };
            self.add_module_item(&mut module_items, name, PerNs::types(module.into()));
        }

        self.result.per_module.insert(module_id, module_items);
    }

    fn add_module_item(&self, module_items: &mut ModuleScope, name: Name, def: PerNs<ModuleDef>) {
        let resolution = Resolution { def, import: None };
        module_items.items.insert(name, resolution);
    }

    fn resolve_imports(&mut self, module_id: ModuleId) {
        for (import_id, import_data) in self.input[&module_id].imports.iter() {
            if self.processed_imports.contains(&(module_id, import_id)) {
                // already done
                continue;
            }
            if self.resolve_import(module_id, import_id, import_data) == ReachedFixedPoint::Yes {
                log::debug!("import {:?} resolved (or definite error)", import_id);
                self.processed_imports.insert((module_id, import_id));
            }
        }
    }

    fn resolve_import(
        &mut self,
        module_id: ModuleId,
        import_id: ImportId,
        import: &ImportData,
    ) -> ReachedFixedPoint {
        log::debug!("resolving import: {:?}", import);
        if import.is_glob {
            return ReachedFixedPoint::Yes;
        };
        let original_module = Module {
            krate: self.krate,
            module_id,
        };
        let (def, reached_fixedpoint) =
            self.result
                .resolve_path_fp(self.db, original_module, &import.path);

        if reached_fixedpoint == ReachedFixedPoint::Yes {
            let last_segment = import.path.segments.last().unwrap();
            let name = import
                .alias
                .clone()
                .unwrap_or_else(|| last_segment.name.clone());
            log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def,);
            self.update(module_id, |items| {
                let res = Resolution {
                    def,
                    import: Some(import_id),
                };
                items.items.insert(name, res);
            });
        }
        reached_fixedpoint
    }

    fn update(&mut self, module_id: ModuleId, f: impl FnOnce(&mut ModuleScope)) {
        let module_items = self.result.per_module.get_mut(module_id).unwrap();
        f(module_items)
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ReachedFixedPoint {
    Yes,
    No,
}

impl ItemMap {
    pub(crate) fn item_map_query(db: &impl PersistentHirDatabase, krate: Crate) -> Arc<ItemMap> {
        let start = time::Instant::now();
        let module_tree = db.module_tree(krate);
        let input = module_tree
            .modules()
            .map(|module_id| {
                (
                    module_id,
                    db.lower_module_module(Module { krate, module_id }),
                )
            })
            .collect::<FxHashMap<_, _>>();

        let resolver = Resolver::new(db, &input, krate);
        let res = resolver.resolve();
        let elapsed = start.elapsed();
        log::info!("item_map: {:?}", elapsed);
        Arc::new(res)
    }

    pub(crate) fn resolve_path(
        &self,
        db: &impl PersistentHirDatabase,
        original_module: Module,
        path: &Path,
    ) -> PerNs<ModuleDef> {
        self.resolve_path_fp(db, original_module, path).0
    }

    // Returns Yes if we are sure that additions to `ItemMap` wouldn't change
    // the result.
    fn resolve_path_fp(
        &self,
        db: &impl PersistentHirDatabase,
        original_module: Module,
        path: &Path,
    ) -> (PerNs<ModuleDef>, ReachedFixedPoint) {
        let mut curr_per_ns: PerNs<ModuleDef> = PerNs::types(match path.kind {
            PathKind::Crate => original_module.crate_root(db).into(),
            PathKind::Self_ | PathKind::Plain => original_module.into(),
            PathKind::Super => {
                if let Some(p) = original_module.parent(db) {
                    p.into()
                } else {
                    log::debug!("super path in root module");
                    return (PerNs::none(), ReachedFixedPoint::Yes);
                }
            }
            PathKind::Abs => {
                // TODO: absolute use is not supported
                return (PerNs::none(), ReachedFixedPoint::Yes);
            }
        });

        for (i, segment) in path.segments.iter().enumerate() {
            let curr = match curr_per_ns.as_ref().take_types() {
                Some(r) => r,
                None => {
                    // we still have path segments left, but the path so far
                    // didn't resolve in the types namespace => no resolution
                    // (don't break here because curr_per_ns might contain
                    // something in the value namespace, and it would be wrong
                    // to return that)
                    return (PerNs::none(), ReachedFixedPoint::No);
                }
            };
            // resolve segment in curr

            curr_per_ns = match curr {
                ModuleDef::Module(module) => {
                    if module.krate != original_module.krate {
                        let path = Path {
                            segments: path.segments[i..].iter().cloned().collect(),
                            kind: PathKind::Self_,
                        };
                        log::debug!("resolving {:?} in other crate", path);
                        let item_map = db.item_map(module.krate);
                        let def = item_map.resolve_path(db, *module, &path);
                        return (def, ReachedFixedPoint::Yes);
                    }

                    match self[module.module_id].items.get(&segment.name) {
                        Some(res) if !res.def.is_none() => res.def,
                        _ => {
                            log::debug!("path segment {:?} not found", segment.name);
                            return (PerNs::none(), ReachedFixedPoint::No);
                        }
                    }
                }
                ModuleDef::Enum(e) => {
                    // enum variant
                    tested_by!(item_map_enum_importing);
                    match e.variant(db, &segment.name) {
                        Some(variant) => PerNs::both(variant.into(), (*e).into()),
                        None => PerNs::none(),
                    }
                }
                _ => {
                    // could be an inherent method call in UFCS form
                    // (`Struct::method`), or some other kind of associated
                    // item... Which we currently don't handle (TODO)
                    log::debug!(
                        "path segment {:?} resolved to non-module {:?}, but is not last",
                        segment.name,
                        curr,
                    );
                    return (PerNs::none(), ReachedFixedPoint::Yes);
                }
            };
        }
        (curr_per_ns, ReachedFixedPoint::Yes)
    }
}

#[cfg(test)]
mod tests;
<|endoftext|>


<commit_before>use super::syscall::sys_debug;

/// Debug new line to console
#[macro_export]
macro_rules! debugln {
    ($($arg:tt)*) => ({
        debug!($($arg)*);
        debug!("\n");
    });
}

/// Debug to console
#[macro_export]
macro_rules! debug {
    ($($arg:tt)*) => ({
        $crate::debug::debug(&format!($($arg)*));
    });
}

pub fn debug(msg: &str) {
    unsafe {
        sys_debug(msg.as_ptr(), msg.len());
    }
}
<commit_msg>Remove old debug impl<commit_after><|endoftext|>