<commit_before>use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, LangItem};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::{lint::in_external_macro, ty::TyS};
use rustc_session::{declare_lint_pass, declare_tool_lint};

use crate::utils::{is_type_lang_item, snippet_with_applicability, span_lint_and_sugg};

declare_clippy_lint! {
    /// **What it does:** Checks for redundant slicing expressions which use the full range, and
    /// do not change the type.
    ///
    /// **Why is this bad?** It unnecessarily adds complexity to the expression.
    ///
    /// **Known problems:** If the type being sliced has an implementation of `Index<RangeFull>`
    /// that actually changes anything then it can't be removed. However, this would be surprising
    /// to people reading the code and should have a note with it.
    ///
    /// **Example:**
    ///
    /// ```ignore
    /// fn get_slice(x: &[u32]) -> &[u32] {
    ///     &x[..]
    /// }
    /// ```
    /// Use instead:
    /// ```ignore
    /// fn get_slice(x: &[u32]) -> &[u32] {
    ///     x
    /// }
    /// ```
    pub REDUNDANT_SLICING,
    complexity,
    "redundant slicing of the whole range of a type"
}

declare_lint_pass!(RedundantSlicing => [REDUNDANT_SLICING]);

impl LateLintPass<'_> for RedundantSlicing {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
        if in_external_macro(cx.sess(), expr.span) {
            return;
        }

        if_chain! {
            if let ExprKind::AddrOf(_, _, addressee) = expr.kind;
            if let ExprKind::Index(indexed, range) = addressee.kind;
            if is_type_lang_item(cx, cx.typeck_results().expr_ty_adjusted(range), LangItem::RangeFull);
            if TyS::same_type(cx.typeck_results().expr_ty(expr), cx.typeck_results().expr_ty(indexed));
            then {
                let mut app = Applicability::MachineApplicable;
                let hint = snippet_with_applicability(cx, indexed.span, "..", &mut app).into_owned();

                span_lint_and_sugg(cx, REDUNDANT_SLICING, expr.span, "redundant slicing of the whole range",
                    "use the original slice instead", hint, app);
            }
        }
    }
}
<commit_msg>Update clippy_lints/src/redundant_slicing.rs<commit_after>use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, LangItem};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::{lint::in_external_macro, ty::TyS};
use rustc_session::{declare_lint_pass, declare_tool_lint};

use crate::utils::{is_type_lang_item, snippet_with_applicability, span_lint_and_sugg};

declare_clippy_lint! {
    /// **What it does:** Checks for redundant slicing expressions which use the full range, and
    /// do not change the type.
    ///
    /// **Why is this bad?** It unnecessarily adds complexity to the expression.
    ///
    /// **Known problems:** If the type being sliced has an implementation of `Index<RangeFull>`
    /// that actually changes anything then it can't be removed. However, this would be surprising
    /// to people reading the code and should have a note with it.
    ///
    /// **Example:**
    ///
    /// ```ignore
    /// fn get_slice(x: &[u32]) -> &[u32] {
    ///     &x[..]
    /// }
    /// ```
    /// Use instead:
    /// ```ignore
    /// fn get_slice(x: &[u32]) -> &[u32] {
    ///     x
    /// }
    /// ```
    pub REDUNDANT_SLICING,
    complexity,
    "redundant slicing of the whole range of a type"
}

declare_lint_pass!(RedundantSlicing => [REDUNDANT_SLICING]);

impl LateLintPass<'_> for RedundantSlicing {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
        if in_external_macro(cx.sess(), expr.span) {
            return;
        }

        if_chain! {
            if let ExprKind::AddrOf(_, _, addressee) = expr.kind;
            if let ExprKind::Index(indexed, range) = addressee.kind;
            if is_type_lang_item(cx, cx.typeck_results().expr_ty_adjusted(range), LangItem::RangeFull);
            if TyS::same_type(cx.typeck_results().expr_ty(expr), cx.typeck_results().expr_ty(indexed));
            then {
                let mut app = Applicability::MachineApplicable;
                let hint = snippet_with_applicability(cx, indexed.span, "..", &mut app).into_owned();

                span_lint_and_sugg(
                    cx,
                    REDUNDANT_SLICING,
                    expr.span,
                    "redundant slicing of the whole range",
                    "use the original slice instead",
                    hint,
                    app,
                );
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::{ptr, mem, time, io};
use std::rc::Rc;
use std::net::{SocketAddr, Shutdown};

use bytes::{Bytes, BytesMut, Buf, BufMut};
use futures::{Future, Poll, Async};
use tokio_io::{AsyncRead, AsyncWrite};

use super::{h1, h2, utils, HttpHandler, IoStream};
use super::settings::WorkerSettings;

const HTTP2_PREFACE: [u8; 14] = *b"PRI * HTTP/2.0";

enum HttpProtocol<T: IoStream, H: 'static> {
    H1(h1::Http1<T, H>),
    H2(h2::Http2<T, H>),
    Unknown(Rc<WorkerSettings<H>>, Option<SocketAddr>, T, BytesMut),
}

impl<T: IoStream, H: 'static> HttpProtocol<T, H> {
    fn is_unknown(&self) -> bool {
        match *self {
            HttpProtocol::Unknown(_, _, _, _) => true,
            _ => false
        }
    }
}

enum ProtocolKind {
    Http1,
    Http2,
}

#[doc(hidden)]
pub struct HttpChannel<T, H> where T: IoStream, H: HttpHandler + 'static {
    proto: Option<HttpProtocol<T, H>>,
    node: Option<Node<HttpChannel<T, H>>>,
}

impl<T, H> HttpChannel<T, H> where T: IoStream, H: HttpHandler + 'static
{
    pub(crate) fn new(settings: Rc<WorkerSettings<H>>,
                      io: T, peer: Option<SocketAddr>, http2: bool) -> HttpChannel<T, H>
    {
        settings.add_channel();
        if http2 {
            HttpChannel {
                node: None,
                proto: Some(HttpProtocol::H2(
                    h2::Http2::new(settings, io, peer, Bytes::new()))) }
        } else {
            HttpChannel {
                node: None,
                proto: Some(HttpProtocol::Unknown(
                    settings, peer, io, BytesMut::with_capacity(4096))) }
        }
    }

    fn shutdown(&mut self) {
        match self.proto {
            Some(HttpProtocol::H1(ref mut h1)) => {
                let io = h1.io();
                let _ = IoStream::set_linger(io, Some(time::Duration::new(0, 0)));
                let _ = IoStream::shutdown(io, Shutdown::Both);
            }
            Some(HttpProtocol::H2(ref mut h2)) => {
                h2.shutdown()
            }
            _ => (),
        }
    }
}

impl<T, H> Future for HttpChannel<T, H> where T: IoStream, H: HttpHandler + 'static
{
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        if !self.proto.as_ref().map(|p| p.is_unknown()).unwrap_or(false) && self.node.is_none() {
            self.node = Some(Node::new(self));
            match self.proto {
                Some(HttpProtocol::H1(ref mut h1)) =>
                    h1.settings().head().insert(self.node.as_ref().unwrap()),
                Some(HttpProtocol::H2(ref mut h2)) =>
                    h2.settings().head().insert(self.node.as_ref().unwrap()),
                _ => (),
            }
        }

        let kind = match self.proto {
            Some(HttpProtocol::H1(ref mut h1)) => {
                let result = h1.poll();
                match result {
                    Ok(Async::Ready(())) | Err(_) => {
                        h1.settings().remove_channel();
                        self.node.as_ref().unwrap().remove();
                    },
                    _ => (),
                }
                return result
            },
            Some(HttpProtocol::H2(ref mut h2)) => {
                let result = h2.poll();
                match result {
                    Ok(Async::Ready(())) | Err(_) => {
                        h2.settings().remove_channel();
                        self.node.as_ref().unwrap().remove();
                    },
                    _ => (),
                }
                return result
            },
            Some(HttpProtocol::Unknown(ref mut settings, _, ref mut io, ref mut buf)) => {
                match utils::read_from_io(io, buf) {
                    Ok(Async::Ready(0)) | Err(_) => {
                        debug!("Ignored premature client disconnection");
                        settings.remove_channel();
                        return Err(())
                    },
                    _ => (),
                }

                if buf.len() >= 14 {
                    if buf[..14] == HTTP2_PREFACE[..] {
                        ProtocolKind::Http2
                    } else {
                        ProtocolKind::Http1
                    }
                } else {
                    return Ok(Async::NotReady);
                }
            },
            None => unreachable!(),
        };

        // upgrade to specific http protocol
        if let Some(HttpProtocol::Unknown(settings, addr, io, buf)) = self.proto.take() {
            match kind {
                ProtocolKind::Http1 => {
                    self.proto = Some(
                        HttpProtocol::H1(h1::Http1::new(settings, io, addr, buf)));
                    return self.poll()
                },
                ProtocolKind::Http2 => {
                    self.proto = Some(
                        HttpProtocol::H2(h2::Http2::new(settings, io, addr, buf.freeze())));
                    return self.poll()
                },
            }
        }
        unreachable!()
    }
}

pub(crate) struct Node<T>
{
    next: Option<*mut Node<()>>,
    prev: Option<*mut Node<()>>,
    element: *mut T,
}

impl<T> Node<T>
{
    fn new(el: &mut T) -> Self {
        Node {
            next: None,
            prev: None,
            element: el as *mut _,
        }
    }

    fn insert<I>(&self, next: &Node<I>) {
        #[allow(mutable_transmutes)]
        unsafe {
            if let Some(ref next2) = self.next {
                let n: &mut Node<()> = mem::transmute(next2.as_ref().unwrap());
                n.prev = Some(next as *const _ as *mut _);
            }
            let slf: &mut Node<T> = mem::transmute(self);
            slf.next = Some(next as *const _ as *mut _);

            let next: &mut Node<T> = mem::transmute(next);
            next.prev = Some(slf as *const _ as *mut _);
        }
    }

