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

use std::fmt;
use std::io;
use std::path::PathBuf;

use externalfiles::ExternalHtml;

#[derive(Clone)]
pub struct Layout {
    pub logo: String,
    pub favicon: String,
    pub external_html: ExternalHtml,
    pub krate: String,
}

pub struct Page<'a> {
    pub title: &'a str,
    pub css_class: &'a str,
    pub root_path: &'a str,
    pub description: &'a str,
    pub keywords: &'a str,
    pub resource_suffix: &'a str,
}

pub fn render<T: fmt::Display, S: fmt::Display>(
    dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T,
    css_file_extension: bool, themes: &[PathBuf])
    -> io::Result<()>
{
    write!(dst,
"<!DOCTYPE html>\
\
\
    <meta charset=\"utf-8\">\
    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\
    <meta name=\"generator\" content=\"rustdoc\">\
    <meta name=\"description\" content=\"{description}\">\
    <meta name=\"keywords\" content=\"{keywords}\">\
    <title>{title}</title>\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}normalize{suffix}.css\">\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}rustdoc{suffix}.css\" \
          id=\"mainThemeStyle\">\
    {themes}\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}dark{suffix}.css\">\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}light{suffix}.css\" \
          id=\"themeStyle\">\
    \
    {css_extension}\
    {favicon}\
    {in_header}\
\
\
    \
    {before_content}\
    \

☰
\
        {logo}\
        {sidebar}\
    \

\
        <button id=\"theme-picker\" aria-label=\"Pick another theme!\">\
            \
        </button>\

\

\
    \
    \
        <form class=\"search-form js-only\">\

\
                <input class=\"search-input\" name=\"search\" \
                       autocomplete=\"off\" \
                       placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
                       type=\"search\">\
                \
                    \
                \

\
        </form>\
    \

{content}
\

\

\
    \

\

Help
\

\

Keyboard Shortcuts
\

\

?
\

Show this help dialog
\

S
\

Focus the search field
\

↑
\

Move up in search results
\

↓
\

Move down in search results
\

↹
\

Switch tab
\

⏎
\

Go to active search result
\

+
\

Expand all sections
\

-
\

Collapse all sections
\

\

\

\

Search Tricks
\

\
                    Prefix searches with a type followed by a colon (e.g. \
                    fn:) to restrict the search to a given type.\

\

\
                    Accepted types are: fn, mod, \
                    struct, enum, \
                    trait, type, macro, \
                    and const.\

\

\
                    Search functions by type signature (e.g. \
                    vec -> usize or * -> vec)\

\

\
                    Search multiple things at once by splitting your query with comma (e.g. \
                    str,u8 or String,struct:Vec,test)\

\

\

\
    \
    {after_content}\
    \
    \
    \
    \
\
",
    css_extension = if css_file_extension {
        format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme{suffix}.css\">",
                root_path = page.root_path,
                suffix=page.resource_suffix)
    } else {
        "".to_owned()
    },
    content   = *t,
    root_path = page.root_path,
    css_class = page.css_class,
    logo      = if layout.logo.is_empty() {
        "".to_string()
    } else {
        format!("\
                 ",
                page.root_path, layout.krate,
                layout.logo)
    },
    title     = page.title,
    description = page.description,
    keywords = page.keywords,
    favicon   = if layout.favicon.is_empty() {
        "".to_string()
    } else {
        format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
    },
    in_header = layout.external_html.in_header,
    before_content = layout.external_html.before_content,
    after_content = layout.external_html.after_content,
    sidebar   = *sidebar,
    krate     = layout.krate,
    themes = themes.iter()
                   .filter_map(|t| t.file_stem())
                   .filter_map(|t| t.to_str())
                   .map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}{}.css">"#,
                                    page.root_path,
                                    t,
                                    page.resource_suffix))
                   .collect::<String>(),
    suffix=page.resource_suffix,
    )
}

pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
    //

"##,
    url = url,
    )
}
<commit_msg>Rollup merge of #50284 - GuillaumeGomez:search-load-failure, r=SimonSapin<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;
use std::io;
use std::path::PathBuf;

use externalfiles::ExternalHtml;

#[derive(Clone)]
pub struct Layout {
    pub logo: String,
    pub favicon: String,
    pub external_html: ExternalHtml,
    pub krate: String,
}

pub struct Page<'a> {
    pub title: &'a str,
    pub css_class: &'a str,
    pub root_path: &'a str,
    pub description: &'a str,
    pub keywords: &'a str,
    pub resource_suffix: &'a str,
}

pub fn render<T: fmt::Display, S: fmt::Display>(
    dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T,
    css_file_extension: bool, themes: &[PathBuf])
    -> io::Result<()>
{
    write!(dst,
"<!DOCTYPE html>\
\
\
    <meta charset=\"utf-8\">\
    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\
    <meta name=\"generator\" content=\"rustdoc\">\
    <meta name=\"description\" content=\"{description}\">\
    <meta name=\"keywords\" content=\"{keywords}\">\
    <title>{title}</title>\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}normalize{suffix}.css\">\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}rustdoc{suffix}.css\" \
          id=\"mainThemeStyle\">\
    {themes}\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}dark{suffix}.css\">\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}light{suffix}.css\" \
          id=\"themeStyle\">\
    \
    {css_extension}\
    {favicon}\
    {in_header}\
\
\
    \
    {before_content}\
    \

☰
\
        {logo}\
        {sidebar}\
    \

\
        <button id=\"theme-picker\" aria-label=\"Pick another theme!\">\
            \
        </button>\

\

\
    \
    \
        <form class=\"search-form js-only\">\

\
                <input class=\"search-input\" name=\"search\" \
                       autocomplete=\"off\" \
                       placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
                       type=\"search\">\
                \
                    \
                \

\
        </form>\
    \

{content}
\

\

\
    \

\

Help
\

\

Keyboard Shortcuts
\

\

?
\

Show this help dialog
\

S
\

Focus the search field
\

↑
\

Move up in search results
\

↓
\

Move down in search results
\

↹
\

Switch tab
\

⏎
\

Go to active search result
\

+
\

Expand all sections
\

-
\

Collapse all sections
\

\

\

\

Search Tricks
\

\
                    Prefix searches with a type followed by a colon (e.g. \
                    fn:) to restrict the search to a given type.\

\

\
                    Accepted types are: fn, mod, \
                    struct, enum, \
                    trait, type, macro, \
                    and const.\

\

\
                    Search functions by type signature (e.g. \
                    vec -> usize or * -> vec)\

\

\
                    Search multiple things at once by splitting your query with comma (e.g. \
                    str,u8 or String,struct:Vec,test)\

\

\

\
    \
    {after_content}\
    \
    \
    \
    \
\
",
    css_extension = if css_file_extension {
        format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme{suffix}.css\">",
                root_path = page.root_path,
                suffix=page.resource_suffix)
    } else {
        "".to_owned()
    },
    content   = *t,
    root_path = page.root_path,
    css_class = page.css_class,
    logo      = if layout.logo.is_empty() {
        "".to_string()
    } else {
        format!("\
                 ",
                page.root_path, layout.krate,
                layout.logo)
    },
    title     = page.title,
    description = page.description,
    keywords = page.keywords,
    favicon   = if layout.favicon.is_empty() {
        "".to_string()
    } else {
        format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
    },
    in_header = layout.external_html.in_header,
    before_content = layout.external_html.before_content,
    after_content = layout.external_html.after_content,
    sidebar   = *sidebar,
    krate     = layout.krate,
    themes = themes.iter()
                   .filter_map(|t| t.file_stem())
                   .filter_map(|t| t.to_str())
                   .map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}{}.css">"#,
                                    page.root_path,
                                    t,
                                    page.resource_suffix))
                   .collect::<String>(),
    suffix=page.resource_suffix,
    )
}

pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
    //

"##,
    url = url,
    )
}
<|endoftext|>


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

use std::fmt;
use std::io::prelude::*;
use std::io;

use externalfiles::ExternalHtml;

#[derive(Clone)]
pub struct Layout {
    pub logo: String,
    pub favicon: String,
    pub external_html: ExternalHtml,
    pub krate: String,
    pub playground_url: String,
}

pub struct Page<'a> {
    pub title: &'a str,
    pub ty: &'a str,
    pub root_path: &'a str,
    pub description: &'a str,
    pub keywords: &'a str
}

