<commit_before>//! Client Connection.  It supports unsecured and secured(SSL) connection
//#[cfg(feature = "ssl")]
//use std::borrow::ToOwned;
#[cfg(feature = "ssl")]
use std::error::Error as StdError;
#[cfg(feature = "ssl")]
use std::io::{ErrorKind, Error};
#[cfg(feature = "ssl")]
use std::sync::{Arc, Mutex};
#[cfg(feature = "ssl")]
use std::result::Result as StdResult;
use std::io::{Write, Read, Result, BufReader, BufWriter};
use std::net::TcpStream;
#[cfg(test)]
use std::net::Shutdown;
use std::os::unix::prelude::AsRawFd;

#[cfg(feature = "ssl")]
use openssl::ssl::{HandshakeError, SslConnectorBuilder, SslContextBuilder, SslContext, Ssl,
                   SslMethod, SslStream, SSL_VERIFY_PEER, SSL_VERIFY_NONE};
#[cfg(feature = "ssl")]
use openssl::error::ErrorStack;
#[cfg(feature = "ssl")]
use openssl::x509;

// use std::bool;
use net::config;
use uuid::Uuid;

// pub mod config;

/// A Connection object.  Make sure you syncronize if uses in multiple threads
pub struct Connection {
    id: String,
    /// BufReader for NetStream (TCP/SSL)
    pub reader: BufReader<NetStream>,
    /// BufWriter for NetStream (TCP/SSL)
    pub writer: BufWriter<NetStream>,
    /// Config for connection
    config: config::Config,
}

/// Implementation for Connectio
impl Connection {
    /// new function to create default Connection object
    fn new(
        reader: BufReader<NetStream>,
        writer: BufWriter<NetStream>,
        config: &config::Config,
    ) -> Connection {
        Connection {
            id: Uuid::new_v4().to_urn_string(),
            reader: reader,
            writer: writer,
            config: config.clone(),
        }
    }

    /// connection unique id

    /// Creates a  TCP connection to the specified server.

    pub fn connect(config: &config::Config) -> Result<Connection> {
        if config.use_ssl.unwrap_or(false) {
            Connection::connect_ssl_internal(config)
        } else {
            Connection::connect_internal(config)
        }
    }

    /// Creates a  TCP/SSL connection to the specified server.
    ///If already connected, it will drop and reconnect

    pub fn reconnect(&mut self) -> Result<Connection> {
        if self.config.use_ssl.unwrap_or(false) {
            Connection::connect_ssl_internal(&self.config)
        } else {
            Connection::connect_internal(&self.config)
        }
    }

    /// Get the connection id
    pub fn id(&self) -> &String {
        &self.id
    }

    /// Is Valid connection
    pub fn is_valid(&self) -> bool {
        match self.reader.get_ref() {
            &NetStream::UnsecuredTcpStream(ref tcp) => {
                debug!("TCP FD:{}", tcp.as_raw_fd());
                if tcp.as_raw_fd() < 0 { false } else { true }
            }
            #[cfg(feature = "ssl")]
            &NetStream::SslTcpStream(ref ssl) => {
                let fd = ssl.lock().unwrap().get_ref().as_raw_fd();
                debug!("SSL FD:{}", fd);
                if fd < 0 {
                    return false;
                } else {
                    return true;
                }
            }
        }
    }

    /// Creates a TCP connection with an optional timeout.

    fn connect_internal(config: &config::Config) -> Result<Connection> {
        let host: &str = &config.server.clone().unwrap();
        let port = config.port.unwrap();
        info!("Connecting to server {}:{}", host, port);
        let stream_socket = try!(TcpStream::connect((host, port)));
        let writer_socket = try!(stream_socket.try_clone());
        // fixme:  socket.set_timeout(config.connect_timeout);
        Ok(Connection::new(
            BufReader::new(NetStream::UnsecuredTcpStream(stream_socket)),
            BufWriter::new(NetStream::UnsecuredTcpStream(writer_socket)),
            config,
        ))
    }

    /// Panics because SSL support was not included at compilation.
    #[cfg(not(feature = "ssl"))]
    fn connect_ssl_internal(config: &config::Config) -> Result<Connection> {
        panic!(
            "Cannot connect to {}:{} over SSL without compiling with SSL support.",
            config.server.clone().unwrap(),
            config.port.unwrap()
        )
    }

    /// Creates a  TCP connection over SSL.
    #[cfg(feature = "ssl")]
    fn connect_ssl_internal(config: &config::Config) -> Result<Connection> {
        let host: &str = &config.server.clone().unwrap();
        let port = config.port.unwrap();
        info!("Connecting to server {}:{}", host, port);

        let socket = try!(TcpStream::connect((host, port)));
        socket.set_read_timeout(config.read_timeout);
        socket.set_write_timeout(config.write_timeout);

        let mut ssl_connector_builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
        {
            let ctx = ssl_connector_builder.builder_mut();

            ctx.set_default_verify_paths().unwrap();

            // verify peer
            if config.verify.unwrap_or(false) {
                ctx.set_verify(SSL_VERIFY_PEER);
            } else {
                ctx.set_verify(SSL_VERIFY_NONE);
            }
            // verify depth
            if config.verify_depth.unwrap_or(0) > 0 {
                ctx.set_verify_depth(config.verify_depth.unwrap());
            }
            if config.certificate_file.is_some() {
                try!(ssl_to_io(ctx.set_certificate_file(
                    config.certificate_file.as_ref().unwrap(),
                    x509::X509_FILETYPE_PEM,
                )));
            }
            if config.private_key_file.is_some() {
                try!(ssl_to_io(ctx.set_private_key_file(
                    config.private_key_file.as_ref().unwrap(),
                    x509::X509_FILETYPE_PEM,
                )));
            }
            if config.ca_file.is_some() {
                try!(ssl_to_io(ctx.set_ca_file(config.ca_file.as_ref().unwrap())));
            }
        }
        let ssl_connector = ssl_connector_builder.build();

        let stream_socket_result =
            match ssl_connector.connect(&*format!("{}:{}", host, port), socket) {
                Ok(s) => s,
                Err(e) => {
                    return Err(Error::new(
                        ErrorKind::Other,
                        &format!(
                            "An SSL error occurred. ({}:{})",
                            e.description(),
                            e.cause().unwrap()
                        )
                            [..],
                    ));
                }
            };

        let stream_socket = Arc::new(Mutex::new(stream_socket_result));
        let writer_stream = Arc::clone(&stream_socket);
        Ok(Connection::new(
            BufReader::new(NetStream::SslTcpStream(stream_socket)),
            BufWriter::new(NetStream::SslTcpStream(writer_stream)),
            config,
        ))

    }
}

/// Converts a Result<T, SslError> isizeo an Result<T>.
#[cfg(feature = "ssl")]
fn ssl_to_io<T>(res: StdResult<T, ErrorStack>) -> Result<T> {
    match res {
        Ok(x) => Ok(x),
        Err(e) => {
            Err(Error::new(
                ErrorKind::Other,
                &format!("An SSL error occurred. ({})", e.description())[..],
            ))
        }
    }
}

/// An abstraction over different networked streams.

pub enum NetStream {
    /// An unsecured TcpStream.
    UnsecuredTcpStream(TcpStream),
    /// An SSL-secured TcpStream.
    /// This is only available when compiled with SSL support.
    #[cfg(feature = "ssl")]
    SslTcpStream(Arc<Mutex<SslStream<TcpStream>>>),
}
// trait Reader {
//     fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
// }
impl Read for NetStream {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        match self {
            &mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.read(buf),
            #[cfg(feature = "ssl")]
            &mut NetStream::SslTcpStream(ref mut stream) => stream.lock().unwrap().read(buf),
        }
    }
}
// trait Writer {
//     fn write(&mut self, buf: &[u8]) -> Result<()>;
//     fn write_all(&mut self, buf: &[u8]) -> Result<()>;
// }
impl Write for NetStream {
    fn write(&mut self, buf: &[u8]) -> Result<(usize)> {
        match self {
            &mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.write(buf),
            #[cfg(feature = "ssl")]
            &mut NetStream::SslTcpStream(ref mut stream) => {
                // Arc::get_mut(stream).unwrap().write(buf)
                stream.lock().unwrap().write(buf)
            }
        }

    }
    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
        match self {
            &mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.write_all(buf),
            #[cfg(feature = "ssl")]
            &mut NetStream::SslTcpStream(ref mut stream) => stream.lock().unwrap().write_all(buf),
        }
    }
    fn flush(&mut self) -> Result<()> {
        match self {
            &mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.flush(),
            #[cfg(feature = "ssl")]
            &mut NetStream::SslTcpStream(ref mut stream) => stream.lock().unwrap().flush(),
        }
    }
}

#[cfg(test)]
#[allow(unused_must_use)]
impl Drop for Connection {
    ///drop method
    fn drop(&mut self) {
        info!(
            "Drop for Connection:Dropping connection id: {}",
            self.id.clone()
        );
        match self.reader.get_mut() {
            &mut NetStream::UnsecuredTcpStream(ref mut stream) => {
                stream.shutdown(Shutdown::Read);
                stream.shutdown(Shutdown::Write);
            }
            #[cfg(feature = "ssl")]
            &mut NetStream::SslTcpStream(ref mut ssl) => {
                ssl.lock().unwrap().shutdown();
            }
        }
    }
}
<commit_msg>removed unused imports<commit_after>//! Client Connection.  It supports unsecured and secured(SSL) connection
//#[cfg(feature = "ssl")]
//use std::borrow::ToOwned;
#[cfg(feature = "ssl")]
use std::error::Error as StdError;
#[cfg(feature = "ssl")]
use std::io::{ErrorKind, Error};
#[cfg(feature = "ssl")]
use std::sync::{Arc, Mutex};
#[cfg(feature = "ssl")]
use std::result::Result as StdResult;
use std::io::{Write, Read, Result, BufReader, BufWriter};
use std::net::TcpStream;
#[cfg(test)]
use std::net::Shutdown;
use std::os::unix::prelude::AsRawFd;

#[cfg(feature = "ssl")]
use openssl::ssl::{SslConnectorBuilder, SslMethod, SslStream, SSL_VERIFY_PEER, SSL_VERIFY_NONE};
#[cfg(feature = "ssl")]
use openssl::error::ErrorStack;
#[cfg(feature = "ssl")]
use openssl::x509;

// use std::bool;
use net::config;
use uuid::Uuid;

// pub mod config;

/// A Connection object.  Make sure you syncronize if uses in multiple threads
pub struct Connection {
    id: String,
    /// BufReader for NetStream (TCP/SSL)
    pub reader: BufReader<NetStream>,
    /// BufWriter for NetStream (TCP/SSL)
    pub writer: BufWriter<NetStream>,
    /// Config for connection
    config: config::Config,
}

/// Implementation for Connectio
impl Connection {
    /// new function to create default Connection object
    fn new(
        reader: BufReader<NetStream>,
        writer: BufWriter<NetStream>,
        config: &config::Config,
    ) -> Connection {
        Connection {
            id: Uuid::new_v4().to_urn_string(),
            reader: reader,
            writer: writer,
            config: config.clone(),
        }
    }

    /// connection unique id

    /// Creates a  TCP connection to the specified server.