    fn remove(&self) {
        #[allow(mutable_transmutes)]
        unsafe {
            if let Some(ref prev) = self.prev {
                let p: &mut Node<()> = mem::transmute(prev.as_ref().unwrap());
                let slf: &mut Node<T> = mem::transmute(self);
                p.next = slf.next.take();
            }
        }
    }
}

impl Node<()> {

    pub(crate) fn head() -> Self {
        Node {
            next: None,
            prev: None,
            element: ptr::null_mut(),
        }
    }

    pub(crate) fn traverse<T, H>(&self) where T: IoStream, H: HttpHandler + 'static {
        let mut next = self.next.as_ref();
        loop {
            if let Some(n) = next {
                unsafe {
                    let n: &Node<()> = mem::transmute(n.as_ref().unwrap());
                    next = n.next.as_ref();

                    if !n.element.is_null() {
                        let ch: &mut HttpChannel<T, H> = mem::transmute(
                            &mut *(n.element as *mut _));
                        ch.shutdown();
                    }
                }
            } else {
                return
            }
        }
    }
}

/// Wrapper for `AsyncRead + AsyncWrite` types
pub(crate) struct WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
   io: T,
}

impl<T> WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    pub fn new(io: T) -> Self {
        WrapperStream{ io }
    }
}

impl<T> IoStream for WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    #[inline]
    fn shutdown(&mut self, _: Shutdown) -> io::Result<()> {
        Ok(())
    }
    #[inline]
    fn set_nodelay(&mut self, _: bool) -> io::Result<()> {
        Ok(())
    }
    #[inline]
    fn set_linger(&mut self, _: Option<time::Duration>) -> io::Result<()> {
        Ok(())
    }
}

impl<T> io::Read for WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.io.read(buf)
    }
}

impl<T> io::Write for WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.io.write(buf)
    }
    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.io.flush()
    }
}

impl<T> AsyncRead for WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    #[inline]
    fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
        self.io.read_buf(buf)
    }
}

impl<T> AsyncWrite for WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    #[inline]
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        self.io.shutdown()
    }
    #[inline]
    fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
        self.io.write_buf(buf)
    }
}
<commit_msg>simplify linked nodes<commit_after>use std::{ptr, mem, time, io};
use std::rc::Rc;
use std::net::{SocketAddr, Shutdown};

use bytes::{Bytes, BytesMut, Buf, BufMut};
use futures::{Future, Poll, Async};
use tokio_io::{AsyncRead, AsyncWrite};

use super::{h1, h2, utils, HttpHandler, IoStream};
use super::settings::WorkerSettings;

const HTTP2_PREFACE: [u8; 14] = *b"PRI * HTTP/2.0";

enum HttpProtocol<T: IoStream, H: 'static> {
    H1(h1::Http1<T, H>),
    H2(h2::Http2<T, H>),
    Unknown(Rc<WorkerSettings<H>>, Option<SocketAddr>, T, BytesMut),
}

impl<T: IoStream, H: 'static> HttpProtocol<T, H> {
    fn is_unknown(&self) -> bool {
        match *self {
            HttpProtocol::Unknown(_, _, _, _) => true,
            _ => false
        }
    }
}

enum ProtocolKind {
    Http1,
    Http2,
}

#[doc(hidden)]
pub struct HttpChannel<T, H> where T: IoStream, H: HttpHandler + 'static {
    proto: Option<HttpProtocol<T, H>>,
    node: Option<Node<HttpChannel<T, H>>>,
}

impl<T, H> HttpChannel<T, H> where T: IoStream, H: HttpHandler + 'static
{
    pub(crate) fn new(settings: Rc<WorkerSettings<H>>,
                      io: T, peer: Option<SocketAddr>, http2: bool) -> HttpChannel<T, H>
    {
        settings.add_channel();
        if http2 {
            HttpChannel {
                node: None,
                proto: Some(HttpProtocol::H2(
                    h2::Http2::new(settings, io, peer, Bytes::new()))) }
        } else {
            HttpChannel {
                node: None,
                proto: Some(HttpProtocol::Unknown(
                    settings, peer, io, BytesMut::with_capacity(4096))) }
        }
    }

    fn shutdown(&mut self) {
        match self.proto {
            Some(HttpProtocol::H1(ref mut h1)) => {
                let io = h1.io();
                let _ = IoStream::set_linger(io, Some(time::Duration::new(0, 0)));
                let _ = IoStream::shutdown(io, Shutdown::Both);
            }
            Some(HttpProtocol::H2(ref mut h2)) => {
                h2.shutdown()
            }
            _ => (),
        }
    }
}

impl<T, H> Future for HttpChannel<T, H> where T: IoStream, H: HttpHandler + 'static
{
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        if !self.proto.as_ref().map(|p| p.is_unknown()).unwrap_or(false) && self.node.is_none() {
            self.node = Some(Node::new(self));
            match self.proto {
                Some(HttpProtocol::H1(ref mut h1)) =>
                    h1.settings().head().insert(self.node.as_ref().unwrap()),
                Some(HttpProtocol::H2(ref mut h2)) =>
                    h2.settings().head().insert(self.node.as_ref().unwrap()),
                _ => (),
            }
        }

        let kind = match self.proto {
            Some(HttpProtocol::H1(ref mut h1)) => {
                let result = h1.poll();
                match result {
                    Ok(Async::Ready(())) | Err(_) => {
                        h1.settings().remove_channel();
                        self.node.as_mut().unwrap().remove();
                    },
                    _ => (),
                }
                return result
            },
            Some(HttpProtocol::H2(ref mut h2)) => {
                let result = h2.poll();
                match result {
                    Ok(Async::Ready(())) | Err(_) => {
                        h2.settings().remove_channel();
                        self.node.as_mut().unwrap().remove();
                    },
                    _ => (),
                }
                return result
            },
            Some(HttpProtocol::Unknown(ref mut settings, _, ref mut io, ref mut buf)) => {
                match utils::read_from_io(io, buf) {
                    Ok(Async::Ready(0)) | Err(_) => {
                        debug!("Ignored premature client disconnection");
                        settings.remove_channel();
                        return Err(())
                    },
                    _ => (),
                }

                if buf.len() >= 14 {
                    if buf[..14] == HTTP2_PREFACE[..] {
                        ProtocolKind::Http2
                    } else {
                        ProtocolKind::Http1
                    }
                } else {
                    return Ok(Async::NotReady);
                }
            },
            None => unreachable!(),
        };

        // upgrade to specific http protocol
        if let Some(HttpProtocol::Unknown(settings, addr, io, buf)) = self.proto.take() {
            match kind {
                ProtocolKind::Http1 => {
                    self.proto = Some(
                        HttpProtocol::H1(h1::Http1::new(settings, io, addr, buf)));
                    return self.poll()
                },
                ProtocolKind::Http2 => {
                    self.proto = Some(
                        HttpProtocol::H2(h2::Http2::new(settings, io, addr, buf.freeze())));
                    return self.poll()
                },
            }
        }
        unreachable!()
    }
}

pub(crate) struct Node<T>
{
    next: Option<*mut Node<()>>,
    prev: Option<*mut Node<()>>,
    element: *mut T,
}

impl<T> Node<T>
{
    fn new(el: &mut T) -> Self {
        Node {
            next: None,
            prev: None,
            element: el as *mut _,
        }
    }

    fn insert<I>(&self, next: &Node<I>) {
        #[allow(mutable_transmutes)]
        unsafe {
            if let Some(ref next2) = self.next {
                let n: &mut Node<()> = mem::transmute(next2.as_ref().unwrap());
                n.prev = Some(next as *const _ as *mut _);
            }
            let slf: &mut Node<T> = mem::transmute(self);
            slf.next = Some(next as *const _ as *mut _);

            let next: &mut Node<T> = mem::transmute(next);
            next.prev = Some(slf as *const _ as *mut _);
        }
    }

    fn remove(&mut self) {
        #[allow(mutable_transmutes)]
        unsafe {
            let mut prev = self.prev.take();
            let next = self.next.take();

            if let Some(ref mut prev) = prev {
                let p: &mut Node<()> = mem::transmute(prev.as_ref().unwrap());
                p.next = next;
            }
        }
    }
}

impl Node<()> {

    pub(crate) fn head() -> Self {
        Node {
            next: None,
            prev: None,
            element: ptr::null_mut(),
        }
    }

    pub(crate) fn traverse<T, H>(&self) where T: IoStream, H: HttpHandler + 'static {
        let mut next = self.next.as_ref();
        loop {
            if let Some(n) = next {
                unsafe {
                    let n: &Node<()> = mem::transmute(n.as_ref().unwrap());
                    next = n.next.as_ref();

                    if !n.element.is_null() {
                        let ch: &mut HttpChannel<T, H> = mem::transmute(
                            &mut *(n.element as *mut _));
                        ch.shutdown();
                    }
                }
            } else {
                return
            }
        }
    }
}

/// Wrapper for `AsyncRead + AsyncWrite` types
pub(crate) struct WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
   io: T,
}

impl<T> WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    pub fn new(io: T) -> Self {
        WrapperStream{ io }
    }
}

impl<T> IoStream for WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    #[inline]
    fn shutdown(&mut self, _: Shutdown) -> io::Result<()> {
        Ok(())
    }
    #[inline]
    fn set_nodelay(&mut self, _: bool) -> io::Result<()> {
        Ok(())
    }
    #[inline]
    fn set_linger(&mut self, _: Option<time::Duration>) -> io::Result<()> {
        Ok(())
    }
}

impl<T> io::Read for WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.io.read(buf)
    }
}

impl<T> io::Write for WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.io.write(buf)
    }
    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.io.flush()
    }
}

impl<T> AsyncRead for WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    #[inline]
    fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
        self.io.read_buf(buf)
    }
}

impl<T> AsyncWrite for WrapperStream<T> where T: AsyncRead + AsyncWrite + 'static {
    #[inline]
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        self.io.shutdown()
    }
    #[inline]
    fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
        self.io.write_buf(buf)
    }
}
<|endoftext|>


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

#![deny(unused_must_use)]
#![feature(clamp, const_nonzero_int_methods, drain_filter)]