pub fn render<T: fmt::Display, S: fmt::Display>(
    dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T)
    -> io::Result<()>
{
    write!(dst,
r##"<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="generator" content="rustdoc">
    <meta name="description" content="{description}">
    <meta name="keywords" content="{keywords}">

    <title>{title}</title>

    <link rel="stylesheet" type="text/css" href="{root_path}main.css">

    {favicon}
    {in_header}

    {before_content}

        {logo}
        {sidebar}

        <form class="search-form js-only">

                <input class="search-input" name="search"
                       autocomplete="off"
                       placeholder="Click or press ‘S’ to search, ‘?’ for more options…"
                       type="search">

        </form>

{content}

Help

Keyboard Shortcuts

?

Show this help dialog

S

Focus the search field

⇤

Move up in search results

⇥

Move down in search results

⏎

Go to active search result

Search Tricks

                    Prefix searches with a type followed by a colon (e.g.
                    fn:) to restrict the search to a given type.

                    Accepted types are: fn, mod,
                    struct, enum,
                    trait, type, macro,
                    and const.

                    Search functions by type signature (e.g.
                    vec -> usize)

    {after_content}

    {play_js}

"##,
    content   = *t,
    root_path = page.root_path,
    ty        = page.ty,
    logo      = if layout.logo.is_empty() {
        "".to_string()
    } else {
        format!("\
                 ",
                page.root_path, layout.krate,
                layout.logo)
    },
    title     = page.title,
    description = page.description,
    keywords = page.keywords,
    favicon   = if layout.favicon.is_empty() {
        "".to_string()
    } else {
        format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
    },
    in_header = layout.external_html.in_header,
    before_content = layout.external_html.before_content,
    after_content = layout.external_html.after_content,
    sidebar   = *sidebar,
    krate     = layout.krate,
    play_url  = layout.playground_url,
    play_js   = if layout.playground_url.is_empty() {
        "".to_string()
    } else {
        format!(r#""#, page.root_path)
    },
    )
}

pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
    //

"##,
    url = url,
    )
}
<commit_msg>Fix unpredictable ordering of sidebar boxes in rustdoc<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;
use std::io::prelude::*;
use std::io;

use externalfiles::ExternalHtml;

#[derive(Clone)]
pub struct Layout {
    pub logo: String,
    pub favicon: String,
    pub external_html: ExternalHtml,
    pub krate: String,
    pub playground_url: String,
}

pub struct Page<'a> {
    pub title: &'a str,
    pub ty: &'a str,
    pub root_path: &'a str,
    pub description: &'a str,
    pub keywords: &'a str
}

pub fn render<T: fmt::Display, S: fmt::Display>(
    dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T)
    -> io::Result<()>
{
    write!(dst,
r##"<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="generator" content="rustdoc">
    <meta name="description" content="{description}">
    <meta name="keywords" content="{keywords}">

    <title>{title}</title>

    <link rel="stylesheet" type="text/css" href="{root_path}main.css">

    {favicon}
    {in_header}

    {before_content}

        {logo}
        {sidebar}

        <form class="search-form js-only">

                <input class="search-input" name="search"
                       autocomplete="off"
                       placeholder="Click or press ‘S’ to search, ‘?’ for more options…"
                       type="search">

        </form>

{content}

Help

Keyboard Shortcuts

?

Show this help dialog

S

Focus the search field

⇤

Move up in search results

⇥

Move down in search results

⏎

Go to active search result

Search Tricks

                    Prefix searches with a type followed by a colon (e.g.
                    fn:) to restrict the search to a given type.

                    Accepted types are: fn, mod,
                    struct, enum,
                    trait, type, macro,
                    and const.

                    Search functions by type signature (e.g.
                    vec -> usize)

    {after_content}

    {play_js}

"##,
    content   = *t,
    root_path = page.root_path,
    ty        = page.ty,
    logo      = if layout.logo.is_empty() {
        "".to_string()
    } else {
        format!("\
                 ",
                page.root_path, layout.krate,
                layout.logo)
    },
    title     = page.title,
    description = page.description,
    keywords = page.keywords,
    favicon   = if layout.favicon.is_empty() {
        "".to_string()
    } else {
        format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
    },
    in_header = layout.external_html.in_header,
    before_content = layout.external_html.before_content,
    after_content = layout.external_html.after_content,
    sidebar   = *sidebar,
    krate     = layout.krate,
    play_url  = layout.playground_url,
    play_js   = if layout.playground_url.is_empty() {
        "".to_string()
    } else {
        format!(r#""#, page.root_path)
    },
    )
}

pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
    //

"##,
    url = url,
    )
}
<|endoftext|>


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

#![unstable(issue = "0", feature = "windows_net")]

use prelude::v1::*;

use cmp;
use io::{self, Read};
use libc::{c_int, c_void, c_ulong};
use mem;
use net::{SocketAddr, Shutdown};
use num::One;
use ops::Neg;
use ptr;
use sync::Once;
use sys::c;
use sys;
use sys_common::{self, AsInner, FromInner, IntoInner};
use sys_common::io::read_to_end_uninitialized;
use sys_common::net;
use time::Duration;

pub type wrlen_t = i32;

pub mod netc {
    pub use sys::c::*;
    pub use sys::c::SOCKADDR as sockaddr;
    pub use sys::c::SOCKADDR_STORAGE_LH as sockaddr_storage;
    pub use sys::c::ADDRINFOA as addrinfo;
    pub use sys::c::ADDRESS_FAMILY as sa_family_t;
}

pub struct Socket(c::SOCKET);

/// Checks whether the Windows socket interface has been started already, and
/// if not, starts it.
pub fn init() {
    static START: Once = Once::new();

    START.call_once(|| unsafe {
        let mut data: c::WSADATA = mem::zeroed();
        let ret = c::WSAStartup(0x202, // version 2.2
                                &mut data);
        assert_eq!(ret, 0);

        let _ = sys_common::at_exit(|| { c::WSACleanup(); });
    });
}

/// Returns the last error from the Windows socket interface.
fn last_error() -> io::Error {
    io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
}

/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
/// and if so, returns the last error from the Windows socket interface. . This
/// function must be called before another call to the socket API is made.
pub fn cvt<T: One + Neg<Output=T> + PartialEq>(t: T) -> io::Result<T> {
    let one: T = T::one();
    if t == -one {
        Err(last_error())
    } else {
        Ok(t)
    }
}

/// Provides the functionality of `cvt` for the return values of `getaddrinfo`
/// and similar, meaning that they return an error if the return value is 0.
pub fn cvt_gai(err: c_int) -> io::Result<()> {
    if err == 0 { return Ok(()) }
    cvt(err).map(|_| ())
}

/// Provides the functionality of `cvt` for a closure.
pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
    where F: FnMut() -> T, T: One + Neg<Output=T> + PartialEq
{
    cvt(f())
}

impl Socket {
    pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
        let fam = match *addr {
            SocketAddr::V4(..) => c::AF_INET,
            SocketAddr::V6(..) => c::AF_INET6,
        };
        let socket = unsafe {
            match c::WSASocketW(fam, ty, 0, ptr::null_mut(), 0,
                                c::WSA_FLAG_OVERLAPPED) {
                c::INVALID_SOCKET => Err(last_error()),
                n => Ok(Socket(n)),
            }
        }?;
        socket.set_no_inherit()?;
        Ok(socket)
    }

    pub fn accept(&self, storage: *mut c::SOCKADDR,
                  len: *mut c_int) -> io::Result<Socket> {
        let socket = unsafe {
            match c::accept(self.0, storage, len) {
                c::INVALID_SOCKET => Err(last_error()),
                n => Ok(Socket(n)),
            }
        }?;
        socket.set_no_inherit()?;
        Ok(socket)
    }

    pub fn duplicate(&self) -> io::Result<Socket> {
        let socket = unsafe {
            let mut info: c::WSAPROTOCOL_INFO = mem::zeroed();
            cvt(c::WSADuplicateSocketW(self.0,
                                            c::GetCurrentProcessId(),
                                            &mut info))?;
            match c::WSASocketW(info.iAddressFamily,
                                info.iSocketType,
                                info.iProtocol,
                                &mut info, 0,
                                c::WSA_FLAG_OVERLAPPED) {
                c::INVALID_SOCKET => Err(last_error()),
                n => Ok(Socket(n)),
            }
        }?;
        socket.set_no_inherit()?;
        Ok(socket)
    }

    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        // On unix when a socket is shut down all further reads return 0, so we
        // do the same on windows to map a shut down socket to returning EOF.
        let len = cmp::min(buf.len(), i32::max_value() as usize) as i32;
        unsafe {
            match c::recv(self.0, buf.as_mut_ptr() as *mut c_void, len, 0) {
                -1 if c::WSAGetLastError() == c::WSAESHUTDOWN => Ok(0),
                -1 => Err(last_error()),
                n => Ok(n as usize)
            }
        }
    }

    pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
        let mut me = self;
        (&mut me).read_to_end(buf)
    }

    pub fn set_timeout(&self, dur: Option<Duration>,
                       kind: c_int) -> io::Result<()> {
        let timeout = match dur {
            Some(dur) => {
                let timeout = sys::dur2timeout(dur);
                if timeout == 0 {
                    return Err(io::Error::new(io::ErrorKind::InvalidInput,
                                              "cannot set a 0 duration timeout"));
                }
                timeout
            }
            None => 0
        };
        net::setsockopt(self, c::SOL_SOCKET, kind, timeout)
    }

    pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> {
        let raw: c::DWORD = net::getsockopt(self, c::SOL_SOCKET, kind)?;
        if raw == 0 {
            Ok(None)
        } else {
            let secs = raw / 1000;
            let nsec = (raw % 1000) * 1000000;
            Ok(Some(Duration::new(secs as u64, nsec as u32)))
        }
    }

    fn set_no_inherit(&self) -> io::Result<()> {
        sys::cvt(unsafe {
            c::SetHandleInformation(self.0 as c::HANDLE,
                                    c::HANDLE_FLAG_INHERIT, 0)
        }).map(|_| ())
    }

    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
        let how = match how {
            Shutdown::Write => c::SD_SEND,
            Shutdown::Read => c::SD_RECEIVE,
            Shutdown::Both => c::SD_BOTH,
        };
        cvt(unsafe { c::shutdown(self.0, how) })?;
        Ok(())
    }

    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
        let mut nonblocking = nonblocking as c_ulong;
        let r = unsafe { c::ioctlsocket(self.0, c::FIONBIO as c_int, &mut nonblocking) };
        if r == 0 {
            Ok(())
        } else {
            Err(io::Error::last_os_error())
        }
    }

    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
        net::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BYTE)
    }

    pub fn nodelay(&self) -> io::Result<bool> {
        let raw: c::BYTE = net::getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)?;
        Ok(raw != 0)
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        let raw: c_int = net::getsockopt(self, c::SOL_SOCKET, c::SO_ERROR)?;
        if raw == 0 {
            Ok(None)
        } else {
            Ok(Some(io::Error::from_raw_os_error(raw as i32)))
        }
    }
}