    pub fn connect(config: &config::Config) -> Result<Connection> {
        if config.use_ssl.unwrap_or(false) {
            Connection::connect_ssl_internal(config)
        } else {
            Connection::connect_internal(config)
        }
    }

    /// Creates a  TCP/SSL connection to the specified server.
    ///If already connected, it will drop and reconnect

    pub fn reconnect(&mut self) -> Result<Connection> {
        if self.config.use_ssl.unwrap_or(false) {
            Connection::connect_ssl_internal(&self.config)
        } else {
            Connection::connect_internal(&self.config)
        }
    }

    /// Get the connection id
    pub fn id(&self) -> &String {
        &self.id
    }

    /// Is Valid connection
    pub fn is_valid(&self) -> bool {
        match self.reader.get_ref() {
            &NetStream::UnsecuredTcpStream(ref tcp) => {
                debug!("TCP FD:{}", tcp.as_raw_fd());
                if tcp.as_raw_fd() < 0 { false } else { true }
            }
            #[cfg(feature = "ssl")]
            &NetStream::SslTcpStream(ref ssl) => {
                let fd = ssl.lock().unwrap().get_ref().as_raw_fd();
                debug!("SSL FD:{}", fd);
                if fd < 0 {
                    return false;
                } else {
                    return true;
                }
            }
        }
    }

    /// Creates a TCP connection with an optional timeout.

    fn connect_internal(config: &config::Config) -> Result<Connection> {
        let host: &str = &config.server.clone().unwrap();
        let port = config.port.unwrap();
        info!("Connecting to server {}:{}", host, port);
        let stream_socket = try!(TcpStream::connect((host, port)));
        let writer_socket = try!(stream_socket.try_clone());
        // fixme:  socket.set_timeout(config.connect_timeout);
        Ok(Connection::new(
            BufReader::new(NetStream::UnsecuredTcpStream(stream_socket)),
            BufWriter::new(NetStream::UnsecuredTcpStream(writer_socket)),
            config,
        ))
    }

    /// Panics because SSL support was not included at compilation.
    #[cfg(not(feature = "ssl"))]
    fn connect_ssl_internal(config: &config::Config) -> Result<Connection> {
        panic!(
            "Cannot connect to {}:{} over SSL without compiling with SSL support.",
            config.server.clone().unwrap(),
            config.port.unwrap()
        )
    }

    /// Creates a  TCP connection over SSL.
    #[cfg(feature = "ssl")]
    fn connect_ssl_internal(config: &config::Config) -> Result<Connection> {
        let host: &str = &config.server.clone().unwrap();
        let port = config.port.unwrap();
        info!("Connecting to server {}:{}", host, port);

        let socket = try!(TcpStream::connect((host, port)));
        socket.set_read_timeout(config.read_timeout);
        socket.set_write_timeout(config.write_timeout);

        let mut ssl_connector_builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
        {
            let ctx = ssl_connector_builder.builder_mut();

            ctx.set_default_verify_paths().unwrap();

            // verify peer
            if config.verify.unwrap_or(false) {
                ctx.set_verify(SSL_VERIFY_PEER);
            } else {
                ctx.set_verify(SSL_VERIFY_NONE);
            }
            // verify depth
            if config.verify_depth.unwrap_or(0) > 0 {
                ctx.set_verify_depth(config.verify_depth.unwrap());
            }
            if config.certificate_file.is_some() {
                try!(ssl_to_io(ctx.set_certificate_file(
                    config.certificate_file.as_ref().unwrap(),
                    x509::X509_FILETYPE_PEM,
                )));
            }
            if config.private_key_file.is_some() {
                try!(ssl_to_io(ctx.set_private_key_file(
                    config.private_key_file.as_ref().unwrap(),
                    x509::X509_FILETYPE_PEM,
                )));
            }
            if config.ca_file.is_some() {
                try!(ssl_to_io(ctx.set_ca_file(config.ca_file.as_ref().unwrap())));
            }
        }
        let ssl_connector = ssl_connector_builder.build();

        let stream_socket_result =
            match ssl_connector.connect(&*format!("{}:{}", host, port), socket) {
                Ok(s) => s,
                Err(e) => {
                    return Err(Error::new(
                        ErrorKind::Other,
                        &format!(
                            "An SSL error occurred. ({}:{})",
                            e.description(),
                            e.cause().unwrap()
                        )
                            [..],
                    ));
                }
            };

        let stream_socket = Arc::new(Mutex::new(stream_socket_result));
        let writer_stream = Arc::clone(&stream_socket);
        Ok(Connection::new(
            BufReader::new(NetStream::SslTcpStream(stream_socket)),
            BufWriter::new(NetStream::SslTcpStream(writer_stream)),
            config,
        ))

    }
}

/// Converts a Result<T, SslError> isizeo an Result<T>.
#[cfg(feature = "ssl")]
fn ssl_to_io<T>(res: StdResult<T, ErrorStack>) -> Result<T> {
    match res {
        Ok(x) => Ok(x),
        Err(e) => {
            Err(Error::new(
                ErrorKind::Other,
                &format!("An SSL error occurred. ({})", e.description())[..],
            ))
        }
    }
}

/// An abstraction over different networked streams.

pub enum NetStream {
    /// An unsecured TcpStream.
    UnsecuredTcpStream(TcpStream),
    /// An SSL-secured TcpStream.
    /// This is only available when compiled with SSL support.
    #[cfg(feature = "ssl")]
    SslTcpStream(Arc<Mutex<SslStream<TcpStream>>>),
}
// trait Reader {
//     fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
// }
impl Read for NetStream {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        match self {
            &mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.read(buf),
            #[cfg(feature = "ssl")]
            &mut NetStream::SslTcpStream(ref mut stream) => stream.lock().unwrap().read(buf),
        }
    }
}
// trait Writer {
//     fn write(&mut self, buf: &[u8]) -> Result<()>;
//     fn write_all(&mut self, buf: &[u8]) -> Result<()>;
// }
impl Write for NetStream {
    fn write(&mut self, buf: &[u8]) -> Result<(usize)> {
        match self {
            &mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.write(buf),
            #[cfg(feature = "ssl")]
            &mut NetStream::SslTcpStream(ref mut stream) => {
                // Arc::get_mut(stream).unwrap().write(buf)
                stream.lock().unwrap().write(buf)
            }
        }

    }
    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
        match self {
            &mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.write_all(buf),
            #[cfg(feature = "ssl")]
            &mut NetStream::SslTcpStream(ref mut stream) => stream.lock().unwrap().write_all(buf),
        }
    }
    fn flush(&mut self) -> Result<()> {
        match self {
            &mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.flush(),
            #[cfg(feature = "ssl")]
            &mut NetStream::SslTcpStream(ref mut stream) => stream.lock().unwrap().flush(),
        }
    }
}

#[cfg(test)]
#[allow(unused_must_use)]
impl Drop for Connection {
    ///drop method
    fn drop(&mut self) {
        info!(
            "Drop for Connection:Dropping connection id: {}",
            self.id.clone()
        );
        match self.reader.get_mut() {
            &mut NetStream::UnsecuredTcpStream(ref mut stream) => {
                stream.shutdown(Shutdown::Read);
                stream.shutdown(Shutdown::Write);
            }
            #[cfg(feature = "ssl")]
            &mut NetStream::SslTcpStream(ref mut ssl) => {
                ssl.lock().unwrap().shutdown();
            }
        }
    }
}
<|endoftext|>


<commit_before>use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_derive(Completer)]
pub fn completer_macro_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;
    let generics = input.generics;
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
    let expanded = quote! {
        impl #impl_generics rustyline::completion::Completer for #name #ty_generics #where_clause {
            type Candidate = std::string::String;
        }
    };
    TokenStream::from(expanded)
}

#[proc_macro_derive(Helper)]
pub fn helper_macro_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;
    let generics = input.generics;
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
    let expanded = quote! {
        impl #impl_generics rustyline::Helper for #name #ty_generics #where_clause {
        }
    };
    TokenStream::from(expanded)
}

#[proc_macro_derive(Highlighter)]
pub fn highlighter_macro_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;
    let generics = input.generics;
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
    let expanded = quote! {
        impl #impl_generics rustyline::highlight::Highlighter for #name #ty_generics #where_clause {
        }
    };
    TokenStream::from(expanded)
}

#[proc_macro_derive(Hinter)]
pub fn hinter_macro_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;
    let generics = input.generics;
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
    let expanded = quote! {
        impl #impl_generics rustyline::hint::Hinter for #name #ty_generics #where_clause {
            type Hint = String;
            fn hint(&self, _line: &str, _pos: usize, _ctx: &rustyline::Context<'_>)
                -> Option<Self::Hint>
            {
                None
            }
        }
    };
    TokenStream::from(expanded)
}

#[proc_macro_derive(Validator)]
pub fn validator_macro_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;
    let generics = input.generics;
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
    let expanded = quote! {
        impl #impl_generics rustyline::validate::Validator for #name #ty_generics #where_clause {
        }
    };
    TokenStream::from(expanded)
}
<commit_msg>Fix proc_macro<commit_after>use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_derive(Completer)]
pub fn completer_macro_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;
    let generics = input.generics;
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
    let expanded = quote! {
        impl #impl_generics ::rustyline::completion::Completer for #name #ty_generics #where_clause {
            type Candidate = ::std::string::String;
        }
    };
    TokenStream::from(expanded)
}

#[proc_macro_derive(Helper)]
pub fn helper_macro_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;
    let generics = input.generics;
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
    let expanded = quote! {
        impl #impl_generics ::rustyline::Helper for #name #ty_generics #where_clause {
        }
    };
    TokenStream::from(expanded)
}

#[proc_macro_derive(Highlighter)]
pub fn highlighter_macro_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;
    let generics = input.generics;
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
    let expanded = quote! {
        impl #impl_generics ::rustyline::highlight::Highlighter for #name #ty_generics #where_clause {
        }
    };
    TokenStream::from(expanded)
}

#[proc_macro_derive(Hinter)]
pub fn hinter_macro_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;
    let generics = input.generics;
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
    let expanded = quote! {
        impl #impl_generics ::rustyline::hint::Hinter for #name #ty_generics #where_clause {
            type Hint = ::std::string::String;
        }
    };
    TokenStream::from(expanded)
}

#[proc_macro_derive(Validator)]
pub fn validator_macro_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;
    let generics = input.generics;
    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
    let expanded = quote! {
        impl #impl_generics ::rustyline::validate::Validator for #name #ty_generics #where_clause {
        }
    };
    TokenStream::from(expanded)
}
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

use clap::{App, Arg};
use futures::{
    future::{self, Ready},
    prelude::*,
};
use service::World;
use std::{
    io,
    net::{IpAddr, SocketAddr},
};
use tarpc::{
    context,
    server::{self, Channel, Handler},
};
use tokio_serde::formats::Json;

// This is the type that implements the generated World trait. It is the business logic
// and is used to start the server.
#[derive(Clone)]
struct HelloServer(SocketAddr);

impl World for HelloServer {
    // Each defined rpc generates two items in the trait, a fn that serves the RPC, and
    // an associated type representing the future output by the fn.

    type HelloFut = Ready<String>;