#[macro_use]
extern crate bitflags;
extern crate byteorder;
extern crate cgmath;
extern crate chrono;
extern crate env_logger;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate num;
#[macro_use]
extern crate num_derive;
extern crate rand;
extern crate regex;
extern crate rodio;
extern crate winit;

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

#![deny(unused_must_use)]
#![feature(clamp, drain_filter)]

#[macro_use]
extern crate bitflags;
extern crate byteorder;
extern crate cgmath;
extern crate chrono;
extern crate env_logger;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate num;
#[macro_use]
extern crate num_derive;
extern crate rand;
extern crate regex;
extern crate rodio;
extern crate winit;

pub mod client;
pub mod common;
pub mod server;
<|endoftext|>


<commit_before>// Copyright 2013-2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

extern crate cairo_sys as ffi;
extern crate libc;

#[macro_use]
extern crate bitflags;

#[cfg(feature = "use_glib")]
#[macro_use]
extern crate glib;

#[cfg(feature = "use_glib")]
extern crate glib_sys as glib_ffi;

#[cfg(feature = "use_glib")]
extern crate gobject_sys as gobject_ffi;

#[cfg(test)]
extern crate tempfile;

// Helper macro for our GValue related trait impls
#[cfg(feature = "use_glib")]
macro_rules! gvalue_impl {
    ($name:ty, $ffi_name:ty, $get_type:expr) => {
        use glib;
        #[allow(unused_imports)]
        use glib::translate::*;
        use glib_ffi;
        use gobject_ffi;

        impl glib::types::StaticType for $name {
            fn static_type() -> glib::types::Type {
                unsafe { from_glib($get_type()) }
            }
        }

        impl<'a> glib::value::FromValueOptional<'a> for $name {
            unsafe fn from_value_optional(v: &'a glib::value::Value) -> Option<Self> {
                let ptr = gobject_ffi::g_value_get_boxed(v.to_glib_none().0);
                assert!(!ptr.is_null());
                from_glib_none(ptr as *mut $ffi_name)
            }
        }

        impl glib::value::SetValue for $name {
            unsafe fn set_value(v: &mut glib::value::Value, s: &Self) {
                gobject_ffi::g_value_set_boxed(
                    v.to_glib_none_mut().0,
                    s.to_glib_none().0 as glib_ffi::gpointer,
                );
            }
        }

        impl glib::value::SetValueOptional for $name {
            unsafe fn set_value_optional(v: &mut glib::value::Value, s: Option<&Self>) {
                if let Some(s) = s {
                    gobject_ffi::g_value_set_boxed(
                        v.to_glib_none_mut().0,
                        s.to_glib_none().0 as glib_ffi::gpointer,
                    );
                } else {
                    gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, ::std::ptr::null_mut());
                }
            }
        }
    };
}

pub use user_data::UserDataKey;

pub use context::{Context, RectangleList};

pub use paths::{Path, PathSegment, PathSegments};

pub use device::Device;

pub use enums::*;

pub use error::{BorrowError, IoError};

pub use patterns::{
    Gradient, LinearGradient, Mesh, Pattern, RadialGradient, SolidPattern, SurfacePattern
};

pub use font::{
    FontExtents, FontFace, FontOptions, FontSlant, FontType, FontWeight, Glyph, ScaledFont,
    TextCluster, TextExtents,
};

pub use matrices::Matrix;

pub use recording_surface::RecordingSurface;
pub use rectangle::Rectangle;
pub use rectangle_int::RectangleInt;

pub use region::Region;

pub use surface::{MappedImageSurface, Surface};

pub use image_surface::{ImageSurface, ImageSurfaceData};

#[cfg(any(feature = "pdf", feature = "svg", feature = "ps", feature = "dox"))]
pub use stream::StreamWithError;

#[cfg(any(feature = "pdf", feature = "dox"))]
pub use pdf::PdfSurface;

#[cfg(any(feature = "ps", feature = "dox"))]
pub use ps::PsSurface;

#[cfg(any(feature = "svg", feature = "dox"))]
pub use svg::SvgSurface;

#[cfg(any(feature = "xcb", feature = "dox"))]
pub use xcb::{
    XCBConnection, XCBDrawable, XCBPixmap, XCBRenderPictFormInfo, XCBScreen, XCBSurface,
    XCBVisualType,
};

#[macro_use]
mod user_data;
mod constants;
pub use constants::*;
mod utils;
pub use utils::*;

mod context;
mod device;
mod enums;
mod error;
mod font;
mod image_surface;
#[cfg(any(feature = "png", feature = "dox"))]
mod image_surface_png;
mod matrices;
mod paths;
mod patterns;
mod recording_surface;
mod rectangle;
mod rectangle_int;
mod region;
mod surface;
#[cfg(any(feature = "xcb", feature = "dox"))]
mod xcb;

#[cfg(any(feature = "pdf", feature = "svg", feature = "ps", feature = "dox"))]
#[macro_use]
mod stream;
#[cfg(any(feature = "pdf", feature = "dox"))]
mod pdf;
#[cfg(any(feature = "ps", feature = "dox"))]
mod ps;
#[cfg(any(feature = "svg", feature = "dox"))]
mod svg;

#[cfg(any(target_os = "macos", target_os = "ios", feature = "dox"))]
mod quartz_surface;
#[cfg(any(target_os = "macos", target_os = "ios", feature = "dox"))]
pub use quartz_surface::QuartzSurface;

#[cfg(any(all(windows, feature = "win32-surface"), feature = "dox"))]
mod win32_surface;

#[cfg(any(all(windows, feature = "win32-surface"), feature = "dox"))]
pub use win32_surface::Win32Surface;
<commit_msg>Include crate features in docs (#286)<commit_after>// Copyright 2013-2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
//! # Cairo bindings
//!   This library contains safe Rust bindings for [Cairo](https://www.cairographics.org/).
//!   It is a part of [Gtk-rs](http://gtk-rs.org/).
//! ## Crate features
//! ### Default-on features
//! * **use_glib** -  Use with [glib](https://gtk-rs.org/docs/glib/)
//! ### Fileformat features
//! * **png** - Reading and writing PNG images
//! * **pdf** - Rendering PDF documents
//! * **svg** - Rendering SVG documents
//! * **ps** - Rendering PostScript documents
//! ### Cairo API version features
//! * **v1_14** - Use Cairo 1.14 APIs
//! * **v1_16** - Use Cairo 1.16 APIs
//! ### Documentation features
//! * **embed-lgpl-docs** - Embed API docs locally
//! * **purge-lgpl-docs** - Remove API docs again (counterpart to `embed-lgpl-docs`)
//! * **dox** - Used to keep system dependent items in documentation
//! ### X Window features
//! * **xcb** - X Window System rendering using the XCB library
//! * **xlib** - X Window System rendering using XLib
//! ### Windows API features
//! * **win32-surface** - Microsoft Windows surface support
extern crate cairo_sys as ffi;
extern crate libc;

#[macro_use]
extern crate bitflags;

#[cfg(feature = "use_glib")]
#[macro_use]
extern crate glib;

#[cfg(feature = "use_glib")]
extern crate glib_sys as glib_ffi;

#[cfg(feature = "use_glib")]
extern crate gobject_sys as gobject_ffi;

#[cfg(test)]
extern crate tempfile;

// Helper macro for our GValue related trait impls
#[cfg(feature = "use_glib")]
macro_rules! gvalue_impl {
    ($name:ty, $ffi_name:ty, $get_type:expr) => {
        use glib;
        #[allow(unused_imports)]
        use glib::translate::*;
        use glib_ffi;
        use gobject_ffi;

        impl glib::types::StaticType for $name {
            fn static_type() -> glib::types::Type {
                unsafe { from_glib($get_type()) }
            }
        }

        impl<'a> glib::value::FromValueOptional<'a> for $name {
            unsafe fn from_value_optional(v: &'a glib::value::Value) -> Option<Self> {
                let ptr = gobject_ffi::g_value_get_boxed(v.to_glib_none().0);
                assert!(!ptr.is_null());
                from_glib_none(ptr as *mut $ffi_name)
            }
        }

        impl glib::value::SetValue for $name {
            unsafe fn set_value(v: &mut glib::value::Value, s: &Self) {
                gobject_ffi::g_value_set_boxed(
                    v.to_glib_none_mut().0,
                    s.to_glib_none().0 as glib_ffi::gpointer,
                );
            }
        }

        impl glib::value::SetValueOptional for $name {
            unsafe fn set_value_optional(v: &mut glib::value::Value, s: Option<&Self>) {
                if let Some(s) = s {
                    gobject_ffi::g_value_set_boxed(
                        v.to_glib_none_mut().0,
                        s.to_glib_none().0 as glib_ffi::gpointer,
                    );
                } else {
                    gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, ::std::ptr::null_mut());
                }
            }
        }
    };
}

pub use user_data::UserDataKey;

pub use context::{Context, RectangleList};

pub use paths::{Path, PathSegment, PathSegments};

pub use device::Device;

pub use enums::*;

pub use error::{BorrowError, IoError};

pub use patterns::{
    Gradient, LinearGradient, Mesh, Pattern, RadialGradient, SolidPattern, SurfacePattern,
};

pub use font::{
    FontExtents, FontFace, FontOptions, FontSlant, FontType, FontWeight, Glyph, ScaledFont,
    TextCluster, TextExtents,
};

pub use matrices::Matrix;

pub use recording_surface::RecordingSurface;
pub use rectangle::Rectangle;
pub use rectangle_int::RectangleInt;

pub use region::Region;

pub use surface::{MappedImageSurface, Surface};

pub use image_surface::{ImageSurface, ImageSurfaceData};

#[cfg(any(feature = "pdf", feature = "svg", feature = "ps", feature = "dox"))]
pub use stream::StreamWithError;

#[cfg(any(feature = "pdf", feature = "dox"))]
pub use pdf::PdfSurface;

#[cfg(any(feature = "ps", feature = "dox"))]
pub use ps::PsSurface;

#[cfg(any(feature = "svg", feature = "dox"))]
pub use svg::SvgSurface;