#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
impl<'a> Read for &'a Socket {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (**self).read(buf)
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        unsafe { read_to_end_uninitialized(self, buf) }
    }
}

impl Drop for Socket {
    fn drop(&mut self) {
        let _ = unsafe { c::closesocket(self.0) };
    }
}

impl AsInner<c::SOCKET> for Socket {
    fn as_inner(&self) -> &c::SOCKET { &self.0 }
}

impl FromInner<c::SOCKET> for Socket {
    fn from_inner(sock: c::SOCKET) -> Socket { Socket(sock) }
}

impl IntoInner<c::SOCKET> for Socket {
    fn into_inner(self) -> c::SOCKET {
        let ret = self.0;
        mem::forget(self);
        ret
    }
}
<commit_msg>Auto merge of #32510 - nodakai:libstd-sys-net-error-check, r=alexcrichton<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![unstable(issue = "0", feature = "windows_net")]

use prelude::v1::*;

use cmp;
use io::{self, Read};
use libc::{c_int, c_void, c_ulong};
use mem;
use net::{SocketAddr, Shutdown};
use num::One;
use ops::Neg;
use ptr;
use sync::Once;
use sys::c;
use sys;
use sys_common::{self, AsInner, FromInner, IntoInner};
use sys_common::io::read_to_end_uninitialized;
use sys_common::net;
use time::Duration;

pub type wrlen_t = i32;

pub mod netc {
    pub use sys::c::*;
    pub use sys::c::SOCKADDR as sockaddr;
    pub use sys::c::SOCKADDR_STORAGE_LH as sockaddr_storage;
    pub use sys::c::ADDRINFOA as addrinfo;
    pub use sys::c::ADDRESS_FAMILY as sa_family_t;
}

pub struct Socket(c::SOCKET);

/// Checks whether the Windows socket interface has been started already, and
/// if not, starts it.
pub fn init() {
    static START: Once = Once::new();

    START.call_once(|| unsafe {
        let mut data: c::WSADATA = mem::zeroed();
        let ret = c::WSAStartup(0x202, // version 2.2
                                &mut data);
        assert_eq!(ret, 0);

        let _ = sys_common::at_exit(|| { c::WSACleanup(); });
    });
}

/// Returns the last error from the Windows socket interface.
fn last_error() -> io::Error {
    io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
}

/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
/// and if so, returns the last error from the Windows socket interface. This
/// function must be called before another call to the socket API is made.
pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> {
    if t == -T::one() {
        Err(last_error())
    } else {
        Ok(t)
    }
}

/// A variant of `cvt` for `getaddrinfo` which return 0 for a success.
pub fn cvt_gai(err: c_int) -> io::Result<()> {
    if err == 0 {
        Ok(())
    } else {
        Err(last_error())
    }
}

/// Just to provide the same interface as sys/unix/net.rs
pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
    where T: One + PartialEq + Neg<Output=T>, F: FnMut() -> T
{
    cvt(f())
}

impl Socket {
    pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
        let fam = match *addr {
            SocketAddr::V4(..) => c::AF_INET,
            SocketAddr::V6(..) => c::AF_INET6,
        };
        let socket = unsafe {
            match c::WSASocketW(fam, ty, 0, ptr::null_mut(), 0,
                                c::WSA_FLAG_OVERLAPPED) {
                c::INVALID_SOCKET => Err(last_error()),
                n => Ok(Socket(n)),
            }
        }?;
        socket.set_no_inherit()?;
        Ok(socket)
    }

    pub fn accept(&self, storage: *mut c::SOCKADDR,
                  len: *mut c_int) -> io::Result<Socket> {
        let socket = unsafe {
            match c::accept(self.0, storage, len) {
                c::INVALID_SOCKET => Err(last_error()),
                n => Ok(Socket(n)),
            }
        }?;
        socket.set_no_inherit()?;
        Ok(socket)
    }

    pub fn duplicate(&self) -> io::Result<Socket> {
        let socket = unsafe {
            let mut info: c::WSAPROTOCOL_INFO = mem::zeroed();
            cvt(c::WSADuplicateSocketW(self.0,
                                            c::GetCurrentProcessId(),
                                            &mut info))?;
            match c::WSASocketW(info.iAddressFamily,
                                info.iSocketType,
                                info.iProtocol,
                                &mut info, 0,
                                c::WSA_FLAG_OVERLAPPED) {
                c::INVALID_SOCKET => Err(last_error()),
                n => Ok(Socket(n)),
            }
        }?;
        socket.set_no_inherit()?;
        Ok(socket)
    }

    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        // On unix when a socket is shut down all further reads return 0, so we
        // do the same on windows to map a shut down socket to returning EOF.
        let len = cmp::min(buf.len(), i32::max_value() as usize) as i32;
        unsafe {
            match c::recv(self.0, buf.as_mut_ptr() as *mut c_void, len, 0) {
                -1 if c::WSAGetLastError() == c::WSAESHUTDOWN => Ok(0),
                -1 => Err(last_error()),
                n => Ok(n as usize)
            }
        }
    }

    pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
        let mut me = self;
        (&mut me).read_to_end(buf)
    }

    pub fn set_timeout(&self, dur: Option<Duration>,
                       kind: c_int) -> io::Result<()> {
        let timeout = match dur {
            Some(dur) => {
                let timeout = sys::dur2timeout(dur);
                if timeout == 0 {
                    return Err(io::Error::new(io::ErrorKind::InvalidInput,
                                              "cannot set a 0 duration timeout"));
                }
                timeout
            }
            None => 0
        };
        net::setsockopt(self, c::SOL_SOCKET, kind, timeout)
    }

    pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> {
        let raw: c::DWORD = net::getsockopt(self, c::SOL_SOCKET, kind)?;
        if raw == 0 {
            Ok(None)
        } else {
            let secs = raw / 1000;
            let nsec = (raw % 1000) * 1000000;
            Ok(Some(Duration::new(secs as u64, nsec as u32)))
        }
    }

    fn set_no_inherit(&self) -> io::Result<()> {
        sys::cvt(unsafe {
            c::SetHandleInformation(self.0 as c::HANDLE,
                                    c::HANDLE_FLAG_INHERIT, 0)
        }).map(|_| ())
    }

    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
        let how = match how {
            Shutdown::Write => c::SD_SEND,
            Shutdown::Read => c::SD_RECEIVE,
            Shutdown::Both => c::SD_BOTH,
        };
        cvt(unsafe { c::shutdown(self.0, how) })?;
        Ok(())
    }

    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
        let mut nonblocking = nonblocking as c_ulong;
        let r = unsafe { c::ioctlsocket(self.0, c::FIONBIO as c_int, &mut nonblocking) };
        if r == 0 {
            Ok(())
        } else {
            Err(io::Error::last_os_error())
        }
    }

    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
        net::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BYTE)
    }

    pub fn nodelay(&self) -> io::Result<bool> {
        let raw: c::BYTE = net::getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)?;
        Ok(raw != 0)
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        let raw: c_int = net::getsockopt(self, c::SOL_SOCKET, c::SO_ERROR)?;
        if raw == 0 {
            Ok(None)
        } else {
            Ok(Some(io::Error::from_raw_os_error(raw as i32)))
        }
    }
}

#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
impl<'a> Read for &'a Socket {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (**self).read(buf)
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        unsafe { read_to_end_uninitialized(self, buf) }
    }
}

impl Drop for Socket {
    fn drop(&mut self) {
        let _ = unsafe { c::closesocket(self.0) };
    }
}

impl AsInner<c::SOCKET> for Socket {
    fn as_inner(&self) -> &c::SOCKET { &self.0 }
}

impl FromInner<c::SOCKET> for Socket {
    fn from_inner(sock: c::SOCKET) -> Socket { Socket(sock) }
}

impl IntoInner<c::SOCKET> for Socket {
    fn into_inner(self) -> c::SOCKET {
        let ret = self.0;
        mem::forget(self);
        ret
    }
}
<|endoftext|>


<commit_before>#![crate_id = "demo-noclip"]
#![feature(macro_rules)]
#![feature(globs)]

extern crate glfw;
extern crate gl;
extern crate snowmew;
extern crate render = "snowmew-render";
extern crate loader = "snowmew-loader";
extern crate position = "snowmew-position";
extern crate graphics = "snowmew-graphics";
extern crate cgmath;
extern crate native;
extern crate green;
extern crate ovr = "oculus-vr";
extern crate OpenCL;
extern crate sync;

use std::io::timer::Timer;
use std::from_str::FromStr;
use sync::Arc;

use cgmath::quaternion::*;
use cgmath::transform::*;
use cgmath::vector::*;
use cgmath::point::*;
use cgmath::matrix::*;
use cgmath::rotation::*;
use cgmath::angle::{ToRad, deg};