    fn hello(self, _: context::Context, name: String) -> Self::HelloFut {
        future::ready(format!(
            "Hello, {}! You are connected from {:?}.",
            name, self.0
        ))
    }
}

#[tokio::main]
async fn main() -> io::Result<()> {
    env_logger::init();

    let flags = App::new("Hello Server")
        .version("0.1")
        .author("Tim <tikue@google.com>")
        .about("Say hello!")
        .arg(
            Arg::with_name("port")
                .short("p")
                .long("port")
                .value_name("NUMBER")
                .help("Sets the port number to listen on")
                .required(true)
                .takes_value(true),
        )
        .get_matches();

    let port = flags.value_of("port").unwrap();
    let port = port
        .parse()
        .unwrap_or_else(|e| panic!(r#"--port value "{}" invalid: {}"#, port, e));

    let server_addr = (IpAddr::from([0, 0, 0, 0]), port);

    // JSON transport is provided by the json_transport tarpc module. It makes it easy
    // to start up a serde-powered json serialization strategy over TCP.
    tarpc::serde_transport::tcp::listen(&server_addr, Json::default)
        .await?
        // Ignore accept errors.
        .filter_map(|r| future::ready(r.ok()))
        .map(server::BaseChannel::with_defaults)
        // Limit channels to 1 per IP.
        .max_channels_per_key(1, |t| t.as_ref().peer_addr().unwrap().ip())
        // serve is generated by the service attribute. It takes as input any type implementing
        // the generated World trait.
        .map(|channel| {
            let server = HelloServer(channel.as_ref().as_ref().peer_addr().unwrap());
            channel.respond_with(server.serve()).execute()
        })
        // Max 10 channels.
        .buffer_unordered(10)
        .for_each(|_| async {})
        .await;

    Ok(())
}
<commit_msg>Use #[tarpc::server] in example-service<commit_after>// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

use clap::{App, Arg};
use futures::{future, prelude::*};
use service::World;
use std::{
    io,
    net::{IpAddr, SocketAddr},
};
use tarpc::{
    context,
    server::{self, Channel, Handler},
};
use tokio_serde::formats::Json;

// This is the type that implements the generated World trait. It is the business logic
// and is used to start the server.
#[derive(Clone)]
struct HelloServer(SocketAddr);

#[tarpc::server]
impl World for HelloServer {
    async fn hello(self, _: context::Context, name: String) -> String {
        format!("Hello, {}! You are connected from {:?}.", name, self.0)
    }
}

#[tokio::main]
async fn main() -> io::Result<()> {
    env_logger::init();

    let flags = App::new("Hello Server")
        .version("0.1")
        .author("Tim <tikue@google.com>")
        .about("Say hello!")
        .arg(
            Arg::with_name("port")
                .short("p")
                .long("port")
                .value_name("NUMBER")
                .help("Sets the port number to listen on")
                .required(true)
                .takes_value(true),
        )
        .get_matches();

    let port = flags.value_of("port").unwrap();
    let port = port
        .parse()
        .unwrap_or_else(|e| panic!(r#"--port value "{}" invalid: {}"#, port, e));

    let server_addr = (IpAddr::from([0, 0, 0, 0]), port);

    // JSON transport is provided by the json_transport tarpc module. It makes it easy
    // to start up a serde-powered json serialization strategy over TCP.
    tarpc::serde_transport::tcp::listen(&server_addr, Json::default)
        .await?
        // Ignore accept errors.
        .filter_map(|r| future::ready(r.ok()))
        .map(server::BaseChannel::with_defaults)
        // Limit channels to 1 per IP.
        .max_channels_per_key(1, |t| t.as_ref().peer_addr().unwrap().ip())
        // serve is generated by the service attribute. It takes as input any type implementing
        // the generated World trait.
        .map(|channel| {
            let server = HelloServer(channel.as_ref().as_ref().peer_addr().unwrap());
            channel.respond_with(server.serve()).execute()
        })
        // Max 10 channels.
        .buffer_unordered(10)
        .for_each(|_| async {})
        .await;

    Ok(())
}
<|endoftext|>


<commit_before>use request::Request;
use method::{List, Get};
use {ROOT_URL, STATIC_URL_ERROR};
use url::Url;
use chrono::{DateTime, UTC};
use super::Region;
use super::{ApiLinks, ApiMeta};
use super::{HasValue, HasPagination, HasResponse};
use request::ActionRequest;

const ACTIONS_SEGMENT: &'static str = "actions";

/// Actions are records of events that have occurred on the resources in your
/// account. These can be things like rebooting a Droplet, or transferring an
/// image to a new region.
///
/// An action object is created every time one of these actions is initiated.
/// The action object contains information about the current status of the
/// action, start and complete timestamps, and the associated resource type
/// and ID.
///
/// Every action that creates an action object is available through this
/// endpoint. Completed actions are not removed from this list and are always
/// available for querying.
///
/// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#actions)
#[derive(Deserialize, Serialize, Debug, Clone, Getters, Setters)]
pub struct Action {
    /// A unique identifier for each Droplet action event. This is used to
    /// reference a specific action that was requested.
    #[get = "pub"]
    id: usize,
    /// The current status of the action. The value of this attribute will be
    /// "in-progress", "completed", or "errored".
    #[get = "pub"]
    status: String,
    /// The type of action that the event is executing (reboot, power_off,
    /// etc.).
    #[get = "pub"]
    started_at: DateTime<UTC>,
    /// A time value given in ISO8601 combined date and time format that
    /// represents when the action was completed.
    #[get = "pub"]
    completed_at: Option<DateTime<UTC>>,
    /// A unique identifier for the resource that the action is associated
    /// with.
    #[get = "pub"]
    resource_id: usize,
    /// The type of resource that the action is associated with.
    #[get = "pub"]
    resource_type: String,
    /// (deprecated) A slug representing the region where the action occurred.
    #[get = "pub"]
    #[deprecated(since = "0.0.1", note = "DigitalOcean has deprecated this.")]
    region: Option<Region>,
    /// A slug representing the region where the action occurred.
    #[get = "pub"]
    region_slug: Option<String>,
}

impl Action {
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#retrieve-an-existing-action)
    pub fn get(id: usize) -> ActionRequest<Get, Action> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(ACTIONS_SEGMENT)
            .push(&id.to_string());

        Request::new(url)
    }
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#list-all-actions)
    pub fn list() -> ActionRequest<List, Vec<Action>> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(ACTIONS_SEGMENT);

        Request::new(url)
    }
}

/// Response type returned from Digital Ocean.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ActionResponse {
    action: Action,
}

impl HasValue for ActionResponse {
    type Value = Action;
    fn value(self) -> Action {
        self.action
    }
}

impl HasResponse for Action {
    type Response = ActionResponse;
}

/// Response type returned from Digital Ocean.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ActionListResponse {
    actions: Vec<Action>,
    links: ApiLinks,
    meta: ApiMeta,
}

impl HasResponse for Vec<Action> {
    type Response = ActionListResponse;
}

impl HasPagination for ActionListResponse {
    fn next_page(&self) -> Option<Url> {
        self.links.next()
    }
}

impl HasValue for ActionListResponse {
    type Value = Vec<Action>;
    fn value(self) -> Vec<Action> {
        self.actions
    }
}
<commit_msg>Remove deprecated code<commit_after>use request::Request;
use method::{List, Get};
use {ROOT_URL, STATIC_URL_ERROR};
use url::Url;
use chrono::{DateTime, UTC};
use super::{ApiLinks, ApiMeta};
use super::{HasValue, HasPagination, HasResponse};
use request::ActionRequest;

const ACTIONS_SEGMENT: &'static str = "actions";

/// Actions are records of events that have occurred on the resources in your
/// account. These can be things like rebooting a Droplet, or transferring an
/// image to a new region.
///
/// An action object is created every time one of these actions is initiated.
/// The action object contains information about the current status of the
/// action, start and complete timestamps, and the associated resource type
/// and ID.
///
/// Every action that creates an action object is available through this
/// endpoint. Completed actions are not removed from this list and are always
/// available for querying.
///
/// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#actions)
#[derive(Deserialize, Serialize, Debug, Clone, Getters, Setters)]
pub struct Action {
    /// A unique identifier for each Droplet action event. This is used to
    /// reference a specific action that was requested.
    #[get = "pub"]
    id: usize,
    /// The current status of the action. The value of this attribute will be
    /// "in-progress", "completed", or "errored".
    #[get = "pub"]
    status: String,
    /// The type of action that the event is executing (reboot, power_off,
    /// etc.).
    #[get = "pub"]
    started_at: DateTime<UTC>,
    /// A time value given in ISO8601 combined date and time format that
    /// represents when the action was completed.
    #[get = "pub"]
    completed_at: Option<DateTime<UTC>>,
    /// A unique identifier for the resource that the action is associated
    /// with.
    #[get = "pub"]
    resource_id: usize,
    /// The type of resource that the action is associated with.
    #[get = "pub"]
    resource_type: String,
    // /// (deprecated) A slug representing the region where the action occurred.
    // #[get = "pub"]
    // #[deprecated(since = "0.0.1", note = "DigitalOcean has deprecated this.")]
    // region: Option<Region>,
    /// A slug representing the region where the action occurred.
    #[get = "pub"]
    region_slug: Option<String>,
}

impl Action {
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#retrieve-an-existing-action)
    pub fn get(id: usize) -> ActionRequest<Get, Action> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(ACTIONS_SEGMENT)
            .push(&id.to_string());

        Request::new(url)
    }
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#list-all-actions)
    pub fn list() -> ActionRequest<List, Vec<Action>> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(ACTIONS_SEGMENT);

        Request::new(url)
    }
}

/// Response type returned from Digital Ocean.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ActionResponse {
    action: Action,
}

impl HasValue for ActionResponse {
    type Value = Action;
    fn value(self) -> Action {
        self.action
    }
}

impl HasResponse for Action {
    type Response = ActionResponse;
}

/// Response type returned from Digital Ocean.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ActionListResponse {
    actions: Vec<Action>,
    links: ApiLinks,
    meta: ApiMeta,
}

impl HasResponse for Vec<Action> {
    type Response = ActionListResponse;
}

impl HasPagination for ActionListResponse {
    fn next_page(&self) -> Option<Url> {
        self.links.next()
    }
}

impl HasValue for ActionListResponse {
    type Value = Vec<Action>;
    fn value(self) -> Vec<Action> {
        self.actions
    }
}
<|endoftext|>


<commit_before>use core::{mem, slice, str};

use raw;

#[cfg(feature = "no-panic")]
use no_panic::no_panic;

/// Safe API for formatting floating point numbers to text.
///
/// ## Example
///
/// ```edition2018
/// let mut buffer = ryu::Buffer::new();
/// let printed = buffer.format(1.234);
/// assert_eq!(printed, "1.234");
/// ```
#[derive(Copy, Clone)]
pub struct Buffer {
    bytes: [u8; 24],
}

impl Buffer {
    /// This is a cheap operation; you don't need to worry about reusing buffers
    /// for efficiency.
    #[inline]
    #[cfg_attr(feature = "no-panic", no_panic)]
    pub fn new() -> Self {
        Buffer {
            bytes: unsafe { mem::uninitialized() },
        }
    }

