<commit_before>use fmt;
use io;
use net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr, ToSocketAddrs};
use time::Duration;
use sys::{unsupported, Void, sgx_ineffective, AsInner, FromInner, IntoInner, TryIntoInner};
use sys::fd::FileDesc;
use convert::TryFrom;
use error;
use sync::Arc;

use super::abi::usercalls;

const DEFAULT_FAKE_TTL: u32 = 64;

#[derive(Debug, Clone)]
pub struct Socket {
    inner: Arc<FileDesc>,
    local_addr: Option<String>,
}

impl Socket {
    fn new(fd: usercalls::raw::Fd, local_addr: String) -> Socket {
        Socket { inner: Arc::new(FileDesc::new(fd)), local_addr: Some(local_addr) }
    }
}

impl AsInner<FileDesc> for Socket {
    fn as_inner(&self) -> &FileDesc { &self.inner }
}

impl TryIntoInner<FileDesc> for Socket {
    fn try_into_inner(self) -> Result<FileDesc, Socket> {
        let Socket { inner, local_addr } = self;
        Arc::try_unwrap(inner).map_err(|inner| Socket { inner, local_addr } )
    }
}

impl FromInner<FileDesc> for Socket {
    fn from_inner(inner: FileDesc) -> Socket {
        Socket { inner: Arc::new(inner), local_addr: None }
    }
}

#[derive(Debug, Clone)]
pub struct TcpStream {
    inner: Socket,
    peer_addr: Option<String>,
}

fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
    match result {
        Ok(saddr) => Ok(saddr.to_string()),
        // need to downcast twice because io::Error::into_inner doesn't return the original
        // value if the conversion fails
        Err(e) => if e.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()).is_some() {
            Ok(e.into_inner().unwrap().downcast::<NonIpSockAddr>().unwrap().host)
        } else {
            Err(e)
        }
    }
}

fn addr_to_sockaddr(addr: &Option<String>) -> io::Result<SocketAddr> {
    addr.as_ref()
        .ok_or(io::ErrorKind::AddrNotAvailable)?
        .to_socket_addrs()
        // unwrap OK: if an iterator is returned, we're guaranteed to get exactly one entry
        .map(|mut it| it.next().unwrap())
}

impl TcpStream {
    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
        let addr = io_err_to_addr(addr)?;
        let (fd, local_addr, peer_addr) = usercalls::connect_stream(&addr)?;
        Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) })
    }

    pub fn connect_timeout(addr: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
        Self::connect(Ok(addr)) // FIXME: ignoring timeout
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        sgx_ineffective(None)
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        sgx_ineffective(None)
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        Ok(0)
    }

    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.inner.read(buf)
    }

    pub fn read_vectored(&self, buf: &mut [IoVecMut<'_>]) -> io::Result<usize> {
        let buf = match buf.get(0) {
            Some(buf) => buf,
            None => return Ok(0),
        };
        self.read(buf)
    }

    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
        self.inner.inner.write(buf)
    }

    pub fn write_vectored(&self, buf: &[IoVec<'_>]) -> io::Result<usize> {
        let buf = match buf.get(0) {
            Some(buf) => buf,
            None => return Ok(0),
        };
        self.read(buf)
    }

    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        addr_to_sockaddr(&self.peer_addr)
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        addr_to_sockaddr(&self.inner.local_addr)
    }

    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn duplicate(&self) -> io::Result<TcpStream> {
        Ok(self.clone())
    }

    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn nodelay(&self) -> io::Result<bool> {
        sgx_ineffective(false)
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn ttl(&self) -> io::Result<u32> {
        sgx_ineffective(DEFAULT_FAKE_TTL)
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        Ok(None)
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        sgx_ineffective(())
    }
}

impl AsInner<Socket> for TcpStream {
    fn as_inner(&self) -> &Socket { &self.inner }
}

// `Inner` includes `peer_addr` so that a `TcpStream` maybe correctly
// reconstructed if `Socket::try_into_inner` fails.
impl IntoInner<(Socket, Option<String>)> for TcpStream {
    fn into_inner(self) -> (Socket, Option<String>) {
        (self.inner, self.peer_addr)
    }
}

impl FromInner<(Socket, Option<String>)> for TcpStream {
    fn from_inner((inner, peer_addr): (Socket, Option<String>)) -> TcpStream {
        TcpStream { inner, peer_addr }
    }
}

#[derive(Debug, Clone)]
pub struct TcpListener {
    inner: Socket,
}

impl TcpListener {
    pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
        let addr = io_err_to_addr(addr)?;
        let (fd, local_addr) = usercalls::bind_stream(&addr)?;
        Ok(TcpListener { inner: Socket::new(fd, local_addr) })
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        addr_to_sockaddr(&self.inner.local_addr)
    }

    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
        let (fd, local_addr, peer_addr) = usercalls::accept_stream(self.inner.inner.raw())?;
        let peer_addr = Some(peer_addr);
        let ret_peer = addr_to_sockaddr(&peer_addr).unwrap_or_else(|_| ([0; 4], 0).into());
        Ok((TcpStream { inner: Socket::new(fd, local_addr), peer_addr }, ret_peer))
    }

    pub fn duplicate(&self) -> io::Result<TcpListener> {
        Ok(self.clone())
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn ttl(&self) -> io::Result<u32> {
        sgx_ineffective(DEFAULT_FAKE_TTL)
    }

    pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn only_v6(&self) -> io::Result<bool> {
        sgx_ineffective(false)
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        Ok(None)
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        sgx_ineffective(())
    }
}

impl AsInner<Socket> for TcpListener {
    fn as_inner(&self) -> &Socket { &self.inner }
}

impl IntoInner<Socket> for TcpListener {
    fn into_inner(self) -> Socket {
        self.inner
    }
}

impl FromInner<Socket> for TcpListener {
    fn from_inner(inner: Socket) -> TcpListener {
        TcpListener { inner }
    }
}

pub struct UdpSocket(Void);

impl UdpSocket {
    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
        unsupported()
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<UdpSocket> {
        match self.0 {}
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn broadcast(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
                         -> io::Result<()> {
        match self.0 {}
    }

    pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
                         -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
                          -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
                          -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn send(&self, _: &[u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for UdpSocket {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

#[derive(Debug)]
pub struct NonIpSockAddr {
    host: String
}

impl error::Error for NonIpSockAddr {
    fn description(&self) -> &str {
        "Failed to convert address to SocketAddr"
    }
}

impl fmt::Display for NonIpSockAddr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Failed to convert address to SocketAddr: {}", self.host)
    }
}

pub struct LookupHost(Void);

impl LookupHost {
    fn new(host: String) -> io::Result<LookupHost> {
        Err(io::Error::new(io::ErrorKind::Other, NonIpSockAddr { host }))
    }

    pub fn port(&self) -> u16 {
        match self.0 {}
    }
}

impl Iterator for LookupHost {
    type Item = SocketAddr;
    fn next(&mut self) -> Option<SocketAddr> {
        match self.0 {}
    }
}

impl<'a> TryFrom<&'a str> for LookupHost {
    type Error = io::Error;

    fn try_from(v: &'a str) -> io::Result<LookupHost> {
        LookupHost::new(v.to_owned())
    }
}

impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
    type Error = io::Error;

    fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
        LookupHost::new(format!("{}:{}", host, port))
    }
}

#[allow(bad_style)]
pub mod netc {
    pub const AF_INET: u8 = 0;
    pub const AF_INET6: u8 = 1;
    pub type sa_family_t = u8;

    #[derive(Copy, Clone)]
    pub struct in_addr {
        pub s_addr: u32,
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr_in {
        pub sin_family: sa_family_t,
        pub sin_port: u16,
        pub sin_addr: in_addr,
    }

    #[derive(Copy, Clone)]
    pub struct in6_addr {
        pub s6_addr: [u8; 16],
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr_in6 {
        pub sin6_family: sa_family_t,
        pub sin6_port: u16,
        pub sin6_addr: in6_addr,
        pub sin6_flowinfo: u32,
        pub sin6_scope_id: u32,
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr {
    }

    pub type socklen_t = usize;
}
<commit_msg>Fix sgx<commit_after>use fmt;
use io::{self, IoVec, IoVecMut};
use net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr, ToSocketAddrs};
use time::Duration;
use sys::{unsupported, Void, sgx_ineffective, AsInner, FromInner, IntoInner, TryIntoInner};
use sys::fd::FileDesc;
use convert::TryFrom;
use error;
use sync::Arc;

use super::abi::usercalls;

const DEFAULT_FAKE_TTL: u32 = 64;

#[derive(Debug, Clone)]
pub struct Socket {
    inner: Arc<FileDesc>,
    local_addr: Option<String>,
}

impl Socket {
    fn new(fd: usercalls::raw::Fd, local_addr: String) -> Socket {
        Socket { inner: Arc::new(FileDesc::new(fd)), local_addr: Some(local_addr) }
    }
}

impl AsInner<FileDesc> for Socket {
    fn as_inner(&self) -> &FileDesc { &self.inner }
}

impl TryIntoInner<FileDesc> for Socket {
    fn try_into_inner(self) -> Result<FileDesc, Socket> {
        let Socket { inner, local_addr } = self;
        Arc::try_unwrap(inner).map_err(|inner| Socket { inner, local_addr } )
    }
}

impl FromInner<FileDesc> for Socket {
    fn from_inner(inner: FileDesc) -> Socket {
        Socket { inner: Arc::new(inner), local_addr: None }
    }
}

#[derive(Debug, Clone)]
pub struct TcpStream {
    inner: Socket,
    peer_addr: Option<String>,
}

fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
    match result {
        Ok(saddr) => Ok(saddr.to_string()),
        // need to downcast twice because io::Error::into_inner doesn't return the original
        // value if the conversion fails
        Err(e) => if e.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()).is_some() {
            Ok(e.into_inner().unwrap().downcast::<NonIpSockAddr>().unwrap().host)
        } else {
            Err(e)
        }
    }
}

fn addr_to_sockaddr(addr: &Option<String>) -> io::Result<SocketAddr> {
    addr.as_ref()
        .ok_or(io::ErrorKind::AddrNotAvailable)?
        .to_socket_addrs()
        // unwrap OK: if an iterator is returned, we're guaranteed to get exactly one entry
        .map(|mut it| it.next().unwrap())
}

impl TcpStream {
    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
        let addr = io_err_to_addr(addr)?;
        let (fd, local_addr, peer_addr) = usercalls::connect_stream(&addr)?;
        Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) })
    }

    pub fn connect_timeout(addr: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
        Self::connect(Ok(addr)) // FIXME: ignoring timeout
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        sgx_ineffective(None)
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        sgx_ineffective(None)
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        Ok(0)
    }

    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.inner.read(buf)
    }

    pub fn read_vectored(&self, buf: &mut [IoVecMut<'_>]) -> io::Result<usize> {
        let buf = match buf.get_mut(0) {
            Some(buf) => buf,
            None => return Ok(0),
        };
        self.read(buf)
    }

    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
        self.inner.inner.write(buf)
    }

    pub fn write_vectored(&self, buf: &[IoVec<'_>]) -> io::Result<usize> {
        let buf = match buf.get(0) {
            Some(buf) => buf,
            None => return Ok(0),
        };
        self.write(buf)
    }

    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        addr_to_sockaddr(&self.peer_addr)
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        addr_to_sockaddr(&self.inner.local_addr)
    }

    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn duplicate(&self) -> io::Result<TcpStream> {
        Ok(self.clone())
    }

    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn nodelay(&self) -> io::Result<bool> {
        sgx_ineffective(false)
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn ttl(&self) -> io::Result<u32> {
        sgx_ineffective(DEFAULT_FAKE_TTL)
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        Ok(None)
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        sgx_ineffective(())
    }
}