use OpenCL::hl::{Device, get_platforms, GPU, CPU};

use snowmew::camera::Camera;
use position::Positions;
use graphics::Graphics;

use render::RenderManager;
use loader::Obj;
use snowmew::common::Common;

use gamedata::GameData;

mod gamedata;

fn get_cl() -> Option<Arc<Device>> {
    let platforms = get_platforms();

    // find a gpu
    for platform in platforms.iter() {
        let devices = platform.get_devices_by_types(&[GPU]);
        if devices.len() != 0 {
            return Some(Arc::new(*devices.get(0)));
        }
    }

    // use cpu if no gpu was found
    for platform in platforms.iter() {
        let devices = platform.get_devices_by_types(&[CPU, GPU]);
        if devices.len() != 0 {
            return Some(Arc::new(*devices.get(0)));
        }
    }

    None
}

#[start]
fn start(argc: int, argv: **u8) -> int {
    native::start(argc, argv, main)
}

fn main() {
    snowmew::start_manual_input(proc(im) {
        let args = std::os::args();
        if args.len() == 1 {
            println!("Please supply a path to an obj to load");
            return;
        }
        let path = Path::new(args.get(1).as_slice());
        let scale: f32 = if args.len() == 3 {
            match FromStr::from_str(args.get(2).as_slice()) {
                Some(v) => v,
                None => 1.0
            }
        } else {1.0};
        let loader = Obj::load(&path).expect("Failed to load OBJ");

        println!("Starting");
        let display = im.hmd().unwrap_or_else(|| {
            im.window((1280, 800)).expect("Failed to create window")
        });
        let mut db = GameData::new();

        let import = db.new_object(None, "import");
        loader.import(import, &mut db);

        let scene = db.new_object(None, "scene");
        let geo_dir = db.find("import/objects").expect("geometry not found from import");
        for (name, id) in db.clone().walk_dir(geo_dir) {
            match db.get_draw(id) {
                Some(d) => {
                    let obj = db.new_object(Some(scene), name);
                    db.set_draw(obj, d.geometry, d.material);
                    db.update_location(obj,
                        Transform3D::new(scale,
                                         Rotation3::from_euler(deg(0f32).to_rad(), deg(0f32).to_rad(), deg(0f32).to_rad()),
                                         Vector3::new(0f32, 0f32, 0f32))
                    );
                }
                None => ()
            }
        }

        let camera_loc = db.new_object(None, "camera");
        db.update_location(camera_loc,
            Transform3D::new(1f32,
                             Rotation3::from_euler(deg(0f32).to_rad(), deg(0f32).to_rad(), deg(0f32).to_rad()),
                             Vector3::new(0f32, 0f32, 0f32)));

        let ih = display.handle();
        let last_input = im.get(&ih);
        let (wx, wy) = last_input.screen_size();

        let mut ren = match get_cl() {
            Some(dev) => RenderManager::new_cl(box db.clone(), display, (wx, wy), dev),
            None => RenderManager::new(box db.clone(), display, (wx, wy))
        };

        let (mut rot_x, mut rot_y) = (0_f64, 0_f64);
        let mut pos = Point3::new(0f32, 0f32, 0f32);
        let mut last_input = im.get(&ih);
        let mut timer = Timer::new().unwrap();
        let timer_port = timer.periodic(10);
        while !last_input.should_close() {
            im.poll();
            let input_state = im.get(&ih);
            timer_port.recv();

            match input_state.is_focused() {
                true => {
                    match input_state.cursor_delta(last_input.time()) {
                        Some((x, y)) => {
                            rot_x += x / 3.;
                            rot_y += y / 3.;

                            rot_y = rot_y.max(-90.).min(90.);
                            if rot_x > 360. {
                                rot_x -= 360.
                            } else if rot_x < -360. {
                                rot_x += 360.
                            }
                        },
                        None => (),
                    }

                },
                false => {}
            }

            let input_vec = Vector3::new(
                if input_state.key_down(glfw::KeyA) {0.05f32} else {0f32} +
                if input_state.key_down(glfw::KeyD) {-0.05f32} else {0f32},
                0f32,
                if input_state.key_down(glfw::KeyW) {0.05f32} else {0f32} +
                if input_state.key_down(glfw::KeyS) {-0.05f32} else {0f32}
            );

            let rot: Quaternion<f32> = Rotation3::from_axis_angle(&Vector3::new(0f32, 1f32, 0f32), deg(-rot_x as f32).to_rad());
            let rot = rot.mul_q(&Rotation3::from_axis_angle(&Vector3::new(1f32, 0f32, 0f32), deg(-rot_y as f32).to_rad()));

            let camera = Camera::new(Transform3D::new(1f32, rot, pos.to_vec()).to_matrix4());
            pos = camera.move(&input_vec.mul_s(-1f32));
            let head_trans = Transform3D::new(1f32, rot, pos.to_vec());
            db.update_location(camera_loc, head_trans);
            ren.update(box db.clone(), scene, camera_loc);
            last_input = input_state;
        }
    });
}<commit_msg>added scale arguments to demo-noclip<commit_after>#![crate_id = "demo-noclip"]
#![feature(macro_rules)]
#![feature(globs)]

extern crate glfw;
extern crate gl;
extern crate snowmew;
extern crate render = "snowmew-render";
extern crate loader = "snowmew-loader";
extern crate position = "snowmew-position";
extern crate graphics = "snowmew-graphics";
extern crate cgmath;
extern crate native;
extern crate green;
extern crate ovr = "oculus-vr";
extern crate OpenCL;
extern crate sync;

use std::io::timer::Timer;
use std::from_str::FromStr;
use sync::Arc;

use cgmath::quaternion::*;
use cgmath::transform::*;
use cgmath::vector::*;
use cgmath::point::*;
use cgmath::matrix::*;
use cgmath::rotation::*;
use cgmath::angle::{ToRad, deg};

use OpenCL::hl::{Device, get_platforms, GPU, CPU};

use snowmew::camera::Camera;
use position::Positions;
use graphics::Graphics;

use render::RenderManager;
use loader::Obj;
use snowmew::common::Common;

use gamedata::GameData;

mod gamedata;

fn get_cl() -> Option<Arc<Device>> {
    let platforms = get_platforms();

    // find a gpu
    for platform in platforms.iter() {
        let devices = platform.get_devices_by_types(&[GPU]);
        if devices.len() != 0 {
            return Some(Arc::new(*devices.get(0)));
        }
    }

    // use cpu if no gpu was found
    for platform in platforms.iter() {
        let devices = platform.get_devices_by_types(&[CPU, GPU]);
        if devices.len() != 0 {
            return Some(Arc::new(*devices.get(0)));
        }
    }

    None
}

#[start]
fn start(argc: int, argv: **u8) -> int {
    native::start(argc, argv, main)
}

fn main() {
    snowmew::start_manual_input(proc(im) {
        let args = std::os::args();
        if args.len() == 1 {
            println!("Please supply a path to an obj to load");
            return;
        }
        let path = Path::new(args.get(1).as_slice());
        let scale: f32 = if args.len() >= 3 {
            match FromStr::from_str(args.get(2).as_slice()) {
                Some(v) => v,
                None => 1.0
            }
        } else {
            1.0
        };

        let loader = Obj::load(&path).expect("Failed to load OBJ");

        println!("Starting");
        let display = im.hmd().unwrap_or_else(|| {
            im.window((1280, 800)).expect("Failed to create window")
        });
        let mut db = GameData::new();

        let import = db.new_object(None, "import");
        loader.import(import, &mut db);

        let scene = db.new_object(None, "scene");
        let geo_dir = db.find("import/objects").expect("geometry not found from import");
        for (name, id) in db.clone().walk_dir(geo_dir) {
            match db.get_draw(id) {
                Some(d) => {
                    let obj = db.new_object(Some(scene), name);
                    db.set_draw(obj, d.geometry, d.material);
                    db.update_location(obj,
                        Transform3D::new(scale,
                                         Rotation3::from_euler(deg(0f32).to_rad(), deg(0f32).to_rad(), deg(0f32).to_rad()),
                                         Vector3::new(0f32, 0f32, 0f32))
                    );
                }
                None => ()
            }
        }

        let ovr_camera = display.is_hmd();
        let camera_loc = db.new_object(None, "camera");
        db.update_location(camera_loc,
            Transform3D::new(1f32,
                             Rotation3::from_euler(deg(0f32).to_rad(), deg(0f32).to_rad(), deg(0f32).to_rad()),
                             Vector3::new(0f32, 0f32, 0f32)));

        let ih = display.handle();
        let last_input = im.get(&ih);
        let (wx, wy) = last_input.screen_size();

        let mut ren = match get_cl() {
            Some(dev) => RenderManager::new_cl(box db.clone(), display, (wx, wy), dev),
            None => RenderManager::new(box db.clone(), display, (wx, wy))
        };

        let (mut rot_x, mut rot_y) = (0_f64, 0_f64);
        let mut pos = if args.len() >= 6 {
            let x = FromStr::from_str(args.get(3).as_slice());
            let y = FromStr::from_str(args.get(4).as_slice());
            let z = FromStr::from_str(args.get(5).as_slice());
            match (x, y, z) {
                (Some(x), Some(y), Some(z)) => {
                    Point3::new(x, y, z)
                }
                _ => Point3::new(0f32, 0., 0.)
            }
        } else {
            Point3::new(0f32, 0f32, 0f32)
        };
        let mut last_input = im.get(&ih);
        let mut timer = Timer::new().unwrap();
        let timer_port = timer.periodic(1);
        while !last_input.should_close() {
            im.poll();
            let input_state = im.get(&ih);
            timer_port.recv();

            match input_state.is_focused() {
                true => {
                    match input_state.cursor_delta(last_input.time()) {
                        Some((x, y)) => {
                            rot_x += x / 3.;
                            rot_y += y / 3.;

                            rot_y = rot_y.max(-90.).min(90.);
                            if rot_x > 360. {
                                rot_x -= 360.
                            } else if rot_x < -360. {
                                rot_x += 360.
                            }
                        },
                        None => (),
                    }

                },
                false => {}
            }

            let input_vec = Vector3::new(
                if input_state.key_down(glfw::KeyA) {0.05f32} else {0f32} +
                if input_state.key_down(glfw::KeyD) {-0.05f32} else {0f32},
                0f32,
                if input_state.key_down(glfw::KeyW) {0.05f32} else {0f32} +
                if input_state.key_down(glfw::KeyS) {-0.05f32} else {0f32}
            );

            let rot: Quaternion<f32> = Rotation3::from_axis_angle(&Vector3::new(0f32, 1f32, 0f32), deg(-rot_x as f32).to_rad());
            let rot = if !ovr_camera {
                rot.mul_q(&Rotation3::from_axis_angle(&Vector3::new(1f32, 0f32, 0f32), deg(-rot_y as f32).to_rad()))
            } else {
                rot
            };

            let camera = Camera::new(Transform3D::new(1f32, rot, pos.to_vec()).to_matrix4());
            pos = camera.move(&input_vec.mul_s(-1f32));
            let head_trans = Transform3D::new(1f32, rot, pos.to_vec());
            db.update_location(camera_loc, head_trans);
            ren.update(box db.clone(), scene, camera_loc);
            last_input = input_state;
        }
    });
}<|endoftext|>