    /// Print a floating point number into this buffer and return a reference to
    /// its string representation within the buffer.
    ///
    /// # Special cases
    ///
    /// This function **does not** check for NaN or infinity. If the input
    /// number is not a finite float, the printed representation will be some
    /// correctly formatted but unspecified numerical value.
    ///
    /// Please check [`is_finite`] yourself before calling this function, or
    /// check [`is_nan`] and [`is_infinite`] and handle those cases yourself.
    ///
    /// [`is_finite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_finite
    /// [`is_nan`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_nan
    /// [`is_infinite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_infinite
    #[inline]
    #[cfg_attr(feature = "no-panic", no_panic)]
    pub fn format<F: Float>(&mut self, f: F) -> &str {
        unsafe {
            let n = f.write_to_ryu_buffer(&mut self.bytes[0]);
            debug_assert!(n <= self.bytes.len());
            let slice = slice::from_raw_parts(&self.bytes[0], n);
            str::from_utf8_unchecked(slice)
        }
    }
}

impl Default for Buffer {
    #[inline]
    #[cfg_attr(feature = "no-panic", no_panic)]
    fn default() -> Self {
        Buffer::new()
    }
}

/// A floating point number, f32 or f64, that can be written into a
/// [`ryu::Buffer`][Buffer].
///
/// This trait is sealed and cannot be implemented for types outside of the
/// `ryu` crate.
pub trait Float: Sealed {
    // Not public API.
    #[doc(hidden)]
    unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize;
}

impl Float for f32 {
    #[doc(hidden)]
    #[inline]
    #[cfg_attr(feature = "no-panic", no_panic)]
    unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize {
        raw::format32(self, result)
    }
}

impl Float for f64 {
    #[doc(hidden)]
    #[inline]
    #[cfg_attr(feature = "no-panic", no_panic)]
    unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize {
        raw::format64(self, result)
    }
}

pub trait Sealed {}
impl Sealed for f32 {}
impl Sealed for f64 {}
<commit_msg>Move write_to_ryu_buffer out of Float trait<commit_after>use core::{mem, slice, str};

use raw;

#[cfg(feature = "no-panic")]
use no_panic::no_panic;

/// Safe API for formatting floating point numbers to text.
///
/// ## Example
///
/// ```edition2018
/// let mut buffer = ryu::Buffer::new();
/// let printed = buffer.format(1.234);
/// assert_eq!(printed, "1.234");
/// ```
#[derive(Copy, Clone)]
pub struct Buffer {
    bytes: [u8; 24],
}

impl Buffer {
    /// This is a cheap operation; you don't need to worry about reusing buffers
    /// for efficiency.
    #[inline]
    #[cfg_attr(feature = "no-panic", no_panic)]
    pub fn new() -> Self {
        Buffer {
            bytes: unsafe { mem::uninitialized() },
        }
    }

    /// Print a floating point number into this buffer and return a reference to
    /// its string representation within the buffer.
    ///
    /// # Special cases
    ///
    /// This function **does not** check for NaN or infinity. If the input
    /// number is not a finite float, the printed representation will be some
    /// correctly formatted but unspecified numerical value.
    ///
    /// Please check [`is_finite`] yourself before calling this function, or
    /// check [`is_nan`] and [`is_infinite`] and handle those cases yourself.
    ///
    /// [`is_finite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_finite
    /// [`is_nan`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_nan
    /// [`is_infinite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_infinite
    #[inline]
    #[cfg_attr(feature = "no-panic", no_panic)]
    pub fn format<F: Float>(&mut self, f: F) -> &str {
        unsafe {
            let n = f.write_to_ryu_buffer(&mut self.bytes[0]);
            debug_assert!(n <= self.bytes.len());
            let slice = slice::from_raw_parts(&self.bytes[0], n);
            str::from_utf8_unchecked(slice)
        }
    }
}

impl Default for Buffer {
    #[inline]
    #[cfg_attr(feature = "no-panic", no_panic)]
    fn default() -> Self {
        Buffer::new()
    }
}

/// A floating point number, f32 or f64, that can be written into a
/// [`ryu::Buffer`][Buffer].
///
/// This trait is sealed and cannot be implemented for types outside of the
/// `ryu` crate.
pub trait Float: Sealed {}
impl Float for f32 {}
impl Float for f64 {}

pub trait Sealed {
    unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize;
}

impl Sealed for f32 {
    #[inline]
    #[cfg_attr(feature = "no-panic", no_panic)]
    unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize {
        raw::format32(self, result)
    }
}

impl Sealed for f64 {
    #[inline]
    #[cfg_attr(feature = "no-panic", no_panic)]
    unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize {
        raw::format64(self, result)
    }
}
<|endoftext|>


<commit_before>use std::iter::Iterator;

// stacks
pub mod linked_stack;
pub mod fixed_capacity_stack;
pub mod resizing_array_stack;

pub trait StackOfStrings {
    /// create an empty stack
    fn new() -> Self;
    /// insert a new string onto stack
    fn push(&mut self, item: String);
    /// remove and return the string most recently added
    fn pop(&mut self) ->  String;
    /// is the stack empty?
    fn is_empty(&self) -> bool;
    /// number of strings on the stack
    fn size(&self) -> usize {
        unimplemented!()
    }
}

/// generic stack
pub trait Stack<T> {
    /// create an empty stack
    fn new() -> Self;
    /// insert a new item onto stack
    fn push(&mut self, item: T);
    /// remove and return the item most recently added
    fn pop(&mut self) ->  T;
    /// is the stack empty?
    fn is_empty(&self) -> bool;
    /// number of strings on the stack
    fn size(&self) -> usize {
        unimplemented!()
    }
}

// queues
pub mod linked_queue;
pub mod resizing_array_queue;

pub trait QueueOfStrings {
    /// create an empty queue
    fn new() -> Self;
    /// insert a new string onto queue
    fn enqueue(&mut self, item: String);
    /// remove and return the string least recently added
    fn dequeue(&mut self) -> String;
    /// is the queue empty?
    fn is_empty(&self) -> bool;
    /// number of strings on the queue
    fn size(&self) -> usize {
        unimplemented!()
    }
}

/// generic queue
pub trait Queue<T> {
    /// create an empty queue
    fn new() -> Self;
    /// insert a new item onto queue
    fn enqueue(&mut self, item: T);
    /// remove and return the item least recently added
    fn dequeue(&mut self) -> T;
    /// is the queue empty?
    fn is_empty(&self) -> bool;
    /// number of items on the queue
    fn size(&self) -> usize {
        unimplemented!()
    }
}

// bag
pub trait Bag<T> {
    fn new() -> Self;
    fn add(&mut self, item: T);
    fn iter(&self) -> Iterator<Item=T>;
    fn size(&self) -> usize {
        unimplemented!()
    }
}

// Programming Assignment 2: Randomized Queues and Deques
// Deque
pub mod linked_deque;

pub trait Deque<T> {
    fn new() -> Self;
    fn is_empty(&self) -> bool;
    fn size(&self) -> usize;
    fn add_first(&mut self, item: T);
    fn add_last(&mut self, item: T);
    fn remove_first(&mut self) -> Option<T>;
    fn remove_last(&mut self) -> Option<T>;
}

// RandomizeQueue
pub mod resizing_array_randomized_queue;

pub trait RandomizedQueue<T> {
    fn new() -> Self;
    fn is_empty(&self) -> bool;
    fn size(&self) -> usize;
    fn enqueue(&mut self, item: T);
    fn dequeue(&mut self) -> Option<T>;
    fn sample(&self) -> Option<&T>;
}
<commit_msg>stacks_and_queues: fix typo<commit_after>use std::iter::Iterator;

// stacks
pub mod linked_stack;
pub mod fixed_capacity_stack;
pub mod resizing_array_stack;

pub trait StackOfStrings {
    /// create an empty stack
    fn new() -> Self;
    /// insert a new string onto stack
    fn push(&mut self, item: String);
    /// remove and return the string most recently added
    fn pop(&mut self) ->  String;
    /// is the stack empty?
    fn is_empty(&self) -> bool;
    /// number of strings on the stack
    fn size(&self) -> usize {
        unimplemented!()
    }
}

/// generic stack
pub trait Stack<T> {
    /// create an empty stack
    fn new() -> Self;
    /// insert a new item onto stack
    fn push(&mut self, item: T);
    /// remove and return the item most recently added
    fn pop(&mut self) ->  T;
    /// is the stack empty?
    fn is_empty(&self) -> bool;
    /// number of strings on the stack
    fn size(&self) -> usize {
        unimplemented!()
    }
}

// queues
pub mod linked_queue;
pub mod resizing_array_queue;

pub trait QueueOfStrings {
    /// create an empty queue
    fn new() -> Self;
    /// insert a new string onto queue
    fn enqueue(&mut self, item: String);
    /// remove and return the string least recently added
    fn dequeue(&mut self) -> String;
    /// is the queue empty?
    fn is_empty(&self) -> bool;
    /// number of strings on the queue
    fn size(&self) -> usize {
        unimplemented!()
    }
}

/// generic queue
pub trait Queue<T> {
    /// create an empty queue
    fn new() -> Self;
    /// insert a new item onto queue
    fn enqueue(&mut self, item: T);
    /// remove and return the item least recently added
    fn dequeue(&mut self) -> T;
    /// is the queue empty?
    fn is_empty(&self) -> bool;
    /// number of items on the queue
    fn size(&self) -> usize {
        unimplemented!()
    }
}

// bag
pub trait Bag<T> {
    fn new() -> Self;
    fn add(&mut self, item: T);
    fn iter(&self) -> Iterator<Item=T>;
    fn size(&self) -> usize {
        unimplemented!()
    }
}

// Programming Assignment 2: Randomized Queues and Deques
// Deque
pub mod linked_deque;

pub trait Deque<T> {
    fn new() -> Self;
    fn is_empty(&self) -> bool;
    fn size(&self) -> usize;
    fn add_first(&mut self, item: T);
    fn add_last(&mut self, item: T);
    fn remove_first(&mut self) -> Option<T>;
    fn remove_last(&mut self) -> Option<T>;
}

// RandomizedQueue
pub mod resizing_array_randomized_queue;

pub trait RandomizedQueue<T> {
    fn new() -> Self;
    fn is_empty(&self) -> bool;
    fn size(&self) -> usize;
    fn enqueue(&mut self, item: T);
    fn dequeue(&mut self) -> Option<T>;
    fn sample(&self) -> Option<&T>;
}
<|endoftext|>


<commit_before>// Copyright 2016 `multipart` Crate Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
//! The client-side abstraction for multipart requests. Enabled with the `client` feature (on by
//! default).
//!
//! Use this when sending POST requests with files to a server.
use mime::Mime;

use std::borrow::Cow;
use std::fs::File;
use std::io;
use std::io::prelude::*;

use std::path::Path;

#[cfg(feature = "hyper")]
pub mod hyper;

pub mod lazy;

mod sized;

pub use self::sized::SizedRequest;

const BOUNDARY_LEN: usize = 16;

macro_rules! map_self {
    ($selff:expr, $try:expr) => (
        match $try {
            Ok(_) => Ok($selff),
            Err(err) => Err(err.into()),
        }
    )
}