impl AsInner<Socket> for TcpStream {
    fn as_inner(&self) -> &Socket { &self.inner }
}

// `Inner` includes `peer_addr` so that a `TcpStream` maybe correctly
// reconstructed if `Socket::try_into_inner` fails.
impl IntoInner<(Socket, Option<String>)> for TcpStream {
    fn into_inner(self) -> (Socket, Option<String>) {
        (self.inner, self.peer_addr)
    }
}

impl FromInner<(Socket, Option<String>)> for TcpStream {
    fn from_inner((inner, peer_addr): (Socket, Option<String>)) -> TcpStream {
        TcpStream { inner, peer_addr }
    }
}

#[derive(Debug, Clone)]
pub struct TcpListener {
    inner: Socket,
}

impl TcpListener {
    pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
        let addr = io_err_to_addr(addr)?;
        let (fd, local_addr) = usercalls::bind_stream(&addr)?;
        Ok(TcpListener { inner: Socket::new(fd, local_addr) })
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        addr_to_sockaddr(&self.inner.local_addr)
    }

    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
        let (fd, local_addr, peer_addr) = usercalls::accept_stream(self.inner.inner.raw())?;
        let peer_addr = Some(peer_addr);
        let ret_peer = addr_to_sockaddr(&peer_addr).unwrap_or_else(|_| ([0; 4], 0).into());
        Ok((TcpStream { inner: Socket::new(fd, local_addr), peer_addr }, ret_peer))
    }

    pub fn duplicate(&self) -> io::Result<TcpListener> {
        Ok(self.clone())
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn ttl(&self) -> io::Result<u32> {
        sgx_ineffective(DEFAULT_FAKE_TTL)
    }

    pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
        sgx_ineffective(())
    }

    pub fn only_v6(&self) -> io::Result<bool> {
        sgx_ineffective(false)
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        Ok(None)
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        sgx_ineffective(())
    }
}

impl AsInner<Socket> for TcpListener {
    fn as_inner(&self) -> &Socket { &self.inner }
}

impl IntoInner<Socket> for TcpListener {
    fn into_inner(self) -> Socket {
        self.inner
    }
}

impl FromInner<Socket> for TcpListener {
    fn from_inner(inner: Socket) -> TcpListener {
        TcpListener { inner }
    }
}

pub struct UdpSocket(Void);

impl UdpSocket {
    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
        unsupported()
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<UdpSocket> {
        match self.0 {}
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn broadcast(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
                         -> io::Result<()> {
        match self.0 {}
    }

    pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
                         -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
                          -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
                          -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn send(&self, _: &[u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for UdpSocket {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

#[derive(Debug)]
pub struct NonIpSockAddr {
    host: String
}

impl error::Error for NonIpSockAddr {
    fn description(&self) -> &str {
        "Failed to convert address to SocketAddr"
    }
}

impl fmt::Display for NonIpSockAddr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Failed to convert address to SocketAddr: {}", self.host)
    }
}

pub struct LookupHost(Void);

impl LookupHost {
    fn new(host: String) -> io::Result<LookupHost> {
        Err(io::Error::new(io::ErrorKind::Other, NonIpSockAddr { host }))
    }

    pub fn port(&self) -> u16 {
        match self.0 {}
    }
}

impl Iterator for LookupHost {
    type Item = SocketAddr;
    fn next(&mut self) -> Option<SocketAddr> {
        match self.0 {}
    }
}

impl<'a> TryFrom<&'a str> for LookupHost {
    type Error = io::Error;

    fn try_from(v: &'a str) -> io::Result<LookupHost> {
        LookupHost::new(v.to_owned())
    }
}

impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
    type Error = io::Error;

    fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
        LookupHost::new(format!("{}:{}", host, port))
    }
}

#[allow(bad_style)]
pub mod netc {
    pub const AF_INET: u8 = 0;
    pub const AF_INET6: u8 = 1;
    pub type sa_family_t = u8;

    #[derive(Copy, Clone)]
    pub struct in_addr {
        pub s_addr: u32,
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr_in {
        pub sin_family: sa_family_t,
        pub sin_port: u16,
        pub sin_addr: in_addr,
    }

    #[derive(Copy, Clone)]
    pub struct in6_addr {
        pub s6_addr: [u8; 16],
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr_in6 {
        pub sin6_family: sa_family_t,
        pub sin6_port: u16,
        pub sin6_addr: in6_addr,
        pub sin6_flowinfo: u32,
        pub sin6_scope_id: u32,
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr {
    }

    pub type socklen_t = usize;
}
<|endoftext|>


<commit_before>// Copyright 2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Support for discrete probability distributions in terms of cumulative distribution
//! functions (CDF).

use std::f64;
use std::iter;
use std::slice;
use std::ops::Range;

use itertools::Itertools;
use ordered_float::OrderedFloat;

use stats::LogProb;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Entry<T: Ord> {
    pub value: T,
    pub prob: LogProb,
}

impl<T: Ord> Entry<T> {
    pub fn new(value: T, prob: LogProb) -> Self {
        Entry {
            value: value,
            prob: prob,
        }
    }
}

/// Implementation of a cumulative distribution function.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CDF<T: Ord> {
    inner: Vec<Entry<T>>,
}

impl<T: Ord> CDF<T> {
    /// Create CDF from given probability mass function (PMF). The PMF may contain duplicate values
    /// the probabilities of which are summed during generation of the CDF.
    ///
    /// # Arguments
    ///
    /// * `pmf` - the PMF as a vector of `Entry` objects
    pub fn from_pmf(mut entries: Vec<Entry<T>>) -> Self {
        entries.sort_by(|a, b| a.value.cmp(&b.value));
        let mut inner: Vec<Entry<T>> = Vec::new();
        for mut e in entries {
            let p = inner
                .last()
                .map_or(LogProb::ln_zero(), |e| e.prob)
                .ln_add_exp(e.prob);
            if !inner.is_empty() && inner.last().unwrap().value == e.value {
                inner.last_mut().unwrap().prob = p;
            } else {
                e.prob = p;
                inner.push(e);
            }
        }
        let mut cdf = CDF { inner: inner };

        if relative_eq!(*cdf.total_prob(), *LogProb::ln_one()) &&
           *cdf.total_prob() > *LogProb::ln_one() {
            cdf.inner.last_mut().unwrap().prob = LogProb::ln_one();
        }

        cdf
    }

    /// Create CDF from iterator. This can be used to replace the values of a CDF.
    pub fn from_cdf<I: Iterator<Item = Entry<T>>>(entries: I) -> Self {
        CDF { inner: entries.collect_vec() }
    }

    /// Reduce CDF by omitting values with zero probability.
    pub fn reduce(self) -> Self {
        let mut inner = Vec::new();
        let mut last = LogProb::ln_zero();
        for e in self.inner {
            if last != e.prob {
                last = e.prob;
                inner.push(e);
            }
        }
        CDF { inner: inner }
    }

    /// Downsample CDF to n entries. Panics if n <= 1 and returns identity if n is greater
    /// than the number of entries.
    pub fn sample(mut self, n: usize) -> Self {
        assert!(n > 1);
        if self.inner.len() <= n {
            self
        } else {
            let s = self.inner.len() / (n - 1);
            let last = self.inner.pop().unwrap();
            let mut inner = self.inner.into_iter().step(s).collect_vec();
            inner.push(last);
            CDF { inner: inner }
        }
    }

    /// Provide iterator.
    pub fn iter(&self) -> slice::Iter<Entry<T>> {
        self.inner.iter()
    }

    /// Iterator over corresponding PMF.
    pub fn iter_pmf(&self) -> CDFPMFIter<T> {
        fn cdf_to_pmf<'a, G: Ord>(last_prob: &mut LogProb,
                                  e: &'a Entry<G>)
                                  -> Option<Entry<&'a G>> {
            let prob = e.prob.ln_sub_exp(*last_prob);
            *last_prob = e.prob;
            Some(Entry::new(&e.value, prob))
        }
        self.inner.iter().scan(LogProb::ln_zero(), cdf_to_pmf)
    }

    /// Get cumulative probability for a given value. If the value is not present,
    /// return the probability of the previous value. Complexity O(log n).
    pub fn get(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        } else {
            Some(match self.inner.binary_search_by(|e| e.value.cmp(value)) {
                     Ok(i) => self.inner[i].prob,
                     Err(i) => {
                         if i > 0 {
                             self.inner[i - 1].prob
                         } else {
                             LogProb::ln_zero()
                         }
                     }
                 })
        }
    }

    /// Get probability (i.e. probability mass) for a given value. Complexity O(log n).
    pub fn get_pmf(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        } else {
            Some(match self.inner.binary_search_by(|e| e.value.cmp(value)) {
                     Ok(i) => {
                         if i > 0 {
                             self.inner[i].prob.ln_sub_exp(self.inner[i - 1].prob)
                         } else {
                             self.inner[0].prob
                         }
                     }
                     Err(i) => {
                         if i > 0 {
                             self.inner[i - 1].prob
                         } else {
                             LogProb::ln_zero()
                         }
                     }
                 })
        }
    }

    /// Return total probability.
    pub fn total_prob(&self) -> LogProb {
        self.inner.last().map_or(LogProb::ln_zero(), |e| e.prob)
    }

    /// Return maximum a posteriori probability estimate (MAP).
    pub fn map(&self) -> Option<&T> {
        if let Some(mut max) = self.iter_pmf().next() {
            for e in self.iter_pmf() {
                if e.prob >= max.prob {
                    max = e;
                }
            }
            Some(max.value)
        } else {
            None
        }
    }

    /// Return w%-credible interval. The width w is a float between 0 and 1. Panics otherwise.
    /// E.g. provide `width=0.95` for the 95% credible interval.
    pub fn credible_interval(&self, width: f64) -> Option<Range<&T>> {
        assert!(width >= 0.0 && width <= 1.0);

        if self.inner.is_empty() {
            return None;
        }

        let margin = 1.0 - width;
        let p_lower = OrderedFloat((margin / 2.0).ln());
        let p_upper = OrderedFloat((1.0 - margin / 2.0).ln());
        let lower = self.inner
            .binary_search_by(|e| OrderedFloat(*e.prob).cmp(&p_lower))
            .unwrap_or_else(|i| if i > 0 { i - 1 } else { 0 });
        let mut upper = self.inner
            .binary_search_by(|e| OrderedFloat(*e.prob).cmp(&p_upper))
            .unwrap_or_else(|i| i);
        if upper == self.inner.len() {
            upper -= 1;
        }

        Some(&self.inner[lower].value..&self.inner[upper].value)
    }

    /// Number of entries in the CDF.
    pub fn len(&self) -> usize {
        self.inner.len()
    }

    pub fn is_empty(&self) -> bool {
        self.inner.is_empty()
    }
}

impl<T: Clone + Ord> CDF<T>
    where f64: From<T>
{
    /// Calculate expected value.
    pub fn expected_value(&self) -> f64 {
        self.iter_pmf()
            .map(|e| f64::from(e.value.clone()) * e.prob.exp())
            .fold(0.0f64, |s, e| s + e)
    }

    /// Calculate variance.
    pub fn variance(&self) -> f64 {
        let ev = self.expected_value();
        self.iter_pmf()
            .map(|e| (f64::from(e.value.clone()) - ev).powi(2) * e.prob.exp())
            .fold(0.0, |s, e| s + e)
    }

    /// Calculate standard deviation.
    pub fn standard_deviation(&self) -> f64 {
        self.variance().sqrt()
    }
}

pub type CDFPMFIter<'a, T> = iter::Scan<slice::Iter<'a, Entry<T>>,
                                        LogProb,
                                        fn(&mut LogProb, &'a Entry<T>) -> Option<Entry<&'a T>>>;

#[cfg(test)]
mod test {
    use super::*;
    use stats::LogProb;
    use ordered_float::NotNaN;

    #[test]
    fn test_cdf() {
        let mut pmf = vec![Entry::new(NotNaN::new(0.0).unwrap(), LogProb(0.1f64.ln()))];
        for i in 0..9 {
            pmf.push(Entry::new(NotNaN::new(i as f64).unwrap(), LogProb(0.1f64.ln())));
        }
        println!("{:?}", pmf);

        let cdf = CDF::from_pmf(pmf.clone());
        println!("{:?}", cdf);
        for e in pmf.iter().skip(2) {
            assert_ulps_eq!(*e.prob,
                            *cdf.get_pmf(&e.value).unwrap(),
                            epsilon = 0.0000000000001);
        }
        assert_relative_eq!(*cdf.total_prob(), 1.0f64.ln());
        assert_relative_eq!(*cdf.get(&NotNaN::new(1.0).unwrap()).unwrap(),
                            0.3f64.ln(),
                            epsilon = 0.00000001);
        {
            let ci = cdf.credible_interval(0.95).unwrap();
            assert_relative_eq!(**ci.start, 0.0);
            assert_relative_eq!(**ci.end, 8.0);
        }

        {
            for e in cdf.iter_pmf() {
                assert_relative_eq!(
                    e.prob.exp(),
                    if **e.value == 0.0 { 0.2 } else { 0.1 }
                );
            }
        }

        assert_relative_eq!(cdf.sample(5).total_prob().exp(), 1.0);
    }
}
<commit_msg>Provide mutable iterator.<commit_after>// Copyright 2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Support for discrete probability distributions in terms of cumulative distribution
//! functions (CDF).

use std::f64;
use std::iter;
use std::slice;
use std::ops::Range;

use itertools::Itertools;
use ordered_float::OrderedFloat;

use stats::LogProb;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Entry<T: Ord> {
    pub value: T,
    pub prob: LogProb,
}

impl<T: Ord> Entry<T> {
    pub fn new(value: T, prob: LogProb) -> Self {
        Entry {
            value: value,
            prob: prob,
        }
    }
}

/// Implementation of a cumulative distribution function.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CDF<T: Ord> {
    inner: Vec<Entry<T>>,
}

impl<T: Ord> CDF<T> {
    /// Create CDF from given probability mass function (PMF). The PMF may contain duplicate values
    /// the probabilities of which are summed during generation of the CDF.
    ///
    /// # Arguments
    ///
    /// * `pmf` - the PMF as a vector of `Entry` objects
    pub fn from_pmf(mut entries: Vec<Entry<T>>) -> Self {
        entries.sort_by(|a, b| a.value.cmp(&b.value));
        let mut inner: Vec<Entry<T>> = Vec::new();
        for mut e in entries {
            let p = inner
                .last()
                .map_or(LogProb::ln_zero(), |e| e.prob)
                .ln_add_exp(e.prob);
            if !inner.is_empty() && inner.last().unwrap().value == e.value {
                inner.last_mut().unwrap().prob = p;
            } else {
                e.prob = p;
                inner.push(e);
            }
        }
        let mut cdf = CDF { inner: inner };

        if relative_eq!(*cdf.total_prob(), *LogProb::ln_one()) &&
           *cdf.total_prob() > *LogProb::ln_one() {
            cdf.inner.last_mut().unwrap().prob = LogProb::ln_one();
        }

        cdf
    }

