<commit_before>#![stable(feature = "futures_api", since = "1.36.0")]

use crate::marker::Unpin;
use crate::ops;
use crate::pin::Pin;
use crate::task::{Context, Poll};

/// A future represents an asynchronous computation.
///
/// A future is a value that may not have finished computing yet. This kind of
/// "asynchronous value" makes it possible for a thread to continue doing useful
/// work while it waits for the value to become available.
///
/// # The `poll` method
///
/// The core method of future, `poll`, *attempts* to resolve the future into a
/// final value. This method does not block if the value is not ready. Instead,
/// the current task is scheduled to be woken up when it's possible to make
/// further progress by `poll`ing again. The `context` passed to the `poll`
/// method can provide a `Waker`, which is a handle for waking up the current
/// task.
///
/// When using a future, you generally won't call `poll` directly, but instead
/// `.await` the value.
#[doc(spotlight)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[stable(feature = "futures_api", since = "1.36.0")]
#[lang = "future_trait"]
pub trait Future {
    /// The type of value produced on completion.
    #[stable(feature = "futures_api", since = "1.36.0")]
    type Output;

    /// Attempt to resolve the future to a final value, registering
    /// the current task for wakeup if the value is not yet available.
    ///
    /// # Return value
    ///
    /// This function returns:
    ///
    /// - [`Poll::Pending`] if the future is not ready yet
    /// - [`Poll::Ready(val)`] with the result `val` of this future if it
    ///   finished successfully.
    ///
    /// Once a future has finished, clients should not `poll` it again.
    ///
    /// When a future is not ready yet, `poll` returns `Poll::Pending` and
    /// stores a clone of the [`Waker`] copied from the current [`Context`].
    /// This [`Waker`] is then woken once the future can make progress.
    /// For example, a future waiting for a socket to become
    /// readable would call `.clone()` on the [`Waker`] and store it.
    /// When a signal arrives elsewhere indicating that the socket is readable,
    /// [`Waker::wake`] is called and the socket future's task is awoken.
    /// Once a task has been woken up, it should attempt to `poll` the future
    /// again, which may or may not produce a final value.
    ///
    /// Note that on multiple calls to `poll`, only the [`Waker`] from the
    /// [`Context`] passed to the most recent call should be scheduled to
    /// receive a wakeup.
    ///
    /// # Runtime characteristics
    ///
    /// Futures alone are *inert*; they must be *actively* `poll`ed to make
    /// progress, meaning that each time the current task is woken up, it should
    /// actively re-`poll` pending futures that it still has an interest in.
    ///
    /// The `poll` function is not called repeatedly in a tight loop -- instead,
    /// it should only be called when the future indicates that it is ready to
    /// make progress (by calling `wake()`). If you're familiar with the
    /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
    /// typically do *not* suffer the same problems of "all wakeups must poll
    /// all events"; they are more like `epoll(4)`.
    ///
    /// An implementation of `poll` should strive to return quickly, and should
    /// not block. Returning quickly prevents unnecessarily clogging up
    /// threads or event loops. If it is known ahead of time that a call to
    /// `poll` may end up taking awhile, the work should be offloaded to a
    /// thread pool (or something similar) to ensure that `poll` can return
    /// quickly.
    ///
    /// # Panics
    ///
    /// Once a future has completed (returned `Ready` from `poll`), calling its
    /// `poll` method again may panic, block forever, or cause other kinds of
    /// problems; the `Future` trait places no requirements on the effects of
    /// such a call. However, as the `poll` method is not marked `unsafe`,
    /// Rust's usual rules apply: calls must never cause undefined behavior
    /// (memory corruption, incorrect use of `unsafe` functions, or the like),
    /// regardless of the future's state.
    ///
    /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
    /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
    /// [`Context`]: ../task/struct.Context.html
    /// [`Waker`]: ../task/struct.Waker.html
    /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake
    #[stable(feature = "futures_api", since = "1.36.0")]
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<F: ?Sized + Future + Unpin> Future for &mut F {
    type Output = F::Output;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        F::poll(Pin::new(&mut **self), cx)
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl
 Future for Pin

where
    P: Unpin + ops::DerefMut,
    P::Target: Future,
{
    type Output = <
::Target as Future>::Output;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        Pin::get_mut(self).as_mut().poll(cx)
    }
}
<commit_msg>Futures: Add link to Waker in trait doc.<commit_after>#![stable(feature = "futures_api", since = "1.36.0")]

use crate::marker::Unpin;
use crate::ops;
use crate::pin::Pin;
use crate::task::{Context, Poll};

/// A future represents an asynchronous computation.
///
/// A future is a value that may not have finished computing yet. This kind of
/// "asynchronous value" makes it possible for a thread to continue doing useful
/// work while it waits for the value to become available.
///
/// # The `poll` method
///
/// The core method of future, `poll`, *attempts* to resolve the future into a
/// final value. This method does not block if the value is not ready. Instead,
/// the current task is scheduled to be woken up when it's possible to make
/// further progress by `poll`ing again. The `context` passed to the `poll`
/// method can provide a [`Waker`], which is a handle for waking up the current
/// task.
///
/// When using a future, you generally won't call `poll` directly, but instead
/// `.await` the value.
///
/// [`Waker`]: ../task/struct.Waker.html
#[doc(spotlight)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[stable(feature = "futures_api", since = "1.36.0")]
#[lang = "future_trait"]
pub trait Future {
    /// The type of value produced on completion.
    #[stable(feature = "futures_api", since = "1.36.0")]
    type Output;