/// The entry point of the client-side multipart API.
///
/// Though they perform I/O, the `.write_*()` methods do not return `io::Result<_>` in order to
/// facilitate method chaining. Upon the first error, all subsequent API calls will be no-ops until
/// `.send()` is called, at which point the error will be reported.
pub struct Multipart<S> {
    writer: MultipartWriter<'static, S>,
}

impl Multipart<()> {
    /// Create a new `Multipart` to wrap a request.
    ///
    /// ## Returns Error
    /// If `req.open_stream()` returns an error.
    pub fn from_request<R: HttpRequest>(req: R) -> Result<Multipart<R::Stream>, R::Error> {
        let (boundary, stream) = try!(open_stream(req, None));

        Ok(Multipart {
            writer: MultipartWriter::new(stream, boundary),
        })
    }
}

impl<S: HttpStream> Multipart<S> {
    /// Write a text field to this multipart request.
    /// `name` and `val` can be either owned `String` or `&str`.
    ///
    /// ##Errors
    /// If something went wrong with the HTTP stream.
    pub fn write_text<N: AsRef<str>, V: AsRef<str>>(&mut self, name: N, val: V) -> Result<&mut Self, S::Error> {
        map_self!(self, self.writer.write_text(name.as_ref(), val.as_ref()))
    }

    /// Open a file pointed to by `path` and write its contents to the multipart request,
    /// supplying its filename and guessing its `Content-Type` from its extension.
    ///
    /// If you want to set these values manually, or use another type that implements `Read`,
    /// use `.write_stream()`.
    ///
    /// `name` can be either `String` or `&str`, and `path` can be `PathBuf` or `&Path`.
    ///
    /// ##Errors
    /// If there was a problem opening the file (was a directory or didn't exist),
    /// or if something went wrong with the HTTP stream.
    pub fn write_file<N: AsRef<str>, P: AsRef<Path>>(&mut self, name: N, path: P) -> Result<&mut Self, S::Error> {
        let name = name.as_ref();
        let path = path.as_ref();

        map_self!(self, self.writer.write_file(name, path))
    }

    /// Write a byte stream to the multipart request as a file field, supplying `filename` if given,
    /// and `content_type` if given or `"application/octet-stream"` if not.
    ///
    /// `name` can be either `String` or `&str`, and `read` can take the `Read` by-value or
    /// with an `&mut` borrow.
    ///
    /// ##Warning
    /// The given `Read` **must** be able to read to EOF (end of file/no more data), meaning
    /// `Read::read()` returns `Ok(0)`. If it never returns EOF it will be read to infinity
    /// and the request will never be completed.
    ///
    /// When using `SizedRequest` this also can cause out-of-control memory usage as the
    /// multipart data has to be written to an in-memory buffer so its size can be calculated.
    ///
    /// Use `Read::take()` if you wish to send data from a `Read`
    /// that will never return EOF otherwise.
    ///
    /// ##Errors
    /// If the reader returned an error, or if something went wrong with the HTTP stream.
    // RFC: How to format this declaration?
    pub fn write_stream<N: AsRef<str>, St: Read>(
        &mut self, name: N, stream: &mut St, filename: Option<&str>, content_type: Option<Mime>
    ) -> Result<&mut Self, S::Error> {
        let name = name.as_ref();

        map_self!(self, self.writer.write_stream(stream, name, filename, content_type))
    }

    /// Finalize the request and return the response from the server, or the last error if set.
    pub fn send(self) -> Result<S::Response, S::Error> {
        self.writer.finish().map_err(io::Error::into).and_then(|body| body.finish())
    }
}

impl<R: HttpRequest> Multipart<SizedRequest<R>>
where <R::Stream as HttpStream>::Error: From<R::Error> {
    /// Create a new `Multipart` using the `SizedRequest` wrapper around `req`.
    pub fn from_request_sized(req: R) -> Result<Self, R::Error> {
        Multipart::from_request(SizedRequest::from_request(req))
    }
}

/// A trait describing an HTTP request that can be used to send multipart data.
pub trait HttpRequest {
    /// The HTTP stream type that can be opend by this request, to which the multipart data will be
    /// written.
    type Stream: HttpStream;
    /// The error type for this request.
    /// Must be compatible with `io::Error` as well as `Self::HttpStream::Error`
    type Error: From<io::Error> + Into<<Self::Stream as HttpStream>::Error>;

    /// Set the `Content-Type` header to `multipart/form-data` and supply the `boundary` value.
    /// If `content_len` is given, set the `Content-Length` header to its value.
    ///
    /// Return `true` if any and all sanity checks passed and the stream is ready to be opened,
    /// or `false` otherwise.
    fn apply_headers(&mut self, boundary: &str, content_len: Option<u64>) -> bool;

    /// Open the request stream and return it or any error otherwise.
    fn open_stream(self) -> Result<Self::Stream, Self::Error>;
}

/// A trait describing an open HTTP stream that can be written to.
pub trait HttpStream: Write {
    /// The request type that opened this stream.
    type Request: HttpRequest;
    /// The response type that will be returned after the request is completed.
    type Response;
    /// The error type for this stream.
    /// Must be compatible with `io::Error` as well as `Self::Request::Error`.
    type Error: From<io::Error> + From<<Self::Request as HttpRequest>::Error>;

    /// Finalize and close the stream and return the response object, or any error otherwise.
    fn finish(self) -> Result<Self::Response, Self::Error>;
}

impl HttpRequest for () {
    type Stream = io::Sink;
    type Error = io::Error;

    fn apply_headers(&mut self, _: &str, _: Option<u64>) -> bool { true }
    fn open_stream(self) -> Result<Self::Stream, Self::Error> { Ok(io::sink()) }
}

impl HttpStream for io::Sink {
    type Request = ();
    type Response = ();
    type Error = io::Error;

    fn finish(self) -> Result<Self::Response, Self::Error> { Ok(()) }
}

fn gen_boundary() -> String {
    ::random_alphanumeric(BOUNDARY_LEN)
}

fn open_stream<R: HttpRequest>(mut req: R, content_len: Option<u64>) -> Result<(String, R::Stream), R::Error> {
    let boundary = gen_boundary();
    req.apply_headers(&boundary, content_len);
    req.open_stream().map(|stream| (boundary, stream))
}

struct MultipartWriter<'a, W> {
    inner: W,
    boundary: Cow<'a, str>,
    data_written: bool,
}

impl<'a, W: Write> MultipartWriter<'a, W> {
    fn new<B: Into<Cow<'a, str>>>(inner: W, boundary: B) -> Self {
        MultipartWriter {
            inner: inner,
            boundary: boundary.into(),
            data_written: false,
        }
    }

    fn write_boundary(&mut self) -> io::Result<()> {
        if self.data_written {
            try!(self.inner.write_all(b"\r\n"));
        }

        write!(self.inner, "--{}\r\n", self.boundary)
    }

    fn write_text(&mut self, name: &str, text: &str) -> io::Result<()> {
        chain_result! {
            self.write_field_headers(name, None, None),
            self.inner.write_all(text.as_bytes())
        }
    }

    fn write_file(&mut self, name: &str, path: &Path) -> io::Result<()> {
        let (content_type, filename) = mime_filename(path);
        let mut file = try!(File::open(path));
        self.write_stream(&mut file, name, filename, Some(content_type))
    }

    fn write_stream<S: Read>(&mut self, stream: &mut S, name: &str, filename: Option<&str>, content_type: Option<Mime>) -> io::Result<()> {
        // This is necessary to make sure it is interpreted as a file on the server end.
        let content_type = Some(content_type.unwrap_or_else(::mime_guess::octet_stream));

        chain_result! {
            self.write_field_headers(name, filename, content_type),
            io::copy(stream, &mut self.inner),
            Ok(())
        }
    }

    fn write_field_headers(&mut self, name: &str, filename: Option<&str>, content_type: Option<Mime>)
    -> io::Result<()> {
        let res = chain_result! {
            // Write the first boundary, or the boundary for the previous field.
            self.write_boundary(),
            { self.data_written = true; Ok(()) },
            write!(self.inner, "Content-Disposition: form-data; name=\"{}\"", name),
            filename.map(|filename| write!(self.inner, "; filename=\"{}\"", filename))
                .unwrap_or(Ok(())),
            content_type.map(|content_type| write!(self.inner, "\r\nContent-Type: {}", content_type))
                .unwrap_or(Ok(())),
            self.inner.write_all(b"\r\n\r\n")
        };

        self.data_written = true;

        res
    }

    fn inner_mut(&mut self) -> &mut W {
        &mut self.inner
    }

    fn finish(mut self) -> io::Result<W> {
        if self.data_written {
            // Write two hyphens after the last boundary occurrence.
            try!(write!(self.inner, "\r\n--{}--", self.boundary));
        }

        Ok(self.inner)
    }
}

fn mime_filename(path: &Path) -> (Mime, Option<&str>) {
    let content_type = ::mime_guess::guess_mime_type(path);
    let filename = opt_filename(path);
    (content_type, filename)
}

fn opt_filename(path: &Path) -> Option<&str> {
    path.file_name().and_then(|filename| filename.to_str())
}
<commit_msg>Remove redundant write<commit_after>// Copyright 2016 `multipart` Crate Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
//! The client-side abstraction for multipart requests. Enabled with the `client` feature (on by
//! default).
//!
//! Use this when sending POST requests with files to a server.
use mime::Mime;

use std::borrow::Cow;
use std::fs::File;
use std::io;
use std::io::prelude::*;

use std::path::Path;

#[cfg(feature = "hyper")]
pub mod hyper;

pub mod lazy;

mod sized;

pub use self::sized::SizedRequest;

const BOUNDARY_LEN: usize = 16;

macro_rules! map_self {
    ($selff:expr, $try:expr) => (
        match $try {
            Ok(_) => Ok($selff),
            Err(err) => Err(err.into()),
        }
    )
}

/// The entry point of the client-side multipart API.
///
/// Though they perform I/O, the `.write_*()` methods do not return `io::Result<_>` in order to
/// facilitate method chaining. Upon the first error, all subsequent API calls will be no-ops until
/// `.send()` is called, at which point the error will be reported.
pub struct Multipart<S> {
    writer: MultipartWriter<'static, S>,
}

impl Multipart<()> {
    /// Create a new `Multipart` to wrap a request.
    ///
    /// ## Returns Error
    /// If `req.open_stream()` returns an error.
    pub fn from_request<R: HttpRequest>(req: R) -> Result<Multipart<R::Stream>, R::Error> {
        let (boundary, stream) = try!(open_stream(req, None));

        Ok(Multipart {
            writer: MultipartWriter::new(stream, boundary),
        })
    }
}

impl<S: HttpStream> Multipart<S> {
    /// Write a text field to this multipart request.
    /// `name` and `val` can be either owned `String` or `&str`.
    ///
    /// ##Errors
    /// If something went wrong with the HTTP stream.
    pub fn write_text<N: AsRef<str>, V: AsRef<str>>(&mut self, name: N, val: V) -> Result<&mut Self, S::Error> {
        map_self!(self, self.writer.write_text(name.as_ref(), val.as_ref()))
    }