<commit_before>use term;

use std::fmt;
use time::precise_time_s;
use std::collections::VecDeque;

/// Keep track of this many past download amounts
const DOWNLOAD_TRACK_COUNT: usize = 5;

/// Tracks download progress and displays information about it to a terminal.
pub struct DownloadTracker {
    /// Content-Length of the to-be downloaded object.
    content_len: Option<u64>,
    /// Total data downloaded in bytes.
    total_downloaded: usize,
    /// Data downloaded this second.
    downloaded_this_sec: usize,
    /// Keeps track of amount of data downloaded every last few secs.
    /// Used for averaging the download speed.
    downloaded_last_few_secs: VecDeque<usize>,
    /// Time stamp of the last second
    last_sec: Option<f64>,
    /// How many seconds have elapsed since the download started
    seconds_elapsed: u32,
    /// The terminal we write the information to.
    term: Box<term::StdoutTerminal>,
}

impl DownloadTracker {
    /// Creates a new DownloadTracker.
    pub fn new() -> Self {
        DownloadTracker {
            content_len: None,
            total_downloaded: 0,
            downloaded_this_sec: 0,
            downloaded_last_few_secs: VecDeque::with_capacity(DOWNLOAD_TRACK_COUNT),
            seconds_elapsed: 0,
            last_sec: None,
            term: term::stdout().expect("Failed to open terminal"),
        }
    }
    /// Notifies self that Content-Length information has been received.
    pub fn content_length_received(&mut self, content_len: u64) {
        self.content_len = Some(content_len);
    }
    /// Notifies self that data of size `len` has been received.
    pub fn data_received(&mut self, len: usize) {
        self.total_downloaded += len;
        self.downloaded_this_sec += len;

        match self.last_sec {
            None => self.last_sec = Some(precise_time_s()),
            Some(start) => {
                let elapsed = precise_time_s() - start;
                if elapsed >= 1.0 {
                    self.seconds_elapsed += 1;

                    self.display();
                    self.last_sec = Some(precise_time_s());
                    if self.downloaded_last_few_secs.len() == DOWNLOAD_TRACK_COUNT {
                        self.downloaded_last_few_secs.pop_back();
                    }
                    self.downloaded_last_few_secs.push_front(self.downloaded_this_sec);
                    self.downloaded_this_sec = 0;
                }
            }
        }
    }
    /// Notifies self that the download has finished.
    pub fn download_finished(&mut self) {
        let _ = writeln!(&mut self.term, "");
        self.last_sec = None;
    }
    /// Display the tracked download information to the terminal.
    fn display(&mut self) {
        let total_h = HumanReadable(self.total_downloaded as f64);

        match self.content_len {
            Some(content_len) => {
                use std::borrow::Cow;

                let percent = (self.total_downloaded as f64 / content_len as f64) * 100.;
                let content_len_h = HumanReadable(content_len as f64);
                let remaining = content_len - self.total_downloaded as u64;
                let sum = self.downloaded_last_few_secs
                              .iter()
                              .fold(0usize, |a, &v| a + v);
                let len = self.downloaded_last_few_secs.len();
                let speed = if len > 0 {
                    (sum / len) as u64
                } else {
                    0
                };
                let eta = if speed > 0 {
                    Cow::Owned(format!("{}s", remaining / speed))
                } else {
                    Cow::Borrowed("Unknown")
                };
                let _ = write!(&mut self.term,
                               "{} / {} ({:.2}%) ~{}/s ETA: {}",
                               total_h,
                               content_len_h,
                               percent,
                               HumanReadable(speed as f64),
                               eta);
            }
            None => {
                let _ = write!(&mut self.term, "{}", total_h);
            }
        }
        // delete_line() doesn't seem to clear the line properly.
        // Instead, let's just print some whitespace to clear it.
        let _ = write!(&mut self.term, "                ");
        let _ = self.term.flush();
        let _ = self.term.carriage_return();
    }
}

/// Human readable representation of data size in bytes
struct HumanReadable<T>(T);

impl<T: Into<f64> + Clone> fmt::Display for HumanReadable<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        const KIB: f64 = 1024.0;
        const MIB: f64 = 1048576.0;
        let size: f64 = self.0.clone().into();

        if size >= MIB {
            write!(f, "{:.2} MiB", size / MIB)
        } else if size >= KIB {
            write!(f, "{:.2} KiB", size / KIB)
        } else {
            write!(f, "{} B", size)
        }
    }
}
<commit_msg>Reorder imports for better style<commit_after>use std::collections::VecDeque;
use std::fmt;
use term;
use time::precise_time_s;

/// Keep track of this many past download amounts
const DOWNLOAD_TRACK_COUNT: usize = 5;

/// Tracks download progress and displays information about it to a terminal.
pub struct DownloadTracker {
    /// Content-Length of the to-be downloaded object.
    content_len: Option<u64>,
    /// Total data downloaded in bytes.
    total_downloaded: usize,
    /// Data downloaded this second.
    downloaded_this_sec: usize,
    /// Keeps track of amount of data downloaded every last few secs.
    /// Used for averaging the download speed.
    downloaded_last_few_secs: VecDeque<usize>,
    /// Time stamp of the last second
    last_sec: Option<f64>,
    /// How many seconds have elapsed since the download started
    seconds_elapsed: u32,
    /// The terminal we write the information to.
    term: Box<term::StdoutTerminal>,
}

impl DownloadTracker {
    /// Creates a new DownloadTracker.
    pub fn new() -> Self {
        DownloadTracker {
            content_len: None,
            total_downloaded: 0,
            downloaded_this_sec: 0,
            downloaded_last_few_secs: VecDeque::with_capacity(DOWNLOAD_TRACK_COUNT),
            seconds_elapsed: 0,
            last_sec: None,
            term: term::stdout().expect("Failed to open terminal"),
        }
    }
    /// Notifies self that Content-Length information has been received.
    pub fn content_length_received(&mut self, content_len: u64) {
        self.content_len = Some(content_len);
    }
    /// Notifies self that data of size `len` has been received.
    pub fn data_received(&mut self, len: usize) {
        self.total_downloaded += len;
        self.downloaded_this_sec += len;

        match self.last_sec {
            None => self.last_sec = Some(precise_time_s()),
            Some(start) => {
                let elapsed = precise_time_s() - start;
                if elapsed >= 1.0 {
                    self.seconds_elapsed += 1;

                    self.display();
                    self.last_sec = Some(precise_time_s());
                    if self.downloaded_last_few_secs.len() == DOWNLOAD_TRACK_COUNT {
                        self.downloaded_last_few_secs.pop_back();
                    }
                    self.downloaded_last_few_secs.push_front(self.downloaded_this_sec);
                    self.downloaded_this_sec = 0;
                }
            }
        }
    }
    /// Notifies self that the download has finished.
    pub fn download_finished(&mut self) {
        let _ = writeln!(&mut self.term, "");
        self.last_sec = None;
    }
    /// Display the tracked download information to the terminal.
    fn display(&mut self) {
        let total_h = HumanReadable(self.total_downloaded as f64);

        match self.content_len {
            Some(content_len) => {
                use std::borrow::Cow;

                let percent = (self.total_downloaded as f64 / content_len as f64) * 100.;
                let content_len_h = HumanReadable(content_len as f64);
                let remaining = content_len - self.total_downloaded as u64;
                let sum = self.downloaded_last_few_secs
                              .iter()
                              .fold(0usize, |a, &v| a + v);
                let len = self.downloaded_last_few_secs.len();
                let speed = if len > 0 {
                    (sum / len) as u64
                } else {
                    0
                };
                let eta = if speed > 0 {
                    Cow::Owned(format!("{}s", remaining / speed))
                } else {
                    Cow::Borrowed("Unknown")
                };
                let _ = write!(&mut self.term,
                               "{} / {} ({:.2}%) ~{}/s ETA: {}",
                               total_h,
                               content_len_h,
                               percent,
                               HumanReadable(speed as f64),
                               eta);
            }
            None => {
                let _ = write!(&mut self.term, "{}", total_h);
            }
        }
        // delete_line() doesn't seem to clear the line properly.
        // Instead, let's just print some whitespace to clear it.
        let _ = write!(&mut self.term, "                ");
        let _ = self.term.flush();
        let _ = self.term.carriage_return();
    }
}