#[cfg(any(feature = "xcb", feature = "dox"))]
pub use xcb::{
    XCBConnection, XCBDrawable, XCBPixmap, XCBRenderPictFormInfo, XCBScreen, XCBSurface,
    XCBVisualType,
};

#[macro_use]
mod user_data;
mod constants;
pub use constants::*;
mod utils;
pub use utils::*;

mod context;
mod device;
mod enums;
mod error;
mod font;
mod image_surface;
#[cfg(any(feature = "png", feature = "dox"))]
mod image_surface_png;
mod matrices;
mod paths;
mod patterns;
mod recording_surface;
mod rectangle;
mod rectangle_int;
mod region;
mod surface;
#[cfg(any(feature = "xcb", feature = "dox"))]
mod xcb;

#[cfg(any(feature = "pdf", feature = "svg", feature = "ps", feature = "dox"))]
#[macro_use]
mod stream;
#[cfg(any(feature = "pdf", feature = "dox"))]
mod pdf;
#[cfg(any(feature = "ps", feature = "dox"))]
mod ps;
#[cfg(any(feature = "svg", feature = "dox"))]
mod svg;

#[cfg(any(target_os = "macos", target_os = "ios", feature = "dox"))]
mod quartz_surface;
#[cfg(any(target_os = "macos", target_os = "ios", feature = "dox"))]
pub use quartz_surface::QuartzSurface;

#[cfg(any(all(windows, feature = "win32-surface"), feature = "dox"))]
mod win32_surface;

#[cfg(any(all(windows, feature = "win32-surface"), feature = "dox"))]
pub use win32_surface::Win32Surface;
<|endoftext|>


<commit_before>//! This is documentation for the `changes-stream` crate.
//!
//! The `changes-stream` crate is designed to give you a readable stream of
//! chunked data, upon which you can register multiple handlers, that are
//! called on Read of the data chunk.

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;
extern crate futures;
extern crate hyper;
extern crate hyper_tls;
extern crate tokio_core;

use futures::Future;
use futures::stream::Stream;
use hyper::Client;
use std::cell::RefCell;

mod event;
use event::Event;

const DELIMITER: &'static str = ",\n";
const PROLOGUE: &'static str = "{\"results\":[";

/// A structure to generate a readable stream on which you can register handlers.
///
/// Internally, the `ChangesStream` struct holds 3 members:
///
/// | Member      | Type                                  | Notes                                                                   |
/// |-------------|---------------------------------------|-------------------------------------------------------------------------|
/// | `db`        | `String`                              | A url pointing to the data you'd like to stream.                        |
/// | `lp`        | [`tokio_core::reactor::Core`]         | The event loop                                                          |
/// | `handlers`  | `Vec<F> where F: Fn(&`[`hyper::Chunk`]`)` | A vector of handlers to be called on each Chunk from the Stream on Read |
///
/// [`tokio_core::reactor::Core`]: ../tokio_core/reactor/struct.Core.html
/// [`hyper::Chunk`]: ../hyper/struct.Chunk.html
pub struct ChangesStream {
    db: hyper::Url,
    lp: tokio_core::reactor::Core,
    handlers: Vec<Box<Fn(&Event)>>,
}

impl ChangesStream {
    /// Constructs a new `ChangesStream` struct
    ///
    /// Takes a single argument, `db`, which represents the
    /// url of the data you wish to stream.
    ///
    /// Every `ChangesStream` struct is initialized with
    /// an event loop ([`tokio_core::reactor::Core`]) and an
    /// empty vector of handlers. See above for more details.
    ///
    /// [`tokio_core::reactor::Core`]: ../tokio_core/reactor/struct.Core.html
    ///
    /// For example, to create a new `ChangesStream` struct
    /// for the npmjs registry, you would write:
    ///
    /// ```no_run
    /// # extern crate serde_json;
    /// # extern crate changes_stream;
    /// # extern crate futures;
    /// #
    /// #
    /// # use changes_stream::ChangesStream;
    /// #
    /// # fn main() {
    ///     let url = "https://replicate.npmjs.com/_changes".to_string();
    ///     let mut changes = ChangesStream::new(url);
    /// #
    /// #   changes.on(|change| {
    /// #       let data = serde_json::to_string(change).unwrap();
    /// #       println!("{}", data);
    /// #   });
    /// #
    /// #   changes.run();
    /// # }
    /// ```
    pub fn new(db: String) -> ChangesStream {
        ChangesStream {
            db: db.parse().unwrap(),
            lp: tokio_core::reactor::Core::new().unwrap(),
            handlers: vec![],
        }
    }

    /// Registers a handler. A handler is simply a function
    /// you'd like to call on a chunk from the stream at the
    /// time the chunk is read.
    ///
    /// `.on()` takes a single argument, a closure. The
    /// closure you pass should take a single [`hyper::Chunk`]
    /// as an argument.
    ///
    /// [`hyper::Chunk`]: ../hyper/struct.Chunk.html
    ///
    /// For example, to write the data in a chunk to standard
    /// out, you would write:
    ///
    /// ```no_run
    /// # extern crate serde_json;
    /// # extern crate changes_stream;
    /// # extern crate futures;
    /// #
    /// # use changes_stream::ChangesStream;
    /// #
    /// # fn main() {
    /// #   let url = "https://replicate.npmjs.com/_changes".to_string();
    /// #   let mut changes = ChangesStream::new(url);
    /// #
    ///    changes.on(|change| {
    ///       let data = serde_json::to_string(change).unwrap();
    ///       println!("{}", data);
    ///    });
    /// #
    /// #   changes.run();
    /// # }
    /// ```
    pub fn on<F: Fn(&Event) + 'static>(&mut self, handler: F) {
        self.handlers.push(Box::new(handler));
    }

    /// Runs the `ChangesStream` struct's event loop, `lp`.
    ///
    /// Call this after you have regsitered all handlers using
    /// `on`.
    ///
    /// Takes no arguments.
    ///
    /// For example:
    ///
    /// ```no_run
    /// # extern crate serde_json;
    /// # extern crate changes_stream;
    /// # extern crate futures;
    /// #
    /// # use changes_stream::ChangesStream;
    /// #
    /// # fn main() {
    /// #   let url = "https://replicate.npmjs.com/_changes".to_string();
    /// #   let mut changes = ChangesStream::new(url);
    /// #
    /// #   changes.on(|change| {
    /// #       let data = serde_json::to_string(change).unwrap();
    /// #       println!("{}", data);
    /// #   });
    /// #
    ///    changes.run();
    /// # }
    /// ```
    pub fn run(mut self) {
        let handle = self.lp.handle();
        let client = Client::configure()
            // 4 is number of threads to use for dns resolution
            .connector(hyper_tls::HttpsConnector::new(4, &handle))
            .build(&handle);

        let handlers = self.handlers;
        self.lp
            .run(client.get(self.db).and_then(move |res| {
                assert!(res.status().is_success());

                // Buffer up incomplete json lines.
                let mut buffer: Vec<u8> = vec![];
                let buffer_cell = RefCell::new(buffer);

                res.body().for_each(move |chunk| {
                    if chunk.starts_with(PROLOGUE.as_bytes()) {
                        return Ok(());
                    }
                    let mut source = chunk.to_vec();
                    let mut borrowed = buffer_cell.borrow_mut();
                    if borrowed.len() > 0 {
                        source = [borrowed.clone(), chunk.to_vec()].concat();
                        borrowed.clear();
                    }
                    if chunk.starts_with(DELIMITER.as_bytes()) {
                        source = chunk[2..].to_vec();
                    }

                    match serde_json::from_slice(source.as_slice()) {
                        Err(_) => {
                            // We probably have an incomplete chunk of json. Buffer it & move on.
                            borrowed.append(&mut chunk.to_vec());
                        }
                        Ok(json) => {
                            let event: Event = json;
                            for handler in &handlers {
                                handler(&event);
                            }
                        }
                    }
                    Ok(())
                })
            }))
            .unwrap();
    }

    pub fn run_with(self, mut lp: tokio_core::reactor::Core) {
        let handle = self.lp.handle();
        let client = Client::configure()
            // 4 is number of threads to use for dns resolution
            .connector(hyper_tls::HttpsConnector::new(4, &handle))
            .build(&handle);

        let handlers = self.handlers;
        lp
            .run(client.get(self.db).and_then(move |res| {
                assert!(res.status().is_success());

                res.body().for_each(move |chunk| {
                    let event: Package = serde_json::from_slice(&chunk).unwrap();
                    for handler in &handlers {
                        handler(&event);
                    }
                    Ok(())
                })
            }))
            .unwrap();

    }
}
<commit_msg>Fix the build<commit_after>//! This is documentation for the `changes-stream` crate.
//!
//! The `changes-stream` crate is designed to give you a readable stream of
//! chunked data, upon which you can register multiple handlers, that are
//! called on Read of the data chunk.

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;
extern crate futures;
extern crate hyper;
extern crate hyper_tls;
extern crate tokio_core;

use futures::Future;
use futures::stream::Stream;
use hyper::Client;
use std::cell::RefCell;

mod event;
use event::Event;

const DELIMITER: &'static str = ",\n";
const PROLOGUE: &'static str = "{\"results\":[";

/// A structure to generate a readable stream on which you can register handlers.
///
/// Internally, the `ChangesStream` struct holds 3 members:
///
/// | Member      | Type                                  | Notes                                                                   |
/// |-------------|---------------------------------------|-------------------------------------------------------------------------|
/// | `db`        | `String`                              | A url pointing to the data you'd like to stream.                        |
/// | `lp`        | [`tokio_core::reactor::Core`]         | The event loop                                                          |
/// | `handlers`  | `Vec<F> where F: Fn(&`[`hyper::Chunk`]`)` | A vector of handlers to be called on each Chunk from the Stream on Read |
///
/// [`tokio_core::reactor::Core`]: ../tokio_core/reactor/struct.Core.html
/// [`hyper::Chunk`]: ../hyper/struct.Chunk.html
pub struct ChangesStream {
    db: hyper::Uri,
    lp: tokio_core::reactor::Core,
    handlers: Vec<Box<Fn(&Event)>>,
}