    /// Open a file pointed to by `path` and write its contents to the multipart request,
    /// supplying its filename and guessing its `Content-Type` from its extension.
    ///
    /// If you want to set these values manually, or use another type that implements `Read`,
    /// use `.write_stream()`.
    ///
    /// `name` can be either `String` or `&str`, and `path` can be `PathBuf` or `&Path`.
    ///
    /// ##Errors
    /// If there was a problem opening the file (was a directory or didn't exist),
    /// or if something went wrong with the HTTP stream.
    pub fn write_file<N: AsRef<str>, P: AsRef<Path>>(&mut self, name: N, path: P) -> Result<&mut Self, S::Error> {
        let name = name.as_ref();
        let path = path.as_ref();

        map_self!(self, self.writer.write_file(name, path))
    }

    /// Write a byte stream to the multipart request as a file field, supplying `filename` if given,
    /// and `content_type` if given or `"application/octet-stream"` if not.
    ///
    /// `name` can be either `String` or `&str`, and `read` can take the `Read` by-value or
    /// with an `&mut` borrow.
    ///
    /// ##Warning
    /// The given `Read` **must** be able to read to EOF (end of file/no more data), meaning
    /// `Read::read()` returns `Ok(0)`. If it never returns EOF it will be read to infinity
    /// and the request will never be completed.
    ///
    /// When using `SizedRequest` this also can cause out-of-control memory usage as the
    /// multipart data has to be written to an in-memory buffer so its size can be calculated.
    ///
    /// Use `Read::take()` if you wish to send data from a `Read`
    /// that will never return EOF otherwise.
    ///
    /// ##Errors
    /// If the reader returned an error, or if something went wrong with the HTTP stream.
    // RFC: How to format this declaration?
    pub fn write_stream<N: AsRef<str>, St: Read>(
        &mut self, name: N, stream: &mut St, filename: Option<&str>, content_type: Option<Mime>
    ) -> Result<&mut Self, S::Error> {
        let name = name.as_ref();

        map_self!(self, self.writer.write_stream(stream, name, filename, content_type))
    }

    /// Finalize the request and return the response from the server, or the last error if set.
    pub fn send(self) -> Result<S::Response, S::Error> {
        self.writer.finish().map_err(io::Error::into).and_then(|body| body.finish())
    }
}

impl<R: HttpRequest> Multipart<SizedRequest<R>>
where <R::Stream as HttpStream>::Error: From<R::Error> {
    /// Create a new `Multipart` using the `SizedRequest` wrapper around `req`.
    pub fn from_request_sized(req: R) -> Result<Self, R::Error> {
        Multipart::from_request(SizedRequest::from_request(req))
    }
}

/// A trait describing an HTTP request that can be used to send multipart data.
pub trait HttpRequest {
    /// The HTTP stream type that can be opend by this request, to which the multipart data will be
    /// written.
    type Stream: HttpStream;
    /// The error type for this request.
    /// Must be compatible with `io::Error` as well as `Self::HttpStream::Error`
    type Error: From<io::Error> + Into<<Self::Stream as HttpStream>::Error>;

    /// Set the `Content-Type` header to `multipart/form-data` and supply the `boundary` value.
    /// If `content_len` is given, set the `Content-Length` header to its value.
    ///
    /// Return `true` if any and all sanity checks passed and the stream is ready to be opened,
    /// or `false` otherwise.
    fn apply_headers(&mut self, boundary: &str, content_len: Option<u64>) -> bool;

    /// Open the request stream and return it or any error otherwise.
    fn open_stream(self) -> Result<Self::Stream, Self::Error>;
}

/// A trait describing an open HTTP stream that can be written to.
pub trait HttpStream: Write {
    /// The request type that opened this stream.
    type Request: HttpRequest;
    /// The response type that will be returned after the request is completed.
    type Response;
    /// The error type for this stream.
    /// Must be compatible with `io::Error` as well as `Self::Request::Error`.
    type Error: From<io::Error> + From<<Self::Request as HttpRequest>::Error>;

    /// Finalize and close the stream and return the response object, or any error otherwise.
    fn finish(self) -> Result<Self::Response, Self::Error>;
}

impl HttpRequest for () {
    type Stream = io::Sink;
    type Error = io::Error;

    fn apply_headers(&mut self, _: &str, _: Option<u64>) -> bool { true }
    fn open_stream(self) -> Result<Self::Stream, Self::Error> { Ok(io::sink()) }
}

impl HttpStream for io::Sink {
    type Request = ();
    type Response = ();
    type Error = io::Error;

    fn finish(self) -> Result<Self::Response, Self::Error> { Ok(()) }
}

fn gen_boundary() -> String {
    ::random_alphanumeric(BOUNDARY_LEN)
}

fn open_stream<R: HttpRequest>(mut req: R, content_len: Option<u64>) -> Result<(String, R::Stream), R::Error> {
    let boundary = gen_boundary();
    req.apply_headers(&boundary, content_len);
    req.open_stream().map(|stream| (boundary, stream))
}

struct MultipartWriter<'a, W> {
    inner: W,
    boundary: Cow<'a, str>,
    data_written: bool,
}

impl<'a, W: Write> MultipartWriter<'a, W> {
    fn new<B: Into<Cow<'a, str>>>(inner: W, boundary: B) -> Self {
        MultipartWriter {
            inner: inner,
            boundary: boundary.into(),
            data_written: false,
        }
    }

    fn write_boundary(&mut self) -> io::Result<()> {
        if self.data_written {
            try!(self.inner.write_all(b"\r\n"));
        }

        write!(self.inner, "--{}\r\n", self.boundary)
    }

    fn write_text(&mut self, name: &str, text: &str) -> io::Result<()> {
        chain_result! {
            self.write_field_headers(name, None, None),
            self.inner.write_all(text.as_bytes())
        }
    }

    fn write_file(&mut self, name: &str, path: &Path) -> io::Result<()> {
        let (content_type, filename) = mime_filename(path);
        let mut file = try!(File::open(path));
        self.write_stream(&mut file, name, filename, Some(content_type))
    }

    fn write_stream<S: Read>(&mut self, stream: &mut S, name: &str, filename: Option<&str>, content_type: Option<Mime>) -> io::Result<()> {
        // This is necessary to make sure it is interpreted as a file on the server end.
        let content_type = Some(content_type.unwrap_or_else(::mime_guess::octet_stream));

        chain_result! {
            self.write_field_headers(name, filename, content_type),
            io::copy(stream, &mut self.inner),
            Ok(())
        }
    }

    fn write_field_headers(&mut self, name: &str, filename: Option<&str>, content_type: Option<Mime>)
    -> io::Result<()> {
        let res = chain_result! {
            // Write the first boundary, or the boundary for the previous field.
            self.write_boundary(),
            { self.data_written = true; Ok(()) },
            write!(self.inner, "Content-Disposition: form-data; name=\"{}\"", name),
            filename.map(|filename| write!(self.inner, "; filename=\"{}\"", filename))
                .unwrap_or(Ok(())),
            content_type.map(|content_type| write!(self.inner, "\r\nContent-Type: {}", content_type))
                .unwrap_or(Ok(())),
            self.inner.write_all(b"\r\n\r\n")
        };

        res
    }

    fn inner_mut(&mut self) -> &mut W {
        &mut self.inner
    }

    fn finish(mut self) -> io::Result<W> {
        if self.data_written {
            // Write two hyphens after the last boundary occurrence.
            try!(write!(self.inner, "\r\n--{}--", self.boundary));
        }

        Ok(self.inner)
    }
}

fn mime_filename(path: &Path) -> (Mime, Option<&str>) {
    let content_type = ::mime_guess::guess_mime_type(path);
    let filename = opt_filename(path);
    (content_type, filename)
}

fn opt_filename(path: &Path) -> Option<&str> {
    path.file_name().and_then(|filename| filename.to_str())
}
<|endoftext|>


<commit_before>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results
// in a runtime panic.

#![feature(never_type)]

use std::{mem, panic};

struct Foo {
    x: u8,
    y: !,
}

fn main() {
    unsafe {
        panic::catch_unwind(|| mem::uninitialized::<!>()).is_err();
        panic::catch_unwind(|| mem::zeroed::<!>()).is_err();

        panic::catch_unwind(|| mem::uninitialized::<Foo>()).is_err();
        panic::catch_unwind(|| mem::zeroed::<Foo>()).is_err();
    }
}
<commit_msg>improve the run-pass test<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results
// in a runtime panic.

#![feature(never_type)]

use std::{mem, panic};

struct Foo {
    x: u8,
    y: !,
}

fn main() {
    unsafe {
        assert_eq!(
            panic::catch_unwind(|| {
                mem::uninitialized::<!>()
            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
                s == "Attempted to instantiate uninhabited type ! using mem::uninitialized"
            })),
            Some(true)
        );

        assert_eq!(
            panic::catch_unwind(|| {
                mem::zeroed::<!>()
            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
                s == "Attempted to instantiate uninhabited type ! using mem::zeroed"
            })),
            Some(true)
        );

        assert_eq!(
            panic::catch_unwind(|| {
                mem::uninitialized::<Foo>()
            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
                s == "Attempted to instantiate uninhabited type Foo using mem::uninitialized"
            })),
            Some(true)
        );

        assert_eq!(
            panic::catch_unwind(|| {
                mem::zeroed::<Foo>()
            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
                s == "Attempted to instantiate uninhabited type Foo using mem::zeroed"
            })),
            Some(true)
        );
    }
}
<|endoftext|>


<commit_before>use futures_core::future::Future;
use futures_core::task::{LocalWaker, Poll, Wake, Waker};
use slab::Slab;
use std::fmt;
use std::cell::UnsafeCell;
use std::marker::Unpin;
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::task::local_waker_from_nonlocal;

/// A future that is cloneable and can be polled in multiple threads.
/// Use `Future::shared()` method to convert any future into a `Shared` future.
#[must_use = "futures do nothing unless polled"]
pub struct Shared<Fut: Future> {
    inner: Option<Arc<Inner<Fut>>>,
    waker_key: usize,
}

struct Inner<Fut: Future> {
    future_or_output: UnsafeCell<FutureOrOutput<Fut>>,
    notifier: Arc<Notifier>,
}

struct Notifier {
    state: AtomicUsize,
    wakers: Mutex<Option<Slab<Option<Waker>>>>,
}

// The future itself is polled behind the `Arc`, so it won't be moved
// when `Shared` is moved.
impl<Fut: Future> Unpin for Shared<Fut> {}

impl<Fut: Future> fmt::Debug for Shared<Fut> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Shared")
            .field("inner", &self.inner)
            .field("waker_key", &self.waker_key)
            .finish()
    }
}

impl<Fut: Future> fmt::Debug for Inner<Fut> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Inner")
            .finish()
    }
}

enum FutureOrOutput<Fut: Future> {
    Future(Fut),
    Output(Fut::Output),
}

unsafe impl<Fut> Send for Inner<Fut>
where
    Fut: Future + Send,
    Fut::Output: Send + Sync,
{}

unsafe impl<Fut> Sync for Inner<Fut>
where
    Fut: Future + Send,
    Fut::Output: Send + Sync,
{}

const IDLE: usize = 0;
const POLLING: usize = 1;
const REPOLL: usize = 2;
const COMPLETE: usize = 3;
const POISONED: usize = 4;

const NULL_WAKER_KEY: usize = usize::max_value();