/// Human readable representation of data size in bytes
struct HumanReadable<T>(T);

impl<T: Into<f64> + Clone> fmt::Display for HumanReadable<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        const KIB: f64 = 1024.0;
        const MIB: f64 = 1048576.0;
        let size: f64 = self.0.clone().into();

        if size >= MIB {
            write!(f, "{:.2} MiB", size / MIB)
        } else if size >= KIB {
            write!(f, "{:.2} KiB", size / KIB)
        } else {
            write!(f, "{} B", size)
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
//
// 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 work was derived from Structopt (https://github.com/TeXitoi/structopt)
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
// MIT/Apache 2.0 license.

use crate::utils;

use clap::{CommandFactory, Parser, Subcommand, ValueEnum};

#[test]
fn doc_comments() {
    /// Lorem ipsum
    #[derive(Parser, PartialEq, Debug)]
    struct LoremIpsum {
        /// Fooify a bar
        /// and a baz
        #[arg(short, long)]
        foo: bool,
    }

    let help = utils::get_long_help::<LoremIpsum>();
    assert!(help.contains("Lorem ipsum"));
    assert!(help.contains("Fooify a bar and a baz"));
}

#[test]
fn help_is_better_than_comments() {
    /// Lorem ipsum
    #[derive(Parser, PartialEq, Debug)]
    #[command(name = "lorem-ipsum", about = "Dolor sit amet")]
    struct LoremIpsum {
        /// Fooify a bar
        #[arg(short, long, help = "DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES")]
        foo: bool,
    }

    let help = utils::get_long_help::<LoremIpsum>();
    assert!(help.contains("Dolor sit amet"));
    assert!(!help.contains("Lorem ipsum"));
    assert!(help.contains("DO NOT PASS A BAR"));
}

#[test]
fn empty_line_in_doc_comment_is_double_linefeed() {
    /// Foo.
    ///
    /// Bar
    #[derive(Parser, PartialEq, Debug)]
    #[command(name = "lorem-ipsum")]
    struct LoremIpsum {}

    let help = utils::get_long_help::<LoremIpsum>();
    assert!(help.starts_with(
        "\
Foo.

Bar

Usage:"
    ));
}

#[test]
fn field_long_doc_comment_both_help_long_help() {
    /// Lorem ipsumclap
    #[derive(Parser, PartialEq, Debug)]
    #[command(name = "lorem-ipsum", about = "Dolor sit amet")]
    struct LoremIpsum {
        /// Dot is removed from multiline comments.
        ///
        /// Long help
        #[arg(long)]
        foo: bool,

        /// Dot is removed from one short comment.
        #[arg(long)]
        bar: bool,
    }

    let short_help = utils::get_help::<LoremIpsum>();
    let long_help = utils::get_long_help::<LoremIpsum>();

    assert!(short_help.contains("Dot is removed from one short comment"));
    assert!(!short_help.contains("Dot is removed from one short comment."));
    assert!(short_help.contains("Dot is removed from multiline comments"));
    assert!(!short_help.contains("Dot is removed from multiline comments."));
    assert!(long_help.contains("Long help"));
    assert!(!short_help.contains("Long help"));
}

#[test]
fn top_long_doc_comment_both_help_long_help() {
    /// Lorem ipsumclap
    #[derive(Parser, Debug)]
    #[command(name = "lorem-ipsum", about = "Dolor sit amet")]
    struct LoremIpsum {
        #[command(subcommand)]
        foo: SubCommand,
    }

    #[derive(Parser, Debug)]
    pub enum SubCommand {
        /// DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES
        ///
        /// Or something else
        Foo {
            #[arg(help = "foo")]
            bars: String,
        },
    }

    let short_help = utils::get_help::<LoremIpsum>();
    let long_help = utils::get_subcommand_long_help::<LoremIpsum>("foo");

    assert!(!short_help.contains("Or something else"));
    assert!(long_help.contains("DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES"));
    assert!(long_help.contains("Or something else"));
}

#[test]
fn verbatim_doc_comment() {
    /// DANCE!
    ///
    ///                    ()
    ///                    |
    ///               (   ()   )
    ///     ) ________    //  )
    ///  ()  |\       \  //
    /// ( \\__ \ ______\//
    ///    \__) |       |
    ///      |  |       |
    ///       \ |       |
    ///        \|_______|
    ///        //    \\
    ///       ((     ||
    ///        \\    ||
    ///      ( ()    ||
    ///       (      () ) )
    #[derive(Parser, Debug)]
    #[command(verbatim_doc_comment)]
    struct SeeFigure1 {
        #[arg(long)]
        foo: bool,
    }

    let help = utils::get_long_help::<SeeFigure1>();
    let sample = r#"
                   ()
                   |
              (   ()   )
    ) ________    //  )
 ()  |\       \  //
( \\__ \ ______\//
   \__) |       |
     |  |       |
      \ |       |
       \|_______|
       //    \\
      ((     ||
       \\    ||
     ( ()    ||
      (      () ) )"#;

    assert!(help.contains(sample))
}

#[test]
fn verbatim_doc_comment_field() {
    #[derive(Parser, Debug)]
    struct Command {
        /// This help ends in a period.
        #[arg(long, verbatim_doc_comment)]
        foo: bool,
        /// This help does not end in a period.
        #[arg(long)]
        bar: bool,
    }

    let help = utils::get_long_help::<Command>();

    assert!(help.contains("This help ends in a period."));
    assert!(help.contains("This help does not end in a period"));
}

#[test]
fn multiline_separates_default() {
    #[derive(Parser, Debug)]
    struct Command {
        /// Multiline
        ///
        /// Doc comment
        #[arg(long, default_value = "x")]
        x: String,
    }

    let help = utils::get_long_help::<Command>();
    assert!(!help.contains("Doc comment [default"));
    assert!(help.lines().any(|s| s.trim().starts_with("[default")));

    // The short help should still have the default on the same line
    let help = utils::get_help::<Command>();
    assert!(help.contains("Multiline [default"));
}

#[test]
fn argenum_multiline_doc_comment() {
    #[derive(ValueEnum, Clone)]
    enum LoremIpsum {
        /// Multiline
        ///
        /// Doc comment
        Bar,
    }
}

#[test]
fn doc_comment_about_handles_both_abouts() {
    /// Opts doc comment summary
    #[derive(Parser, Debug)]
    pub struct Opts {
        #[command(subcommand)]
        pub cmd: Sub,
    }

    /// Sub doc comment summary
    ///
    /// Sub doc comment body
    #[derive(Parser, PartialEq, Eq, Debug)]
    pub enum Sub {
        Compress { output: String },
    }

    let cmd = Opts::command();
    assert_eq!(
        cmd.get_about().map(|s| s.to_string()),
        Some("Opts doc comment summary".to_owned())
    );
    // clap will fallback to `about` on `None`.  The main care about is not providing a `Sub` doc
    // comment.
    assert_eq!(cmd.get_long_about(), None);
}

#[test]
fn respect_subcommand_doc_comment() {
    #[derive(Parser, Debug)]
    pub enum Cmd {
        /// For child
        #[command(subcommand)]
        Child(Child),
    }

    #[derive(Subcommand, Debug)]
    pub enum Child {
        One,
        Twp,
    }

    const OUTPUT: &str = "\
Usage: cmd <COMMAND>

Commands:
  child  For child
  help   Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help information
";
    utils::assert_output::<Cmd>("cmd --help", OUTPUT, false);
}
<commit_msg>test(derive): Rename text case<commit_after>// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
//
// 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 work was derived from Structopt (https://github.com/TeXitoi/structopt)
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
// MIT/Apache 2.0 license.

use crate::utils;

use clap::{CommandFactory, Parser, Subcommand, ValueEnum};

#[test]
fn doc_comments() {
    /// Lorem ipsum
    #[derive(Parser, PartialEq, Debug)]
    struct LoremIpsum {
        /// Fooify a bar
        /// and a baz
        #[arg(short, long)]
        foo: bool,
    }

    let help = utils::get_long_help::<LoremIpsum>();
    assert!(help.contains("Lorem ipsum"));
    assert!(help.contains("Fooify a bar and a baz"));
}

#[test]
fn help_is_better_than_comments() {
    /// Lorem ipsum
    #[derive(Parser, PartialEq, Debug)]
    #[command(name = "lorem-ipsum", about = "Dolor sit amet")]
    struct LoremIpsum {
        /// Fooify a bar
        #[arg(short, long, help = "DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES")]
        foo: bool,
    }

    let help = utils::get_long_help::<LoremIpsum>();
    assert!(help.contains("Dolor sit amet"));
    assert!(!help.contains("Lorem ipsum"));
    assert!(help.contains("DO NOT PASS A BAR"));
}

#[test]
fn empty_line_in_doc_comment_is_double_linefeed() {
    /// Foo.
    ///
    /// Bar
    #[derive(Parser, PartialEq, Debug)]
    #[command(name = "lorem-ipsum")]
    struct LoremIpsum {}

    let help = utils::get_long_help::<LoremIpsum>();
    assert!(help.starts_with(
        "\
Foo.

Bar

Usage:"
    ));
}

#[test]
fn field_long_doc_comment_both_help_long_help() {
    /// Lorem ipsumclap
    #[derive(Parser, PartialEq, Debug)]
    #[command(name = "lorem-ipsum", about = "Dolor sit amet")]
    struct LoremIpsum {
        /// Dot is removed from multiline comments.
        ///
        /// Long help
        #[arg(long)]
        foo: bool,

        /// Dot is removed from one short comment.
        #[arg(long)]
        bar: bool,
    }

    let short_help = utils::get_help::<LoremIpsum>();
    let long_help = utils::get_long_help::<LoremIpsum>();

    assert!(short_help.contains("Dot is removed from one short comment"));
    assert!(!short_help.contains("Dot is removed from one short comment."));
    assert!(short_help.contains("Dot is removed from multiline comments"));
    assert!(!short_help.contains("Dot is removed from multiline comments."));
    assert!(long_help.contains("Long help"));
    assert!(!short_help.contains("Long help"));
}

#[test]
fn top_long_doc_comment_both_help_long_help() {
    /// Lorem ipsumclap
    #[derive(Parser, Debug)]
    #[command(name = "lorem-ipsum", about = "Dolor sit amet")]
    struct LoremIpsum {
        #[command(subcommand)]
        foo: SubCommand,
    }

    #[derive(Parser, Debug)]
    pub enum SubCommand {
        /// DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES
        ///
        /// Or something else
        Foo {
            #[arg(help = "foo")]
            bars: String,
        },
    }

    let short_help = utils::get_help::<LoremIpsum>();
    let long_help = utils::get_subcommand_long_help::<LoremIpsum>("foo");

    assert!(!short_help.contains("Or something else"));
    assert!(long_help.contains("DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES"));
    assert!(long_help.contains("Or something else"));
}

#[test]
fn verbatim_doc_comment() {
    /// DANCE!
    ///
    ///                    ()
    ///                    |
    ///               (   ()   )
    ///     ) ________    //  )
    ///  ()  |\       \  //
    /// ( \\__ \ ______\//
    ///    \__) |       |
    ///      |  |       |
    ///       \ |       |
    ///        \|_______|
    ///        //    \\
    ///       ((     ||
    ///        \\    ||
    ///      ( ()    ||
    ///       (      () ) )
    #[derive(Parser, Debug)]
    #[command(verbatim_doc_comment)]
    struct SeeFigure1 {
        #[arg(long)]
        foo: bool,
    }

    let help = utils::get_long_help::<SeeFigure1>();
    let sample = r#"
                   ()
                   |
              (   ()   )
    ) ________    //  )
 ()  |\       \  //
( \\__ \ ______\//
   \__) |       |
     |  |       |
      \ |       |
       \|_______|
       //    \\
      ((     ||
       \\    ||
     ( ()    ||
      (      () ) )"#;

    assert!(help.contains(sample))
}

#[test]
fn verbatim_doc_comment_field() {
    #[derive(Parser, Debug)]
    struct Command {
        /// This help ends in a period.
        #[arg(long, verbatim_doc_comment)]
        foo: bool,
        /// This help does not end in a period.
        #[arg(long)]
        bar: bool,
    }

    let help = utils::get_long_help::<Command>();

    assert!(help.contains("This help ends in a period."));
    assert!(help.contains("This help does not end in a period"));
}

#[test]
fn multiline_separates_default() {
    #[derive(Parser, Debug)]
    struct Command {
        /// Multiline
        ///
        /// Doc comment
        #[arg(long, default_value = "x")]
        x: String,
    }

    let help = utils::get_long_help::<Command>();
    assert!(!help.contains("Doc comment [default"));
    assert!(help.lines().any(|s| s.trim().starts_with("[default")));

    // The short help should still have the default on the same line
    let help = utils::get_help::<Command>();
    assert!(help.contains("Multiline [default"));
}

#[test]
fn value_enum_multiline_doc_comment() {
    #[derive(ValueEnum, Clone)]
    enum LoremIpsum {
        /// Multiline
        ///
        /// Doc comment
        Bar,
    }
}

#[test]
fn doc_comment_about_handles_both_abouts() {
    /// Opts doc comment summary
    #[derive(Parser, Debug)]
    pub struct Opts {
        #[command(subcommand)]
        pub cmd: Sub,
    }

    /// Sub doc comment summary
    ///
    /// Sub doc comment body
    #[derive(Parser, PartialEq, Eq, Debug)]
    pub enum Sub {
        Compress { output: String },
    }

    let cmd = Opts::command();
    assert_eq!(
        cmd.get_about().map(|s| s.to_string()),
        Some("Opts doc comment summary".to_owned())
    );
    // clap will fallback to `about` on `None`.  The main care about is not providing a `Sub` doc
    // comment.
    assert_eq!(cmd.get_long_about(), None);
}

#[test]
fn respect_subcommand_doc_comment() {
    #[derive(Parser, Debug)]
    pub enum Cmd {
        /// For child
        #[command(subcommand)]
        Child(Child),
    }

    #[derive(Subcommand, Debug)]
    pub enum Child {
        One,
        Twp,
    }

    const OUTPUT: &str = "\
Usage: cmd <COMMAND>

Commands:
  child  For child
  help   Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help information
";
    utils::assert_output::<Cmd>("cmd --help", OUTPUT, false);
}
<|endoftext|>


<commit_before>extern crate regex;
use regex::Regex;

use expression;
use expression::enums;

type Expression = expression::Expression;

pub fn parse_input(input: &String,
                   numeric_regex: &Regex,
                   function_regex: &Regex)
                   -> (String, Result<expression::Expression, String>) {
    let (variable, expr) = string_to_expr(input, numeric_regex, function_regex);
    convert_to_postfix(input, variable, expr)
}

fn string_to_expr(input: &String,
                  numeric_regex: &Regex,
                  function_regex: &Regex)
                  -> (String, Expression) {
    // 1. Replace everthing except letters/numbers with their enums
    // 2. Then go through and replace things with Literals or functions
    let mut variable: String = String::new();
    let mut expr: Expression = Expression::new(Vec::new());
    let mut builder: String = String::new();
    for c in input.chars() {
        match c {
            '(' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Open);
            }
            ')' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Close);
            }
            '+' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Op(enums::Operator::Add));
            }
            '-' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    expr.push(enums::Token::Op(enums::Operator::Sub));
                    builder = String::new();
                } else if builder.len() == 0 {
                    expr.push(enums::Token::Op(enums::Operator::Negate));
                }
            }
            '*' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Op(enums::Operator::Mul));
            }
            '/' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Op(enums::Operator::Div));
            }
            '^' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Op(enums::Operator::Pow));
            }
            ',' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Comma);
            }
            '%' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Op(enums::Operator::Mod));
            }
            '=' => {
                if builder.len() > 0 {
                    variable = builder.clone();
                    builder = String::new();
                }
            }
            _ => {
                builder.push(c);
            }
        }
    }
    if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
        expr.push(x);
    }
    (variable, expr)
}