impl ChangesStream {
    /// Constructs a new `ChangesStream` struct
    ///
    /// Takes a single argument, `db`, which represents the
    /// url of the data you wish to stream.
    ///
    /// Every `ChangesStream` struct is initialized with
    /// an event loop ([`tokio_core::reactor::Core`]) and an
    /// empty vector of handlers. See above for more details.
    ///
    /// [`tokio_core::reactor::Core`]: ../tokio_core/reactor/struct.Core.html
    ///
    /// For example, to create a new `ChangesStream` struct
    /// for the npmjs registry, you would write:
    ///
    /// ```no_run
    /// # extern crate serde_json;
    /// # extern crate changes_stream;
    /// # extern crate futures;
    /// #
    /// #
    /// # use changes_stream::ChangesStream;
    /// #
    /// # fn main() {
    ///     let url = "https://replicate.npmjs.com/_changes".to_string();
    ///     let mut changes = ChangesStream::new(url);
    /// #
    /// #   changes.on(|change| {
    /// #       let data = serde_json::to_string(change).unwrap();
    /// #       println!("{}", data);
    /// #   });
    /// #
    /// #   changes.run();
    /// # }
    /// ```
    pub fn new(db: String) -> ChangesStream {
        ChangesStream {
            db: db.parse().unwrap(),
            lp: tokio_core::reactor::Core::new().unwrap(),
            handlers: vec![],
        }
    }

    /// Registers a handler. A handler is simply a function
    /// you'd like to call on a chunk from the stream at the
    /// time the chunk is read.
    ///
    /// `.on()` takes a single argument, a closure. The
    /// closure you pass should take a single [`hyper::Chunk`]
    /// as an argument.
    ///
    /// [`hyper::Chunk`]: ../hyper/struct.Chunk.html
    ///
    /// For example, to write the data in a chunk to standard
    /// out, you would write:
    ///
    /// ```no_run
    /// # extern crate serde_json;
    /// # extern crate changes_stream;
    /// # extern crate futures;
    /// #
    /// # use changes_stream::ChangesStream;
    /// #
    /// # fn main() {
    /// #   let url = "https://replicate.npmjs.com/_changes".to_string();
    /// #   let mut changes = ChangesStream::new(url);
    /// #
    ///    changes.on(|change| {
    ///       let data = serde_json::to_string(change).unwrap();
    ///       println!("{}", data);
    ///    });
    /// #
    /// #   changes.run();
    /// # }
    /// ```
    pub fn on<F: Fn(&Event) + 'static>(&mut self, handler: F) {
        self.handlers.push(Box::new(handler));
    }

    /// Runs the `ChangesStream` struct's event loop, `lp`.
    ///
    /// Call this after you have regsitered all handlers using
    /// `on`.
    ///
    /// Takes no arguments.
    ///
    /// For example:
    ///
    /// ```no_run
    /// # extern crate serde_json;
    /// # extern crate changes_stream;
    /// # extern crate futures;
    /// #
    /// # use changes_stream::ChangesStream;
    /// #
    /// # fn main() {
    /// #   let url = "https://replicate.npmjs.com/_changes".to_string();
    /// #   let mut changes = ChangesStream::new(url);
    /// #
    /// #   changes.on(|change| {
    /// #       let data = serde_json::to_string(change).unwrap();
    /// #       println!("{}", data);
    /// #   });
    /// #
    ///    changes.run();
    /// # }
    /// ```
    pub fn run(mut self) {
        let handle = self.lp.handle();
        let client = Client::configure()
            // 4 is number of threads to use for dns resolution
            .connector(hyper_tls::HttpsConnector::new(4, &handle))
            .build(&handle);

        let handlers = self.handlers;
        self.lp
            .run(client.get(self.db).and_then(move |res| {
                assert!(res.status().is_success());

                // Buffer up incomplete json lines.
                let buffer: Vec<u8> = vec![];
                let buffer_cell = RefCell::new(buffer);

                res.body().for_each(move |chunk| {
                    if chunk.starts_with(PROLOGUE.as_bytes()) {
                        return Ok(());
                    }
                    let mut source = chunk.to_vec();
                    let mut borrowed = buffer_cell.borrow_mut();
                    if borrowed.len() > 0 {
                        source = [borrowed.clone(), chunk.to_vec()].concat();
                        borrowed.clear();
                    }
                    if chunk.starts_with(DELIMITER.as_bytes()) {
                        source = chunk[2..].to_vec();
                    }

                    match serde_json::from_slice(source.as_slice()) {
                        Err(_) => {
                            // We probably have an incomplete chunk of json. Buffer it & move on.
                            borrowed.append(&mut chunk.to_vec());
                        }
                        Ok(json) => {
                            let event: Event = json;
                            for handler in &handlers {
                                handler(&event);
                            }
                        }
                    }
                    Ok(())
                })
            }))
            .unwrap();
    }

    pub fn run_with(self, mut lp: tokio_core::reactor::Core) {
        let handle = self.lp.handle();
        let client = Client::configure()
            // 4 is number of threads to use for dns resolution
            .connector(hyper_tls::HttpsConnector::new(4, &handle))
            .build(&handle);

        let handlers = self.handlers;
        lp
            .run(client.get(self.db).and_then(move |res| {
                assert!(res.status().is_success());

                res.body().for_each(move |chunk| {
                    let event: Event = serde_json::from_slice(&chunk).unwrap();
                    for handler in &handlers {
                        handler(&event);
                    }
                    Ok(())
                })
            }))
            .unwrap();

    }
}
<|endoftext|>


<commit_before>// Take a look at the license at the top of the repository in the LICENSE file.

#![doc = include_str!("../README.md")]
#![allow(unknown_lints)]
#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::non_send_fields_in_send_ty)]
#![allow(renamed_and_removed_lints)]
#![allow(unknown_lints)]

#[macro_use]
mod macros;

cfg_if::cfg_if! {
    if #[cfg(feature = "unknown-ci")] {
        // This is used in CI to check that the build for unknown targets is compiling fine.
        mod unknown;
        use unknown as sys;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 0;
    } else if #[cfg(any(target_os = "macos", target_os = "ios"))] {
        mod apple;
        use apple as sys;
        extern crate core_foundation_sys;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 1;
    } else if #[cfg(windows)] {
        mod windows;
        use windows as sys;
        extern crate winapi;
        extern crate ntapi;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 1;
    } else if #[cfg(any(target_os = "linux", target_os = "android"))] {
        mod linux;
        use linux as sys;
        pub(crate) mod users;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 1;
    } else if #[cfg(target_os = "freebsd")] {
        mod freebsd;
        use freebsd as sys;
        pub(crate) mod users;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 1;
    } else {
        mod unknown;
        use unknown as sys;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 0;
    }
}

pub use common::{
    get_current_pid, CpuRefreshKind, DiskType, DiskUsage, Gid, LoadAvg, NetworksIter, Pid, PidExt,
    ProcessRefreshKind, ProcessStatus, RefreshKind, Signal, Uid, User,
};
pub use sys::{Component, Cpu, Disk, NetworkData, Networks, Process, System};
pub use traits::{
    ComponentExt, CpuExt, DiskExt, NetworkExt, NetworksExt, ProcessExt, SystemExt, UserExt,
};

#[cfg(feature = "c-interface")]
pub use c_interface::*;

#[cfg(feature = "c-interface")]
mod c_interface;
mod common;
mod debug;
mod system;
mod traits;
mod utils;

/// This function is only used on linux targets, on the other platforms it does nothing and returns
/// `false`.
///
/// On linux, to improve performance, we keep a `/proc` file open for each process we index with
/// a maximum number of files open equivalent to half of the system limit.
///
/// The problem is that some users might need all the available file descriptors so we need to
/// allow them to change this limit.
///
/// Note that if you set a limit bigger than the system limit, the system limit will be set.
///
/// Returns `true` if the new value has been set.
///
/// ```no_run
/// use sysinfo::{System, SystemExt, set_open_files_limit};
///
/// // We call the function before any call to the processes update.
/// if !set_open_files_limit(10) {
///     // It'll always return false on non-linux targets.
///     eprintln!("failed to update the open files limit...");
/// }
/// let s = System::new_all();
/// ```
pub fn set_open_files_limit(mut _new_limit: isize) -> bool {
    cfg_if::cfg_if! {
        if #[cfg(all(not(feature = "unknown-ci"), any(target_os = "linux", target_os = "android")))]
        {
            if _new_limit < 0 {
                _new_limit = 0;
            }
            let max = sys::system::get_max_nb_fds();
            if _new_limit > max {
                _new_limit = max;
            }
            unsafe {
                if let Ok(ref mut x) = sys::system::REMAINING_FILES.lock() {
                    // If files are already open, to be sure that the number won't be bigger when those
                    // files are closed, we subtract the current number of opened files to the new
                    // limit.
                    let diff = max.saturating_sub(**x);
                    **x = _new_limit.saturating_sub(diff);
                    true
                } else {
                    false
                }
            }
        } else {
            false
        }
    }
}

// FIXME: Can be removed once negative trait bounds are supported.
#[cfg(doctest)]
mod doctest {
    /// Check that `Process` doesn't implement `Clone`.
    ///
    /// First we check that the "basic" code works:
    ///
    /// ```no_run
    /// use sysinfo::{Process, System, SystemExt};
    ///
    /// let mut s = System::new_all();
    /// let p: &Process = s.processes().values().next().unwrap();
    /// ```
    ///
    /// And now we check if it fails when we try to clone it:
    ///
    /// ```compile_fail
    /// use sysinfo::{Process, System, SystemExt};
    ///
    /// let mut s = System::new_all();
    /// let p: &Process = s.processes().values().next().unwrap();
    /// let p = (*p).clone();
    /// ```
    mod process_clone {}