impl<Fut: Future> Shared<Fut> {
    pub(super) fn new(future: Fut) -> Shared<Fut> {
        Shared {
            inner: Some(Arc::new(Inner {
                future_or_output: UnsafeCell::new(FutureOrOutput::Future(future)),
                notifier: Arc::new(Notifier {
                    state: AtomicUsize::new(IDLE),
                    wakers: Mutex::new(Some(Slab::new())),
                }),
            })),
            waker_key: NULL_WAKER_KEY,
        }
    }
}

impl<Fut> Shared<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    /// If any clone of this `Shared` has completed execution and there are still at least one
    /// clone of this `Shared` alive then, returns its result immediately
    /// without blocking. Otherwise, returns None without triggering the work represented by
    /// this `Shared`.
    pub fn peek(&self) -> Option<&Fut::Output> {
        match self.inner.as_ref().map(|inner| inner.notifier.state.load(SeqCst)) {
            Some(COMPLETE) => unsafe { Some(self.inner().get_output()) },
            Some(POISONED) => panic!("inner future panicked during poll"),
            _ => None,
        }
    }

    fn inner(&self) -> &Arc<Inner<Fut>> {
        Self::inner_(&self.inner)
    }

    fn inner_(inner: &Option<Arc<Inner<Fut>>>) -> &Arc<Inner<Fut>> {
        inner.as_ref().expect("Shared future polled again after completion")
    }

    /// Registers the current task to receive a wakeup when `Inner` is awoken.
    fn set_waker(&mut self, lw: &LocalWaker) {
        // Acquire the lock first before checking COMPLETE to ensure there
        // isn't a race.
        let mut wakers = Self::inner_(&self.inner).notifier.wakers.lock().unwrap();
        let wakers = if let Some(wakers) = wakers.as_mut() {
            wakers
        } else {
            // The value is already available, so there's no need to set the waker.
            return
        };
        if self.waker_key == NULL_WAKER_KEY {
            self.waker_key = wakers.insert(Some(lw.clone().into_waker()));
        } else {
            let waker_slot = &mut wakers[self.waker_key];
            let needs_replacement = if let Some(old_waker) = waker_slot {
                // If there's still an unwoken waker in the slot, only replace
                // if the current one wouldn't wake the same task.
                !lw.will_wake_nonlocal(old_waker)
            } else {
                true
            };
            if needs_replacement {
                *waker_slot = Some(lw.clone().into_waker());
            }
        }
        debug_assert!(self.waker_key != NULL_WAKER_KEY);
    }

    /// Safety: callers must first ensure that `self.inner.state`
    /// is `COMPLETE`
    unsafe fn take_or_clone_output(inner: Arc<Inner<Fut>>) -> Fut::Output {
        match Arc::try_unwrap(inner) {
            Ok(inner) => {
                match inner.future_or_output.into_inner() {
                    FutureOrOutput::Output(item) => item,
                    FutureOrOutput::Future(_) => unreachable!(),
                }
            }
            Err(inner) => inner.get_output().clone(),
        }
    }

}

impl<Fut> Inner<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    /// Safety: callers must first ensure that `self.inner.state`
    /// is `COMPLETE`
    unsafe fn get_output(&self) -> &Fut::Output {
        match &*self.future_or_output.get() {
            FutureOrOutput::Output(ref item) => &item,
            FutureOrOutput::Future(_) => unreachable!(),
        }
    }
}

impl<Fut: Future> Future for Shared<Fut>
where
    Fut::Output: Clone,
{
    type Output = Fut::Output;

    fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
        let this = &mut *self;

        // Assert that we aren't completed
        this.inner();

        this.set_waker(lw);

        match this.inner().notifier.state.compare_and_swap(IDLE, POLLING, SeqCst) {
            IDLE => {
                // Lock acquired, fall through
            }
            POLLING | REPOLL => {
                // Another task is currently polling, at this point we just want
                // to ensure that our task handle is currently registered

                return Poll::Pending;
            }
            COMPLETE => {
                let inner = self.inner.take().unwrap();
                return unsafe { Poll::Ready(Self::take_or_clone_output(inner)) };
            }
            POISONED => panic!("inner future panicked during poll"),
            _ => unreachable!(),
        }

        let waker = local_waker_from_nonlocal(this.inner().notifier.clone());
        let lw = &waker;

        struct Reset<'a>(&'a AtomicUsize);

        impl<'a> Drop for Reset<'a> {
            fn drop(&mut self) {
                use std::thread;

                if thread::panicking() {
                    self.0.store(POISONED, SeqCst);
                }
            }
        }

        let output = loop {
            let inner = this.inner();
            let _reset = Reset(&inner.notifier.state);

            // Poll the future
            let res = unsafe {
                if let FutureOrOutput::Future(future) =
                    &mut *inner.future_or_output.get()
                {
                    Pin::new_unchecked(future).poll(lw)
                } else {
                    unreachable!()
                }
            };
            match res {
                Poll::Pending => {
                    // Not ready, try to release the handle
                    match inner
                        .notifier
                        .state
                        .compare_and_swap(POLLING, IDLE, SeqCst)
                    {
                        POLLING => {
                            // Success
                            return Poll::Pending;
                        }
                        REPOLL => {
                            // Gotta poll again!
                            let prev = inner.notifier.state.swap(POLLING, SeqCst);
                            assert_eq!(prev, REPOLL);
                        }
                        _ => unreachable!(),
                    }
                }
                Poll::Ready(output) => break output,
            }
        };

        if Arc::get_mut(this.inner.as_mut().unwrap()).is_some() {
            this.inner.take();
            return Poll::Ready(output);
        }

        let inner = this.inner();

        let _reset = Reset(&inner.notifier.state);

        unsafe {
            *inner.future_or_output.get() =
                FutureOrOutput::Output(output.clone());
        }

        // Complete the future
        let mut lock = inner.notifier.wakers.lock().unwrap();
        inner.notifier.state.store(COMPLETE, SeqCst);
        let wakers = &mut lock.take().unwrap();
        for (_key, opt_waker) in wakers {
            if let Some(waker) = opt_waker.take() {
                waker.wake();
            }
        }

        Poll::Ready(output)
    }
}

impl<Fut> Clone for Shared<Fut>
where
    Fut: Future,
{
    fn clone(&self) -> Self {
        Shared {
            inner: self.inner.clone(),
            waker_key: NULL_WAKER_KEY,
        }
    }
}

impl<Fut> Drop for Shared<Fut>
where
    Fut: Future,
{
    fn drop(&mut self) {
        if self.waker_key != NULL_WAKER_KEY {
            if let Some(ref inner) = self.inner {
                if let Ok(mut wakers) = inner.notifier.wakers.lock() {
                    if let Some(wakers) = wakers.as_mut() {
                        wakers.remove(self.waker_key);
                    }
                }
            }
        }
    }
}

impl Wake for Notifier {
    fn wake(arc_self: &Arc<Self>) {
        arc_self.state.compare_and_swap(POLLING, REPOLL, SeqCst);

        let wakers = &mut *arc_self.wakers.lock().unwrap();
        if let Some(wakers) = wakers.as_mut() {
            for (_key, opt_waker) in wakers {
                if let Some(waker) = opt_waker.take() {
                    waker.wake();
                }
            }
        }
    }
}
<commit_msg>doc: Update Shared::peek's doc to match<commit_after>use futures_core::future::Future;
use futures_core::task::{LocalWaker, Poll, Wake, Waker};
use slab::Slab;
use std::fmt;
use std::cell::UnsafeCell;
use std::marker::Unpin;
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::task::local_waker_from_nonlocal;

/// A future that is cloneable and can be polled in multiple threads.
/// Use `Future::shared()` method to convert any future into a `Shared` future.
#[must_use = "futures do nothing unless polled"]
pub struct Shared<Fut: Future> {
    inner: Option<Arc<Inner<Fut>>>,
    waker_key: usize,
}

struct Inner<Fut: Future> {
    future_or_output: UnsafeCell<FutureOrOutput<Fut>>,
    notifier: Arc<Notifier>,
}

struct Notifier {
    state: AtomicUsize,
    wakers: Mutex<Option<Slab<Option<Waker>>>>,
}

// The future itself is polled behind the `Arc`, so it won't be moved
// when `Shared` is moved.
impl<Fut: Future> Unpin for Shared<Fut> {}

impl<Fut: Future> fmt::Debug for Shared<Fut> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Shared")
            .field("inner", &self.inner)
            .field("waker_key", &self.waker_key)
            .finish()
    }
}

impl<Fut: Future> fmt::Debug for Inner<Fut> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Inner")
            .finish()
    }
}

enum FutureOrOutput<Fut: Future> {
    Future(Fut),
    Output(Fut::Output),
}

unsafe impl<Fut> Send for Inner<Fut>
where
    Fut: Future + Send,
    Fut::Output: Send + Sync,
{}

unsafe impl<Fut> Sync for Inner<Fut>
where
    Fut: Future + Send,
    Fut::Output: Send + Sync,
{}

const IDLE: usize = 0;
const POLLING: usize = 1;
const REPOLL: usize = 2;
const COMPLETE: usize = 3;
const POISONED: usize = 4;

const NULL_WAKER_KEY: usize = usize::max_value();

impl<Fut: Future> Shared<Fut> {
    pub(super) fn new(future: Fut) -> Shared<Fut> {
        Shared {
            inner: Some(Arc::new(Inner {
                future_or_output: UnsafeCell::new(FutureOrOutput::Future(future)),
                notifier: Arc::new(Notifier {
                    state: AtomicUsize::new(IDLE),
                    wakers: Mutex::new(Some(Slab::new())),
                }),
            })),
            waker_key: NULL_WAKER_KEY,
        }
    }
}

impl<Fut> Shared<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    /// Returns Some containing a reference to this `Shared`'s output if it has
    /// already been computed by a clone or `None` if it hasn't been computed yet
    /// or if this `Shared` already returned its output from poll.
    pub fn peek(&self) -> Option<&Fut::Output> {
        match self.inner.as_ref().map(|inner| inner.notifier.state.load(SeqCst)) {
            Some(COMPLETE) => unsafe { Some(self.inner().get_output()) },
            Some(POISONED) => panic!("inner future panicked during poll"),
            _ => None,
        }
    }

    fn inner(&self) -> &Arc<Inner<Fut>> {
        Self::inner_(&self.inner)
    }

    fn inner_(inner: &Option<Arc<Inner<Fut>>>) -> &Arc<Inner<Fut>> {
        inner.as_ref().expect("Shared future polled again after completion")
    }

    /// Registers the current task to receive a wakeup when `Inner` is awoken.
    fn set_waker(&mut self, lw: &LocalWaker) {
        // Acquire the lock first before checking COMPLETE to ensure there
        // isn't a race.
        let mut wakers = Self::inner_(&self.inner).notifier.wakers.lock().unwrap();
        let wakers = if let Some(wakers) = wakers.as_mut() {
            wakers
        } else {
            // The value is already available, so there's no need to set the waker.
            return
        };
        if self.waker_key == NULL_WAKER_KEY {
            self.waker_key = wakers.insert(Some(lw.clone().into_waker()));
        } else {
            let waker_slot = &mut wakers[self.waker_key];
            let needs_replacement = if let Some(old_waker) = waker_slot {
                // If there's still an unwoken waker in the slot, only replace
                // if the current one wouldn't wake the same task.
                !lw.will_wake_nonlocal(old_waker)
            } else {
                true
            };
            if needs_replacement {
                *waker_slot = Some(lw.clone().into_waker());
            }
        }
        debug_assert!(self.waker_key != NULL_WAKER_KEY);
    }

    /// Safety: callers must first ensure that `self.inner.state`
    /// is `COMPLETE`
    unsafe fn take_or_clone_output(inner: Arc<Inner<Fut>>) -> Fut::Output {
        match Arc::try_unwrap(inner) {
            Ok(inner) => {
                match inner.future_or_output.into_inner() {
                    FutureOrOutput::Output(item) => item,
                    FutureOrOutput::Future(_) => unreachable!(),
                }
            }
            Err(inner) => inner.get_output().clone(),
        }
    }

}