    /// Create CDF from iterator. This can be used to replace the values of a CDF.
    pub fn from_cdf<I: Iterator<Item = Entry<T>>>(entries: I) -> Self {
        CDF { inner: entries.collect_vec() }
    }

    /// Reduce CDF by omitting values with zero probability.
    pub fn reduce(self) -> Self {
        let mut inner = Vec::new();
        let mut last = LogProb::ln_zero();
        for e in self.inner {
            if last != e.prob {
                last = e.prob;
                inner.push(e);
            }
        }
        CDF { inner: inner }
    }

    /// Downsample CDF to n entries. Panics if n <= 1 and returns identity if n is greater
    /// than the number of entries.
    pub fn sample(mut self, n: usize) -> Self {
        assert!(n > 1);
        if self.inner.len() <= n {
            self
        } else {
            let s = self.inner.len() / (n - 1);
            let last = self.inner.pop().unwrap();
            let mut inner = self.inner.into_iter().step(s).collect_vec();
            inner.push(last);
            CDF { inner: inner }
        }
    }

    /// Provide iterator.
    pub fn iter(&self) -> slice::Iter<Entry<T>> {
        self.inner.iter()
    }

    /// Mutable iterator over entries. This does not check for consistency. In other words, you
    /// should not change the order of the entries, nor the probabilities!
    pub fn iter_mut(&mut self) -> slice::IterMut<Entry<T>> {
        self.inner.iter_mut()
    }

    /// Iterator over corresponding PMF.
    pub fn iter_pmf(&self) -> CDFPMFIter<T> {
        fn cdf_to_pmf<'a, G: Ord>(last_prob: &mut LogProb,
                                  e: &'a Entry<G>)
                                  -> Option<Entry<&'a G>> {
            let prob = e.prob.ln_sub_exp(*last_prob);
            *last_prob = e.prob;
            Some(Entry::new(&e.value, prob))
        }
        self.inner.iter().scan(LogProb::ln_zero(), cdf_to_pmf)
    }

    /// Get cumulative probability for a given value. If the value is not present,
    /// return the probability of the previous value. Complexity O(log n).
    pub fn get(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        } else {
            Some(match self.inner.binary_search_by(|e| e.value.cmp(value)) {
                     Ok(i) => self.inner[i].prob,
                     Err(i) => {
                         if i > 0 {
                             self.inner[i - 1].prob
                         } else {
                             LogProb::ln_zero()
                         }
                     }
                 })
        }
    }

    /// Get probability (i.e. probability mass) for a given value. Complexity O(log n).
    pub fn get_pmf(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        } else {
            Some(match self.inner.binary_search_by(|e| e.value.cmp(value)) {
                     Ok(i) => {
                         if i > 0 {
                             self.inner[i].prob.ln_sub_exp(self.inner[i - 1].prob)
                         } else {
                             self.inner[0].prob
                         }
                     }
                     Err(i) => {
                         if i > 0 {
                             self.inner[i - 1].prob
                         } else {
                             LogProb::ln_zero()
                         }
                     }
                 })
        }
    }

    /// Return total probability.
    pub fn total_prob(&self) -> LogProb {
        self.inner.last().map_or(LogProb::ln_zero(), |e| e.prob)
    }

    /// Return maximum a posteriori probability estimate (MAP).
    pub fn map(&self) -> Option<&T> {
        if let Some(mut max) = self.iter_pmf().next() {
            for e in self.iter_pmf() {
                if e.prob >= max.prob {
                    max = e;
                }
            }
            Some(max.value)
        } else {
            None
        }
    }

    /// Return w%-credible interval. The width w is a float between 0 and 1. Panics otherwise.
    /// E.g. provide `width=0.95` for the 95% credible interval.
    pub fn credible_interval(&self, width: f64) -> Option<Range<&T>> {
        assert!(width >= 0.0 && width <= 1.0);

        if self.inner.is_empty() {
            return None;
        }

        let margin = 1.0 - width;
        let p_lower = OrderedFloat((margin / 2.0).ln());
        let p_upper = OrderedFloat((1.0 - margin / 2.0).ln());
        let lower = self.inner
            .binary_search_by(|e| OrderedFloat(*e.prob).cmp(&p_lower))
            .unwrap_or_else(|i| if i > 0 { i - 1 } else { 0 });
        let mut upper = self.inner
            .binary_search_by(|e| OrderedFloat(*e.prob).cmp(&p_upper))
            .unwrap_or_else(|i| i);
        if upper == self.inner.len() {
            upper -= 1;
        }

        Some(&self.inner[lower].value..&self.inner[upper].value)
    }

    /// Number of entries in the CDF.
    pub fn len(&self) -> usize {
        self.inner.len()
    }

    pub fn is_empty(&self) -> bool {
        self.inner.is_empty()
    }
}

impl<T: Clone + Ord> CDF<T>
    where f64: From<T>
{
    /// Calculate expected value.
    pub fn expected_value(&self) -> f64 {
        self.iter_pmf()
            .map(|e| f64::from(e.value.clone()) * e.prob.exp())
            .fold(0.0f64, |s, e| s + e)
    }

    /// Calculate variance.
    pub fn variance(&self) -> f64 {
        let ev = self.expected_value();
        self.iter_pmf()
            .map(|e| (f64::from(e.value.clone()) - ev).powi(2) * e.prob.exp())
            .fold(0.0, |s, e| s + e)
    }

    /// Calculate standard deviation.
    pub fn standard_deviation(&self) -> f64 {
        self.variance().sqrt()
    }
}