fn convert_to_postfix(input: &String,
                      variable: String,
                      expr: Expression)
                      -> (String, Result<Expression, String>) {
    let mut op_stack: Vec<enums::Token> = Vec::with_capacity(input.len());
    let mut out_queue: Vec<enums::Token> = Vec::with_capacity(input.len());
    for i in 0..expr.len() {
        let current_token = expr.get_token(i);
        match current_token {
            &enums::Token::Literal(ref x) => out_queue.push(enums::Token::Literal(x.clone())),
            &enums::Token::Func(ref x) => op_stack.push(enums::Token::Func(x.clone())),
            &enums::Token::Comma => {
                loop {
                    let stack_token = op_stack.pop();
                    if !stack_token.is_some() {
                        return (variable,
                                Err("Malformed Expression, comma but no Parenthesis".to_owned()));
                    }
                    let stack_token = stack_token.unwrap();
                    match stack_token {
                        enums::Token::Open => {
                            op_stack.push(stack_token);
                            break;
                        }
                        _ => out_queue.push(stack_token),
                    }
                }
            }
            &enums::Token::Op(ref o1) => {
                loop {
                    if op_stack.len() < 1 {
                        break;
                    }
                    let o2 = op_stack.pop().unwrap(); // top of stack, must exist based off of previous if
                    match o1 {
                        &enums::Operator::Negate => {
                            op_stack.push(o2);
                            break;
                        }
                        &enums::Operator::Pow => {
                            match o2 {
                                enums::Token::Op(enums::Operator::Negate) => out_queue.push(o2),
                                _ => {
                                    op_stack.push(o2);
                                    break;
                                }
                            }
                        }
                        &enums::Operator::Mul |
                        &enums::Operator::Div |
                        &enums::Operator::Mod => {
                            match o2 {
                                enums::Token::Op(enums::Operator::Negate) |
                                enums::Token::Op(enums::Operator::Pow) |
                                enums::Token::Op(enums::Operator::Mul) |
                                enums::Token::Op(enums::Operator::Div) |
                                enums::Token::Op(enums::Operator::Mod) => out_queue.push(o2),
                                _ => {
                                    op_stack.push(o2);
                                    break;
                                }
                            }
                        }
                        &enums::Operator::Add |
                        &enums::Operator::Sub => {
                            match o2 {
                                enums::Token::Op(enums::Operator::Negate) |
                                enums::Token::Op(enums::Operator::Pow) |
                                enums::Token::Op(enums::Operator::Mul) |
                                enums::Token::Op(enums::Operator::Div) |
                                enums::Token::Op(enums::Operator::Mod) |
                                enums::Token::Op(enums::Operator::Add) |
                                enums::Token::Op(enums::Operator::Sub) => out_queue.push(o2),
                                _ => {
                                    op_stack.push(o2);
                                    break;
                                }
                            }
                        }
                    }
                }
                op_stack.push(enums::Token::Op(o1.clone()));
            }
            &enums::Token::Open => op_stack.push(enums::Token::Open),
            &enums::Token::Close => {
                loop {
                    let stack_token = op_stack.pop();
                    if !stack_token.is_some() {
                        return (variable,
                                Err("Malformed Expression, found a ) without (".to_owned()));
                    }
                    let stack_token = stack_token.unwrap();
                    match stack_token {
                        enums::Token::Open => break,
                        _ => out_queue.push(stack_token),
                    }
                }
                if op_stack.len() > 0 {
                    let next_stack_token = op_stack.pop().unwrap(); // must exist based off of previous if
                    match next_stack_token {
                        enums::Token::Func(ref x) => out_queue.push(enums::Token::Func(x.clone())),
                        _ => op_stack.push(next_stack_token),
                    }
                }
            }
            &enums::Token::Var(ref x) => out_queue.push(enums::Token::Var(x.clone())),
            &enums::Token::Unknown(ref x) => {
                let mut message: String = "You either misspelled a function, or it is not yet \
                                           implemented. The unknown string was: ".to_owned();
                message.push_str(x);
                return (variable, Err(message));
            }
            _ => break,
        }
    }
    while op_stack.len() > 0 {
        out_queue.push(op_stack.pop().unwrap()); // The item must exist
    }
    (variable, Ok(Expression::new(out_queue)))
}