impl<Fut> Inner<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    /// Safety: callers must first ensure that `self.inner.state`
    /// is `COMPLETE`
    unsafe fn get_output(&self) -> &Fut::Output {
        match &*self.future_or_output.get() {
            FutureOrOutput::Output(ref item) => &item,
            FutureOrOutput::Future(_) => unreachable!(),
        }
    }
}

impl<Fut: Future> Future for Shared<Fut>
where
    Fut::Output: Clone,
{
    type Output = Fut::Output;

    fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
        let this = &mut *self;

        // Assert that we aren't completed
        this.inner();

        this.set_waker(lw);

        match this.inner().notifier.state.compare_and_swap(IDLE, POLLING, SeqCst) {
            IDLE => {
                // Lock acquired, fall through
            }
            POLLING | REPOLL => {
                // Another task is currently polling, at this point we just want
                // to ensure that our task handle is currently registered

                return Poll::Pending;
            }
            COMPLETE => {
                let inner = self.inner.take().unwrap();
                return unsafe { Poll::Ready(Self::take_or_clone_output(inner)) };
            }
            POISONED => panic!("inner future panicked during poll"),
            _ => unreachable!(),
        }

        let waker = local_waker_from_nonlocal(this.inner().notifier.clone());
        let lw = &waker;

        struct Reset<'a>(&'a AtomicUsize);

        impl<'a> Drop for Reset<'a> {
            fn drop(&mut self) {
                use std::thread;

                if thread::panicking() {
                    self.0.store(POISONED, SeqCst);
                }
            }
        }

        let output = loop {
            let inner = this.inner();
            let _reset = Reset(&inner.notifier.state);

            // Poll the future
            let res = unsafe {
                if let FutureOrOutput::Future(future) =
                    &mut *inner.future_or_output.get()
                {
                    Pin::new_unchecked(future).poll(lw)
                } else {
                    unreachable!()
                }
            };
            match res {
                Poll::Pending => {
                    // Not ready, try to release the handle
                    match inner
                        .notifier
                        .state
                        .compare_and_swap(POLLING, IDLE, SeqCst)
                    {
                        POLLING => {
                            // Success
                            return Poll::Pending;
                        }
                        REPOLL => {
                            // Gotta poll again!
                            let prev = inner.notifier.state.swap(POLLING, SeqCst);
                            assert_eq!(prev, REPOLL);
                        }
                        _ => unreachable!(),
                    }
                }
                Poll::Ready(output) => break output,
            }
        };

        if Arc::get_mut(this.inner.as_mut().unwrap()).is_some() {
            this.inner.take();
            return Poll::Ready(output);
        }

        let inner = this.inner();

        let _reset = Reset(&inner.notifier.state);

        unsafe {
            *inner.future_or_output.get() =
                FutureOrOutput::Output(output.clone());
        }

        // Complete the future
        let mut lock = inner.notifier.wakers.lock().unwrap();
        inner.notifier.state.store(COMPLETE, SeqCst);
        let wakers = &mut lock.take().unwrap();
        for (_key, opt_waker) in wakers {
            if let Some(waker) = opt_waker.take() {
                waker.wake();
            }
        }

        Poll::Ready(output)
    }
}

impl<Fut> Clone for Shared<Fut>
where
    Fut: Future,
{
    fn clone(&self) -> Self {
        Shared {
            inner: self.inner.clone(),
            waker_key: NULL_WAKER_KEY,
        }
    }
}

impl<Fut> Drop for Shared<Fut>
where
    Fut: Future,
{
    fn drop(&mut self) {
        if self.waker_key != NULL_WAKER_KEY {
            if let Some(ref inner) = self.inner {
                if let Ok(mut wakers) = inner.notifier.wakers.lock() {
                    if let Some(wakers) = wakers.as_mut() {
                        wakers.remove(self.waker_key);
                    }
                }
            }
        }
    }
}

impl Wake for Notifier {
    fn wake(arc_self: &Arc<Self>) {
        arc_self.state.compare_and_swap(POLLING, REPOLL, SeqCst);

        let wakers = &mut *arc_self.wakers.lock().unwrap();
        if let Some(wakers) = wakers.as_mut() {
            for (_key, opt_waker) in wakers {
                if let Some(waker) = opt_waker.take() {
                    waker.wake();
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>//! The entry point, bitch.
#![crate_type = "bin"]
#![deny(warnings)]
#![deny(missing_doc)]
#![feature(globs)]
#![feature(macro_rules)]
#![feature(unsafe_destructor)]

// TODO(cgaebel): This is just to make the `time` macro work. I'm not sure how
// to disable warnings only in a macro.
#![allow(unused_unsafe)]

extern crate gl;
extern crate libc;
extern crate nalgebra;
extern crate ncollide3df32;
extern crate piston;
extern crate sdl2;
extern crate sdl2_game_window;

mod color;
mod cstr_cache;
mod fontloader;
mod glw;
mod main;
mod octree;
mod stopwatch;
mod ttf;
mod vertex;

#[allow(dead_code)]
fn main() {
  return main::main();
}
<commit_msg>professionalism<commit_after>//! The entry point.
#![crate_type = "bin"]
#![deny(warnings)]
#![deny(missing_doc)]
#![feature(globs)]
#![feature(macro_rules)]
#![feature(unsafe_destructor)]

// TODO(cgaebel): This is just to make the `time` macro work. I'm not sure how
// to disable warnings only in a macro.
#![allow(unused_unsafe)]

extern crate gl;
extern crate libc;
extern crate nalgebra;
extern crate ncollide3df32;
extern crate piston;
extern crate sdl2;
extern crate sdl2_game_window;

mod color;
mod cstr_cache;
mod fontloader;
mod glw;
mod main;
mod octree;
mod stopwatch;
mod ttf;
mod vertex;

#[allow(dead_code)]
fn main() {
  return main::main();
}
<|endoftext|>


<commit_before>use std::fs;
use std::io;
use std::path::Path;
use std::sync::Arc;

use memmap::{Mmap, Protection};

/// A read only view into a memory map.
///
/// Reading a memory map is unsafe because we cannot guarantee that its
/// underlying memory is not mutated by external processes. This read only
/// memory map guarantees that consumers can at least never modify the
/// underlying data.
///
/// It is principally useful for controlling which region of a file an `Fst`
/// reads. Taking a slice from it is still considered unsafe.
pub struct MmapReadOnly {
    map: Arc<Mmap>,
    offset: usize,
    len: usize,
}

impl MmapReadOnly {
    /// Create a new memory map from an existing file handle.
    pub fn open(file: &fs::File) -> io::Result<MmapReadOnly> {
        Ok(try!(Mmap::open(file, Protection::Read)).into())
    }

    /// Open a new memory map from the path given.
    pub fn open_path<P: AsRef<Path>>(path: P) -> io::Result<MmapReadOnly> {
        MmapReadOnly::open(&try!(fs::File::open(path)))
    }

    /// Returns the size in byte of the memory map.
    ///
    /// If it is a range, the size is the size of the range.
    pub fn len(&self,) -> usize {
        self.len
    }

    /// Slice this memory map to a new `offset` and `len`.
    ///
    /// If the new range is outside the bounds of `self`, then this method
    /// panics.
    pub fn range(&self, offset: usize, len: usize) -> MmapReadOnly {
        assert!(offset + len <= self.len);
        MmapReadOnly {
            map: self.map.clone(),
            offset: self.offset + offset,
            len: len,
        }
    }

    /// Read the memory map as a `&[u8]`.
    pub unsafe fn as_slice(&self) -> &[u8] {
        &self.map.as_slice()[self.offset..self.offset + self.len]
    }
}

impl Clone for MmapReadOnly {
    fn clone(&self) -> MmapReadOnly {
        MmapReadOnly{
            map: self.map.clone(),
            offset: self.offset,
            len: self.len,
        }
    }
}

impl From<Mmap> for MmapReadOnly {
    fn from(mmap: Mmap) -> MmapReadOnly {
        From::from(Arc::new(mmap))
    }
}

impl From<Arc<Mmap>> for MmapReadOnly {
    fn from(mmap_arc: Arc<Mmap>) -> MmapReadOnly {
        let len = mmap_arc.len();
        MmapReadOnly {
            map: mmap_arc,
            offset: 0,
            len: len,
        }
    }
}
<commit_msg>mmap: remove public dependency on memmap crate<commit_after>use std::fs;
use std::io;
use std::path::Path;
use std::sync::Arc;

use memmap::{Mmap, Protection};

/// A read only view into a memory map.
///
/// Reading a memory map is unsafe because we cannot guarantee that its
/// underlying memory is not mutated by external processes. This read only
/// memory map guarantees that consumers can at least never modify the
/// underlying data.
///
/// It is principally useful for controlling which region of a file an `Fst`
/// reads. Taking a slice from it is still considered unsafe.
pub struct MmapReadOnly {
    map: Arc<Mmap>,
    offset: usize,
    len: usize,
}

impl MmapReadOnly {
    /// Create a new memory map from an existing file handle.
    pub fn open(file: &fs::File) -> io::Result<MmapReadOnly> {
        let mmap = try!(Mmap::open(file, Protection::Read));
        let len = mmap.len();
        Ok(MmapReadOnly {
            map: Arc::new(mmap),
            offset: 0,
            len: len,
        })
    }

    /// Open a new memory map from the path given.
    pub fn open_path<P: AsRef<Path>>(path: P) -> io::Result<MmapReadOnly> {
        MmapReadOnly::open(&try!(fs::File::open(path)))
    }

    /// Returns the size in byte of the memory map.
    ///
    /// If it is a range, the size is the size of the range.
    pub fn len(&self,) -> usize {
        self.len
    }

    /// Slice this memory map to a new `offset` and `len`.
    ///
    /// If the new range is outside the bounds of `self`, then this method
    /// panics.
    pub fn range(&self, offset: usize, len: usize) -> MmapReadOnly {
        assert!(offset + len <= self.len);
        MmapReadOnly {
            map: self.map.clone(),
            offset: self.offset + offset,
            len: len,
        }
    }

    /// Read the memory map as a `&[u8]`.
    pub unsafe fn as_slice(&self) -> &[u8] {
        &self.map.as_slice()[self.offset..self.offset + self.len]
    }
}

impl Clone for MmapReadOnly {
    fn clone(&self) -> MmapReadOnly {
        MmapReadOnly{
            map: self.map.clone(),
            offset: self.offset,
            len: self.len,
        }
    }
}
<|endoftext|>