pub type CDFPMFIter<'a, T> = iter::Scan<slice::Iter<'a, Entry<T>>,
                                        LogProb,
                                        fn(&mut LogProb, &'a Entry<T>) -> Option<Entry<&'a T>>>;

#[cfg(test)]
mod test {
    use super::*;
    use stats::LogProb;
    use ordered_float::NotNaN;

    #[test]
    fn test_cdf() {
        let mut pmf = vec![Entry::new(NotNaN::new(0.0).unwrap(), LogProb(0.1f64.ln()))];
        for i in 0..9 {
            pmf.push(Entry::new(NotNaN::new(i as f64).unwrap(), LogProb(0.1f64.ln())));
        }
        println!("{:?}", pmf);

        let cdf = CDF::from_pmf(pmf.clone());
        println!("{:?}", cdf);
        for e in pmf.iter().skip(2) {
            assert_ulps_eq!(*e.prob,
                            *cdf.get_pmf(&e.value).unwrap(),
                            epsilon = 0.0000000000001);
        }
        assert_relative_eq!(*cdf.total_prob(), 1.0f64.ln());
        assert_relative_eq!(*cdf.get(&NotNaN::new(1.0).unwrap()).unwrap(),
                            0.3f64.ln(),
                            epsilon = 0.00000001);
        {
            let ci = cdf.credible_interval(0.95).unwrap();
            assert_relative_eq!(**ci.start, 0.0);
            assert_relative_eq!(**ci.end, 8.0);
        }

        {
            for e in cdf.iter_pmf() {
                assert_relative_eq!(
                    e.prob.exp(),
                    if **e.value == 0.0 { 0.2 } else { 0.1 }
                );
            }
        }

        assert_relative_eq!(cdf.sample(5).total_prob().exp(), 1.0);
    }
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result as FMTResult;
use std::path::Path;
use std::path::PathBuf;
use std::vec::Vec;
use std::fs::File as FSFile;
use std::fs::create_dir_all;
use std::fs::remove_file;
use std::io::Read;
use std::io::Write;
use std::vec::IntoIter;

use glob::glob;
use glob::Paths;

use storage::file::File;
use storage::file_id::*;
use storage::parser::{FileHeaderParser, Parser, ParserError};

use module::Module;
use runtime::Runtime;

pub type BackendOperationResult<T = ()> = Result<T, StorageBackendError>;

pub struct StorageBackend {
    basepath: String,
    storepath: String,
}

impl StorageBackend {

    pub fn new(rt: &Runtime) -> BackendOperationResult<StorageBackend> {
        let storepath = rt.get_rtp() + "/store/";
        debug!("Trying to create {}", storepath);
        create_dir_all(&storepath).and_then(|_| {
            debug!("Creating succeeded, constructing backend instance");
            Ok(StorageBackend {
                basepath: rt.get_rtp(),
                storepath: storepath.clone(),
            })
        }).or_else(|e| {
            debug!("Creating failed, constructing error instance");
            let mut serr = StorageBackendError::build(
                "create_dir_all()",
                "Could not create store directories",
                Some(storepath)
            );
            serr.caused_by = Some(Box::new(e));
            Err(serr)
        })
    }

    fn build<M: Module>(rt: &Runtime, m: &M) -> StorageBackend {
        let path = rt.get_rtp() + m.name() + "/store";
        // TODO: Don't use "/store" but value from configuration
        debug!("Building StorageBackend for {}", path);
        StorageBackend::new(path)
    }

    fn get_file_ids(&self, m: &Module) -> Option<Vec<FileID>> {
        let list = glob(&self.prefix_of_files_for_module(m)[..]);

        if let Ok(globlist) = list {
            let mut v = vec![];
            for entry in globlist {
                if let Ok(path) = entry {
                    debug!(" - File: {:?}", path);
                    v.push(from_pathbuf(&path));
                } else {
                    // Entry is not a path
                }
            }

            Some(v)
        } else {
            None
        }
    }

    pub fn iter_ids(&self, m: &Module) -> Option<IntoIter<FileID>>
    {
        glob(&self.prefix_of_files_for_module(m)[..]).and_then(|globlist| {
            let v = globlist.filter_map(Result::ok)
                            .map(|pbuf| from_pathbuf(&pbuf))
                            .collect::<Vec<FileID>>()
                            .into_iter();
            Ok(v)
        }).ok()
    }

    pub fn iter_files<'a, HP>(&self, m: &'a Module, p: &Parser<HP>)
        -> Option<IntoIter<File<'a>>>
        where HP: FileHeaderParser
    {
        self.iter_ids(m).and_then(|ids| {
            Some(ids.filter_map(|id| self.get_file_by_id(m, &id, p))
                    .collect::<Vec<File>>()
                    .into_iter())
        })
    }

    /*
     * Write a file to disk.
     *
     * The file is moved to this function as the file won't be edited afterwards
     */
    pub fn put_file<HP>(&self, f: File, p: &Parser<HP>) -> BackendOperationResult
        where HP: FileHeaderParser
    {
        let written = write_with_parser(&f, p);
        if written.is_err() { return Err(written.err().unwrap()); }
        let string = written.unwrap();

        let path = self.build_filepath(&f);
        debug!("Writing file: {}", path);
        debug!("      string: {}", string);

        FSFile::create(&path).map(|file| {
            debug!("Created file at '{}'", path);
            file.write_all(&string.clone().into_bytes())
                .map_err(|ioerr| {
                    debug!("Could not write file");
                    let mut err = StorageBackendError::build(
                            "File::write_all()",
                            "Could not write out File contents",
                            "", None
                        );
                    err.caused_by = Some(&ioerr);
                    err
                })
        }).map_err(|writeerr| {
            debug!("Could not create file at '{}'", path);
            let mut err = StorageBackendError::build(
                "File::create()",
                "Creating file on disk failed",
                "", None
            );
            err.caused_by = Some(Box::new(writeerr));
            err
        }).and(Ok(()))
    }

    /*
     * Update a file. We have the UUID and can find the file on FS with it and
     * then replace its contents with the contents of the passed file object
     */
    pub fn update_file<HP>(&self, f: File, p: &Parser<HP>) -> BackendOperationResult
        where HP: FileHeaderParser
    {
        let contents = write_with_parser(&f, p);
        if contents.is_err() { return Err(contents.err().unwrap()); }
        let string = contents.unwrap();

        let path = self.build_filepath(&f);
        debug!("Writing file: {}", path);
        debug!("      string: {}", string);

        FSFile::open(&path).map(|mut file| {
            debug!("Open file at '{}'", path);
            file.write_all(&string.clone().into_bytes())
                .map_err(|ioerr| {
                    debug!("Could not write file");
                    let mut err = StorageBackendError::build(
                            "File::write()",
                            "Tried to write contents of this file, though operation did not succeed",
                            Some(string)
                        );
                    err.caused_by = Some(Box::new(ioerr));
                    err
                })
        }).map_err(|writeerr| {
            debug!("Could not write file at '{}'", path);
            let mut err = StorageBackendError::build(
                "File::open()",
                "Tried to update contents of this file, though file doesn't exist",
                None
            );
            err.caused_by = Some(Box::new(writeerr));
            err
        }).and(Ok(()))
    }

    /*
     * Find a file by its ID and return it if found. Return nothing if not
     * found, of course.
     *
     * TODO: Needs refactoring, as there might be an error when reading from
     * disk OR the id just does not exist.
     */
    pub fn get_file_by_id<'a, HP>(&self, m: &'a Module, id: FileID, p: &Parser<HP>) -> Option<File<'a>>
        where HP: FileHeaderParser
    {
        debug!("Searching for file with id '{}'", id);
        if let Ok(mut fs) = FSFile::open(self.build_filepath_with_id(m, id.clone())) {
            let mut s = String::new();
            fs.read_to_string(&mut s);
            debug!("Success reading file with id '{}'", id);
            debug!("Parsing to internal structure now");
            p.read(s).and_then(|(h, d)| Ok(File::from_parser_result(m, id.clone(), h, d))).ok()
        } else {
            debug!("No file with id '{}'", id);
            None
        }
    }

    pub fn remove_file(&self, m: &Module, file: File, checked: bool) -> BackendOperationResult {
        if checked {
            error!("Checked remove not implemented yet. I will crash now");
            unimplemented!()
        }

        debug!("Doing unchecked remove");
        info!("Going to remove file: {}", file);

        let fp = self.build_filepath(&file);
        remove_file(fp).map_err(|e| {
            let mut serr = StorageBackendError::build(
                "remove_file()",
                "File removal failed",
                Some(format!("{}", file))
            );
            serr.caused_by = Some(Box::new(e));
            serr
        })
    }

    fn build_filepath(&self, f: &File) -> String {
        self.build_filepath_with_id(f.owner(), f.id())
    }

    fn build_filepath_with_id(&self, owner: &Module, id: FileID) -> String {
        debug!("Building filepath with id");
        debug!("  basepath: '{}'", self.basepath);
        debug!(" storepath: '{}'", self.storepath);
        debug!("  id      : '{}'", id);
        self.storepath.clone() + owner.name() + "-" + &id[..] + ".imag"
    }

}

#[derive(Debug)]
pub struct StorageBackendError<'a> {
    pub action: String,             // The file system action in words
    pub desc: String,               // A short description
    pub data_dump: Option<String>,  // Data dump, if any
    pub caused_by: Option<Box<Error>>,  // caused from this error
}

impl<'a> StorageBackendError<'a> {
    fn new(action: String,
           desc  : String,
           data  : Option<String>) -> StorageBackendError<'a>
    {
        StorageBackendError {
            action:         action,
            desc:           desc,
            data_dump:      data,
            caused_by:      None,
        }
    }

    fn build(action: &'static str,
             desc:   &'static str,
           data  : Option<String>) -> StorageBackendError<'a>
    {
        StorageBackendError {
            action:         String::from(action),
            desc:           String::from(desc),
            dataDump:       data,
            caused_by:      None,
        }
    }

}

impl<'a> Error for StorageBackendError<'a> {

    fn description(&self) -> &str {
        &self.desc[..]
    }

    fn cause(&self) -> Option<&Error> {
        self.caused_by.as_ref().map(|e| &**e)
    }

}

impl<'a> Display for StorageBackendError<'a> {
    fn fmt(&self, f: &mut Formatter) -> FMTResult {
        write!(f, "StorageBackendError[{}]: {}",
               self.action, self.desc)
    }
}