fn decide_what_to_push(builder: &String,
                       numeric_regex: &Regex,
                       function_regex: &Regex)
                       -> Option<enums::Token> {
    if builder.len() > 0 {
        let to_push;
        if numeric_regex.is_match(&builder[..]) {
            to_push = enums::Token::Literal(builder.clone());
        } else if function_regex.is_match(&builder[..]) {
            to_push = enums::map_string_to_func(&builder);
        } else {
            to_push = enums::Token::Var(builder.clone());
        }
        return Some(to_push);
    }
    None
}
<commit_msg>Outdated Comments<commit_after>extern crate regex;
use regex::Regex;

use expression;
use expression::enums;

type Expression = expression::Expression;

pub fn parse_input(input: &String,
                   numeric_regex: &Regex,
                   function_regex: &Regex)
                   -> (String, Result<expression::Expression, String>) {
    let (variable, expr) = string_to_expr(input, numeric_regex, function_regex);
    convert_to_postfix(input, variable, expr)
}

fn string_to_expr(input: &String,
                  numeric_regex: &Regex,
                  function_regex: &Regex)
                  -> (String, Expression) {
    let mut variable: String = String::new();
    let mut expr: Expression = Expression::new(Vec::new());
    let mut builder: String = String::new();
    for c in input.chars() {
        match c {
            '(' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Open);
            }
            ')' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Close);
            }
            '+' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Op(enums::Operator::Add));
            }
            '-' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    expr.push(enums::Token::Op(enums::Operator::Sub));
                    builder = String::new();
                } else if builder.len() == 0 {
                    expr.push(enums::Token::Op(enums::Operator::Negate));
                }
            }
            '*' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Op(enums::Operator::Mul));
            }
            '/' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Op(enums::Operator::Div));
            }
            '^' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Op(enums::Operator::Pow));
            }
            ',' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Comma);
            }
            '%' => {
                if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
                    expr.push(x);
                    builder = String::new();
                }
                expr.push(enums::Token::Op(enums::Operator::Mod));
            }
            '=' => {
                if builder.len() > 0 {
                    variable = builder.clone();
                    builder = String::new();
                }
            }
            _ => {
                builder.push(c);
            }
        }
    }
    if let Some(x) = decide_what_to_push(&builder, numeric_regex, function_regex) {
        expr.push(x);
    }
    (variable, expr)
}

fn convert_to_postfix(input: &String,
                      variable: String,
                      expr: Expression)
                      -> (String, Result<Expression, String>) {
    let mut op_stack: Vec<enums::Token> = Vec::with_capacity(input.len());
    let mut out_queue: Vec<enums::Token> = Vec::with_capacity(input.len());
    for i in 0..expr.len() {
        let current_token = expr.get_token(i);
        match current_token {
            &enums::Token::Literal(ref x) => out_queue.push(enums::Token::Literal(x.clone())),
            &enums::Token::Func(ref x) => op_stack.push(enums::Token::Func(x.clone())),
            &enums::Token::Comma => {
                loop {
                    let stack_token = op_stack.pop();
                    if !stack_token.is_some() {
                        return (variable,
                                Err("Malformed Expression, comma but no Parenthesis".to_owned()));
                    }
                    let stack_token = stack_token.unwrap();
                    match stack_token {
                        enums::Token::Open => {
                            op_stack.push(stack_token);
                            break;
                        }
                        _ => out_queue.push(stack_token),
                    }
                }
            }
            &enums::Token::Op(ref o1) => {
                loop {
                    if op_stack.len() < 1 {
                        break;
                    }
                    let o2 = op_stack.pop().unwrap(); // top of stack, must exist based off of previous if
                    match o1 {
                        &enums::Operator::Negate => {
                            op_stack.push(o2);
                            break;
                        }
                        &enums::Operator::Pow => {
                            match o2 {
                                enums::Token::Op(enums::Operator::Negate) => out_queue.push(o2),
                                _ => {
                                    op_stack.push(o2);
                                    break;
                                }
                            }
                        }
                        &enums::Operator::Mul |
                        &enums::Operator::Div |
                        &enums::Operator::Mod => {
                            match o2 {
                                enums::Token::Op(enums::Operator::Negate) |
                                enums::Token::Op(enums::Operator::Pow) |
                                enums::Token::Op(enums::Operator::Mul) |
                                enums::Token::Op(enums::Operator::Div) |
                                enums::Token::Op(enums::Operator::Mod) => out_queue.push(o2),
                                _ => {
                                    op_stack.push(o2);
                                    break;
                                }
                            }
                        }
                        &enums::Operator::Add |
                        &enums::Operator::Sub => {
                            match o2 {
                                enums::Token::Op(enums::Operator::Negate) |
                                enums::Token::Op(enums::Operator::Pow) |
                                enums::Token::Op(enums::Operator::Mul) |
                                enums::Token::Op(enums::Operator::Div) |
                                enums::Token::Op(enums::Operator::Mod) |
                                enums::Token::Op(enums::Operator::Add) |
                                enums::Token::Op(enums::Operator::Sub) => out_queue.push(o2),
                                _ => {
                                    op_stack.push(o2);
                                    break;
                                }
                            }
                        }
                    }
                }
                op_stack.push(enums::Token::Op(o1.clone()));
            }
            &enums::Token::Open => op_stack.push(enums::Token::Open),
            &enums::Token::Close => {
                loop {
                    let stack_token = op_stack.pop();
                    if !stack_token.is_some() {
                        return (variable,
                                Err("Malformed Expression, found a ) without (".to_owned()));
                    }
                    let stack_token = stack_token.unwrap();
                    match stack_token {
                        enums::Token::Open => break,
                        _ => out_queue.push(stack_token),
                    }
                }
                if op_stack.len() > 0 {
                    let next_stack_token = op_stack.pop().unwrap(); // must exist based off of previous if
                    match next_stack_token {
                        enums::Token::Func(ref x) => out_queue.push(enums::Token::Func(x.clone())),
                        _ => op_stack.push(next_stack_token),
                    }
                }
            }
            &enums::Token::Var(ref x) => out_queue.push(enums::Token::Var(x.clone())),
            &enums::Token::Unknown(ref x) => {
                let mut message: String = "You either misspelled a function, or it is not yet \
                                           implemented. The unknown string was: ".to_owned();
                message.push_str(x);
                return (variable, Err(message));
            }
            _ => break,
        }
    }
    while op_stack.len() > 0 {
        out_queue.push(op_stack.pop().unwrap()); // The item must exist
    }
    (variable, Ok(Expression::new(out_queue)))
}

fn decide_what_to_push(builder: &String,
                       numeric_regex: &Regex,
                       function_regex: &Regex)
                       -> Option<enums::Token> {
    if builder.len() > 0 {
        let to_push;
        if numeric_regex.is_match(&builder[..]) {
            to_push = enums::Token::Literal(builder.clone());
        } else if function_regex.is_match(&builder[..]) {
            to_push = enums::map_string_to_func(&builder);
        } else {
            to_push = enums::Token::Var(builder.clone());
        }
        return Some(to_push);
    }
    None
}
<|endoftext|>