    /// Check that `System` doesn't implement `Clone`.
    ///
    /// First we check that the "basic" code works:
    ///
    /// ```no_run
    /// use sysinfo::{Process, System, SystemExt};
    ///
    /// let s = System::new();
    /// ```
    ///
    /// And now we check if it fails when we try to clone it:
    ///
    /// ```compile_fail
    /// use sysinfo::{Process, System, SystemExt};
    ///
    /// let s = System::new();
    /// let s = s.clone();
    /// ```
    mod system_clone {}
}

#[cfg(test)]
mod test {
    use crate::*;

    #[cfg(feature = "unknown-ci")]
    #[test]
    fn check_unknown_ci_feature() {
        assert!(!System::IS_SUPPORTED);
    }

    #[test]
    fn check_process_memory_usage() {
        let mut s = System::new();
        s.refresh_all();

        if System::IS_SUPPORTED {
            // No process should have 0 as memory usage.
            #[cfg(not(feature = "apple-sandbox"))]
            assert!(!s.processes().iter().all(|(_, proc_)| proc_.memory() == 0));
        } else {
            // There should be no process, but if there is one, its memory usage should be 0.
            assert!(s.processes().iter().all(|(_, proc_)| proc_.memory() == 0));
        }
    }

    #[test]
    fn check_memory_usage() {
        let mut s = System::new();

        assert_eq!(s.total_memory(), 0);
        assert_eq!(s.free_memory(), 0);
        assert_eq!(s.available_memory(), 0);
        assert_eq!(s.used_memory(), 0);
        assert_eq!(s.total_swap(), 0);
        assert_eq!(s.free_swap(), 0);
        assert_eq!(s.used_swap(), 0);

        s.refresh_memory();
        if System::IS_SUPPORTED {
            assert!(s.total_memory() > 0);
            assert!(s.used_memory() > 0);
            if s.total_swap() > 0 {
                // I think it's pretty safe to assume that there is still some swap left...
                assert!(s.free_swap() > 0);
            }
        } else {
            assert_eq!(s.total_memory(), 0);
            assert_eq!(s.used_memory(), 0);
            assert_eq!(s.total_swap(), 0);
            assert_eq!(s.free_swap(), 0);
        }
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn check_processes_cpu_usage() {
        if !System::IS_SUPPORTED {
            return;
        }
        let mut s = System::new();

        s.refresh_processes();
        // All CPU usage will start at zero until the second refresh
        assert!(s
            .processes()
            .iter()
            .all(|(_, proc_)| proc_.cpu_usage() == 0.0));

        // Wait a bit to update CPU usage values
        std::thread::sleep(std::time::Duration::from_millis(100));
        s.refresh_processes();
        assert!(s
            .processes()
            .iter()
            .all(|(_, proc_)| proc_.cpu_usage() >= 0.0
                && proc_.cpu_usage() <= (s.cpus().len() as f32) * 100.0));
        assert!(s
            .processes()
            .iter()
            .any(|(_, proc_)| proc_.cpu_usage() > 0.0));
    }

    #[test]
    fn check_users() {
        let mut s = System::new();
        assert!(s.users().is_empty());
        s.refresh_users_list();
        assert!(s.users().len() >= MIN_USERS);

        let mut s = System::new();
        assert!(s.users().is_empty());
        s.refresh_all();
        assert!(s.users().is_empty());

        let s = System::new_all();
        assert!(s.users().len() >= MIN_USERS);
    }

    #[test]
    fn check_uid_gid() {
        let mut s = System::new();
        assert!(s.users().is_empty());
        s.refresh_users_list();
        let users = s.users();
        assert!(users.len() >= MIN_USERS);

        if System::IS_SUPPORTED {
            #[cfg(not(target_os = "windows"))]
            {
                let user = users
                    .iter()
                    .find(|u| u.name() == "root")
                    .expect("no root user");
                assert_eq!(**user.id(), 0);
                assert_eq!(*user.group_id(), 0);
                if let Some(user) = users.iter().find(|u| *u.group_id() > 0) {
                    assert!(**user.id() > 0);
                    assert!(*user.group_id() > 0);
                }
                assert!(users.iter().filter(|u| **u.id() > 0).count() > 0);
            }

            // And now check that our `get_user_by_id` method works.
            s.refresh_processes();
            assert!(s
                .processes()
                .iter()
                .filter_map(|(_, p)| p.user_id())
                .any(|uid| s.get_user_by_id(uid).is_some()));
        }
    }

    #[test]
    fn check_system_info() {
        // We don't want to test on unsupported systems.
        if System::IS_SUPPORTED {
            let s = System::new();
            assert!(!s.name().expect("Failed to get system name").is_empty());

            assert!(!s
                .kernel_version()
                .expect("Failed to get kernel version")
                .is_empty());

            assert!(!s.os_version().expect("Failed to get os version").is_empty());

            assert!(!s
                .long_os_version()
                .expect("Failed to get long OS version")
                .is_empty());
        }
    }

    #[test]
    fn check_host_name() {
        // We don't want to test on unsupported systems.
        if System::IS_SUPPORTED {
            let s = System::new();
            assert!(s.host_name().is_some());
        }
    }

    #[test]
    fn check_refresh_process_return_value() {
        // We don't want to test on unsupported systems.
        if System::IS_SUPPORTED {
            let _pid = get_current_pid().expect("Failed to get current PID");

            #[cfg(not(feature = "apple-sandbox"))]
            {
                let mut s = System::new();
                // First check what happens in case the process isn't already in our process list.
                assert!(s.refresh_process(_pid));
                // Then check that it still returns true if the process is already in our process list.
                assert!(s.refresh_process(_pid));
            }
        }
    }

    #[test]
    fn ensure_is_supported_is_set_correctly() {
        if MIN_USERS > 0 {
            assert!(System::IS_SUPPORTED);
        } else {
            assert!(!System::IS_SUPPORTED);
        }
    }

    #[test]
    fn check_cpus_number() {
        let mut s = System::new();

        // This information isn't retrieved by default.
        assert!(s.cpus().is_empty());
        if System::IS_SUPPORTED {
            // The physical cores count is recomputed every time the function is called, so the
            // information must be relevant even with nothing initialized.
            let physical_cores_count = s
                .physical_core_count()
                .expect("failed to get number of physical cores");

            s.refresh_cpu();
            // The cpus shouldn't be empty anymore.
            assert!(!s.cpus().is_empty());

            // In case we are running inside a VM, it's possible to not have a physical core, only
            // logical ones, which is why we don't test `physical_cores_count > 0`.
            let physical_cores_count2 = s
                .physical_core_count()
                .expect("failed to get number of physical cores");
            assert!(physical_cores_count2 <= s.cpus().len());
            assert_eq!(physical_cores_count, physical_cores_count2);
        } else {
            assert_eq!(s.physical_core_count(), None);
        }
        assert!(s.physical_core_count().unwrap_or(0) <= s.cpus().len());
    }

    #[test]
    fn check_nb_supported_signals() {
        if System::IS_SUPPORTED {
            assert!(
                !System::SUPPORTED_SIGNALS.is_empty(),
                "SUPPORTED_SIGNALS shoudn't be empty on supported systems!"
            );
        } else {
            assert!(
                System::SUPPORTED_SIGNALS.is_empty(),
                "SUPPORTED_SIGNALS should be empty on not support systems!"
            );
        }
    }

    // Ensure that the CPUs frequency isn't retrieved until we ask for it.
    #[test]
    #[cfg(not(target_os = "freebsd"))] // In a VM, it'll fail.
    fn check_cpu_frequency() {
        if !System::IS_SUPPORTED {
            return;
        }
        let mut s = System::new();
        s.refresh_processes();
        for proc_ in s.cpus() {
            assert_eq!(proc_.frequency(), 0);
        }
        s.refresh_cpu();
        for proc_ in s.cpus() {
            assert_ne!(proc_.frequency(), 0);
        }
    }
}
<commit_msg>Add test to ensure that the CPU usage is computed<commit_after>// Take a look at the license at the top of the repository in the LICENSE file.

#![doc = include_str!("../README.md")]
#![allow(unknown_lints)]
#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::non_send_fields_in_send_ty)]
#![allow(renamed_and_removed_lints)]
#![allow(unknown_lints)]

#[macro_use]
mod macros;

cfg_if::cfg_if! {
    if #[cfg(feature = "unknown-ci")] {
        // This is used in CI to check that the build for unknown targets is compiling fine.
        mod unknown;
        use unknown as sys;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 0;
    } else if #[cfg(any(target_os = "macos", target_os = "ios"))] {
        mod apple;
        use apple as sys;
        extern crate core_foundation_sys;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 1;
    } else if #[cfg(windows)] {
        mod windows;
        use windows as sys;
        extern crate winapi;
        extern crate ntapi;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 1;
    } else if #[cfg(any(target_os = "linux", target_os = "android"))] {
        mod linux;
        use linux as sys;
        pub(crate) mod users;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 1;
    } else if #[cfg(target_os = "freebsd")] {
        mod freebsd;
        use freebsd as sys;
        pub(crate) mod users;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 1;
    } else {
        mod unknown;
        use unknown as sys;

        #[cfg(test)]
        pub(crate) const MIN_USERS: usize = 0;
    }
}

pub use common::{
    get_current_pid, CpuRefreshKind, DiskType, DiskUsage, Gid, LoadAvg, NetworksIter, Pid, PidExt,
    ProcessRefreshKind, ProcessStatus, RefreshKind, Signal, Uid, User,
};
pub use sys::{Component, Cpu, Disk, NetworkData, Networks, Process, System};
pub use traits::{
    ComponentExt, CpuExt, DiskExt, NetworkExt, NetworksExt, ProcessExt, SystemExt, UserExt,
};

#[cfg(feature = "c-interface")]
pub use c_interface::*;

#[cfg(feature = "c-interface")]
mod c_interface;
mod common;
mod debug;
mod system;
mod traits;
mod utils;