fn write_with_parser<'a, HP>(f: &File, p: &Parser<HP>) -> Result<String, StorageBackendError<'a>> {
    p.write(f.contents())
        .or_else(|err| {
            let mut serr = StorageBackendError::build(
                "Parser::write()",
                "Cannot parse file contents",
                "Cannot translate internal representation of file contents into on-disk representation",
                None
            );
            serr.caused_by = Some(&err);
            Err(serr)
        })
}
<commit_msg>Reimplement StorageBackend::update_file()<commit_after>use std::error::Error;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result as FMTResult;
use std::path::Path;
use std::path::PathBuf;
use std::vec::Vec;
use std::fs::File as FSFile;
use std::fs::create_dir_all;
use std::fs::remove_file;
use std::io::Read;
use std::io::Write;
use std::vec::IntoIter;

use glob::glob;
use glob::Paths;

use storage::file::File;
use storage::file_id::*;
use storage::parser::{FileHeaderParser, Parser, ParserError};

use module::Module;
use runtime::Runtime;

pub type BackendOperationResult<T = ()> = Result<T, StorageBackendError>;

pub struct StorageBackend {
    basepath: String,
    storepath: String,
}

impl StorageBackend {

    pub fn new(rt: &Runtime) -> BackendOperationResult<StorageBackend> {
        let storepath = rt.get_rtp() + "/store/";
        debug!("Trying to create {}", storepath);
        create_dir_all(&storepath).and_then(|_| {
            debug!("Creating succeeded, constructing backend instance");
            Ok(StorageBackend {
                basepath: rt.get_rtp(),
                storepath: storepath.clone(),
            })
        }).or_else(|e| {
            debug!("Creating failed, constructing error instance");
            let mut serr = StorageBackendError::build(
                "create_dir_all()",
                "Could not create store directories",
                Some(storepath)
            );
            serr.caused_by = Some(Box::new(e));
            Err(serr)
        })
    }

    fn build<M: Module>(rt: &Runtime, m: &M) -> StorageBackend {
        let path = rt.get_rtp() + m.name() + "/store";
        // TODO: Don't use "/store" but value from configuration
        debug!("Building StorageBackend for {}", path);
        StorageBackend::new(path)
    }

    fn get_file_ids(&self, m: &Module) -> Option<Vec<FileID>> {
        let list = glob(&self.prefix_of_files_for_module(m)[..]);

        if let Ok(globlist) = list {
            let mut v = vec![];
            for entry in globlist {
                if let Ok(path) = entry {
                    debug!(" - File: {:?}", path);
                    v.push(from_pathbuf(&path));
                } else {
                    // Entry is not a path
                }
            }

            Some(v)
        } else {
            None
        }
    }

    pub fn iter_ids(&self, m: &Module) -> Option<IntoIter<FileID>>
    {
        glob(&self.prefix_of_files_for_module(m)[..]).and_then(|globlist| {
            let v = globlist.filter_map(Result::ok)
                            .map(|pbuf| from_pathbuf(&pbuf))
                            .collect::<Vec<FileID>>()
                            .into_iter();
            Ok(v)
        }).ok()
    }

    pub fn iter_files<'a, HP>(&self, m: &'a Module, p: &Parser<HP>)
        -> Option<IntoIter<File<'a>>>
        where HP: FileHeaderParser
    {
        self.iter_ids(m).and_then(|ids| {
            Some(ids.filter_map(|id| self.get_file_by_id(m, &id, p))
                    .collect::<Vec<File>>()
                    .into_iter())
        })
    }

    /*
     * Write a file to disk.
     *
     * The file is moved to this function as the file won't be edited afterwards
     */
    pub fn put_file<HP>(&self, f: File, p: &Parser<HP>) -> BackendOperationResult
        where HP: FileHeaderParser
    {
        let written = write_with_parser(&f, p);
        if written.is_err() { return Err(written.err().unwrap()); }
        let string = written.unwrap();

        let path = self.build_filepath(&f);
        debug!("Writing file: {}", path);
        debug!("      string: {}", string);

        FSFile::create(&path).map(|file| {
            debug!("Created file at '{}'", path);
            file.write_all(&string.clone().into_bytes())
                .map_err(|ioerr| {
                    debug!("Could not write file");
                    let mut err = StorageBackendError::build(
                            "File::write_all()",
                            "Could not write out File contents",
                            "", None
                        );
                    err.caused_by = Some(&ioerr);
                    err
                })
        }).map_err(|writeerr| {
            debug!("Could not create file at '{}'", path);
            let mut err = StorageBackendError::build(
                "File::create()",
                "Creating file on disk failed",
                "", None
            );
            err.caused_by = Some(Box::new(writeerr));
            err
        }).and(Ok(()))
    }

    /*
     * Update a file. We have the UUID and can find the file on FS with it and
     * then replace its contents with the contents of the passed file object
     */
    pub fn update_file<HP>(&self, f: File, p: &Parser<HP>) -> BackendOperationResult
        where HP: FileHeaderParser
    {
        let contents = write_with_parser(&f, p);
        if contents.is_err() { return Err(contents.err().unwrap()); }
        let string = contents.unwrap();

        let path = self.build_filepath(&f);
        debug!("Writing file: {}", path);
        debug!("      string: {}", string);

        FSFile::open(&path).map(|file| {
            debug!("Open file at '{}'", path);
            file.write_all(&string.clone().into_bytes())
                .map_err(|ioerr| {
                    debug!("Could not write file");
                    let mut err = StorageBackendError::build(
                            "File::write()",
                            "",
                            "Tried to write contents of this file, though operation did not succeed",
                            Some(string)
                        );
                    err.caused_by = Some(&ioerr);
                    err
                })
        }).map_err(|writeerr| {
            debug!("Could not write file at '{}'", path);
            let mut err = StorageBackendError::build(
                "File::open()",
                "",
                "Tried to update contents of this file, though file doesn't exist",
                None
            );
            err.caused_by = Some(&writeerr);
            err
        }).and(Ok(()))
    }

    /*
     * Find a file by its ID and return it if found. Return nothing if not
     * found, of course.
     *
     * TODO: Needs refactoring, as there might be an error when reading from
     * disk OR the id just does not exist.
     */
    pub fn get_file_by_id<'a, HP>(&self, m: &'a Module, id: FileID, p: &Parser<HP>) -> Option<File<'a>>
        where HP: FileHeaderParser
    {
        debug!("Searching for file with id '{}'", id);
        if let Ok(mut fs) = FSFile::open(self.build_filepath_with_id(m, id.clone())) {
            let mut s = String::new();
            fs.read_to_string(&mut s);
            debug!("Success reading file with id '{}'", id);
            debug!("Parsing to internal structure now");
            p.read(s).and_then(|(h, d)| Ok(File::from_parser_result(m, id.clone(), h, d))).ok()
        } else {
            debug!("No file with id '{}'", id);
            None
        }
    }

    pub fn remove_file(&self, m: &Module, file: File, checked: bool) -> BackendOperationResult {
        if checked {
            error!("Checked remove not implemented yet. I will crash now");
            unimplemented!()
        }

        debug!("Doing unchecked remove");
        info!("Going to remove file: {}", file);

        let fp = self.build_filepath(&file);
        remove_file(fp).map_err(|e| {
            let mut serr = StorageBackendError::build(
                "remove_file()",
                "File removal failed",
                Some(format!("{}", file))
            );
            serr.caused_by = Some(Box::new(e));
            serr
        })
    }

    fn build_filepath(&self, f: &File) -> String {
        self.build_filepath_with_id(f.owner(), f.id())
    }

    fn build_filepath_with_id(&self, owner: &Module, id: FileID) -> String {
        debug!("Building filepath with id");
        debug!("  basepath: '{}'", self.basepath);
        debug!(" storepath: '{}'", self.storepath);
        debug!("  id      : '{}'", id);
        self.storepath.clone() + owner.name() + "-" + &id[..] + ".imag"
    }

}

#[derive(Debug)]
pub struct StorageBackendError<'a> {
    pub action: String,             // The file system action in words
    pub desc: String,               // A short description
    pub data_dump: Option<String>,  // Data dump, if any
    pub caused_by: Option<Box<Error>>,  // caused from this error
}

impl<'a> StorageBackendError<'a> {
    fn new(action: String,
           desc  : String,
           data  : Option<String>) -> StorageBackendError<'a>
    {
        StorageBackendError {
            action:         action,
            desc:           desc,
            data_dump:      data,
            caused_by:      None,
        }
    }

    fn build(action: &'static str,
             desc:   &'static str,
           data  : Option<String>) -> StorageBackendError<'a>
    {
        StorageBackendError {
            action:         String::from(action),
            desc:           String::from(desc),
            dataDump:       data,
            caused_by:      None,
        }
    }

}

impl<'a> Error for StorageBackendError<'a> {

    fn description(&self) -> &str {
        &self.desc[..]
    }

    fn cause(&self) -> Option<&Error> {
        self.caused_by.as_ref().map(|e| &**e)
    }

}

impl<'a> Display for StorageBackendError<'a> {
    fn fmt(&self, f: &mut Formatter) -> FMTResult {
        write!(f, "StorageBackendError[{}]: {}",
               self.action, self.desc)
    }
}

fn write_with_parser<'a, HP>(f: &File, p: &Parser<HP>) -> Result<String, StorageBackendError<'a>> {
    p.write(f.contents())
        .or_else(|err| {
            let mut serr = StorageBackendError::build(
                "Parser::write()",
                "Cannot parse file contents",
                "Cannot translate internal representation of file contents into on-disk representation",
                None
            );
            serr.caused_by = Some(&err);
            Err(serr)
        })
}
<|endoftext|>


<commit_before>extern crate glium;
extern crate image;
extern crate zip;
extern crate cgmath;
extern crate notify;
extern crate lightfield_loader;

use std::io::Read;
use std::fs::File;
use std::io::Cursor;
use std::mem;

use lightfield_loader::{Lightfield, LightfieldView};

use glium::backend::Facade;
use glium::texture::{MipmapsOption, UncompressedFloatFormat};
use glium::texture::pixel_buffer::PixelBuffer;
use glium::texture::texture2d_array::Texture2dArray;
use std::iter::FromIterator;

use image::{DynamicImage, GenericImage, ImageFormat, Pixel, Rgb};

pub struct LightfieldTexture {
    pub tex: Texture2dArray,
}