    /// Attempt to resolve the future to a final value, registering
    /// the current task for wakeup if the value is not yet available.
    ///
    /// # Return value
    ///
    /// This function returns:
    ///
    /// - [`Poll::Pending`] if the future is not ready yet
    /// - [`Poll::Ready(val)`] with the result `val` of this future if it
    ///   finished successfully.
    ///
    /// Once a future has finished, clients should not `poll` it again.
    ///
    /// When a future is not ready yet, `poll` returns `Poll::Pending` and
    /// stores a clone of the [`Waker`] copied from the current [`Context`].
    /// This [`Waker`] is then woken once the future can make progress.
    /// For example, a future waiting for a socket to become
    /// readable would call `.clone()` on the [`Waker`] and store it.
    /// When a signal arrives elsewhere indicating that the socket is readable,
    /// [`Waker::wake`] is called and the socket future's task is awoken.
    /// Once a task has been woken up, it should attempt to `poll` the future
    /// again, which may or may not produce a final value.
    ///
    /// Note that on multiple calls to `poll`, only the [`Waker`] from the
    /// [`Context`] passed to the most recent call should be scheduled to
    /// receive a wakeup.
    ///
    /// # Runtime characteristics
    ///
    /// Futures alone are *inert*; they must be *actively* `poll`ed to make
    /// progress, meaning that each time the current task is woken up, it should
    /// actively re-`poll` pending futures that it still has an interest in.
    ///
    /// The `poll` function is not called repeatedly in a tight loop -- instead,
    /// it should only be called when the future indicates that it is ready to
    /// make progress (by calling `wake()`). If you're familiar with the
    /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
    /// typically do *not* suffer the same problems of "all wakeups must poll
    /// all events"; they are more like `epoll(4)`.
    ///
    /// An implementation of `poll` should strive to return quickly, and should
    /// not block. Returning quickly prevents unnecessarily clogging up
    /// threads or event loops. If it is known ahead of time that a call to
    /// `poll` may end up taking awhile, the work should be offloaded to a
    /// thread pool (or something similar) to ensure that `poll` can return
    /// quickly.
    ///
    /// # Panics
    ///
    /// Once a future has completed (returned `Ready` from `poll`), calling its
    /// `poll` method again may panic, block forever, or cause other kinds of
    /// problems; the `Future` trait places no requirements on the effects of
    /// such a call. However, as the `poll` method is not marked `unsafe`,
    /// Rust's usual rules apply: calls must never cause undefined behavior
    /// (memory corruption, incorrect use of `unsafe` functions, or the like),
    /// regardless of the future's state.
    ///
    /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
    /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
    /// [`Context`]: ../task/struct.Context.html
    /// [`Waker`]: ../task/struct.Waker.html
    /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake
    #[stable(feature = "futures_api", since = "1.36.0")]
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<F: ?Sized + Future + Unpin> Future for &mut F {
    type Output = F::Output;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        F::poll(Pin::new(&mut **self), cx)
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl
 Future for Pin

where
    P: Unpin + ops::DerefMut,
    P::Target: Future,
{
    type Output = <
::Target as Future>::Output;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        Pin::get_mut(self).as_mut().poll(cx)
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-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.

//! Some lints that are built in to the compiler.
//!
//! These are the built-in lints that are emitted direct in the main
//! compiler code, rather than using their own custom pass. Those
//! lints are all available in `rustc_lint::builtin`.

use lint::{LintPass, LateLintPass, LintArray};

declare_lint! {
    pub CONST_ERR,
    Warn,
    "constant evaluation detected erroneous expression"
}

declare_lint! {
    pub UNUSED_IMPORTS,
    Warn,
    "imports that are never used"
}

declare_lint! {
    pub UNUSED_EXTERN_CRATES,
    Warn,
    "extern crates that are never used"
}

declare_lint! {
    pub UNUSED_QUALIFICATIONS,
    Allow,
    "detects unnecessarily qualified names"
}

declare_lint! {
    pub UNKNOWN_LINTS,
    Warn,
    "unrecognized lint attribute"
}

declare_lint! {
    pub UNUSED_VARIABLES,
    Warn,
    "detect variables which are not used in any way"
}

declare_lint! {
    pub UNUSED_ASSIGNMENTS,
    Warn,
    "detect assignments that will never be read"
}

declare_lint! {
    pub DEAD_CODE,
    Warn,
    "detect unused, unexported items"
}

declare_lint! {
    pub UNREACHABLE_CODE,
    Warn,
    "detects unreachable code paths"
}

declare_lint! {
    pub UNREACHABLE_PATTERNS,
    Warn,
    "detects unreachable patterns"
}

declare_lint! {
    pub UNUSED_MACROS,
    Warn,
    "detects macros that were not used"
}

declare_lint! {
    pub WARNINGS,
    Warn,
    "mass-change the level for lints which produce warnings"
}

declare_lint! {
    pub UNUSED_FEATURES,
    Warn,
    "unused or unknown features found in crate-level #[feature] directives"
}

declare_lint! {
    pub STABLE_FEATURES,
    Warn,
    "stable features found in #[feature] directive"
}

declare_lint! {
    pub UNKNOWN_CRATE_TYPES,
    Deny,
    "unknown crate type found in #[crate_type] directive"
}

declare_lint! {
    pub FAT_PTR_TRANSMUTES,
    Allow,
    "detects transmutes of fat pointers"
}

declare_lint! {
    pub TRIVIAL_CASTS,
    Allow,
    "detects trivial casts which could be removed"
}

declare_lint! {
    pub TRIVIAL_NUMERIC_CASTS,
    Allow,
    "detects trivial casts of numeric types which could be removed"
}

declare_lint! {
    pub PRIVATE_IN_PUBLIC,
    Warn,
    "detect private items in public interfaces not caught by the old implementation"
}

declare_lint! {
    pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
    Deny,
    "detect public reexports of private extern crates"
}

declare_lint! {
    pub INVALID_TYPE_PARAM_DEFAULT,
    Deny,
    "type parameter default erroneously allowed in invalid location"
}

declare_lint! {
    pub RENAMED_AND_REMOVED_LINTS,
    Warn,
    "lints that have been renamed or removed"
}

declare_lint! {
    pub RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
    Deny,
    "attempt to resolve a trait on an expression whose type cannot be inferred but which \
     currently defaults to ()"
}

declare_lint! {
    pub SAFE_EXTERN_STATICS,
    Deny,
    "safe access to extern statics was erroneously allowed"
}

declare_lint! {
    pub PATTERNS_IN_FNS_WITHOUT_BODY,
    Warn,
    "patterns in functions without body were erroneously allowed"
}

declare_lint! {
    pub EXTRA_REQUIREMENT_IN_IMPL,
    Deny,
    "detects extra requirements in impls that were erroneously allowed"
}

declare_lint! {
    pub LEGACY_DIRECTORY_OWNERSHIP,
    Deny,
    "non-inline, non-`#[path]` modules (e.g. `mod foo;`) were erroneously allowed in some files \
     not named `mod.rs`"
}

declare_lint! {
    pub LEGACY_IMPORTS,
    Deny,
    "detects names that resolve to ambiguous glob imports with RFC 1560"
}

declare_lint! {
    pub LEGACY_CONSTRUCTOR_VISIBILITY,
    Deny,
    "detects use of struct constructors that would be invisible with new visibility rules"
}

declare_lint! {
    pub MISSING_FRAGMENT_SPECIFIER,
    Deny,
    "detects missing fragment specifiers in unused `macro_rules!` patterns"
}

declare_lint! {
    pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
    Deny,
    "detects parenthesized generic parameters in type and module names"
}

declare_lint! {
    pub LATE_BOUND_LIFETIME_ARGUMENTS,
    Warn,
    "detects generic lifetime arguments in path segments with late bound lifetime parameters"
}

declare_lint! {
    pub DEPRECATED,
    Warn,
    "detects use of deprecated items"
}

declare_lint! {
    pub UNUSED_UNSAFE,
    Warn,
    "unnecessary use of an `unsafe` block"
}

/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
pub struct HardwiredLints;

impl LintPass for HardwiredLints {
    fn get_lints(&self) -> LintArray {
        lint_array!(
            UNUSED_IMPORTS,
            UNUSED_EXTERN_CRATES,
            UNUSED_QUALIFICATIONS,
            UNKNOWN_LINTS,
            UNUSED_VARIABLES,
            UNUSED_ASSIGNMENTS,
            DEAD_CODE,
            UNREACHABLE_CODE,
            UNREACHABLE_PATTERNS,
            UNUSED_MACROS,
            WARNINGS,
            UNUSED_FEATURES,
            STABLE_FEATURES,
            UNKNOWN_CRATE_TYPES,
            FAT_PTR_TRANSMUTES,
            TRIVIAL_CASTS,
            TRIVIAL_NUMERIC_CASTS,
            PRIVATE_IN_PUBLIC,
            PUB_USE_OF_PRIVATE_EXTERN_CRATE,
            INVALID_TYPE_PARAM_DEFAULT,
            CONST_ERR,
            RENAMED_AND_REMOVED_LINTS,
            RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
            SAFE_EXTERN_STATICS,
            PATTERNS_IN_FNS_WITHOUT_BODY,
            EXTRA_REQUIREMENT_IN_IMPL,
            LEGACY_DIRECTORY_OWNERSHIP,
            LEGACY_IMPORTS,
            LEGACY_CONSTRUCTOR_VISIBILITY,
            MISSING_FRAGMENT_SPECIFIER,
            PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
            LATE_BOUND_LIFETIME_ARGUMENTS,
            DEPRECATED,
            UNUSED_UNSAFE
        )
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}
<commit_msg>Allow unused extern crate again<commit_after>// Copyright 2012-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.

//! Some lints that are built in to the compiler.
//!
//! These are the built-in lints that are emitted direct in the main
//! compiler code, rather than using their own custom pass. Those
//! lints are all available in `rustc_lint::builtin`.

use lint::{LintPass, LateLintPass, LintArray};

declare_lint! {
    pub CONST_ERR,
    Warn,
    "constant evaluation detected erroneous expression"
}

declare_lint! {
    pub UNUSED_IMPORTS,
    Warn,
    "imports that are never used"
}

declare_lint! {
    pub UNUSED_EXTERN_CRATES,
    Allow,
    "extern crates that are never used"
}

declare_lint! {
    pub UNUSED_QUALIFICATIONS,
    Allow,
    "detects unnecessarily qualified names"
}

declare_lint! {
    pub UNKNOWN_LINTS,
    Warn,
    "unrecognized lint attribute"
}

declare_lint! {
    pub UNUSED_VARIABLES,
    Warn,
    "detect variables which are not used in any way"
}

declare_lint! {
    pub UNUSED_ASSIGNMENTS,
    Warn,
    "detect assignments that will never be read"
}

declare_lint! {
    pub DEAD_CODE,
    Warn,
    "detect unused, unexported items"
}

declare_lint! {
    pub UNREACHABLE_CODE,
    Warn,
    "detects unreachable code paths"
}

declare_lint! {
    pub UNREACHABLE_PATTERNS,
    Warn,
    "detects unreachable patterns"
}

declare_lint! {
    pub UNUSED_MACROS,
    Warn,
    "detects macros that were not used"
}

declare_lint! {
    pub WARNINGS,
    Warn,
    "mass-change the level for lints which produce warnings"
}

declare_lint! {
    pub UNUSED_FEATURES,
    Warn,
    "unused or unknown features found in crate-level #[feature] directives"
}

declare_lint! {
    pub STABLE_FEATURES,
    Warn,
    "stable features found in #[feature] directive"
}

declare_lint! {
    pub UNKNOWN_CRATE_TYPES,
    Deny,
    "unknown crate type found in #[crate_type] directive"
}

declare_lint! {
    pub FAT_PTR_TRANSMUTES,
    Allow,
    "detects transmutes of fat pointers"
}

declare_lint! {
    pub TRIVIAL_CASTS,
    Allow,
    "detects trivial casts which could be removed"
}

declare_lint! {
    pub TRIVIAL_NUMERIC_CASTS,
    Allow,
    "detects trivial casts of numeric types which could be removed"
}

declare_lint! {
    pub PRIVATE_IN_PUBLIC,
    Warn,
    "detect private items in public interfaces not caught by the old implementation"
}

declare_lint! {
    pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
    Deny,
    "detect public reexports of private extern crates"
}

declare_lint! {
    pub INVALID_TYPE_PARAM_DEFAULT,
    Deny,
    "type parameter default erroneously allowed in invalid location"
}

declare_lint! {
    pub RENAMED_AND_REMOVED_LINTS,
    Warn,
    "lints that have been renamed or removed"
}

declare_lint! {
    pub RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
    Deny,
    "attempt to resolve a trait on an expression whose type cannot be inferred but which \
     currently defaults to ()"
}

declare_lint! {
    pub SAFE_EXTERN_STATICS,
    Deny,
    "safe access to extern statics was erroneously allowed"
}

declare_lint! {
    pub PATTERNS_IN_FNS_WITHOUT_BODY,
    Warn,
    "patterns in functions without body were erroneously allowed"
}

declare_lint! {
    pub EXTRA_REQUIREMENT_IN_IMPL,
    Deny,
    "detects extra requirements in impls that were erroneously allowed"
}

declare_lint! {
    pub LEGACY_DIRECTORY_OWNERSHIP,
    Deny,
    "non-inline, non-`#[path]` modules (e.g. `mod foo;`) were erroneously allowed in some files \
     not named `mod.rs`"
}

declare_lint! {
    pub LEGACY_IMPORTS,
    Deny,
    "detects names that resolve to ambiguous glob imports with RFC 1560"
}

declare_lint! {
    pub LEGACY_CONSTRUCTOR_VISIBILITY,
    Deny,
    "detects use of struct constructors that would be invisible with new visibility rules"
}

declare_lint! {
    pub MISSING_FRAGMENT_SPECIFIER,
    Deny,
    "detects missing fragment specifiers in unused `macro_rules!` patterns"
}

declare_lint! {
    pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
    Deny,
    "detects parenthesized generic parameters in type and module names"
}

declare_lint! {
    pub LATE_BOUND_LIFETIME_ARGUMENTS,
    Warn,
    "detects generic lifetime arguments in path segments with late bound lifetime parameters"
}

declare_lint! {
    pub DEPRECATED,
    Warn,
    "detects use of deprecated items"
}

declare_lint! {
    pub UNUSED_UNSAFE,
    Warn,
    "unnecessary use of an `unsafe` block"
}

/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
pub struct HardwiredLints;

impl LintPass for HardwiredLints {
    fn get_lints(&self) -> LintArray {
        lint_array!(
            UNUSED_IMPORTS,
            UNUSED_EXTERN_CRATES,
            UNUSED_QUALIFICATIONS,
            UNKNOWN_LINTS,
            UNUSED_VARIABLES,
            UNUSED_ASSIGNMENTS,
            DEAD_CODE,
            UNREACHABLE_CODE,
            UNREACHABLE_PATTERNS,
            UNUSED_MACROS,
            WARNINGS,
            UNUSED_FEATURES,
            STABLE_FEATURES,
            UNKNOWN_CRATE_TYPES,
            FAT_PTR_TRANSMUTES,
            TRIVIAL_CASTS,
            TRIVIAL_NUMERIC_CASTS,
            PRIVATE_IN_PUBLIC,
            PUB_USE_OF_PRIVATE_EXTERN_CRATE,
            INVALID_TYPE_PARAM_DEFAULT,
            CONST_ERR,
            RENAMED_AND_REMOVED_LINTS,
            RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
            SAFE_EXTERN_STATICS,
            PATTERNS_IN_FNS_WITHOUT_BODY,
            EXTRA_REQUIREMENT_IN_IMPL,
            LEGACY_DIRECTORY_OWNERSHIP,
            LEGACY_IMPORTS,
            LEGACY_CONSTRUCTOR_VISIBILITY,
            MISSING_FRAGMENT_SPECIFIER,
            PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
            LATE_BOUND_LIFETIME_ARGUMENTS,
            DEPRECATED,
            UNUSED_UNSAFE
        )
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}
<|endoftext|>


<commit_before>import dom::rcu;
import dom::rcu::methods;
import gfx::geom;
import gfx::geom::{size, rect, point, au};
import util::{tree};

enum box = @{
    tree: tree::fields<box>,
    node: node,
    mut bounds: geom::rect<au>
};

enum node_data = {
    tree: tree::fields<node>,
    kind: node_kind,

    // Points to the primary box.  Note that there may be multiple
    // boxes per DOM node.
    mut box: option<box>,
};

enum node_kind {
    nk_div,
    nk_img(size<au>)
}

type node = rcu::handle<node_data>;

impl of tree::tree for box {
    fn tree_fields() -> tree::fields<box> {
        ret self.tree;
    }
}

impl of tree::tree for node {
    fn tree_fields() -> tree::fields<node> {
        ret self.get().tree;
    }
}

fn new_node(+k: node_kind) -> node {
    rcu::handle(node_data({tree: tree::empty(),
                           kind: k,
                           mut box: none}))
}

fn new_box(n: node) -> box {
    box(@{tree: tree::empty(),
          node: n,
          mut bounds: geom::zero_rect_au()})
}

fn linked_box(n: node) -> box {
    let b = new_box(n);
    n.box = some(b);
    ret b;
}

fn reflow_block(root: box, available_width: au) {
    // Root here is the root of the reflow, not necessarily the doc as
    // a whole.

    alt root.node.get().kind {
      nk_img(size) {
        root.bounds.size = size;
        ret;
      }

      nk_div { /* fallthrough */ }
    }

    let mut current_height = 0;
    for tree::each_child(root) {|c|
        let mut blk_available_width = available_width;
        // FIXME subtract borders, margins, etc
        c.bounds.origin = {x: au(0), y: au(current_height)};
        reflow_block(c, blk_available_width);
        current_height += *c.bounds.size.height;
    }

    root.bounds.size = {width: available_width, // FIXME
                        height: au(current_height)};
}

#[cfg(test)]
mod test {

    /*
    use sdl;
    import sdl::video;

    fn with_screen(f: fn(*sdl::surface)) {
        let screen = video::set_video_mode(
            320, 200, 32,
            [video::hwsurface], [video::doublebuf]);
        assert screen != ptr::null();

        f(screen);

        video::free_surface(screen);
    }
    */

    fn flat_bounds(root: box) -> [geom::rect<au>] {
        let mut r = [];
        for tree::each_child(root) {|c|
            r += flat_bounds(c);
        }
        ret r + [root.bounds];
    }

    #[test]
    fn do_layout() {
        let n0 = new_node(nk_img(size(au(10),au(10))));
        let n1 = new_node(nk_img(size(au(10),au(15))));
        let n2 = new_node(nk_img(size(au(10),au(20))));
        let n3 = new_node(nk_div);

        tree::add_child(n3, n0);
        tree::add_child(n3, n1);
        tree::add_child(n3, n2);

        let b0 = linked_box(n0);
        let b1 = linked_box(n1);
        let b2 = linked_box(n2);
        let b3 = linked_box(n3);

        tree::add_child(b3, b0);
        tree::add_child(b3, b1);
        tree::add_child(b3, b2);

        reflow_block(b3, au(100));
        let fb = flat_bounds(b3);
        #debug["fb=%?", fb];
        assert fb == [geom::box(au(0), au(0), au(10), au(10)),   // n0
                      geom::box(au(0), au(10), au(10), au(15)),  // n1
                      geom::box(au(0), au(25), au(10), au(20)),  // n2
                      geom::box(au(0), au(0), au(100), au(45))]; // n3
    }
}

<commit_msg>add comment<commit_after>import dom::rcu;
import dom::rcu::methods;
import gfx::geom;
import gfx::geom::{size, rect, point, au};
import util::{tree};

enum box = @{
    tree: tree::fields<box>,
    node: node,
    mut bounds: geom::rect<au>
};

enum node_data = {
    tree: tree::fields<node>,
    kind: node_kind,

    // Points to the primary box.  Note that there may be multiple
    // boxes per DOM node.
    mut box: option<box>,
};

enum node_kind {
    nk_div,
    nk_img(size<au>)
}

type node = rcu::handle<node_data>;

impl of tree::tree for box {
    fn tree_fields() -> tree::fields<box> {
        ret self.tree;
    }
}

impl of tree::tree for node {
    fn tree_fields() -> tree::fields<node> {
        ret self.get().tree;
    }
}

fn new_node(+k: node_kind) -> node {
    rcu::handle(node_data({tree: tree::empty(),
                           kind: k,
                           mut box: none}))
}

fn new_box(n: node) -> box {
    box(@{tree: tree::empty(),
          node: n,
          mut bounds: geom::zero_rect_au()})
}

fn linked_box(n: node) -> box {
    let b = new_box(n);
    n.box = some(b);
    ret b;
}

fn reflow_block(root: box, available_width: au) {
    // Root here is the root of the reflow, not necessarily the doc as
    // a whole.
    //
    // This routine:
    // - generates root.bounds.size
    // - generates root.bounds.origin for each child
    // - and recursively computes the bounds for each child

    alt root.node.get().kind {
      nk_img(size) {
        root.bounds.size = size;
        ret;
      }

      nk_div { /* fallthrough */ }
    }

    let mut current_height = 0;
    for tree::each_child(root) {|c|
        let mut blk_available_width = available_width;
        // FIXME subtract borders, margins, etc
        c.bounds.origin = {x: au(0), y: au(current_height)};
        reflow_block(c, blk_available_width);
        current_height += *c.bounds.size.height;
    }

    root.bounds.size = {width: available_width, // FIXME
                        height: au(current_height)};
}

#[cfg(test)]
mod test {

    /*
    use sdl;
    import sdl::video;

    fn with_screen(f: fn(*sdl::surface)) {
        let screen = video::set_video_mode(
            320, 200, 32,
            [video::hwsurface], [video::doublebuf]);
        assert screen != ptr::null();

        f(screen);

        video::free_surface(screen);
    }
    */

    fn flat_bounds(root: box) -> [geom::rect<au>] {
        let mut r = [];
        for tree::each_child(root) {|c|
            r += flat_bounds(c);
        }
        ret r + [root.bounds];
    }

    #[test]
    fn do_layout() {
        let n0 = new_node(nk_img(size(au(10),au(10))));
        let n1 = new_node(nk_img(size(au(10),au(15))));
        let n2 = new_node(nk_img(size(au(10),au(20))));
        let n3 = new_node(nk_div);

        tree::add_child(n3, n0);
        tree::add_child(n3, n1);
        tree::add_child(n3, n2);

        let b0 = linked_box(n0);
        let b1 = linked_box(n1);
        let b2 = linked_box(n2);
        let b3 = linked_box(n3);

        tree::add_child(b3, b0);
        tree::add_child(b3, b1);
        tree::add_child(b3, b2);

        reflow_block(b3, au(100));
        let fb = flat_bounds(b3);
        #debug["fb=%?", fb];
        assert fb == [geom::box(au(0), au(0), au(10), au(10)),   // n0
                      geom::box(au(0), au(10), au(10), au(15)),  // n1
                      geom::box(au(0), au(25), au(10), au(20)),  // n2
                      geom::box(au(0), au(0), au(100), au(45))]; // n3
    }
}

<|endoftext|>


<commit_before>// Copyright 2012 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.

//! Unsafe casting functions

use mem;
use intrinsics;
use ptr::copy_nonoverlapping_memory;

/// Casts the value at `src` to U. The two types must have the same length.
#[inline]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
    let mut dest: U = mem::uninit();
    let dest_ptr: *mut u8 = transmute(&mut dest);
    let src_ptr: *u8 = transmute(src);
    copy_nonoverlapping_memory(dest_ptr, src_ptr, mem::size_of::<U>());
    dest
}

/**
 * Move a thing into the void
 *
 * The forget function will take ownership of the provided value but neglect
 * to run any required cleanup or memory-management operations on it. This
 * can be used for various acts of magick.
 */
#[inline]
pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing); }

/**
 * Force-increment the reference count on a shared box. If used
 * carelessly, this can leak the box.
 */
#[inline]
pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); }

/**
 * Transform a value of one type into a value of another type.
 * Both types must have the same size and alignment.
 *
 * # Example
 *
 * ```rust
 * use std::cast;
 *
 * let v: &[u8] = unsafe { cast::transmute("L") };
 * assert!(v == [76u8]);
 * ```
 */
#[inline]
pub unsafe fn transmute<L, G>(thing: L) -> G {
    intrinsics::transmute(thing)
}

/// Coerce an immutable reference to be mutable.
#[inline]
pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }

/// Coerce a reference to have an arbitrary associated region.
#[inline]
pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T {
    transmute(ptr)
}

/// Coerce an immutable reference to be mutable.
#[inline]
pub unsafe fn transmute_mut_unsafe<T>(ptr: *T) -> *mut T {
    transmute(ptr)
}

/// Coerce an immutable reference to be mutable.
#[inline]
pub unsafe fn transmute_immut_unsafe<T>(ptr: *mut T) -> *T {
    transmute(ptr)
}

/// Coerce a mutable reference to have an arbitrary associated region.
#[inline]
pub unsafe fn transmute_mut_region<'a,'b,T>(ptr: &'a mut T) -> &'b mut T {
    transmute(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_lifetime<'a,S,T>(_ptr: &'a S, ptr: &T) -> &'a T {
    transmute_region(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_mut_lifetime<'a,S,T>(_ptr: &'a mut S, ptr: &mut T) -> &'a mut T {
    transmute_mut_region(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
    transmute_region(ptr)
}

/****************************************************************************
 * Tests
 ****************************************************************************/

#[cfg(test)]
mod tests {
    use cast::{bump_box_refcount, transmute};
    use raw;

    #[test]
    fn test_transmute_copy() {
        assert_eq!(1u, unsafe { ::cast::transmute_copy(&1) });
    }

    #[test]
    fn test_bump_managed_refcount() {
        unsafe {
            let managed = @~"box box box";      // refcount 1
            bump_box_refcount(managed);     // refcount 2
            let ptr: *int = transmute(managed); // refcount 2
            let _box1: @~str = ::cast::transmute_copy(&ptr);
            let _box2: @~str = ::cast::transmute_copy(&ptr);
            assert!(*_box1 == ~"box box box");
            assert!(*_box2 == ~"box box box");
            // Will destroy _box1 and _box2. Without the bump, this would
            // use-after-free. With too many bumps, it would leak.
        }
    }

    #[test]
    fn test_transmute() {
        unsafe {
            let x = @100u8;
            let x: *raw::Box<u8> = transmute(x);
            assert!((*x).data == 100);
            let _x: @int = transmute(x);
        }
    }

    #[test]
    fn test_transmute2() {
        unsafe {
            assert_eq!(~[76u8], transmute(~"L"));
        }
    }
}
<commit_msg>Remove std::cast::transmute_immut_unsafe<commit_after>// Copyright 2012 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.

//! Unsafe casting functions

use mem;
use intrinsics;
use ptr::copy_nonoverlapping_memory;

/// Casts the value at `src` to U. The two types must have the same length.
#[inline]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
    let mut dest: U = mem::uninit();
    let dest_ptr: *mut u8 = transmute(&mut dest);
    let src_ptr: *u8 = transmute(src);
    copy_nonoverlapping_memory(dest_ptr, src_ptr, mem::size_of::<U>());
    dest
}

/**
 * Move a thing into the void
 *
 * The forget function will take ownership of the provided value but neglect
 * to run any required cleanup or memory-management operations on it. This
 * can be used for various acts of magick.
 */
#[inline]
pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing); }