/// This function is only used on linux targets, on the other platforms it does nothing and returns
/// `false`.
///
/// On linux, to improve performance, we keep a `/proc` file open for each process we index with
/// a maximum number of files open equivalent to half of the system limit.
///
/// The problem is that some users might need all the available file descriptors so we need to
/// allow them to change this limit.
///
/// Note that if you set a limit bigger than the system limit, the system limit will be set.
///
/// Returns `true` if the new value has been set.
///
/// ```no_run
/// use sysinfo::{System, SystemExt, set_open_files_limit};
///
/// // We call the function before any call to the processes update.
/// if !set_open_files_limit(10) {
///     // It'll always return false on non-linux targets.
///     eprintln!("failed to update the open files limit...");
/// }
/// let s = System::new_all();
/// ```
pub fn set_open_files_limit(mut _new_limit: isize) -> bool {
    cfg_if::cfg_if! {
        if #[cfg(all(not(feature = "unknown-ci"), any(target_os = "linux", target_os = "android")))]
        {
            if _new_limit < 0 {
                _new_limit = 0;
            }
            let max = sys::system::get_max_nb_fds();
            if _new_limit > max {
                _new_limit = max;
            }
            unsafe {
                if let Ok(ref mut x) = sys::system::REMAINING_FILES.lock() {
                    // If files are already open, to be sure that the number won't be bigger when those
                    // files are closed, we subtract the current number of opened files to the new
                    // limit.
                    let diff = max.saturating_sub(**x);
                    **x = _new_limit.saturating_sub(diff);
                    true
                } else {
                    false
                }
            }
        } else {
            false
        }
    }
}

// FIXME: Can be removed once negative trait bounds are supported.
#[cfg(doctest)]
mod doctest {
    /// Check that `Process` doesn't implement `Clone`.
    ///
    /// First we check that the "basic" code works:
    ///
    /// ```no_run
    /// use sysinfo::{Process, System, SystemExt};
    ///
    /// let mut s = System::new_all();
    /// let p: &Process = s.processes().values().next().unwrap();
    /// ```
    ///
    /// And now we check if it fails when we try to clone it:
    ///
    /// ```compile_fail
    /// use sysinfo::{Process, System, SystemExt};
    ///
    /// let mut s = System::new_all();
    /// let p: &Process = s.processes().values().next().unwrap();
    /// let p = (*p).clone();
    /// ```
    mod process_clone {}

    /// Check that `System` doesn't implement `Clone`.
    ///
    /// First we check that the "basic" code works:
    ///
    /// ```no_run
    /// use sysinfo::{Process, System, SystemExt};
    ///
    /// let s = System::new();
    /// ```
    ///
    /// And now we check if it fails when we try to clone it:
    ///
    /// ```compile_fail
    /// use sysinfo::{Process, System, SystemExt};
    ///
    /// let s = System::new();
    /// let s = s.clone();
    /// ```
    mod system_clone {}
}

#[cfg(test)]
mod test {
    use crate::*;

    #[cfg(feature = "unknown-ci")]
    #[test]
    fn check_unknown_ci_feature() {
        assert!(!System::IS_SUPPORTED);
    }

    #[test]
    fn check_process_memory_usage() {
        let mut s = System::new();
        s.refresh_all();

        if System::IS_SUPPORTED {
            // No process should have 0 as memory usage.
            #[cfg(not(feature = "apple-sandbox"))]
            assert!(!s.processes().iter().all(|(_, proc_)| proc_.memory() == 0));
        } else {
            // There should be no process, but if there is one, its memory usage should be 0.
            assert!(s.processes().iter().all(|(_, proc_)| proc_.memory() == 0));
        }
    }

    #[test]
    fn check_memory_usage() {
        let mut s = System::new();

        assert_eq!(s.total_memory(), 0);
        assert_eq!(s.free_memory(), 0);
        assert_eq!(s.available_memory(), 0);
        assert_eq!(s.used_memory(), 0);
        assert_eq!(s.total_swap(), 0);
        assert_eq!(s.free_swap(), 0);
        assert_eq!(s.used_swap(), 0);

        s.refresh_memory();
        if System::IS_SUPPORTED {
            assert!(s.total_memory() > 0);
            assert!(s.used_memory() > 0);
            if s.total_swap() > 0 {
                // I think it's pretty safe to assume that there is still some swap left...
                assert!(s.free_swap() > 0);
            }
        } else {
            assert_eq!(s.total_memory(), 0);
            assert_eq!(s.used_memory(), 0);
            assert_eq!(s.total_swap(), 0);
            assert_eq!(s.free_swap(), 0);
        }
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn check_processes_cpu_usage() {
        if !System::IS_SUPPORTED {
            return;
        }
        let mut s = System::new();

        s.refresh_processes();
        // All CPU usage will start at zero until the second refresh
        assert!(s
            .processes()
            .iter()
            .all(|(_, proc_)| proc_.cpu_usage() == 0.0));

        // Wait a bit to update CPU usage values
        std::thread::sleep(std::time::Duration::from_millis(100));
        s.refresh_processes();
        assert!(s
            .processes()
            .iter()
            .all(|(_, proc_)| proc_.cpu_usage() >= 0.0
                && proc_.cpu_usage() <= (s.cpus().len() as f32) * 100.0));
        assert!(s
            .processes()
            .iter()
            .any(|(_, proc_)| proc_.cpu_usage() > 0.0));
    }

    #[test]
    fn check_cpu_usage() {
        if !System::IS_SUPPORTED {
            return;
        }
        let mut s = System::new();
        for _ in 0..10 {
            s.refresh_cpu();
            // Wait a bit to update CPU usage values
            std::thread::sleep(std::time::Duration::from_millis(100));
            if s.cpus().iter().any(|c| c.cpu_usage() > 0.0) {
                // All good!
                return;
            }
        }
        panic!("CPU usage is always zero...");
    }

    #[test]
    fn check_users() {
        let mut s = System::new();
        assert!(s.users().is_empty());
        s.refresh_users_list();
        assert!(s.users().len() >= MIN_USERS);

        let mut s = System::new();
        assert!(s.users().is_empty());
        s.refresh_all();
        assert!(s.users().is_empty());

        let s = System::new_all();
        assert!(s.users().len() >= MIN_USERS);
    }

    #[test]
    fn check_uid_gid() {
        let mut s = System::new();
        assert!(s.users().is_empty());
        s.refresh_users_list();
        let users = s.users();
        assert!(users.len() >= MIN_USERS);

        if System::IS_SUPPORTED {
            #[cfg(not(target_os = "windows"))]
            {
                let user = users
                    .iter()
                    .find(|u| u.name() == "root")
                    .expect("no root user");
                assert_eq!(**user.id(), 0);
                assert_eq!(*user.group_id(), 0);
                if let Some(user) = users.iter().find(|u| *u.group_id() > 0) {
                    assert!(**user.id() > 0);
                    assert!(*user.group_id() > 0);
                }
                assert!(users.iter().filter(|u| **u.id() > 0).count() > 0);
            }

            // And now check that our `get_user_by_id` method works.
            s.refresh_processes();
            assert!(s
                .processes()
                .iter()
                .filter_map(|(_, p)| p.user_id())
                .any(|uid| s.get_user_by_id(uid).is_some()));
        }
    }

    #[test]
    fn check_system_info() {
        // We don't want to test on unsupported systems.
        if System::IS_SUPPORTED {
            let s = System::new();
            assert!(!s.name().expect("Failed to get system name").is_empty());

            assert!(!s
                .kernel_version()
                .expect("Failed to get kernel version")
                .is_empty());

            assert!(!s.os_version().expect("Failed to get os version").is_empty());

            assert!(!s
                .long_os_version()
                .expect("Failed to get long OS version")
                .is_empty());
        }
    }

    #[test]
    fn check_host_name() {
        // We don't want to test on unsupported systems.
        if System::IS_SUPPORTED {
            let s = System::new();
            assert!(s.host_name().is_some());
        }
    }

    #[test]
    fn check_refresh_process_return_value() {
        // We don't want to test on unsupported systems.
        if System::IS_SUPPORTED {
            let _pid = get_current_pid().expect("Failed to get current PID");

            #[cfg(not(feature = "apple-sandbox"))]
            {
                let mut s = System::new();
                // First check what happens in case the process isn't already in our process list.
                assert!(s.refresh_process(_pid));
                // Then check that it still returns true if the process is already in our process list.
                assert!(s.refresh_process(_pid));
            }
        }
    }

    #[test]
    fn ensure_is_supported_is_set_correctly() {
        if MIN_USERS > 0 {
            assert!(System::IS_SUPPORTED);
        } else {
            assert!(!System::IS_SUPPORTED);
        }
    }

    #[test]
    fn check_cpus_number() {
        let mut s = System::new();

        // This information isn't retrieved by default.
        assert!(s.cpus().is_empty());
        if System::IS_SUPPORTED {
            // The physical cores count is recomputed every time the function is called, so the
            // information must be relevant even with nothing initialized.
            let physical_cores_count = s
                .physical_core_count()
                .expect("failed to get number of physical cores");

            s.refresh_cpu();
            // The cpus shouldn't be empty anymore.
            assert!(!s.cpus().is_empty());

            // In case we are running inside a VM, it's possible to not have a physical core, only
            // logical ones, which is why we don't test `physical_cores_count > 0`.
            let physical_cores_count2 = s
                .physical_core_count()
                .expect("failed to get number of physical cores");
            assert!(physical_cores_count2 <= s.cpus().len());
            assert_eq!(physical_cores_count, physical_cores_count2);
        } else {
            assert_eq!(s.physical_core_count(), None);
        }
        assert!(s.physical_core_count().unwrap_or(0) <= s.cpus().len());
    }

    #[test]
    fn check_nb_supported_signals() {
        if System::IS_SUPPORTED {
            assert!(
                !System::SUPPORTED_SIGNALS.is_empty(),
                "SUPPORTED_SIGNALS shoudn't be empty on supported systems!"
            );
        } else {
            assert!(
                System::SUPPORTED_SIGNALS.is_empty(),
                "SUPPORTED_SIGNALS should be empty on not support systems!"
            );
        }
    }

    // Ensure that the CPUs frequency isn't retrieved until we ask for it.
    #[test]
    #[cfg(not(target_os = "freebsd"))] // In a VM, it'll fail.
    fn check_cpu_frequency() {
        if !System::IS_SUPPORTED {
            return;
        }
        let mut s = System::new();
        s.refresh_processes();
        for proc_ in s.cpus() {
            assert_eq!(proc_.frequency(), 0);
        }
        s.refresh_cpu();
        for proc_ in s.cpus() {
            assert_ne!(proc_.frequency(), 0);
        }
    }
}
<|endoftext|>


<commit_before>#![crate_type="dylib"]
#![crate_name="enabled"]
#![feature(plugin_registrar)]
#![doc(html_logo_url = "https://avatars.io/gravatar/d0ad9c6f37bb5aceac2d7ac95ba82607?size=large",
       html_favicon_url="https://avatars.io/gravatar/d0ad9c6f37bb5aceac2d7ac95ba82607?size=small")]