impl LightfieldTexture {
    #![allow(dead_code)]
    pub fn new<F: Facade>(facade: &F, zip_filename: &str) -> LightfieldTexture {
        let lf = Lightfield::from_zip(zip_filename).unwrap();

        // FIXME n's and sizes
        let nx = 1;
        let ny = 1;
        let n = nx * ny;
        let img0 = &lf.views[0].image;
        let width = img0.width();
        let height = img0.height();
        let num_pixels = (width * height) as usize;

        let tex = Texture2dArray::empty_with_format(facade,
                                                    UncompressedFloatFormat::U8U8U8,
                                                    MipmapsOption::NoMipmap,
                                                    width,
                                                    height,
                                                    n)
                      .unwrap();

        for view in &lf.views {
            let image = &view.image;
            assert!(image.width() == width);
            assert!(image.height() == height);
            match image {
                &DynamicImage::ImageRgb8(_) => {}
                _ => {
                    panic!("Cannot handle this image type");
                }
            }
            let layer = 0; // iy*nx+ix;
            println!("loading layer {}", layer);
            assert!(layer < n);
            // TODO: due to wrong pixelbuffer format, texture upload uses format = GL_RED_INTEGER
            // how can i write() to a pixelbuffer with T=(u8,u8,u8,u8) from a [u8] src?
            let buffer = PixelBuffer::<(u8, u8, u8)>::new_empty(facade, num_pixels);
            let pixels: &Vec<u8> = &image.raw_pixels();

            /* //disabled code: format-changing copy for now to make sure no bugs are here
            // better make sure the rust tuple representation is packed,
            // so we can kind of safely transmute
            assert!(mem::size_of::<[(u8,u8,u8); 2]>() == 6);
            let pixel_tuples = unsafe {mem::transmute::<&[u8], &[(u8, u8, u8)]>(pixels)};
            buffer.write(pixel_tuples);
            */
            let rgb_iter = pixels.chunks(3).map(|v| (v[0], v[1], v[2]));
            let tuples: Vec<(u8,u8,u8)> = Vec::from_iter(rgb_iter);
            println!("pixels: {}", pixels.len());
            println!("tuples: {}", tuples.len());
            buffer.write(tuples.as_slice());
            tex.main_level().raw_upload_from_pixel_buffer(buffer.as_slice(),
                                                          0..width,
                                                          0..height,
                                                          layer..layer + 1);
            break; // XXX debug
        }
        unsafe { tex.generate_mipmaps() };
        LightfieldTexture { tex: tex }
    }
}
<commit_msg>Load all layers, not just one<commit_after>extern crate glium;
extern crate image;
extern crate zip;
extern crate cgmath;
extern crate notify;
extern crate lightfield_loader;

use std::io::Read;
use std::fs::File;
use std::io::Cursor;
use std::mem;

use lightfield_loader::{Lightfield, LightfieldView};

use glium::backend::Facade;
use glium::texture::{MipmapsOption, UncompressedFloatFormat};
use glium::texture::pixel_buffer::PixelBuffer;
use glium::texture::texture2d_array::Texture2dArray;
use std::iter::FromIterator;

use image::{DynamicImage, GenericImage, ImageFormat, Pixel, Rgb};

pub struct LightfieldTexture {
    pub tex: Texture2dArray,
}

impl LightfieldTexture {
    #![allow(dead_code)]
    pub fn new<F: Facade>(facade: &F, zip_filename: &str) -> LightfieldTexture {
        let lf = Lightfield::from_zip(zip_filename).unwrap();

        // FIXME n's and sizes
        let nlayers = lf.views.len() as u32;
        let img0 = &lf.views[0].image;
        let width = img0.width();
        let height = img0.height();
        let num_pixels = (width * height) as usize;

        let tex = Texture2dArray::empty_with_format(facade,
                                                    UncompressedFloatFormat::U8U8U8,
                                                    MipmapsOption::NoMipmap,
                                                    width,
                                                    height,
                                                    nlayers)
                      .unwrap();

        for (_layeridx, view) in lf.views.iter().enumerate() {
            let layeridx = _layeridx as u32;
            let image = &view.image;
            assert!(image.width() == width);
            assert!(image.height() == height);
            match image {
                &DynamicImage::ImageRgb8(_) => {}
                _ => {
                    panic!("Cannot handle this image type");
                }
            }
            println!("loading layer {}", layeridx);
            // TODO: due to wrong pixelbuffer format, texture upload uses format = GL_RED_INTEGER
            // how can i write() to a pixelbuffer with T=(u8,u8,u8,u8) from a [u8] src?
            let buffer = PixelBuffer::<(u8, u8, u8)>::new_empty(facade, num_pixels);
            let pixels: &Vec<u8> = &image.raw_pixels();

            /* //disabled code: format-changing copy for now to make sure no bugs are here
            // better make sure the rust tuple representation is packed,
            // so we can kind of safely transmute
            assert!(mem::size_of::<[(u8,u8,u8); 2]>() == 6);
            let pixel_tuples = unsafe {mem::transmute::<&[u8], &[(u8, u8, u8)]>(pixels)};
            buffer.write(pixel_tuples);
            */
            let rgb_iter = pixels.chunks(3).map(|v| (v[0], v[1], v[2]));
            let tuples: Vec<(u8,u8,u8)> = Vec::from_iter(rgb_iter);
            buffer.write(tuples.as_slice());
            tex.main_level().raw_upload_from_pixel_buffer(buffer.as_slice(),
                                                          0..width,
                                                          0..height,
                                                          layeridx..layeridx + 1);
        }
        unsafe { tex.generate_mipmaps() };
        LightfieldTexture { tex: tex }
    }
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
extern crate parity_wasm;

use test::Bencher;
use parity_wasm::builder::module;
use parity_wasm::elements::{ExportEntry, Internal, ImportEntry, External, Opcodes, Opcode};
use parity_wasm::interpreter::{ProgramInstance, ModuleInstanceInterface, RuntimeValue};

#[bench]
fn export_entry_performance(b: &mut Bencher) {
	// create module with 1000 functions
	const NUM_FUNCTIONS: u32 = 1000;
	let mut callee_module = module();
	for i in 0..NUM_FUNCTIONS {
		callee_module = callee_module
			.with_export(ExportEntry::new(format!("func{}", i), Internal::Function(i)))
			.function()
				.signature().return_type().i32().build()
				.body().with_opcodes(Opcodes::new(vec![
					Opcode::I32Const(i as i32),
					Opcode::End,
				])).build()
				.build();
	}
	let callee_module = callee_module.build();

	// create module which call one of 1000 functions
	let caller_module = module()
		.with_import(ImportEntry::new("callee_module".into(), "func500".into(), External::Function(0)))
		.function()
			.signature().return_type().i32().build()
			.body().with_opcodes(Opcodes::new(vec![
				Opcode::Call(0),
				Opcode::I32Const(1000),
				Opcode::I32Add,
				Opcode::End,
			])).build()
			.build()
		.build();

	// add both modules to program
	let program = ProgramInstance::new();
	program.add_module("callee_module", callee_module, None).unwrap();
	let caller_module = program.add_module("caller_module", caller_module, None).unwrap();

	// run bench
	b.iter(||
		assert_eq!(caller_module.execute_index(1, vec![].into()).unwrap(), Some(RuntimeValue::I32(1500)))
	);

	// test export_entry_performance ... bench:       3,497 ns/iter (+/- 200)
}
<commit_msg>Delete interpreter.rs<commit_after><|endoftext|>


<commit_before>use crate::EitherOrBoth::*;

use either::Either;

/// Value that either holds a single A or B, or both.
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum EitherOrBoth<A, B> {
    /// Both values are present.
    Both(A, B),
    /// Only the left value of type `A` is present.
    Left(A),
    /// Only the right value of type `B` is present.
    Right(B),
}

impl<A, B> EitherOrBoth<A, B> {
    /// If `Left`, or `Both`, return true, otherwise, return false.
    pub fn has_left(&self) -> bool {
        self.as_ref().left().is_some()
    }

    /// If `Right`, or `Both`, return true, otherwise, return false.
    pub fn has_right(&self) -> bool {
        self.as_ref().right().is_some()
    }

    /// If Left, return true otherwise, return false.
    /// Exclusive version of [`has_left`](Self::has_left).
    pub fn is_left(&self) -> bool {
        match *self {
            Left(_) => true,
            _ => false,
        }
    }

    /// If Right, return true otherwise, return false.
    /// Exclusive version of [`has_right`](Self::has_right).
    pub fn is_right(&self) -> bool {
        match *self {
            Right(_) => true,
            _ => false,
        }
    }

    /// If Right, return true otherwise, return false.
    /// Equivalent to `self.as_ref().both().is_some()`.
    pub fn is_both(&self) -> bool {
        self.as_ref().both().is_some()
    }

    /// If `Left`, or `Both`, return `Some` with the left value, otherwise, return `None`.
    pub fn left(self) -> Option<A> {
        match self {
            Left(left) | Both(left, _) => Some(left),
            _ => None,
        }
    }

    /// If `Right`, or `Both`, return `Some` with the right value, otherwise, return `None`.
    pub fn right(self) -> Option<B> {
        match self {
            Right(right) | Both(_, right) => Some(right),
            _ => None,
        }
    }

    /// If Both, return `Some` tuple containing left and right.
    pub fn both(self) -> Option<(A, B)> {
        match self {
            Both(a, b) => Some((a, b)),
            _ => None,
        }
    }

    /// Converts from `&EitherOrBoth<A, B>` to `EitherOrBoth<&A, &B>`.
    pub fn as_ref(&self) -> EitherOrBoth<&A, &B> {
        match *self {
            Left(ref left) => Left(left),
            Right(ref right) => Right(right),
            Both(ref left, ref right) => Both(left, right),
        }
    }

    /// Converts from `&mut EitherOrBoth<A, B>` to `EitherOrBoth<&mut A, &mut B>`.
    pub fn as_mut(&mut self) -> EitherOrBoth<&mut A, &mut B> {
        match *self {
            Left(ref mut left) => Left(left),
            Right(ref mut right) => Right(right),
            Both(ref mut left, ref mut right) => Both(left, right),
        }
    }

    /// Convert `EitherOrBoth<A, B>` to `EitherOrBoth<B, A>`.
    pub fn flip(self) -> EitherOrBoth<B, A> {
        match self {
            Left(a) => Right(a),
            Right(b) => Left(b),
            Both(a, b) => Both(b, a),
        }
    }

    /// Apply the function `f` on the value `a` in `Left(a)` or `Both(a, b)` variants. If it is
    /// present rewrapping the result in `self`'s original variant.
    pub fn map_left<F, M>(self, f: F) -> EitherOrBoth<M, B>
    where
        F: FnOnce(A) -> M,
    {
        match self {
            Both(a, b) => Both(f(a), b),
            Left(a) => Left(f(a)),
            Right(b) => Right(b),
        }
    }

    /// Apply the function `f` on the value `b` in `Right(b)` or `Both(a, b)` variants.
    /// If it is present rewrapping the result in `self`'s original variant.
    pub fn map_right<F, M>(self, f: F) -> EitherOrBoth<A, M>
    where
        F: FnOnce(B) -> M,
    {
        match self {
            Left(a) => Left(a),
            Right(b) => Right(f(b)),
            Both(a, b) => Both(a, f(b)),
        }
    }