/**
 * Force-increment the reference count on a shared box. If used
 * carelessly, this can leak the box.
 */
#[inline]
pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); }

/**
 * Transform a value of one type into a value of another type.
 * Both types must have the same size and alignment.
 *
 * # Example
 *
 * ```rust
 * use std::cast;
 *
 * let v: &[u8] = unsafe { cast::transmute("L") };
 * assert!(v == [76u8]);
 * ```
 */
#[inline]
pub unsafe fn transmute<L, G>(thing: L) -> G {
    intrinsics::transmute(thing)
}

/// Coerce an immutable reference to be mutable.
#[inline]
pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }

/// Coerce a reference to have an arbitrary associated region.
#[inline]
pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T {
    transmute(ptr)
}

/// Coerce an immutable reference to be mutable.
#[inline]
pub unsafe fn transmute_mut_unsafe<T>(ptr: *T) -> *mut T {
    transmute(ptr)
}

/// Coerce a mutable reference to have an arbitrary associated region.
#[inline]
pub unsafe fn transmute_mut_region<'a,'b,T>(ptr: &'a mut T) -> &'b mut T {
    transmute(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_lifetime<'a,S,T>(_ptr: &'a S, ptr: &T) -> &'a T {
    transmute_region(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_mut_lifetime<'a,S,T>(_ptr: &'a mut S, ptr: &mut T) -> &'a mut T {
    transmute_mut_region(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
    transmute_region(ptr)
}

/****************************************************************************
 * Tests
 ****************************************************************************/

#[cfg(test)]
mod tests {
    use cast::{bump_box_refcount, transmute};
    use raw;

    #[test]
    fn test_transmute_copy() {
        assert_eq!(1u, unsafe { ::cast::transmute_copy(&1) });
    }

    #[test]
    fn test_bump_managed_refcount() {
        unsafe {
            let managed = @~"box box box";      // refcount 1
            bump_box_refcount(managed);     // refcount 2
            let ptr: *int = transmute(managed); // refcount 2
            let _box1: @~str = ::cast::transmute_copy(&ptr);
            let _box2: @~str = ::cast::transmute_copy(&ptr);
            assert!(*_box1 == ~"box box box");
            assert!(*_box2 == ~"box box box");
            // Will destroy _box1 and _box2. Without the bump, this would
            // use-after-free. With too many bumps, it would leak.
        }
    }

    #[test]
    fn test_transmute() {
        unsafe {
            let x = @100u8;
            let x: *raw::Box<u8> = transmute(x);
            assert!((*x).data == 100);
            let _x: @int = transmute(x);
        }
    }

    #[test]
    fn test_transmute2() {
        unsafe {
            assert_eq!(~[76u8], transmute(~"L"));
        }
    }
}
<|endoftext|>


<commit_before>/// A dynamic, mutable location.
///
/// Similar to a mutable option type, but friendlier.

struct Cell<T> {
    mut value: option<T>;
}

/// Creates a new full cell with the given value.
fn Cell<T>(+value: T) -> Cell<T> {
    Cell { value: some(move value) }
}

fn empty_cell<T>() -> Cell<T> {
    Cell { value: none }
}

impl<T> Cell<T> {
    /// Yields the value, failing if the cell is empty.
    fn take() -> T {
        let mut value = none;
        value <-> self.value;
        if value.is_none() {
            fail ~"attempt to take an empty cell";
        }
        return option::unwrap(value);
    }

    /// Returns the value, failing if the cell is full.
    fn put_back(+value: T) {
        if self.value.is_none() {
            fail ~"attempt to put a value back into a full cell";
        }
        self.value = some(move value);
    }

    /// Returns true if the cell is empty and false if the cell is full.
    fn is_empty() -> bool {
        self.value.is_none()
    }
}
<commit_msg>std: Add tests for cell. Fix a logic error<commit_after>/// A dynamic, mutable location.
///
/// Similar to a mutable option type, but friendlier.

struct Cell<T> {
    mut value: option<T>;
}

/// Creates a new full cell with the given value.
fn Cell<T>(+value: T) -> Cell<T> {
    Cell { value: some(move value) }
}

fn empty_cell<T>() -> Cell<T> {
    Cell { value: none }
}

impl<T> Cell<T> {
    /// Yields the value, failing if the cell is empty.
    fn take() -> T {
        if self.is_empty() {
            fail ~"attempt to take an empty cell";
        }

        let mut value = none;
        value <-> self.value;
        return option::unwrap(value);
    }

    /// Returns the value, failing if the cell is full.
    fn put_back(+value: T) {
        if !self.is_empty() {
            fail ~"attempt to put a value back into a full cell";
        }
        self.value = some(move value);
    }

    /// Returns true if the cell is empty and false if the cell is full.
    fn is_empty() -> bool {
        self.value.is_none()
    }
}

#[test]
fn test_basic() {
    let value_cell = Cell(~10);
    assert !value_cell.is_empty();
    let value = value_cell.take();
    assert value == ~10;
    assert value_cell.is_empty();
    value_cell.put_back(value);
    assert !value_cell.is_empty();
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_take_empty() {
    let value_cell = empty_cell::<~int>();
    value_cell.take();
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_put_back_non_empty() {
    let value_cell = Cell(~10);
    value_cell.put_back(~20);
}<|endoftext|>


<commit_before>#![crate_name = "paste"]
#![feature(collections, core, old_io, old_path, rustc_private)]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Arcterus <arcterus@mail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate getopts;
extern crate libc;

use std::old_io as io;
use std::iter::repeat;

#[path = "../common/util.rs"]
#[macro_use]
mod util;

static NAME: &'static str = "paste";
static VERSION: &'static str = "1.0.0";

pub fn uumain(args: Vec<String>) -> i32 {
    let program = args[0].clone();

    let opts = [
        getopts::optflag("s", "serial", "paste one file at a time instead of in parallel"),
        getopts::optopt("d", "delimiters", "reuse characters from LIST instead of TABs", "LIST"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit")
    ];
    let matches = match getopts::getopts(args.tail(), &opts) {
        Ok(m) => m,
        Err(f) => crash!(1, "{}", f)
    };
    if matches.opt_present("help") {
        println!("{} {}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {0} [OPTION]... [FILE]...", program);
        println!("");
        print!("{}", getopts::usage("Write lines consisting of the sequentially corresponding lines from each FILE, separated by TABs, to standard output.", &opts));
    } else if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
    } else {
        let serial = matches.opt_present("serial");
        let delimiters = match matches.opt_str("delimiters") {
            Some(m) => m,
            None => "\t".to_string()
        };
        paste(matches.free, serial, delimiters.as_slice());
    }

    0
}

fn paste(filenames: Vec<String>, serial: bool, delimiters: &str) {
    let mut files: Vec<io::BufferedReader<Box<Reader>>> = filenames.into_iter().map(|name|
        io::BufferedReader::new(
            if name.as_slice() == "-" {
                Box::new(io::stdio::stdin_raw()) as Box<Reader>
            } else {
                let r = crash_if_err!(1, io::File::open(&Path::new(name)));
                Box::new(r) as Box<Reader>
            }
        )
    ).collect();
    let delimiters: Vec<String> = delimiters.chars().map(|x| x.to_string()).collect();
    let mut delim_count = 0;
    if serial {
        for file in files.iter_mut() {
            let mut output = String::new();
            loop {
                match file.read_line() {
                    Ok(line) => {
                        output.push_str(line.as_slice().trim_right());
                        output.push_str(delimiters[delim_count % delimiters.len()].as_slice());
                    }
                    Err(f) => if f.kind == io::EndOfFile {
                        break
                    } else {
                        crash!(1, "{}", f.to_string())
                    }
                }
                delim_count += 1;
            }
            println!("{}", output.as_slice().slice_to(output.len() - 1));
        }
    } else {
        let mut eof : Vec<bool> = repeat(false).take(files.len()).collect();
        loop {
            let mut output = "".to_string();
            let mut eof_count = 0;
            for (i, file) in files.iter_mut().enumerate() {
                if eof[i] {
                    eof_count += 1;
                } else {
                    match file.read_line() {
                        Ok(line) => output.push_str(&line.as_slice()[..line.len() - 1]),
                        Err(f) => if f.kind == io::EndOfFile {
                            eof[i] = true;
                            eof_count += 1;
                        } else {
                            crash!(1, "{}", f.to_string());
                        }
                    }
                }
                output.push_str(delimiters[delim_count % delimiters.len()].as_slice());
                delim_count += 1;
            }
            if files.len() == eof_count {
                break;
            }
            println!("{}", output.as_slice().slice_to(output.len() - 1));
            delim_count = 0;
        }
    }
}
<commit_msg>Update paste to nightly build.<commit_after>#![crate_name = "paste"]
#![feature(rustc_private)]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Arcterus <arcterus@mail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate getopts;
extern crate libc;

use std::io::{BufRead, BufReader, Read, stdin, Write};
use std::iter::repeat;
use std::fs::File;
use std::path::Path;

#[path = "../common/util.rs"]
#[macro_use]
mod util;

static NAME: &'static str = "paste";
static VERSION: &'static str = "1.0.0";

pub fn uumain(args: Vec<String>) -> i32 {
    let program = &args[0];

    let opts = [
        getopts::optflag("s", "serial", "paste one file at a time instead of in parallel"),
        getopts::optopt("d", "delimiters", "reuse characters from LIST instead of TABs", "LIST"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit")
    ];
    let matches = match getopts::getopts(&args[1..], &opts) {
        Ok(m) => m,
        Err(e) => crash!(1, "{}", e)
    };
    if matches.opt_present("help") {
        println!("{} {}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {0} [OPTION]... [FILE]...", program);
        println!("");
        print!("{}", getopts::usage("Write lines consisting of the sequentially corresponding lines from each FILE, separated by TABs, to standard output.", &opts));
    } else if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
    } else {
        let serial = matches.opt_present("serial");
        let delimiters = matches.opt_str("delimiters").unwrap_or("\t".to_string());
        paste(matches.free, serial, delimiters);
    }

    0
}

fn paste(filenames: Vec<String>, serial: bool, delimiters: String) {
    let mut files: Vec<BufReader<Box<Read>>> = filenames.into_iter().map(|name|
        BufReader::new(
            if name == "-" {
                Box::new(stdin()) as Box<Read>
            } else {
                let r = crash_if_err!(1, File::open(Path::new(&name)));
                Box::new(r) as Box<Read>
            }
        )
    ).collect();
    let delimiters: Vec<String> = delimiters.chars().map(|x| x.to_string()).collect();
    let mut delim_count = 0;
    if serial {
        for file in files.iter_mut() {
            let mut output = String::new();
            loop {
                let mut line = String::new();
                match file.read_line(&mut line) {
                    Ok(0) => break,
                    Ok(_) => {
                        output.push_str(line.trim_right());
                        output.push_str(&delimiters[delim_count % delimiters.len()]);
                    }
                    Err(e) => crash!(1, "{}", e.to_string())
                }
                delim_count += 1;
            }
            println!("{}", &output[..output.len()-1]);
        }
    } else {
        let mut eof: Vec<bool> = repeat(false).take(files.len()).collect();
        loop {
            let mut output = String::new();
            let mut eof_count = 0;
            for (i, file) in files.iter_mut().enumerate() {
                if eof[i] {
                    eof_count += 1;
                } else {
                    let mut line = String::new();
                    match file.read_line(&mut line) {
                        Ok(0) => {
                            eof[i] = true;
                            eof_count += 1;
                        }
                        Ok(_) => output.push_str(line.trim_right()),
                        Err(e) => crash!(1, "{}", e.to_string())
                    }
                }
                output.push_str(&delimiters[delim_count % delimiters.len()]);
                delim_count += 1;
            }
            if files.len() == eof_count {
                break;
            }
            println!("{}", &output[..output.len()-1]);
            delim_count = 0;
        }
    }
}
<|endoftext|>


<commit_before>// Bloom
//
// HTTP REST API caching middleware
// Copyright: 2017, Valerian Saliou <valerian@valeriansaliou.name>
// License: Mozilla Public License v2.0 (MPL v2.0)

use futures::future::{self, Future};
use httparse;
use hyper::{Error, Method, StatusCode, Headers};
use hyper::header::{Origin, IfNoneMatch, ETag, EntityTag};
use hyper::server::{Request, Response};
use farmhash;

use super::header::ProxyHeader;
use super::tunnel::ProxyTunnel;
use header::janitor::HeaderJanitor;
use header::request_shard::HeaderRequestBloomRequestShard;
use header::status::{HeaderBloomStatus, HeaderBloomStatusValue};
use cache::read::CacheRead;
use cache::write::CacheWrite;
use cache::route::CacheRoute;
use LINE_FEED;

pub struct ProxyServe;

const CACHED_PARSE_MAX_HEADERS: usize = 100;

pub type ProxyServeFuture = Box<Future<Item = Response, Error = Error>>;

impl ProxyServe {
    pub fn handle(req: Request) -> ProxyServeFuture {
        info!("handled request: {} on {}", req.method(), req.path());

        if req.headers().has::<HeaderRequestBloomRequestShard>() == true {
            match *req.method() {
                Method::Options | Method::Head | Method::Get | Method::Post | Method::Patch |
                Method::Put | Method::Delete => Self::accept(req),
                _ => Self::reject(req, StatusCode::MethodNotAllowed),
            }
        } else {
            Self::reject(req, StatusCode::NotExtended)
        }
    }

    fn accept(req: Request) -> ProxyServeFuture {
        Self::tunnel(req)
    }

    fn reject(req: Request, status: StatusCode) -> ProxyServeFuture {
        let mut headers = Headers::new();

        headers.set::<HeaderBloomStatus>(HeaderBloomStatus(HeaderBloomStatusValue::Reject));

        Self::respond(&req.method(), status, headers, format!("{}", status))
    }

    fn tunnel(req: Request) -> ProxyServeFuture {
        let (method, uri, version, headers, body) = req.deconstruct();
        let (headers, auth, shard) = ProxyHeader::parse_from_request(headers);

        let auth_hash = CacheRoute::hash(&auth);

        let (ns, ns_mask) = CacheRoute::gen_key_cache(
            shard,
            &auth_hash,
            version,
            &method,
            uri.path(),
            uri.query(),
            headers.get::<Origin>(),
        );

        info!("tunneling for ns = {}", ns);

        Box::new(
            CacheRead::acquire(&ns, &method)
                .or_else(|_| Err(Error::Incomplete))
                .and_then(move |result| {
                    match result {
                        Ok(value) => Self::dispatch_cached(&method, &headers, &value),
                        Err(_) => {
                            // Clone method value for closures. Sadly, it looks like Rust borrow \
                            //   checker doesnt discriminate properly on this check.
                            let method_success = method.to_owned();
                            let method_failure = method.to_owned();

                            Box::new(
                                ProxyTunnel::run(&method, &uri, &headers, body, shard)
                                    .and_then(move |tunnel_res| {
                                        CacheWrite::save(
                                            ns,
                                            ns_mask,
                                            auth_hash,
                                            shard,
                                            method,
                                            version,
                                            tunnel_res.status(),
                                            tunnel_res.headers().to_owned(),
                                            tunnel_res.body(),
                                        )
                                    })
                                    .and_then(move |mut result| match result.body {
                                        Ok(body_string) => {
                                            Self::dispatch_fetched(
                                                &method_success,
                                                &result.status,
                                                result.headers,
                                                HeaderBloomStatusValue::Miss,
                                                body_string,
                                                result.value,
                                            )
                                        }
                                        Err(body_string_values) => {
                                            match body_string_values {
                                                Some(body_string) => {
                                                    // Enforce clean headers, has usually they get \
                                                    //   cleaned from cache writer
                                                    HeaderJanitor::clean(&mut result.headers);

                                                    Self::dispatch_fetched(
                                                        &method_success,
                                                        &result.status,
                                                        result.headers,
                                                        HeaderBloomStatusValue::Direct,
                                                        body_string,
                                                        result.value,
                                                    )
                                                }
                                                _ => Self::dispatch_failure(&method_success),
                                            }
                                        }
                                    })
                                    .or_else(move |_| Self::dispatch_failure(&method_failure)),
                            )
                        }
                    }
                }),
        )
    }

    fn dispatch_cached(method: &Method, headers: &Headers, res_string: &str) -> ProxyServeFuture {
        // Process ETag for cached content
        let (res_hash, res_etag) = Self::body_fingerprint(res_string);

        let isnt_modified = match headers.get::<IfNoneMatch>() {
            Some(req_if_none_match) => {
                (*req_if_none_match == IfNoneMatch::Items(vec![EntityTag::new(false, res_hash)]))
            }
            _ => false,
        };

        // Response not modified for client?
        if isnt_modified == true {
            // Process non-modified + cached headers
            let mut headers = Headers::new();

            ProxyHeader::set_common(&mut headers, res_etag);
            headers.set::<HeaderBloomStatus>(HeaderBloomStatus(HeaderBloomStatusValue::Hit));

            // Serve non-modified response
            return Self::respond(method, StatusCode::NotModified, headers, String::from(""));
        }

        // Response modified
        let mut headers = [httparse::EMPTY_HEADER; CACHED_PARSE_MAX_HEADERS];
        let mut res = httparse::Response::new(&mut headers);

        // Split headers from body
        let mut res_body_string = String::new();
        let mut is_last_line_empty = false;

        for res_line in res_string.lines() {
            if res_body_string.is_empty() == false || is_last_line_empty == true {
                // Write to body
                res_body_string.push_str(res_line.as_ref());
                res_body_string.push_str(LINE_FEED);
            }

            is_last_line_empty = res_line.is_empty();
        }

        match res.parse(res_string.as_bytes()) {
            Ok(_) => {
                // Process cached status
                let code = res.code.unwrap_or(500u16);
                let status = StatusCode::try_from(code).unwrap_or(StatusCode::Unregistered(code));

                // Process cached headers
                let mut headers = Headers::new();

                for header in res.headers {
                    if let (Ok(header_name), Ok(header_value)) =
                        (
                            String::from_utf8(Vec::from(header.name)),
                            String::from_utf8(Vec::from(header.value)),
                        )
                    {
                        headers.set_raw(header_name, header_value);
                    }
                }

                ProxyHeader::set_common(&mut headers, res_etag);
                headers.set::<HeaderBloomStatus>(HeaderBloomStatus(HeaderBloomStatusValue::Hit));

                // Serve cached response
                Self::respond(method, status, headers, res_body_string)
            }
            Err(err) => {
                error!("failed parsing cached response: {}", err);

                Self::dispatch_failure(method)
            }
        }
    }

    fn dispatch_fetched(
        method: &Method,
        status: &StatusCode,
        mut headers: Headers,
        bloom_status: HeaderBloomStatusValue,
        body_string: String,
        result_string: Option<String>,
    ) -> ProxyServeFuture {
        // Process ETag for content?
        if let Some(result_string_value) = result_string {
            let (_, res_etag) = Self::body_fingerprint(&result_string_value);

            ProxyHeader::set_common(&mut headers, res_etag);
        }

        headers.set(HeaderBloomStatus(bloom_status));

        Self::respond(method, *status, headers, body_string)
    }

    fn dispatch_failure(method: &Method) -> ProxyServeFuture {
        let status = StatusCode::BadGateway;

        let mut headers = Headers::new();

        headers.set::<HeaderBloomStatus>(HeaderBloomStatus(HeaderBloomStatusValue::Offline));

        Self::respond(method, status, headers, format!("{}", status))
    }

    fn body_fingerprint(body_string: &str) -> (String, ETag) {
        let body_hash = format!("{:x}", farmhash::fingerprint64(body_string.as_bytes()));
        let body_etag = ETag(EntityTag::new(false, body_hash.to_owned()));

        (body_hash, body_etag)
    }

    fn respond(
        method: &Method,
        status: StatusCode,
        headers: Headers,
        body_string: String,
    ) -> ProxyServeFuture {
        Box::new(future::ok(match method {
            &Method::Get | &Method::Post | &Method::Patch | &Method::Put => {
                Response::new()
                    .with_status(status)
                    .with_headers(headers)
                    .with_body(body_string)
            }
            _ => Response::new().with_status(status).with_headers(headers),
        }))
    }
}
<commit_msg>RFC-compliant ETag comparison<commit_after>// Bloom
//
// HTTP REST API caching middleware
// Copyright: 2017, Valerian Saliou <valerian@valeriansaliou.name>
// License: Mozilla Public License v2.0 (MPL v2.0)

use futures::future::{self, Future};
use httparse;
use hyper::{Error, Method, StatusCode, Headers};
use hyper::header::{Origin, IfNoneMatch, ETag, EntityTag};
use hyper::server::{Request, Response};
use farmhash;

use super::header::ProxyHeader;
use super::tunnel::ProxyTunnel;
use header::janitor::HeaderJanitor;
use header::request_shard::HeaderRequestBloomRequestShard;
use header::status::{HeaderBloomStatus, HeaderBloomStatusValue};
use cache::read::CacheRead;
use cache::write::CacheWrite;
use cache::route::CacheRoute;
use LINE_FEED;

pub struct ProxyServe;

const CACHED_PARSE_MAX_HEADERS: usize = 100;

pub type ProxyServeFuture = Box<Future<Item = Response, Error = Error>>;

impl ProxyServe {
    pub fn handle(req: Request) -> ProxyServeFuture {
        info!("handled request: {} on {}", req.method(), req.path());

        if req.headers().has::<HeaderRequestBloomRequestShard>() == true {
            match *req.method() {
                Method::Options | Method::Head | Method::Get | Method::Post | Method::Patch |
                Method::Put | Method::Delete => Self::accept(req),
                _ => Self::reject(req, StatusCode::MethodNotAllowed),
            }
        } else {
            Self::reject(req, StatusCode::NotExtended)
        }
    }

    fn accept(req: Request) -> ProxyServeFuture {
        Self::tunnel(req)
    }

    fn reject(req: Request, status: StatusCode) -> ProxyServeFuture {
        let mut headers = Headers::new();

        headers.set::<HeaderBloomStatus>(HeaderBloomStatus(HeaderBloomStatusValue::Reject));

        Self::respond(&req.method(), status, headers, format!("{}", status))
    }

    fn tunnel(req: Request) -> ProxyServeFuture {
        let (method, uri, version, headers, body) = req.deconstruct();
        let (headers, auth, shard) = ProxyHeader::parse_from_request(headers);

        let auth_hash = CacheRoute::hash(&auth);

        let (ns, ns_mask) = CacheRoute::gen_key_cache(
            shard,
            &auth_hash,
            version,
            &method,
            uri.path(),
            uri.query(),
            headers.get::<Origin>(),
        );

        info!("tunneling for ns = {}", ns);

        Box::new(
            CacheRead::acquire(&ns, &method)
                .or_else(|_| Err(Error::Incomplete))
                .and_then(move |result| {
                    match result {
                        Ok(value) => Self::dispatch_cached(&method, &headers, &value),
                        Err(_) => {
                            // Clone method value for closures. Sadly, it looks like Rust borrow \
                            //   checker doesnt discriminate properly on this check.
                            let method_success = method.to_owned();
                            let method_failure = method.to_owned();

                            Box::new(
                                ProxyTunnel::run(&method, &uri, &headers, body, shard)
                                    .and_then(move |tunnel_res| {
                                        CacheWrite::save(
                                            ns,
                                            ns_mask,
                                            auth_hash,
                                            shard,
                                            method,
                                            version,
                                            tunnel_res.status(),
                                            tunnel_res.headers().to_owned(),
                                            tunnel_res.body(),
                                        )
                                    })
                                    .and_then(move |mut result| match result.body {
                                        Ok(body_string) => {
                                            Self::dispatch_fetched(
                                                &method_success,
                                                &result.status,
                                                result.headers,
                                                HeaderBloomStatusValue::Miss,
                                                body_string,
                                                result.value,
                                            )
                                        }
                                        Err(body_string_values) => {
                                            match body_string_values {
                                                Some(body_string) => {
                                                    // Enforce clean headers, has usually they get \
                                                    //   cleaned from cache writer
                                                    HeaderJanitor::clean(&mut result.headers);

                                                    Self::dispatch_fetched(
                                                        &method_success,
                                                        &result.status,
                                                        result.headers,
                                                        HeaderBloomStatusValue::Direct,
                                                        body_string,
                                                        result.value,
                                                    )
                                                }
                                                _ => Self::dispatch_failure(&method_success),
                                            }
                                        }
                                    })
                                    .or_else(move |_| Self::dispatch_failure(&method_failure)),
                            )
                        }
                    }
                }),
        )
    }

    fn dispatch_cached(method: &Method, headers: &Headers, res_string: &str) -> ProxyServeFuture {
        // Process ETag for cached content
        let (res_hash, res_etag) = Self::body_fingerprint(res_string);

        let isnt_modified = match headers.get::<IfNoneMatch>() {
            Some(req_if_none_match) => {
                match *req_if_none_match {
                    IfNoneMatch::Any => true,
                    IfNoneMatch::Items(ref req_etags) => {
                        if let Some(req_etag) = req_etags.first() {
                            req_etag.weak_eq(&EntityTag::new(false, res_hash))
                        } else {
                            false
                        }
                    }
                }
            }
            _ => false,
        };

        // Response not modified for client?
        if isnt_modified == true {
            // Process non-modified + cached headers
            let mut headers = Headers::new();

            ProxyHeader::set_common(&mut headers, res_etag);
            headers.set::<HeaderBloomStatus>(HeaderBloomStatus(HeaderBloomStatusValue::Hit));

            // Serve non-modified response
            return Self::respond(method, StatusCode::NotModified, headers, String::from(""));
        }

        // Response modified
        let mut headers = [httparse::EMPTY_HEADER; CACHED_PARSE_MAX_HEADERS];
        let mut res = httparse::Response::new(&mut headers);

        // Split headers from body
        let mut res_body_string = String::new();
        let mut is_last_line_empty = false;

        for res_line in res_string.lines() {
            if res_body_string.is_empty() == false || is_last_line_empty == true {
                // Write to body
                res_body_string.push_str(res_line.as_ref());
                res_body_string.push_str(LINE_FEED);
            }

            is_last_line_empty = res_line.is_empty();
        }

        match res.parse(res_string.as_bytes()) {
            Ok(_) => {
                // Process cached status
                let code = res.code.unwrap_or(500u16);
                let status = StatusCode::try_from(code).unwrap_or(StatusCode::Unregistered(code));

                // Process cached headers
                let mut headers = Headers::new();

                for header in res.headers {
                    if let (Ok(header_name), Ok(header_value)) =
                        (
                            String::from_utf8(Vec::from(header.name)),
                            String::from_utf8(Vec::from(header.value)),
                        )
                    {
                        headers.set_raw(header_name, header_value);
                    }
                }

                ProxyHeader::set_common(&mut headers, res_etag);
                headers.set::<HeaderBloomStatus>(HeaderBloomStatus(HeaderBloomStatusValue::Hit));

                // Serve cached response
                Self::respond(method, status, headers, res_body_string)
            }
            Err(err) => {
                error!("failed parsing cached response: {}", err);

                Self::dispatch_failure(method)
            }
        }
    }

    fn dispatch_fetched(
        method: &Method,
        status: &StatusCode,
        mut headers: Headers,
        bloom_status: HeaderBloomStatusValue,
        body_string: String,
        result_string: Option<String>,
    ) -> ProxyServeFuture {
        // Process ETag for content?
        if let Some(result_string_value) = result_string {
            let (_, res_etag) = Self::body_fingerprint(&result_string_value);

            ProxyHeader::set_common(&mut headers, res_etag);
        }

        headers.set(HeaderBloomStatus(bloom_status));

        Self::respond(method, *status, headers, body_string)
    }

    fn dispatch_failure(method: &Method) -> ProxyServeFuture {
        let status = StatusCode::BadGateway;

        let mut headers = Headers::new();

        headers.set::<HeaderBloomStatus>(HeaderBloomStatus(HeaderBloomStatusValue::Offline));

        Self::respond(method, status, headers, format!("{}", status))
    }

    fn body_fingerprint(body_string: &str) -> (String, ETag) {
        let body_hash = format!("{:x}", farmhash::fingerprint64(body_string.as_bytes()));
        let body_etag = ETag(EntityTag::new(false, body_hash.to_owned()));

        (body_hash, body_etag)
    }

    fn respond(
        method: &Method,
        status: StatusCode,
        headers: Headers,
        body_string: String,
    ) -> ProxyServeFuture {
        Box::new(future::ok(match method {
            &Method::Get | &Method::Post | &Method::Patch | &Method::Put => {
                Response::new()
                    .with_status(status)
                    .with_headers(headers)
                    .with_body(body_string)
            }
            _ => Response::new().with_status(status).with_headers(headers),
        }))
    }
}
<|endoftext|>


<commit_before>extern crate rand;

use self::rand::{thread_rng, Rng};

/**
* Chooses n samples of weights. The greater the weight the more likely it gets chosen.
* This function returns only the indices of the weights.
*
* @invariant sum of weights must not overflow.
*
* @param weights Weights that get chosen by their weight/probability. One weight can be greater 1.
* @param n Number of randomly chosen indices by weight.
* @return Indices of the weights. Randomly chosen by their weight.
*/
pub fn random_choice(weights: &Vec<f64>, n: usize) -> Vec<usize>{
    // Save accumulated sum of the weights in order to calculate the intervals
    // between accumulated weights
    let mut accumulated_sum = Vec::with_capacity(weights.len());

    accumulated_sum.push(weights[0]);

    for i in 1 .. weights.len() {
        let acc_sum = accumulated_sum[i - 1] + weights[i];
        accumulated_sum.push(acc_sum);
    }

    let sum: f64 = accumulated_sum[weights.len() - 1];
    let spoke_gap: f64 = sum / n as f64;

    // next_f64() ∈ [0.0, 1.0)
    let spin = thread_rng().next_f64() * spoke_gap;
    let mut choices: Vec<usize> = Vec::with_capacity(n);
    let mut i: usize = 0;
    let mut current_spoke: f64 = spin;

    for _ in 0 .. n {
        current_spoke += spoke_gap;
        current_spoke %= sum;

        // accumulated_sum[i] is the interval end
        // (accumulated_sum[i] - weight[i]) is the interval begin
        // Following condition must be true: interval begin <= current_spoke < interval end
        // If the condition is not true, then increment i in order to get the next greater intervals.
        while accumulated_sum[i] <= current_spoke || (accumulated_sum[i] - weights[i]) > current_spoke {
            i += 1;
            i %= weights.len();
        }
        choices.push(i);
    }

    choices
}

#[cfg(test)]
mod tests {
    #[test]
    fn basics() {
        let test_vec = vec![1.0, 2.0, 3.0, 10.0];
        //let sum:f64 = test_vec.iter().fold(0.0, |acc, &i| acc + i);

        //assert_eq!(6.0, sum);

        let indices = super::random_choice(&test_vec, 10 as usize);

        for index in indices {
            print!("{}, ", index);
        }
    }
}<commit_msg>Rewriting random choice. One allocation less<commit_after>extern crate rand;

use self::rand::{thread_rng, Rng};

/**
* Chooses n samples by their weights. The greater their weights the more likely they get chosen.
*
* @invariant sum of weights must not overflow.
* @param samples The to be selected samples
* @param weights Weights that get chosen by their weight/probability. One weight can be greater 1.
* @param n Number of randomly chosen indices by weight.
* @return randomly selected samples by their weight
*/
pub fn random_choice<'a, T>(samples: &'a Vec<T>, weights: &Vec<f64>, n: usize) -> Vec<&'a T>{
    // TODO Check, if weight.len() > 0 and n > 0

    let sum:f64 = weights.iter().fold(0.0, |acc, &i| acc + i);
    let spoke_gap: f64 = sum / n as f64;

    // next_f64() ∈ [0.0, 1.0)
    let spin = thread_rng().next_f64() * spoke_gap;

    let mut i: usize = 0;
    let mut accumulated_weights = weights[0];
    let mut choices: Vec<&T> = Vec::with_capacity(n);
    let mut current_spoke: f64 = spin;

    for _ in 0 .. n {
        while accumulated_weights < current_spoke {
            i += 1;
            accumulated_weights += weights[i];
        }
        choices.push(&samples[i]);
        current_spoke += spoke_gap;
    }

    choices
}

#[cfg(test)]
mod tests {
    #[test]
    fn basics() {
        let test_vec: Vec<f64> = vec![3.1, 1.2, 1.3, 2.0];
        //let sum:f64 = test_vec.iter().fold(0.0, |acc, &i| acc + i);

        //assert_eq!(6.0, sum);

        let choices = super::random_choice(&test_vec, &test_vec, 4 as usize);

        for choice in choices {
            print!("{}, ", choice);
        }
    }
}<|endoftext|>


<commit_before>// Copyright 2013-2015, 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>

use libc::c_char;
use glib::translate::*;
use ffi;

pub struct RecentData {
    display_name: String,
    description: String,
    mime_type: String,
    app_name: String,
    app_exec: String,
    groups: Vec<String>,
    is_private: bool,
}

#[doc(hidden)]
impl <'a> ToGlibPtr<'a, *mut ffi::GtkRecentData> for RecentData {
    type Storage = (Box<ffi::GtkRecentData>,
                    [Stash<'a, *mut c_char, String>; 5],
                    Stash<'a, *mut *mut c_char, [String]>);

    fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::GtkRecentData, Self> {
        let display_name = self.display_name.to_glib_none();
        let description = self.description.to_glib_none();
        let mime_type = self.mime_type.to_glib_none();
        let app_name = self.app_name.to_glib_none();
        let app_exec = self.app_exec.to_glib_none();
        let groups = self.groups.to_glib_none();

        let mut data = Box::new(ffi::GtkRecentData {
            display_name: display_name.0,
            description: description.0,
            mime_type: mime_type.0,
            app_name: app_name.0,
            app_exec: app_exec.0,
            groups: groups.0,
            is_private: self.is_private.to_glib(),
        });

        Stash(&mut *data, (data, [display_name, description, mime_type,
                                  app_name, app_exec], groups))
    }
}
<commit_msg>Make RecentData fields public<commit_after>// Copyright 2013-2015, 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>

use libc::c_char;
use glib::translate::*;
use ffi;

pub struct RecentData {
    pub display_name: Option<String>,
    pub description: Option<String>,
    pub mime_type: String,
    pub app_name: String,
    pub app_exec: String,
    pub groups: Vec<String>,
    pub is_private: bool,
}

#[doc(hidden)]
impl <'a> ToGlibPtr<'a, *mut ffi::GtkRecentData> for RecentData {
    type Storage = (Box<ffi::GtkRecentData>,
                    [Stash<'a, *mut c_char, Option<String>>; 2],
                    [Stash<'a, *mut c_char, String>; 3],
                    Stash<'a, *mut *mut c_char, [String]>);

    fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::GtkRecentData, Self> {
        let display_name = self.display_name.to_glib_none();
        let description = self.description.to_glib_none();
        let mime_type = self.mime_type.to_glib_none();
        let app_name = self.app_name.to_glib_none();
        let app_exec = self.app_exec.to_glib_none();
        let groups = self.groups.to_glib_none();

        let mut data = Box::new(ffi::GtkRecentData {
            display_name: display_name.0,
            description: description.0,
            mime_type: mime_type.0,
            app_name: app_name.0,
            app_exec: app_exec.0,
            groups: groups.0,
            is_private: self.is_private.to_glib(),
        });

        Stash(&mut *data, (data, [display_name, description],
                                 [mime_type, app_name, app_exec],
                                 groups))
    }
}
<|endoftext|>


<commit_before>//! HTTP/HTTPS URL type for Iron.

use url::{self, Host};
use std::fmt;

/// HTTP/HTTPS URL type for Iron.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Url {
    /// The generic rust-url that corresponds to this Url
    generic_url: url::Url,
}

impl Url {
    /// Create a URL from a string.
    ///
    /// The input must be a valid URL with a special scheme for this to succeed.
    ///
    /// HTTP and HTTPS are special schemes.
    ///
    /// See: http://url.spec.whatwg.org/#special-scheme
    pub fn parse(input: &str) -> Result<Url, String> {
        // Parse the string using rust-url, then convert.
        match url::Url::parse(input) {
            Ok(raw_url) => Url::from_generic_url(raw_url),
            Err(e) => Err(format!("{}", e))
        }
    }

    /// Create a `Url` from a `rust-url` `Url`.
    pub fn from_generic_url(raw_url: url::Url) -> Result<Url, String> {
        // Create an Iron URL by verifying the `rust-url` `Url` is a special
        // scheme that Iron supports.
        if raw_url.cannot_be_a_base() {
            Err(format!("Not a special scheme: `{}`", raw_url.scheme()))
        } else if raw_url.port_or_known_default().is_none() {
            Err(format!("Invalid special scheme: `{}`", raw_url.scheme()))
        } else {
            Ok(Url {
                generic_url: raw_url,
            })
        }
    }

    /// Create a `rust-url` `Url` from a `Url`.
    #[deprecated(since="0.5.0", note="use `into` from the `Into` trait instead")]
    pub fn into_generic_url(self) -> url::Url {
        self.generic_url
    }

    /// The lower-cased scheme of the URL, typically "http" or "https".
    pub fn scheme(&self) -> &str {
        self.generic_url.scheme()
    }

    /// The host field of the URL, probably a domain.
    pub fn host(&self) -> Host<&str> {
        // `unwrap` is safe here because urls that cannot be a base don't have a host
        self.generic_url.host().unwrap()
    }

    /// The connection port.
    pub fn port(&self) -> u16 {
        // `unwrap` is safe here because we checked `port_or_known_default`
        // in `from_generic_url`.
        self.generic_url.port_or_known_default().unwrap()
    }

    /// The URL path, the resource to be accessed.
    ///
    /// A *non-empty* vector encoding the parts of the URL path.
    /// Empty entries of `""` correspond to trailing slashes.
    pub fn path(&self) -> Vec<&str> {
        // `unwrap` is safe here because urls that can be a base will have `Some`.
        self.generic_url.path_segments().unwrap().collect()
    }

    /// The URL username field, from the userinfo section of the URL.
    ///
    /// `None` if the `@` character was not part of the input OR
    /// if a blank username was provided.
    /// Otherwise, a non-empty string.
    pub fn username(&self) -> Option<&str> {
        // Map empty usernames to None.
        match self.generic_url.username() {
            "" => None,
            username => Some(username)
        }
    }

    /// The URL password field, from the userinfo section of the URL.
    ///
    /// `None` if the `@` character was not part of the input OR
    /// if a blank password was provided.
    /// Otherwise, a non-empty string.
    pub fn password(&self) -> Option<&str> {
        // Map empty passwords to None.
        match self.generic_url.password() {
            None => None,
            Some(ref x) if x.is_empty() => None,
            Some(password) => Some(password)
        }
    }

    /// The URL query string.
    ///
    /// `None` if the `?` character was not part of the input.
    /// Otherwise, a possibly empty, percent encoded string.
    pub fn query(&self) -> Option<&str> {
        self.generic_url.query()
    }

    /// The URL fragment.
    ///
    /// `None` if the `#` character was not part of the input.
    /// Otherwise, a possibly empty, percent encoded string.
    pub fn fragment(&self) -> Option<&str> {
        self.generic_url.fragment()
    }
}

impl fmt::Display for Url {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        try!(self.generic_url.fmt(formatter));
        Ok(())
    }
}

impl Into<url::Url> for Url {
    fn into(self) -> url::Url { self.generic_url }
}

impl AsRef<url::Url> for Url {
    fn as_ref(&self) -> &url::Url { &self.generic_url }
}

impl AsMut<url::Url> for Url {
    fn as_mut(&mut self) -> &mut url::Url { &mut self.generic_url }
}

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

    #[test]
    fn test_default_port() {
        assert_eq!(Url::parse("http://example.com/wow").unwrap().port(), 80u16);
        assert_eq!(Url::parse("https://example.com/wow").unwrap().port(), 443u16);
    }

    #[test]
    fn test_explicit_port() {
        assert_eq!(Url::parse("http://localhost:3097").unwrap().port(), 3097u16);
    }

    #[test]
    fn test_empty_username() {
        assert!(Url::parse("http://@example.com").unwrap().username().is_none());
        assert!(Url::parse("http://:password@example.com").unwrap().username().is_none());
    }

    #[test]
    fn test_not_empty_username() {
        let url = Url::parse("http://john:pass@example.com").unwrap();
        assert_eq!(url.username().unwrap(), "john");

        let url = Url::parse("http://john:@example.com").unwrap();
        assert_eq!(url.username().unwrap(), "john");
    }

    #[test]
    fn test_empty_password() {
        assert!(Url::parse("http://michael@example.com").unwrap().password().is_none());
        assert!(Url::parse("http://:@example.com").unwrap().password().is_none());
    }

    #[test]
    fn test_not_empty_password() {
        let url = Url::parse("http://michael:pass@example.com").unwrap();
        assert_eq!(url.password().unwrap(), "pass");

        let url = Url::parse("http://:pass@example.com").unwrap();
        assert_eq!(url.password().unwrap(), "pass");
    }

    #[test]
    fn test_formatting() {
        assert_eq!(Url::parse("http://michael@example.com/path/?q=wow").unwrap().to_string(),
                    "http://michael@example.com/path/?q=wow".to_string());
    }

    #[test]
    fn test_conversion() {
        let url_str = "https://user:password@iron.com:8080/path?q=wow#fragment";
        let url = Url::parse(url_str).unwrap();

        // Convert to a generic URL and check fidelity.
        let raw_url: ::url::Url = url.clone().into();
        assert_eq!(::url::Url::parse(url_str).unwrap(), raw_url);

        // Convert back to an Iron URL and check fidelity.
        let new_url = Url::from_generic_url(raw_url).unwrap();
        assert_eq!(url, new_url);
    }

    #[test]
    fn test_https_non_default_port() {
        let parsed = Url::parse("https://example.com:8080").unwrap().to_string();
        assert_eq!(parsed, "https://example.com:8080/");
    }

    #[test]
    fn test_https_default_port() {
        let parsed = Url::parse("https://example.com:443").unwrap().to_string();
        assert_eq!(parsed, "https://example.com/");
    }
}
<commit_msg>into_generic_url deprecated since 0.4.1<commit_after>//! HTTP/HTTPS URL type for Iron.

use url::{self, Host};
use std::fmt;

/// HTTP/HTTPS URL type for Iron.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Url {
    /// The generic rust-url that corresponds to this Url
    generic_url: url::Url,
}

impl Url {
    /// Create a URL from a string.
    ///
    /// The input must be a valid URL with a special scheme for this to succeed.
    ///
    /// HTTP and HTTPS are special schemes.
    ///
    /// See: http://url.spec.whatwg.org/#special-scheme
    pub fn parse(input: &str) -> Result<Url, String> {
        // Parse the string using rust-url, then convert.
        match url::Url::parse(input) {
            Ok(raw_url) => Url::from_generic_url(raw_url),
            Err(e) => Err(format!("{}", e))
        }
    }

    /// Create a `Url` from a `rust-url` `Url`.
    pub fn from_generic_url(raw_url: url::Url) -> Result<Url, String> {
        // Create an Iron URL by verifying the `rust-url` `Url` is a special
        // scheme that Iron supports.
        if raw_url.cannot_be_a_base() {
            Err(format!("Not a special scheme: `{}`", raw_url.scheme()))
        } else if raw_url.port_or_known_default().is_none() {
            Err(format!("Invalid special scheme: `{}`", raw_url.scheme()))
        } else {
            Ok(Url {
                generic_url: raw_url,
            })
        }
    }

    /// Create a `rust-url` `Url` from a `Url`.
    #[deprecated(since="0.4.1", note="use `into` from the `Into` trait instead")]
    pub fn into_generic_url(self) -> url::Url {
        self.generic_url
    }

    /// The lower-cased scheme of the URL, typically "http" or "https".
    pub fn scheme(&self) -> &str {
        self.generic_url.scheme()
    }

    /// The host field of the URL, probably a domain.
    pub fn host(&self) -> Host<&str> {
        // `unwrap` is safe here because urls that cannot be a base don't have a host
        self.generic_url.host().unwrap()
    }

    /// The connection port.
    pub fn port(&self) -> u16 {
        // `unwrap` is safe here because we checked `port_or_known_default`
        // in `from_generic_url`.
        self.generic_url.port_or_known_default().unwrap()
    }

    /// The URL path, the resource to be accessed.
    ///
    /// A *non-empty* vector encoding the parts of the URL path.
    /// Empty entries of `""` correspond to trailing slashes.
    pub fn path(&self) -> Vec<&str> {
        // `unwrap` is safe here because urls that can be a base will have `Some`.
        self.generic_url.path_segments().unwrap().collect()
    }

    /// The URL username field, from the userinfo section of the URL.
    ///
    /// `None` if the `@` character was not part of the input OR
    /// if a blank username was provided.
    /// Otherwise, a non-empty string.
    pub fn username(&self) -> Option<&str> {
        // Map empty usernames to None.
        match self.generic_url.username() {
            "" => None,
            username => Some(username)
        }
    }

    /// The URL password field, from the userinfo section of the URL.
    ///
    /// `None` if the `@` character was not part of the input OR
    /// if a blank password was provided.
    /// Otherwise, a non-empty string.
    pub fn password(&self) -> Option<&str> {
        // Map empty passwords to None.
        match self.generic_url.password() {
            None => None,
            Some(ref x) if x.is_empty() => None,
            Some(password) => Some(password)
        }
    }

    /// The URL query string.
    ///
    /// `None` if the `?` character was not part of the input.
    /// Otherwise, a possibly empty, percent encoded string.
    pub fn query(&self) -> Option<&str> {
        self.generic_url.query()
    }

    /// The URL fragment.
    ///
    /// `None` if the `#` character was not part of the input.
    /// Otherwise, a possibly empty, percent encoded string.
    pub fn fragment(&self) -> Option<&str> {
        self.generic_url.fragment()
    }
}

impl fmt::Display for Url {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        try!(self.generic_url.fmt(formatter));
        Ok(())
    }
}

impl Into<url::Url> for Url {
    fn into(self) -> url::Url { self.generic_url }
}

impl AsRef<url::Url> for Url {
    fn as_ref(&self) -> &url::Url { &self.generic_url }
}

impl AsMut<url::Url> for Url {
    fn as_mut(&mut self) -> &mut url::Url { &mut self.generic_url }
}

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

    #[test]
    fn test_default_port() {
        assert_eq!(Url::parse("http://example.com/wow").unwrap().port(), 80u16);
        assert_eq!(Url::parse("https://example.com/wow").unwrap().port(), 443u16);
    }

    #[test]
    fn test_explicit_port() {
        assert_eq!(Url::parse("http://localhost:3097").unwrap().port(), 3097u16);
    }

    #[test]
    fn test_empty_username() {
        assert!(Url::parse("http://@example.com").unwrap().username().is_none());
        assert!(Url::parse("http://:password@example.com").unwrap().username().is_none());
    }

    #[test]
    fn test_not_empty_username() {
        let url = Url::parse("http://john:pass@example.com").unwrap();
        assert_eq!(url.username().unwrap(), "john");

        let url = Url::parse("http://john:@example.com").unwrap();
        assert_eq!(url.username().unwrap(), "john");
    }

    #[test]
    fn test_empty_password() {
        assert!(Url::parse("http://michael@example.com").unwrap().password().is_none());
        assert!(Url::parse("http://:@example.com").unwrap().password().is_none());
    }

    #[test]
    fn test_not_empty_password() {
        let url = Url::parse("http://michael:pass@example.com").unwrap();
        assert_eq!(url.password().unwrap(), "pass");

        let url = Url::parse("http://:pass@example.com").unwrap();
        assert_eq!(url.password().unwrap(), "pass");
    }

    #[test]
    fn test_formatting() {
        assert_eq!(Url::parse("http://michael@example.com/path/?q=wow").unwrap().to_string(),
                    "http://michael@example.com/path/?q=wow".to_string());
    }

    #[test]
    fn test_conversion() {
        let url_str = "https://user:password@iron.com:8080/path?q=wow#fragment";
        let url = Url::parse(url_str).unwrap();

        // Convert to a generic URL and check fidelity.
        let raw_url: ::url::Url = url.clone().into();
        assert_eq!(::url::Url::parse(url_str).unwrap(), raw_url);

        // Convert back to an Iron URL and check fidelity.
        let new_url = Url::from_generic_url(raw_url).unwrap();
        assert_eq!(url, new_url);
    }

    #[test]
    fn test_https_non_default_port() {
        let parsed = Url::parse("https://example.com:8080").unwrap().to_string();
        assert_eq!(parsed, "https://example.com:8080/");
    }

    #[test]
    fn test_https_default_port() {
        let parsed = Url::parse("https://example.com:443").unwrap().to_string();
        assert_eq!(parsed, "https://example.com/");
    }
}
<|endoftext|>