//! This crate defines an `is_enabled` and an `is_disabled` macro.
//!
//! The usage is `is_enabled!(TYPE -> NAME)` becomes `cfg!(TYPE_NAME)` and
//! `is_disabled!(TYPE -> NAME)` becomes `cfg!(NTYPE_NAME)`

#![feature(rustc_private)]
extern crate syntax;
extern crate rustc;

use std::borrow::*;
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::ast::{TokenTree, TtToken};
use syntax::ext::cfg;
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult};
use rustc::plugin::Registry;

enum IDType {
    Titled(token::InternedString, token::InternedString),
    Normal(token::InternedString),
}

impl IDType {
    fn get_full(&self) -> String {
        match *self {
            IDType::Titled(ref t, ref n) => {
                let mut ret = (**t).to_owned();
                ret.push('_');
                ret.push_str(&**n);
                ret
            },
            IDType::Normal(ref n) => (**n).to_owned(),
        }
    }
}

fn expand(prefix: String, cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> {
    use IDType::*;
    let id = match args {
        [TtToken(_, token::Ident(title, _)), TtToken(_, token::RArrow), TtToken(_, token::Ident(name, _))] =>
            Titled(token::get_ident(title), token::get_ident(name)),
        [TtToken(_, token::Ident(name, _))] => Normal(token::get_ident(name)),
        _ => {
            cx.span_err(sp, "Argument should be 'module_name->option_name' or 'option_name'");
            return DummyResult::any(sp);
        }
    };
    let mut check_name = prefix;
    check_name.push_str(&id.get_full()[..]);
    let outtok = token::gensym_ident(&check_name[..]);
    let toktree = [TtToken(sp, token::Ident(outtok, token::Plain))];
    cfg::expand_cfg(cx, sp, &toktree)
}

fn expand_is_disabled(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> {
    expand("N".to_string(), cx, sp, args)
}

fn expand_is_enabled(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> {
    expand("".to_string(), cx, sp, args)
}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("is_enabled", expand_is_enabled);
    reg.register_macro("is_disabled", expand_is_disabled);
}
<commit_msg>add feature gate<commit_after>#![crate_type="dylib"]
#![crate_name="enabled"]
#![feature(plugin_registrar, slice_patterns)]
#![doc(html_logo_url = "https://avatars.io/gravatar/d0ad9c6f37bb5aceac2d7ac95ba82607?size=large",
       html_favicon_url="https://avatars.io/gravatar/d0ad9c6f37bb5aceac2d7ac95ba82607?size=small")]

//! This crate defines an `is_enabled` and an `is_disabled` macro.
//!
//! The usage is `is_enabled!(TYPE -> NAME)` becomes `cfg!(TYPE_NAME)` and
//! `is_disabled!(TYPE -> NAME)` becomes `cfg!(NTYPE_NAME)`

#![feature(rustc_private)]
extern crate syntax;
extern crate rustc;

use std::borrow::*;
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::ast::{TokenTree, TtToken};
use syntax::ext::cfg;
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult};
use rustc::plugin::Registry;

enum IDType {
    Titled(token::InternedString, token::InternedString),
    Normal(token::InternedString),
}

impl IDType {
    fn get_full(&self) -> String {
        match *self {
            IDType::Titled(ref t, ref n) => {
                let mut ret = (**t).to_owned();
                ret.push('_');
                ret.push_str(&**n);
                ret
            },
            IDType::Normal(ref n) => (**n).to_owned(),
        }
    }
}

fn expand(prefix: String, cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> {
    use IDType::*;
    let id = match args {
        [TtToken(_, token::Ident(title, _)), TtToken(_, token::RArrow), TtToken(_, token::Ident(name, _))] =>
            Titled(token::get_ident(title), token::get_ident(name)),
        [TtToken(_, token::Ident(name, _))] => Normal(token::get_ident(name)),
        _ => {
            cx.span_err(sp, "Argument should be 'module_name->option_name' or 'option_name'");
            return DummyResult::any(sp);
        }
    };
    let mut check_name = prefix;
    check_name.push_str(&id.get_full()[..]);
    let outtok = token::gensym_ident(&check_name[..]);
    let toktree = [TtToken(sp, token::Ident(outtok, token::Plain))];
    cfg::expand_cfg(cx, sp, &toktree)
}

fn expand_is_disabled(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> {
    expand("N".to_string(), cx, sp, args)
}

fn expand_is_enabled(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> {
    expand("".to_string(), cx, sp, args)
}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("is_enabled", expand_is_enabled);
    reg.register_macro("is_disabled", expand_is_disabled);
}
<|endoftext|>


<commit_before>#![feature(plugin_registrar, rustc_private)]

extern crate rustc;
extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::Registry;
use std::rc::Rc;
use syntax::ast::Ident;
use syntax::tokenstream::TokenTree;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, MacResult};
use syntax::parse::token::{DelimToken, Token};

mod parser_any_macro;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("interpolate_idents", interpolate_idents);
}

fn interpolate_idents<'a>(cx: &'a mut ExtCtxt,
              _: Span,
              tts: &[TokenTree]) -> Box<MacResult + 'a> {
    fn concat_idents(tts: &Vec<TokenTree>, delim: DelimToken) -> Option<TokenTree> {
        match delim {
            DelimToken::Bracket => {
                let mut new_ident = String::new();
                let mut new_span: Option<Span> = None;

                for token in tts.iter() {
                    match token {
                        &TokenTree::Token(ref span, Token::Ident(ref ident)) => {
                            match new_span {
                                Some(ref mut s) => { s.hi = span.hi; },
                                None => { new_span = Some(span.clone()); },
                            }
                            new_ident.push_str(&ident.name.as_str());
                        },
                        _ => return None,
                    }
                }

                match new_span {
                    Some(s) => {
                        let new_ident = Ident::from_str(&new_ident[..]);
                        Some(TokenTree::Token(s, Token::Ident(new_ident)))
                    },
                    None => None
                }
            },
            _ => None,
        }
    }

    fn map_tts(tts: &[TokenTree]) -> Vec<TokenTree> {
        tts.iter().map(|t| {
            match t {
                &TokenTree::Delimited(ref s, ref d) => {
                    match concat_idents(&d.tts, d.delim) {
                        Some(t) => t,
                        None => {
                            TokenTree::Delimited(s.clone(), Rc::new(syntax::tokenstream::Delimited {
                                delim: d.delim,
                                tts: map_tts(&*d.tts),
                            }))
                        },
                    }
                },
                &TokenTree::Sequence(ref s, ref d) => {
                    TokenTree::Sequence(s.clone(), Rc::new(syntax::tokenstream::SequenceRepetition {
                        tts: map_tts(&*d.tts),
                        separator: d.separator.clone(),
                        op: d.op,
                        num_captures: d.num_captures,
                    }))
                },
                _ => t.clone(),
            }
        }).collect()
    }

    let parser = cx.new_parser_from_tts(&map_tts(tts)[..]);
    Box::new(parser_any_macro::ParserAnyMacro::new(parser)) as Box<MacResult>
}
<commit_msg>Update to nightly 2017-03-03<commit_after>#![feature(plugin_registrar, rustc_private)]

extern crate rustc;
extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::Registry;
use std::rc::Rc;
use syntax::ast::Ident;
use syntax::tokenstream::TokenTree;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, MacResult};
use syntax::parse::token::{DelimToken, Token};

mod parser_any_macro;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("interpolate_idents", interpolate_idents);
}

fn interpolate_idents<'a>(cx: &'a mut ExtCtxt,
              _: Span,
              tts: &[TokenTree]) -> Box<MacResult + 'a> {
    fn concat_idents(tts: &Vec<TokenTree>, delim: DelimToken) -> Option<TokenTree> {
        match delim {
            DelimToken::Bracket => {
                let mut new_ident = String::new();
                let mut new_span: Option<Span> = None;

                for token in tts.iter() {
                    match token {
                        &TokenTree::Token(ref span, Token::Ident(ref ident)) => {
                            match new_span {
                                Some(ref mut s) => { s.hi = span.hi; },
                                None => { new_span = Some(span.clone()); },
                            }
                            new_ident.push_str(&ident.name.as_str());
                        },
                        _ => return None,
                    }
                }

                match new_span {
                    Some(s) => {
                        let new_ident = Ident::from_str(&new_ident[..]);
                        Some(TokenTree::Token(s, Token::Ident(new_ident)))
                    },
                    None => None
                }
            },
            _ => None,
        }
    }

    fn map_tts(tts: &[TokenTree]) -> Vec<TokenTree> {
        tts.iter().map(|t| {
            match t {
                &TokenTree::Delimited(ref s, ref d) => {
                    match concat_idents(&d.tts, d.delim) {
                        Some(t) => t,
                        None => {
                            TokenTree::Delimited(s.clone(), Rc::new(syntax::tokenstream::Delimited {
                                delim: d.delim,
                                tts: map_tts(&*d.tts),
                            }))
                        },
                    }
                },
                &TokenTree::Token(..) => t.clone(),
            }
        }).collect()
    }

    let parser = cx.new_parser_from_tts(&map_tts(tts)[..]);
    Box::new(parser_any_macro::ParserAnyMacro::new(parser)) as Box<MacResult>
}
<|endoftext|>