    /// Apply the functions `f` and `g` on the value `a` and `b` respectively;
    /// found in `Left(a)`, `Right(b)`, or `Both(a, b)` variants.
    /// The Result is rewrapped `self`'s original variant.
    pub fn map_any<F, L, G, R>(self, f: F, g: G) -> EitherOrBoth<L, R>
    where
        F: FnOnce(A) -> L,
        G: FnOnce(B) -> R,
    {
        match self {
            Left(a) => Left(f(a)),
            Right(b) => Right(g(b)),
            Both(a, b) => Both(f(a), g(b)),
        }
    }

    /// Apply the function `f` on the value `b` in `Right(b)` or `Both(a, _)` variants if it is
    /// present.
    pub fn left_and_then<F, L>(self, f: F) -> EitherOrBoth<L, B>
    where
        F: FnOnce(A) -> EitherOrBoth<L, B>,
    {
        match self {
            Left(a) | Both(a, _) => f(a),
            Right(b) => Right(b),
        }
    }

    /// Apply the function `f` on the value `a`
    /// in `Left(a)` or `Both(a, _)` variants if it is present.
    pub fn right_and_then<F, R>(self, f: F) -> EitherOrBoth<A, R>
    where
        F: FnOnce(B) -> EitherOrBoth<A, R>,
    {
        match self {
            Left(a) => Left(a),
            Right(b) | Both(_, b) => f(b),
        }
    }
}

impl<T> EitherOrBoth<T, T> {
    /// Return either value of left, right, or the product of `f` applied where `Both` are present.
    pub fn reduce<F>(self, f: F) -> T
    where
        F: FnOnce(T, T) -> T,
    {
        match self {
            Left(a) => a,
            Right(b) => b,
            Both(a, b) => f(a, b),
        }
    }
}

impl<A, B> Into<Option<Either<A, B>>> for EitherOrBoth<A, B> {
    fn into(self) -> Option<Either<A, B>> {
        match self {
            EitherOrBoth::Left(l) => Some(Either::Left(l)),
            EitherOrBoth::Right(r) => Some(Either::Right(r)),
            _ => None,
        }
    }
}
<commit_msg>either_or_both: Fix Left/Right confusion in docstrings<commit_after>use crate::EitherOrBoth::*;

use either::Either;

/// Value that either holds a single A or B, or both.
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum EitherOrBoth<A, B> {
    /// Both values are present.
    Both(A, B),
    /// Only the left value of type `A` is present.
    Left(A),
    /// Only the right value of type `B` is present.
    Right(B),
}

impl<A, B> EitherOrBoth<A, B> {
    /// If `Left`, or `Both`, return true, otherwise, return false.
    pub fn has_left(&self) -> bool {
        self.as_ref().left().is_some()
    }

    /// If `Right`, or `Both`, return true, otherwise, return false.
    pub fn has_right(&self) -> bool {
        self.as_ref().right().is_some()
    }

    /// If Left, return true otherwise, return false.
    /// Exclusive version of [`has_left`](Self::has_left).
    pub fn is_left(&self) -> bool {
        match *self {
            Left(_) => true,
            _ => false,
        }
    }

    /// If Right, return true otherwise, return false.
    /// Exclusive version of [`has_right`](Self::has_right).
    pub fn is_right(&self) -> bool {
        match *self {
            Right(_) => true,
            _ => false,
        }
    }

    /// If Right, return true otherwise, return false.
    /// Equivalent to `self.as_ref().both().is_some()`.
    pub fn is_both(&self) -> bool {
        self.as_ref().both().is_some()
    }

    /// If `Left`, or `Both`, return `Some` with the left value, otherwise, return `None`.
    pub fn left(self) -> Option<A> {
        match self {
            Left(left) | Both(left, _) => Some(left),
            _ => None,
        }
    }

    /// If `Right`, or `Both`, return `Some` with the right value, otherwise, return `None`.
    pub fn right(self) -> Option<B> {
        match self {
            Right(right) | Both(_, right) => Some(right),
            _ => None,
        }
    }

    /// If Both, return `Some` tuple containing left and right.
    pub fn both(self) -> Option<(A, B)> {
        match self {
            Both(a, b) => Some((a, b)),
            _ => None,
        }
    }

    /// Converts from `&EitherOrBoth<A, B>` to `EitherOrBoth<&A, &B>`.
    pub fn as_ref(&self) -> EitherOrBoth<&A, &B> {
        match *self {
            Left(ref left) => Left(left),
            Right(ref right) => Right(right),
            Both(ref left, ref right) => Both(left, right),
        }
    }

    /// Converts from `&mut EitherOrBoth<A, B>` to `EitherOrBoth<&mut A, &mut B>`.
    pub fn as_mut(&mut self) -> EitherOrBoth<&mut A, &mut B> {
        match *self {
            Left(ref mut left) => Left(left),
            Right(ref mut right) => Right(right),
            Both(ref mut left, ref mut right) => Both(left, right),
        }
    }

    /// Convert `EitherOrBoth<A, B>` to `EitherOrBoth<B, A>`.
    pub fn flip(self) -> EitherOrBoth<B, A> {
        match self {
            Left(a) => Right(a),
            Right(b) => Left(b),
            Both(a, b) => Both(b, a),
        }
    }

    /// Apply the function `f` on the value `a` in `Left(a)` or `Both(a, b)` variants. If it is
    /// present rewrapping the result in `self`'s original variant.
    pub fn map_left<F, M>(self, f: F) -> EitherOrBoth<M, B>
    where
        F: FnOnce(A) -> M,
    {
        match self {
            Both(a, b) => Both(f(a), b),
            Left(a) => Left(f(a)),
            Right(b) => Right(b),
        }
    }

    /// Apply the function `f` on the value `b` in `Right(b)` or `Both(a, b)` variants.
    /// If it is present rewrapping the result in `self`'s original variant.
    pub fn map_right<F, M>(self, f: F) -> EitherOrBoth<A, M>
    where
        F: FnOnce(B) -> M,
    {
        match self {
            Left(a) => Left(a),
            Right(b) => Right(f(b)),
            Both(a, b) => Both(a, f(b)),
        }
    }

    /// Apply the functions `f` and `g` on the value `a` and `b` respectively;
    /// found in `Left(a)`, `Right(b)`, or `Both(a, b)` variants.
    /// The Result is rewrapped `self`'s original variant.
    pub fn map_any<F, L, G, R>(self, f: F, g: G) -> EitherOrBoth<L, R>
    where
        F: FnOnce(A) -> L,
        G: FnOnce(B) -> R,
    {
        match self {
            Left(a) => Left(f(a)),
            Right(b) => Right(g(b)),
            Both(a, b) => Both(f(a), g(b)),
        }
    }

    /// Apply the function `f` on the value `a` in `Left(a)` or `Both(a, _)` variants if it is
    /// present.
    pub fn left_and_then<F, L>(self, f: F) -> EitherOrBoth<L, B>
    where
        F: FnOnce(A) -> EitherOrBoth<L, B>,
    {
        match self {
            Left(a) | Both(a, _) => f(a),
            Right(b) => Right(b),
        }
    }

    /// Apply the function `f` on the value `b`
    /// in `Right(b)` or `Both(_, b)` variants if it is present.
    pub fn right_and_then<F, R>(self, f: F) -> EitherOrBoth<A, R>
    where
        F: FnOnce(B) -> EitherOrBoth<A, R>,
    {
        match self {
            Left(a) => Left(a),
            Right(b) | Both(_, b) => f(b),
        }
    }
}

impl<T> EitherOrBoth<T, T> {
    /// Return either value of left, right, or the product of `f` applied where `Both` are present.
    pub fn reduce<F>(self, f: F) -> T
    where
        F: FnOnce(T, T) -> T,
    {
        match self {
            Left(a) => a,
            Right(b) => b,
            Both(a, b) => f(a, b),
        }
    }
}

impl<A, B> Into<Option<Either<A, B>>> for EitherOrBoth<A, B> {
    fn into(self) -> Option<Either<A, B>> {
        match self {
            EitherOrBoth::Left(l) => Some(Either::Left(l)),
            EitherOrBoth::Right(r) => Some(Either::Right(r)),
            _ => None,
        }
    }
}
<|endoftext|>


<commit_before>use crate::utils::{implements_trait, snippet, span_lint_and_then};
use rustc_errors::Applicability;
use rustc_hir::{AsyncGeneratorKind, Body, BodyId, ExprKind, GeneratorKind, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:**
    /// Checks for async blocks that yield values of types that can themselves
    /// be awaited.
    ///
    /// **Why is this bad?**
    /// An await is likely missing.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// async fn foo() {}
    ///
    /// fn bar() {
    ///   let x = async {
    ///     foo()
    ///   };
    /// }
    /// ```
    /// Use instead:
    /// ```rust
    /// async fn foo() {}
    ///
    /// fn bar() {
    ///   let x = async {
    ///     foo().await
    ///   };
    /// }
    /// ```
    pub ASYNC_YIELDS_ASYNC,
    correctness,
    "async blocks that return a type that can be awaited"
}

declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]);

impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
        use AsyncGeneratorKind::{Block, Closure};
        // For functions, with explicitly defined types, don't warn.
        // XXXkhuey maybe we should?
        if let Some(GeneratorKind::Async(Block | Closure)) = body.generator_kind {
            if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() {
                let body_id = BodyId {
                    hir_id: body.value.hir_id,
                };
                let def_id = cx.tcx.hir().body_owner_def_id(body_id);
                let typeck_results = cx.tcx.typeck(def_id);
                let expr_ty = typeck_results.expr_ty(&body.value);

                if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {
                    let return_expr_span = match &body.value.kind {
                        // XXXkhuey there has to be a better way.
                        ExprKind::Block(block, _) => block.expr.map(|e| e.span),
                        ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span),
                        _ => None,
                    };
                    if let Some(return_expr_span) = return_expr_span {
                        span_lint_and_then(
                            cx,
                            ASYNC_YIELDS_ASYNC,
                            return_expr_span,
                            "an async construct yields a type which is itself awaitable",
                            |db| {
                                db.span_label(body.value.span, "outer async construct");
                                db.span_label(return_expr_span, "awaitable value not awaited");
                                db.span_suggestion(
                                    return_expr_span,
                                    "consider awaiting this value",
                                    format!("{}.await", snippet(cx, return_expr_span, "..")),
                                    Applicability::MaybeIncorrect,
                                );
                            },
                        );
                    }
                }
            }
        }
    }
}
<commit_msg>Formatting changes requested by ThibsG.<commit_after>use crate::utils::{implements_trait, snippet, span_lint_and_then};
use rustc_errors::Applicability;
use rustc_hir::{AsyncGeneratorKind, Body, BodyId, ExprKind, GeneratorKind, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for async blocks that yield values of types
    /// that can themselves be awaited.
    ///
    /// **Why is this bad?** An await is likely missing.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// async fn foo() {}
    ///
    /// fn bar() {
    ///   let x = async {
    ///     foo()
    ///   };
    /// }
    /// ```
    /// Use instead:
    /// ```rust
    /// async fn foo() {}
    ///
    /// fn bar() {
    ///   let x = async {
    ///     foo().await
    ///   };
    /// }
    /// ```
    pub ASYNC_YIELDS_ASYNC,
    correctness,
    "async blocks that return a type that can be awaited"
}

declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]);

impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
        use AsyncGeneratorKind::{Block, Closure};
        // For functions, with explicitly defined types, don't warn.
        // XXXkhuey maybe we should?
        if let Some(GeneratorKind::Async(Block | Closure)) = body.generator_kind {
            if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() {
                let body_id = BodyId {
                    hir_id: body.value.hir_id,
                };
                let def_id = cx.tcx.hir().body_owner_def_id(body_id);
                let typeck_results = cx.tcx.typeck(def_id);
                let expr_ty = typeck_results.expr_ty(&body.value);

                if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {
                    let return_expr_span = match &body.value.kind {
                        // XXXkhuey there has to be a better way.
                        ExprKind::Block(block, _) => block.expr.map(|e| e.span),
                        ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span),
                        _ => None,
                    };
                    if let Some(return_expr_span) = return_expr_span {
                        span_lint_and_then(
                            cx,
                            ASYNC_YIELDS_ASYNC,
                            return_expr_span,
                            "an async construct yields a type which is itself awaitable",
                            |db| {
                                db.span_label(body.value.span, "outer async construct");
                                db.span_label(return_expr_span, "awaitable value not awaited");
                                db.span_suggestion(
                                    return_expr_span,
                                    "consider awaiting this value",
                                    format!("{}.await", snippet(cx, return_expr_span, "..")),
                                    Applicability::MaybeIncorrect,
                                );
                            },
                        );
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate itertools;
extern crate time;

use itertools::Itertools;
use time::PreciseTime;

fn check_sum_zero(v: Vec<i32>) -> bool {
    let int_list = v;

    for i in (1..int_list.len()+1).rev() {

        let iter = int_list.iter();

        for item in iter.combinations(i) {
            let a = item.into_iter();
            let sum: i32 = a.sum();

            if sum == 0 {
                return true;
            }
        }
    }
    return false;
}

fn main() {
    // Main function only for benchmarking Optional bonus 2
    println!("Running optional bonus 2 test...");

    let start = PreciseTime::now();

    let list_1 = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29];

    println!("Result: {:?}", check_sum_zero(list_1));

    let end = PreciseTime::now();

    println!("Second to finish: {}", start.to(end));

}

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

    #[test]
    fn base_examples_ok() {

        let list_ok = [vec![-5, -3, -1, 2, 4, 6], vec![-1, 1],
            vec![-97364, -71561, -69336, 19675, 71561, 97863],
            vec![-53974, -39140, -36561, -23935, -15680, 0], vec![-2, 2, 3]];

        for list_vector in list_ok.iter() {
            assert_eq!(true, check_sum_zero(list_vector.to_vec()));
        }

    }

    #[test]
    fn base_examples_no_ok() {
        let list_no_ok = [vec![1, 2, 3], vec![]];

        for list_vector in list_no_ok.iter() {
            assert_eq!(false, check_sum_zero(list_vector.to_vec()));
        }
    }

    #[test]
    fn optional_bonus_ok() {
        let list_ok = [vec![0], vec![-3, 1, 2],
            vec![-98634, -86888, -48841, -40483, 2612, 9225, 17848, 71967, 84319, 88875]];

        for list_vector in list_ok.iter() {
            assert_eq!(true, check_sum_zero(list_vector.to_vec()));
        }
    }

    #[test]
    fn optional_bonus_examples_no_ok() {
        let list_no_ok = [vec![-83314, -82838, -80120, -63468, -62478, -59378, -56958, -50061, -34791, -32264, -21928, -14988, 23767, 24417, 26403, 26511, 36399, 78055],
            vec![-92953, -91613, -89733, -50673, -16067, -9172, 8852, 30883, 46690, 46968, 56772, 58703, 59150, 78476, 84413, 90106, 94777, 95148],
            vec![-94624, -86776, -85833, -80822, -71902, -54562, -38638, -26483, -20207, -1290, 12414, 12627, 19509, 30894, 32505, 46825, 50321, 69294],
            vec![-83964, -81834, -78386, -70497, -69357, -61867, -49127, -47916, -38361, -35772, -29803, -15343, 6918, 19662, 44614, 66049, 93789, 95405],
            vec![-68808, -58968, -45958, -36013, -32810, -28726, -13488, 3986, 26342, 29245, 30686, 47966, 58352, 68610, 74533, 77939, 80520, 87195]];

        for list_vector in list_no_ok.iter() {
            assert_eq!(false, check_sum_zero(list_vector.to_vec()));
        }
    }

    #[test]
    fn optional_bonus_examples_ok() {
        let list_ok = [vec![-97162, -95761, -94672, -87254, -57207, -22163, -20207, -1753, 11646, 13652, 14572, 30580, 52502, 64282, 74896, 83730, 89889, 92200],
            vec![-93976, -93807, -64604, -59939, -44394, -36454, -34635, -16483, 267, 3245, 8031, 10622, 44815, 46829, 61689, 65756, 69220, 70121],
            vec![-92474, -61685, -55348, -42019, -35902, -7815, -5579, 4490, 14778, 19399, 34202, 46624, 55800, 57719, 60260, 71511, 75665, 82754],
            vec![-85029, -84549, -82646, -80493, -73373, -57478, -56711, -42456, -38923, -29277, -3685, -3164, 26863, 29890, 37187, 46607, 69300, 84808],
            vec![-87565, -71009, -49312, -47554, -27197, 905, 2839, 8657, 14622, 32217, 35567, 38470, 46885, 59236, 64704, 82944, 86902, 90487]];

        for list_vector in list_ok.iter() {
            assert_eq!(true, check_sum_zero(list_vector.to_vec()));
        }
    }

    #[test]
    fn optional_bonus_2() {
        let list_1 = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];

        assert_eq!(false, check_sum_zero(list_1));

    }
}<commit_msg>Refactor<commit_after>extern crate itertools;
extern crate time;

use itertools::Itertools;
use time::PreciseTime;

fn check_sum_zero(v: Vec<i32>) -> bool {
    let int_list = v;

    for i in (1..int_list.len()+1).rev() {

        let iter = int_list.iter();

        for item in iter.combinations(i) {
            let a = item.into_iter();
            let sum: i32 = a.sum();

            if sum == 0 {
                return true;
            }
        }
    }
    return false;
}

fn main() {
    // Main function only for benchmarking Optional bonus 2
    let start = PreciseTime::now();
    println!("Running optional bonus 2 test...");

    let list_1 = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24];

    println!("Result: {:?}", check_sum_zero(list_1));

    let end = PreciseTime::now();

    println!("Second to finish: {}", start.to(end));

}

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

    #[test]
    fn base_examples_ok() {

        let list_ok = [vec![-5, -3, -1, 2, 4, 6], vec![-1, 1],
            vec![-97364, -71561, -69336, 19675, 71561, 97863],
            vec![-53974, -39140, -36561, -23935, -15680, 0], vec![-2, 2, 3]];

        for list_vector in list_ok.iter() {
            assert_eq!(true, check_sum_zero(list_vector.to_vec()));
        }

    }

    #[test]
    fn base_examples_no_ok() {
        let list_no_ok = [vec![1, 2, 3], vec![]];

        for list_vector in list_no_ok.iter() {
            assert_eq!(false, check_sum_zero(list_vector.to_vec()));
        }
    }

    #[test]
    fn optional_bonus_ok() {
        let list_ok = [vec![0], vec![-3, 1, 2],
            vec![-98634, -86888, -48841, -40483, 2612, 9225, 17848, 71967, 84319, 88875]];

        for list_vector in list_ok.iter() {
            assert_eq!(true, check_sum_zero(list_vector.to_vec()));
        }
    }

    #[test]
    fn optional_bonus_examples_no_ok() {
        let list_no_ok = [vec![-83314, -82838, -80120, -63468, -62478, -59378, -56958, -50061, -34791, -32264, -21928, -14988, 23767, 24417, 26403, 26511, 36399, 78055],
            vec![-92953, -91613, -89733, -50673, -16067, -9172, 8852, 30883, 46690, 46968, 56772, 58703, 59150, 78476, 84413, 90106, 94777, 95148],
            vec![-94624, -86776, -85833, -80822, -71902, -54562, -38638, -26483, -20207, -1290, 12414, 12627, 19509, 30894, 32505, 46825, 50321, 69294],
            vec![-83964, -81834, -78386, -70497, -69357, -61867, -49127, -47916, -38361, -35772, -29803, -15343, 6918, 19662, 44614, 66049, 93789, 95405],
            vec![-68808, -58968, -45958, -36013, -32810, -28726, -13488, 3986, 26342, 29245, 30686, 47966, 58352, 68610, 74533, 77939, 80520, 87195]];

        for list_vector in list_no_ok.iter() {
            assert_eq!(false, check_sum_zero(list_vector.to_vec()));
        }
    }

    #[test]
    fn optional_bonus_examples_ok() {
        let list_ok = [vec![-97162, -95761, -94672, -87254, -57207, -22163, -20207, -1753, 11646, 13652, 14572, 30580, 52502, 64282, 74896, 83730, 89889, 92200],
            vec![-93976, -93807, -64604, -59939, -44394, -36454, -34635, -16483, 267, 3245, 8031, 10622, 44815, 46829, 61689, 65756, 69220, 70121],
            vec![-92474, -61685, -55348, -42019, -35902, -7815, -5579, 4490, 14778, 19399, 34202, 46624, 55800, 57719, 60260, 71511, 75665, 82754],
            vec![-85029, -84549, -82646, -80493, -73373, -57478, -56711, -42456, -38923, -29277, -3685, -3164, 26863, 29890, 37187, 46607, 69300, 84808],
            vec![-87565, -71009, -49312, -47554, -27197, 905, 2839, 8657, 14622, 32217, 35567, 38470, 46885, 59236, 64704, 82944, 86902, 90487]];

        for list_vector in list_ok.iter() {
            assert_eq!(true, check_sum_zero(list_vector.to_vec()));
        }
    }
}<|endoftext|>