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

use mem;
use ops::{self, Add, Sub};
use usize;

use super::{FusedIterator, TrustedLen};

/// Objects that can be stepped over in both directions.
///
/// The `steps_between` function provides a way to efficiently compare
/// two `Step` objects.
#[unstable(feature = "step_trait",
           reason = "likely to be replaced by finer-grained traits",
           issue = "42168")]
pub trait Step: PartialOrd + Sized {
    /// Returns the number of steps between two step objects. The count is
    /// inclusive of `start` and exclusive of `end`.
    ///
    /// Returns `None` if it is not possible to calculate `steps_between`
    /// without overflow.
    fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>;

    /// Same as `steps_between`, but with a `by` of 1
    fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize>;

    /// Replaces this step with `1`, returning itself
    fn replace_one(&mut self) -> Self;

    /// Replaces this step with `0`, returning itself
    fn replace_zero(&mut self) -> Self;

    /// Adds one to this step, returning the result
    fn add_one(&self) -> Self;

    /// Subtracts one to this step, returning the result
    fn sub_one(&self) -> Self;
}

macro_rules! step_impl_unsigned {
    ($($t:ty)*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            #[allow(trivial_numeric_casts)]
            fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
                if *by == 0 { return None; }
                if *start < *end {
                    // Note: We assume $t <= usize here
                    let diff = (*end - *start) as usize;
                    let by = *by as usize;
                    if diff % by > 0 {
                        Some(diff / by + 1)
                    } else {
                        Some(diff / by)
                    }
                } else {
                    Some(0)
                }
            }

            #[inline]
            fn replace_one(&mut self) -> Self {
                mem::replace(self, 1)
            }

            #[inline]
            fn replace_zero(&mut self) -> Self {
                mem::replace(self, 0)
            }

            #[inline]
            fn add_one(&self) -> Self {
                Add::add(*self, 1)
            }

            #[inline]
            fn sub_one(&self) -> Self {
                Sub::sub(*self, 1)
            }

            #[inline]
            fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
                Self::steps_between(start, end, &1)
            }
        }
    )*)
}
macro_rules! step_impl_signed {
    ($($t:ty)*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            #[allow(trivial_numeric_casts)]
            fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
                if *by == 0 { return None; }
                let diff: usize;
                let by_u: usize;
                if *by > 0 {
                    if *start >= *end {
                        return Some(0);
                    }
                    // Note: We assume $t <= isize here
                    // Use .wrapping_sub and cast to usize to compute the
                    // difference that may not fit inside the range of isize.
                    diff = (*end as isize).wrapping_sub(*start as isize) as usize;
                    by_u = *by as usize;
                } else {
                    if *start <= *end {
                        return Some(0);
                    }
                    diff = (*start as isize).wrapping_sub(*end as isize) as usize;
                    by_u = (*by as isize).wrapping_mul(-1) as usize;
                }
                if diff % by_u > 0 {
                    Some(diff / by_u + 1)
                } else {
                    Some(diff / by_u)
                }
            }

            #[inline]
            fn replace_one(&mut self) -> Self {
                mem::replace(self, 1)
            }

            #[inline]
            fn replace_zero(&mut self) -> Self {
                mem::replace(self, 0)
            }

            #[inline]
            fn add_one(&self) -> Self {
                Add::add(*self, 1)
            }

            #[inline]
            fn sub_one(&self) -> Self {
                Sub::sub(*self, 1)
            }

            #[inline]
            fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
                Self::steps_between(start, end, &1)
            }
        }
    )*)
}

macro_rules! step_impl_no_between {
    ($($t:ty)*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            fn steps_between(_a: &$t, _b: &$t, _by: &$t) -> Option<usize> {
                None
            }

            #[inline]
            fn replace_one(&mut self) -> Self {
                mem::replace(self, 1)
            }

            #[inline]
            fn replace_zero(&mut self) -> Self {
                mem::replace(self, 0)
            }

            #[inline]
            fn add_one(&self) -> Self {
                Add::add(*self, 1)
            }

            #[inline]
            fn sub_one(&self) -> Self {
                Sub::sub(*self, 1)
            }

            #[inline]
            fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
                Self::steps_between(start, end, &1)
            }
        }
    )*)
}

step_impl_unsigned!(usize u8 u16 u32);
step_impl_signed!(isize i8 i16 i32);
#[cfg(target_pointer_width = "64")]
step_impl_unsigned!(u64);
#[cfg(target_pointer_width = "64")]
step_impl_signed!(i64);
// If the target pointer width is not 64-bits, we
// assume here that it is less than 64-bits.
#[cfg(not(target_pointer_width = "64"))]
step_impl_no_between!(u64 i64);
step_impl_no_between!(u128 i128);

macro_rules! range_exact_iter_impl {
    ($($t:ty)*) => ($(
        #[stable(feature = "rust1", since = "1.0.0")]
        impl ExactSizeIterator for ops::Range<$t> { }
    )*)
}

macro_rules! range_incl_exact_iter_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "inclusive_range",
                   reason = "recently added, follows RFC",
                   issue = "28237")]
        impl ExactSizeIterator for ops::RangeInclusive<$t> { }
    )*)
}

macro_rules! range_trusted_len_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "trusted_len", issue = "37572")]
        unsafe impl TrustedLen for ops::Range<$t> { }
    )*)
}

macro_rules! range_incl_trusted_len_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "inclusive_range",
                   reason = "recently added, follows RFC",
                   issue = "28237")]
        unsafe impl TrustedLen for ops::RangeInclusive<$t> { }
    )*)
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> Iterator for ops::Range<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        if self.start < self.end {
            let mut n = self.start.add_one();
            mem::swap(&mut n, &mut self.start);
            Some(n)
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        match Step::steps_between_by_one(&self.start, &self.end) {
            Some(hint) => (hint, Some(hint)),
            None => (0, None)
        }
    }
}

// These macros generate `ExactSizeIterator` impls for various range types.
// Range<{u,i}64> and RangeInclusive<{u,i}{32,64,size}> are excluded
// because they cannot guarantee having a length <= usize::MAX, which is
// required by ExactSizeIterator.
range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
range_incl_exact_iter_impl!(u8 u16 i8 i16);

// These macros generate `TrustedLen` impls.
//
// They need to guarantee that .size_hint() is either exact, or that
// the upper bound is None when it does not fit the type limits.
range_trusted_len_impl!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);
range_incl_trusted_len_impl!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step + Clone> DoubleEndedIterator for ops::Range<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        if self.start < self.end {
            self.end = self.end.sub_one();
            Some(self.end.clone())
        } else {
            None
        }
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::Range<A> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> Iterator for ops::RangeFrom<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        let mut n = self.start.add_one();
        mem::swap(&mut n, &mut self.start);
        Some(n)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (usize::MAX, None)
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::RangeFrom<A> {}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> Iterator for ops::RangeInclusive<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        use cmp::Ordering::*;

        match self.start.partial_cmp(&self.end) {
            Some(Less) => {
                let n = self.start.add_one();
                Some(mem::replace(&mut self.start, n))
            },
            Some(Equal) => {
                let last = self.start.replace_one();
                self.end.replace_zero();
                Some(last)
            },
            _ => None,
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        if !(self.start <= self.end) {
            return (0, Some(0));
        }

        match Step::steps_between_by_one(&self.start, &self.end) {
            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
            None => (0, None),
        }
    }
}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        use cmp::Ordering::*;

        match self.start.partial_cmp(&self.end) {
            Some(Less) => {
                let n = self.end.sub_one();
                Some(mem::replace(&mut self.end, n))
            },
            Some(Equal) => {
                let last = self.end.replace_zero();
                self.start.replace_one();
                Some(last)
            },
            _ => None,
        }
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}
<commit_msg>Remove Step::steps_between, rename steps_between_by_one to steps_between<commit_after>// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use mem;
use ops::{self, Add, Sub};
use usize;

use super::{FusedIterator, TrustedLen};

/// Objects that can be stepped over in both directions.
///
/// The `steps_between` function provides a way to efficiently compare
/// two `Step` objects.
#[unstable(feature = "step_trait",
           reason = "likely to be replaced by finer-grained traits",
           issue = "42168")]
pub trait Step: PartialOrd + Sized {
    /// Returns the number of steps between two step objects. The count is
    /// inclusive of `start` and exclusive of `end`.
    ///
    /// Returns `None` if it is not possible to calculate `steps_between`
    /// without overflow.
    fn steps_between(start: &Self, end: &Self) -> Option<usize>;

    /// Replaces this step with `1`, returning itself
    fn replace_one(&mut self) -> Self;

    /// Replaces this step with `0`, returning itself
    fn replace_zero(&mut self) -> Self;

    /// Adds one to this step, returning the result
    fn add_one(&self) -> Self;

    /// Subtracts one to this step, returning the result
    fn sub_one(&self) -> Self;
}

macro_rules! step_impl_unsigned {
    ($($t:ty)*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            #[allow(trivial_numeric_casts)]
            fn steps_between(start: &$t, end: &$t) -> Option<usize> {
                if *start < *end {
                    // Note: We assume $t <= usize here
                    Some((*end - *start) as usize)
                } else {
                    Some(0)
                }
            }

            #[inline]
            fn replace_one(&mut self) -> Self {
                mem::replace(self, 1)
            }

            #[inline]
            fn replace_zero(&mut self) -> Self {
                mem::replace(self, 0)
            }

            #[inline]
            fn add_one(&self) -> Self {
                Add::add(*self, 1)
            }

            #[inline]
            fn sub_one(&self) -> Self {
                Sub::sub(*self, 1)
            }
        }
    )*)
}
macro_rules! step_impl_signed {
    ($($t:ty)*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            #[allow(trivial_numeric_casts)]
            fn steps_between(start: &$t, end: &$t) -> Option<usize> {
                if *start < *end {
                    // Note: We assume $t <= isize here
                    // Use .wrapping_sub and cast to usize to compute the
                    // difference that may not fit inside the range of isize.
                    Some((*end as isize).wrapping_sub(*start as isize) as usize)
                } else {
                    Some(0)
                }
            }

            #[inline]
            fn replace_one(&mut self) -> Self {
                mem::replace(self, 1)
            }

            #[inline]
            fn replace_zero(&mut self) -> Self {
                mem::replace(self, 0)
            }

            #[inline]
            fn add_one(&self) -> Self {
                Add::add(*self, 1)
            }

            #[inline]
            fn sub_one(&self) -> Self {
                Sub::sub(*self, 1)
            }
        }
    )*)
}

macro_rules! step_impl_no_between {
    ($($t:ty)*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            fn steps_between(_start: &Self, _end: &Self) -> Option<usize> {
                None
            }

            #[inline]
            fn replace_one(&mut self) -> Self {
                mem::replace(self, 1)
            }

            #[inline]
            fn replace_zero(&mut self) -> Self {
                mem::replace(self, 0)
            }

            #[inline]
            fn add_one(&self) -> Self {
                Add::add(*self, 1)
            }

            #[inline]
            fn sub_one(&self) -> Self {
                Sub::sub(*self, 1)
            }
        }
    )*)
}

step_impl_unsigned!(usize u8 u16 u32);
step_impl_signed!(isize i8 i16 i32);
#[cfg(target_pointer_width = "64")]
step_impl_unsigned!(u64);
#[cfg(target_pointer_width = "64")]
step_impl_signed!(i64);
// If the target pointer width is not 64-bits, we
// assume here that it is less than 64-bits.
#[cfg(not(target_pointer_width = "64"))]
step_impl_no_between!(u64 i64);
step_impl_no_between!(u128 i128);

macro_rules! range_exact_iter_impl {
    ($($t:ty)*) => ($(
        #[stable(feature = "rust1", since = "1.0.0")]
        impl ExactSizeIterator for ops::Range<$t> { }
    )*)
}

macro_rules! range_incl_exact_iter_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "inclusive_range",
                   reason = "recently added, follows RFC",
                   issue = "28237")]
        impl ExactSizeIterator for ops::RangeInclusive<$t> { }
    )*)
}

macro_rules! range_trusted_len_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "trusted_len", issue = "37572")]
        unsafe impl TrustedLen for ops::Range<$t> { }
    )*)
}

macro_rules! range_incl_trusted_len_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "inclusive_range",
                   reason = "recently added, follows RFC",
                   issue = "28237")]
        unsafe impl TrustedLen for ops::RangeInclusive<$t> { }
    )*)
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> Iterator for ops::Range<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        if self.start < self.end {
            let mut n = self.start.add_one();
            mem::swap(&mut n, &mut self.start);
            Some(n)
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        match Step::steps_between(&self.start, &self.end) {
            Some(hint) => (hint, Some(hint)),
            None => (0, None)
        }
    }
}

// These macros generate `ExactSizeIterator` impls for various range types.
// Range<{u,i}64> and RangeInclusive<{u,i}{32,64,size}> are excluded
// because they cannot guarantee having a length <= usize::MAX, which is
// required by ExactSizeIterator.
range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
range_incl_exact_iter_impl!(u8 u16 i8 i16);

// These macros generate `TrustedLen` impls.
//
// They need to guarantee that .size_hint() is either exact, or that
// the upper bound is None when it does not fit the type limits.
range_trusted_len_impl!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);
range_incl_trusted_len_impl!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step + Clone> DoubleEndedIterator for ops::Range<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        if self.start < self.end {
            self.end = self.end.sub_one();
            Some(self.end.clone())
        } else {
            None
        }
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::Range<A> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> Iterator for ops::RangeFrom<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        let mut n = self.start.add_one();
        mem::swap(&mut n, &mut self.start);
        Some(n)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (usize::MAX, None)
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::RangeFrom<A> {}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> Iterator for ops::RangeInclusive<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        use cmp::Ordering::*;

        match self.start.partial_cmp(&self.end) {
            Some(Less) => {
                let n = self.start.add_one();
                Some(mem::replace(&mut self.start, n))
            },
            Some(Equal) => {
                let last = self.start.replace_one();
                self.end.replace_zero();
                Some(last)
            },
            _ => None,
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        if !(self.start <= self.end) {
            return (0, Some(0));
        }

        match Step::steps_between(&self.start, &self.end) {
            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
            None => (0, None),
        }
    }
}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        use cmp::Ordering::*;

        match self.start.partial_cmp(&self.end) {
            Some(Less) => {
                let n = self.end.sub_one();
                Some(mem::replace(&mut self.end, n))
            },
            Some(Equal) => {
                let last = self.end.replace_zero();
                self.start.replace_one();
                Some(last)
            },
            _ => None,
        }
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}
<|endoftext|>


<commit_before>#![doc(html_root_url = "https://hyperium.github.io/hyper/hyper/index.html")]
#![feature(core, io, unsafe_destructor, into_cow, convert)]
#![deny(missing_docs)]
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(test, feature(test))]

//! # Hyper
//! Hyper is a fast, modern HTTP implementation written in and for Rust. It
//! is a low-level typesafe abstraction over raw HTTP, providing an elegant
//! layer over "stringly-typed" HTTP.
//!
//! Hyper offers both an HTTP/S client an HTTP server which can be used to drive
//! complex web applications written entirely in Rust.
//!
//! ## Internal Design
//!
//! Hyper is designed as a relatively low-level wrapper over raw HTTP. It should
//! allow the implementation of higher-level abstractions with as little pain as
//! possible, and should not irrevocably hide any information from its users.
//!
//! ### Common Functionality
//!
//! Functionality and code shared between the Server and Client implementations can
//! be found in `src` directly - this includes `NetworkStream`s, `Method`s,
//! `StatusCode`, and so on.
//!
//! #### Methods
//!
//! Methods are represented as a single `enum` to remain as simple as possible.
//! Extension Methods are represented as raw `String`s. A method's safety and
//! idempotence can be accessed using the `safe` and `idempotent` methods.
//!
//! #### StatusCode
//!
//! Status codes are also represented as a single, exhaustive, `enum`. This
//! representation is efficient, typesafe, and ergonomic as it allows the use of
//! `match` to disambiguate known status codes.
//!
//! #### Headers
//!
//! Hyper's header representation is likely the most complex API exposed by Hyper.
//!
//! Hyper's headers are an abstraction over an internal `HashMap` and provides a
//! typesafe API for interacting with headers that does not rely on the use of
//! "string-typing."
//!
//! Each HTTP header in Hyper has an associated type and implementation of the
//! `Header` trait, which defines an HTTP headers name as a string, how to parse
//! that header, and how to format that header.
//!
//! Headers are then parsed from the string representation lazily when the typed
//! representation of a header is requested and formatted back into their string
//! representation when headers are written back to the client.
//!
//! #### NetworkStream and NetworkAcceptor
//!
//! These are found in `src/net.rs` and define the interface that acceptors and
//! streams must fulfill for them to be used within Hyper. They are by and large
//! internal tools and you should only need to mess around with them if you want to
//! mock or replace `TcpStream` and `TcpAcceptor`.
//!
//! ### Server
//!
//! Server-specific functionality, such as `Request` and `Response`
//! representations, are found in in `src/server`.
//!
//! #### Handler + Server
//!
//! A `Handler` in Hyper accepts a `Request` and `Response`. This is where
//! user-code can handle each connection. The server accepts connections in a
//! task pool with a customizable number of threads, and passes the Request /
//! Response to the handler.
//!
//! #### Request
//!
//! An incoming HTTP Request is represented as a struct containing
//! a `Reader` over a `NetworkStream`, which represents the body, headers, a remote
//! address, an HTTP version, and a `Method` - relatively standard stuff.
//!
//! `Request` implements `Reader` itself, meaning that you can ergonomically get
//! the body out of a `Request` using standard `Reader` methods and helpers.
//!
//! #### Response
//!
//! An outgoing HTTP Response is also represented as a struct containing a `Writer`
//! over a `NetworkStream` which represents the Response body in addition to
//! standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer`
//! implementation provides a streaming interface for sending data over to the
//! client.
//!
//! One of the traditional problems with representing outgoing HTTP Responses is
//! tracking the write-status of the Response - have we written the status-line,
//! the headers, the body, etc.? Hyper tracks this information statically using the
//! type system and prevents you, using the type system, from writing headers after
//! you have started writing to the body or vice versa.
//!
//! Hyper does this through a phantom type parameter in the definition of Response,
//! which tracks whether you are allowed to write to the headers or the body. This
//! phantom type can have two values `Fresh` or `Streaming`, with `Fresh`
//! indicating that you can write the headers and `Streaming` indicating that you
//! may write to the body, but not the headers.
//!
//! ### Client
//!
//! Client-specific functionality, such as `Request` and `Response`
//! representations, are found in `src/client`.
//!
//! #### Request
//!
//! An outgoing HTTP Request is represented as a struct containing a `Writer` over
//! a `NetworkStream` which represents the Request body in addition to the standard
//! information such as headers and the request method.
//!
//! Outgoing Requests track their write-status in almost exactly the same way as
//! outgoing HTTP Responses do on the Server, so we will defer to the explanation
//! in the documentation for sever Response.
//!
//! Requests expose an efficient streaming interface instead of a builder pattern,
//! but they also provide the needed interface for creating a builder pattern over
//! the API exposed by core Hyper.
//!
//! #### Response
//!
//! Incoming HTTP Responses are represented as a struct containing a `Reader` over
//! a `NetworkStream` and contain headers, a status, and an http version. They
//! implement `Reader` and can be read to get the data out of a `Response`.
//!

extern crate rustc_serialize as serialize;
extern crate time;
extern crate url;
extern crate openssl;
extern crate cookie;
extern crate unicase;
extern crate httparse;
extern crate num_cpus;

#[macro_use]
extern crate log;

#[cfg(test)]
extern crate test;

pub use mimewrapper::mime;
pub use url::Url;
pub use client::Client;
pub use error::{HttpResult, HttpError};
pub use method::Method::{Get, Head, Post, Delete};
pub use status::StatusCode::{Ok, BadRequest, NotFound};
pub use server::Server;

macro_rules! todo(
    ($($arg:tt)*) => (if cfg!(not(ndebug)) {
        trace!("TODO: {:?}", format_args!($($arg)*))
    })
);

macro_rules! inspect(
    ($name:expr, $value:expr) => ({
        let v = $value;
        trace!("inspect: {:?} = {:?}", $name, v);
        v
    })
);

#[cfg(test)]
#[macro_use]
mod mock;
#[doc(hidden)]
pub mod buffer;
pub mod client;
pub mod error;
pub mod method;
pub mod header;
pub mod http;
pub mod net;
pub mod server;
pub mod status;
pub mod uri;
pub mod version;

mod mimewrapper {
    /// Re-exporting the mime crate, for convenience.
    extern crate mime;
}

#[allow(unconditional_recursion)]
fn _assert_send<T: Send>() {
    _assert_send::<client::Request<net::Fresh>>();
    _assert_send::<client::Response>();
}
<commit_msg>docs(mainpage): fix typo<commit_after>#![doc(html_root_url = "https://hyperium.github.io/hyper/hyper/index.html")]
#![feature(core, io, unsafe_destructor, into_cow, convert)]
#![deny(missing_docs)]
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(test, feature(test))]

//! # Hyper
//! Hyper is a fast, modern HTTP implementation written in and for Rust. It
//! is a low-level typesafe abstraction over raw HTTP, providing an elegant
//! layer over "stringly-typed" HTTP.
//!
//! Hyper offers both an HTTP/S client an HTTP server which can be used to drive
//! complex web applications written entirely in Rust.
//!
//! ## Internal Design
//!
//! Hyper is designed as a relatively low-level wrapper over raw HTTP. It should
//! allow the implementation of higher-level abstractions with as little pain as
//! possible, and should not irrevocably hide any information from its users.
//!
//! ### Common Functionality
//!
//! Functionality and code shared between the Server and Client implementations can
//! be found in `src` directly - this includes `NetworkStream`s, `Method`s,
//! `StatusCode`, and so on.
//!
//! #### Methods
//!
//! Methods are represented as a single `enum` to remain as simple as possible.
//! Extension Methods are represented as raw `String`s. A method's safety and
//! idempotence can be accessed using the `safe` and `idempotent` methods.
//!
//! #### StatusCode
//!
//! Status codes are also represented as a single, exhaustive, `enum`. This
//! representation is efficient, typesafe, and ergonomic as it allows the use of
//! `match` to disambiguate known status codes.
//!
//! #### Headers
//!
//! Hyper's header representation is likely the most complex API exposed by Hyper.
//!
//! Hyper's headers are an abstraction over an internal `HashMap` and provides a
//! typesafe API for interacting with headers that does not rely on the use of
//! "string-typing."
//!
//! Each HTTP header in Hyper has an associated type and implementation of the
//! `Header` trait, which defines an HTTP headers name as a string, how to parse
//! that header, and how to format that header.
//!
//! Headers are then parsed from the string representation lazily when the typed
//! representation of a header is requested and formatted back into their string
//! representation when headers are written back to the client.
//!
//! #### NetworkStream and NetworkAcceptor
//!
//! These are found in `src/net.rs` and define the interface that acceptors and
//! streams must fulfill for them to be used within Hyper. They are by and large
//! internal tools and you should only need to mess around with them if you want to
//! mock or replace `TcpStream` and `TcpAcceptor`.
//!
//! ### Server
//!
//! Server-specific functionality, such as `Request` and `Response`
//! representations, are found in in `src/server`.
//!
//! #### Handler + Server
//!
//! A `Handler` in Hyper accepts a `Request` and `Response`. This is where
//! user-code can handle each connection. The server accepts connections in a
//! task pool with a customizable number of threads, and passes the Request /
//! Response to the handler.
//!
//! #### Request
//!
//! An incoming HTTP Request is represented as a struct containing
//! a `Reader` over a `NetworkStream`, which represents the body, headers, a remote
//! address, an HTTP version, and a `Method` - relatively standard stuff.
//!
//! `Request` implements `Reader` itself, meaning that you can ergonomically get
//! the body out of a `Request` using standard `Reader` methods and helpers.
//!
//! #### Response
//!
//! An outgoing HTTP Response is also represented as a struct containing a `Writer`
//! over a `NetworkStream` which represents the Response body in addition to
//! standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer`
//! implementation provides a streaming interface for sending data over to the
//! client.
//!
//! One of the traditional problems with representing outgoing HTTP Responses is
//! tracking the write-status of the Response - have we written the status-line,
//! the headers, the body, etc.? Hyper tracks this information statically using the
//! type system and prevents you, using the type system, from writing headers after
//! you have started writing to the body or vice versa.
//!
//! Hyper does this through a phantom type parameter in the definition of Response,
//! which tracks whether you are allowed to write to the headers or the body. This
//! phantom type can have two values `Fresh` or `Streaming`, with `Fresh`
//! indicating that you can write the headers and `Streaming` indicating that you
//! may write to the body, but not the headers.
//!
//! ### Client
//!
//! Client-specific functionality, such as `Request` and `Response`
//! representations, are found in `src/client`.
//!
//! #### Request
//!
//! An outgoing HTTP Request is represented as a struct containing a `Writer` over
//! a `NetworkStream` which represents the Request body in addition to the standard
//! information such as headers and the request method.
//!
//! Outgoing Requests track their write-status in almost exactly the same way as
//! outgoing HTTP Responses do on the Server, so we will defer to the explanation
//! in the documentation for server Response.
//!
//! Requests expose an efficient streaming interface instead of a builder pattern,
//! but they also provide the needed interface for creating a builder pattern over
//! the API exposed by core Hyper.
//!
//! #### Response
//!
//! Incoming HTTP Responses are represented as a struct containing a `Reader` over
//! a `NetworkStream` and contain headers, a status, and an http version. They
//! implement `Reader` and can be read to get the data out of a `Response`.
//!

extern crate rustc_serialize as serialize;
extern crate time;
extern crate url;
extern crate openssl;
extern crate cookie;
extern crate unicase;
extern crate httparse;
extern crate num_cpus;

#[macro_use]
extern crate log;

#[cfg(test)]
extern crate test;

pub use mimewrapper::mime;
pub use url::Url;
pub use client::Client;
pub use error::{HttpResult, HttpError};
pub use method::Method::{Get, Head, Post, Delete};
pub use status::StatusCode::{Ok, BadRequest, NotFound};
pub use server::Server;

macro_rules! todo(
    ($($arg:tt)*) => (if cfg!(not(ndebug)) {
        trace!("TODO: {:?}", format_args!($($arg)*))
    })
);

macro_rules! inspect(
    ($name:expr, $value:expr) => ({
        let v = $value;
        trace!("inspect: {:?} = {:?}", $name, v);
        v
    })
);

#[cfg(test)]
#[macro_use]
mod mock;
#[doc(hidden)]
pub mod buffer;
pub mod client;
pub mod error;
pub mod method;
pub mod header;
pub mod http;
pub mod net;
pub mod server;
pub mod status;
pub mod uri;
pub mod version;

mod mimewrapper {
    /// Re-exporting the mime crate, for convenience.
    extern crate mime;
}

#[allow(unconditional_recursion)]
fn _assert_send<T: Send>() {
    _assert_send::<client::Request<net::Fresh>>();
    _assert_send::<client::Response>();
}
<|endoftext|>


<commit_before><commit_msg>result chaining<commit_after><|endoftext|>


<commit_before><commit_msg>Add a reference to an EntryTable as a parameter to Archive::read_secret_data<commit_after><|endoftext|>


<commit_before><commit_msg>A few lints.<commit_after><|endoftext|>


<commit_before>//! Simple time handling.
//!
//! ![MSRV 1.38.0](https://img.shields.io/badge/MSRV-1.38.0-red)
//!
//! # Features
//!
//! ## `#![no_std]`
//!
//! Currently, all structs except `Instant` are useable wiht `#![no_std]`. As
//! support for the standard library is enabled by default, you muse use
//! `default_features = false` in your `Cargo.toml` to enable this.
//!
//! ```none
//! [dependencies]
//! time = { version = "0.2", default-features = false }
//! ```
//!
//! Of the structs that are useable, some methods may only be enabled due a
//! reliance on `Instant`. These will be documented alongside the method.
//!
//! ## Serde
//!
//! [Serde](https://github.com/serde-rs/serde) support is behind a feature flag.
//! To enable it, use the `serialization` feature. This is not enabled by
//! default. It _is_ compatible with `#![no_std]`, so long as an allocator is
//! present.
//!
//! ```none
//! [dependencies]
//! time = { version = "0.2", features = ["serialization"] }
//! ```

#![cfg_attr(not(feature = "std"), no_std)]
#![deny(
    anonymous_parameters,
    rust_2018_idioms,
    trivial_casts,
    trivial_numeric_casts,
    unreachable_pub,
    unsafe_code,
    const_err,
    illegal_floating_point_literal_pattern,
    late_bound_lifetime_arguments,
    path_statements,
    patterns_in_fns_without_body,
    clippy::all
)]
#![warn(
    unused_extern_crates,
    box_pointers,
    missing_copy_implementations,
    missing_debug_implementations,
    single_use_lifetimes,
    unused_qualifications,
    variant_size_differences,
    clippy::pedantic,
    clippy::nursery,
    clippy::missing_docs_in_private_items
)]
#![allow(
    clippy::suspicious_arithmetic_impl,
    clippy::inline_always,
    // TODO Change to `warn` once rust-lang/rust-clippy#4605 is resolved.
    clippy::cast_sign_loss,
    clippy::cast_possible_wrap,
    clippy::cast_lossless,
)]

// Include the `format!` macro in `#![no_std]` environments.
#[macro_use]
extern crate alloc;

macro_rules! format_conditional {
    ($conditional:ident) => {
        format!(concat!(stringify!($conditional), "={}"), $conditional)
    };

    ($first_conditional:ident, $($conditional:ident),*) => {{
        let mut s = alloc::string::String::new();
        s.push_str(&format_conditional!($first_conditional));
        $(s.push_str(&format!(concat!(", ", stringify!($conditional), "={}"), $conditional));)*
        s
    }}
}

macro_rules! assert_value_in_range {
    ($value:ident in $start:expr => $end:expr) => {
        if !($start..=$end).contains(&$value) {
            panic!(
                concat!(stringify!($value), " must be in the range {}..={}"),
                $start,
                $end,
            );
        }
    };

    ($value:ident in $start:expr => exclusive $end:expr) => {
        if !($start..$end).contains(&$value) {
            panic!(
                concat!(stringify!($value), " must be in the range {}..{}"),
                $start,
                $end,
            );
        }
    };

    ($value:ident in $start:expr => $end:expr, given $($conditional:ident),+ $(,)?) => {
        if !($start..=$end).contains(&$value) {
            panic!(
                concat!(stringify!($value), " must be in the range {}..={} given{}"),
                $start,
                $end,
                &format_conditional!($($conditional),+)
            );
        };
    };
}

/// The `Date` struct and its associated `impl`s.
mod date;
/// The `DateTime` struct and its associated `impl`s.
mod date_time;
/// The `Duration` struct and its associated `impl`s.
mod duration;
/// The `Instant` struct and its associated `impl`s.
#[cfg(feature = "std")]
mod instant;
/// A collection of traits extending built-in numerical types.
mod numerical_traits;
/// The `OffsetDateTime` struct and its associated `impl`s.
mod offset_date_time;
/// Ensure certain methods are present on all types.
mod shim;
/// The `Sign` struct and its associated `impl`s.
mod sign;
/// The `Time` struct and its associated `impl`s.
mod time;
/// The `UtcOffset` struct and its associated `impl`s.
mod utc_offset;
/// Days of the week.
mod weekday;

pub use self::time::Time;
use core::fmt;
pub use date::{days_in_year, is_leap_year, weeks_in_year, Date};
pub use date_time::DateTime;
pub use duration::Duration;
#[cfg(feature = "std")]
pub use instant::Instant;
pub use numerical_traits::NumericalDuration;
pub use offset_date_time::OffsetDateTime;
pub(crate) use shim::NumberExt;
pub use sign::Sign;
pub use utc_offset::UtcOffset;
pub use weekday::Weekday;

/// A collection of traits (and possibly types, enums, etc.) that are useful to
/// import. Unlike the standard library, this must be explicitly included.
///
/// ```rust,no_run
/// use time::prelude::*;
/// ```
///
/// The prelude may grow in minor releases. Any removals will only occur in
/// major releases.
pub mod prelude {
    pub use crate::NumericalDuration;
}

/// An error type indicating that a conversion failed because the target type
/// could not store the initial value.
///
/// ```rust
/// # use time::{Duration, OutOfRangeError};
/// # use core::time::Duration as StdDuration;
/// # use core::{any::Any, convert::TryFrom};
/// // "Construct" an `OutOfRangeError`.
/// let error = StdDuration::try_from(Duration::seconds(-1)).unwrap_err();
/// assert!(Any::is::<OutOfRangeError>(&error));
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct OutOfRangeError {
    /// Include zero-sized field so users can't construct this explicitly. This
    /// ensures forwards-compatibility, as anyone matching on this type has to
    /// explicitly discard the fields.
    unused: (),
}

impl OutOfRangeError {
    /// Create an new `OutOfRangeError`.
    pub(crate) const fn new() -> Self {
        Self { unused: () }
    }
}

impl fmt::Display for OutOfRangeError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::fmt::Result {
        f.write_str("Source value is out of range for the target type")
    }
}

#[cfg(feature = "std")]
impl std::error::Error for OutOfRangeError {}

// For some back-compatibility, we're also implementing some deprecated types.

#[cfg(feature = "std")]
#[allow(clippy::missing_docs_in_private_items)]
#[deprecated(since = "0.2.0", note = "Use `Instant`")]
pub type PreciseTime = Instant;

#[cfg(feature = "std")]
#[allow(clippy::missing_docs_in_private_items)]
#[deprecated(since = "0.2.0", note = "Use `Instant`")]
pub type SteadyTime = Instant;
<commit_msg>Add given value in error message<commit_after>//! Simple time handling.
//!
//! ![MSRV 1.38.0](https://img.shields.io/badge/MSRV-1.38.0-red)
//!
//! # Features
//!
//! ## `#![no_std]`
//!
//! Currently, all structs except `Instant` are useable wiht `#![no_std]`. As
//! support for the standard library is enabled by default, you muse use
//! `default_features = false` in your `Cargo.toml` to enable this.
//!
//! ```none
//! [dependencies]
//! time = { version = "0.2", default-features = false }
//! ```
//!
//! Of the structs that are useable, some methods may only be enabled due a
//! reliance on `Instant`. These will be documented alongside the method.
//!
//! ## Serde
//!
//! [Serde](https://github.com/serde-rs/serde) support is behind a feature flag.
//! To enable it, use the `serialization` feature. This is not enabled by
//! default. It _is_ compatible with `#![no_std]`, so long as an allocator is
//! present.
//!
//! ```none
//! [dependencies]
//! time = { version = "0.2", features = ["serialization"] }
//! ```

#![cfg_attr(not(feature = "std"), no_std)]
#![deny(
    anonymous_parameters,
    rust_2018_idioms,
    trivial_casts,
    trivial_numeric_casts,
    unreachable_pub,
    unsafe_code,
    const_err,
    illegal_floating_point_literal_pattern,
    late_bound_lifetime_arguments,
    path_statements,
    patterns_in_fns_without_body,
    clippy::all
)]
#![warn(
    unused_extern_crates,
    box_pointers,
    missing_copy_implementations,
    missing_debug_implementations,
    single_use_lifetimes,
    unused_qualifications,
    variant_size_differences,
    clippy::pedantic,
    clippy::nursery,
    clippy::missing_docs_in_private_items
)]
#![allow(
    clippy::suspicious_arithmetic_impl,
    clippy::inline_always,
    // TODO Change to `warn` once rust-lang/rust-clippy#4605 is resolved.
    clippy::cast_sign_loss,
    clippy::cast_possible_wrap,
    clippy::cast_lossless,
)]

// Include the `format!` macro in `#![no_std]` environments.
#[macro_use]
extern crate alloc;

macro_rules! format_conditional {
    ($conditional:ident) => {
        format!(concat!(stringify!($conditional), "={}"), $conditional)
    };

    ($first_conditional:ident, $($conditional:ident),*) => {{
        let mut s = alloc::string::String::new();
        s.push_str(&format_conditional!($first_conditional));
        $(s.push_str(&format!(concat!(", ", stringify!($conditional), "={}"), $conditional));)*
        s
    }}
}

macro_rules! assert_value_in_range {
    ($value:ident in $start:expr => $end:expr) => {
        if !($start..=$end).contains(&$value) {
            panic!(
                concat!(stringify!($value), " must be in the range {}..={} (was {})"),
                $start,
                $end,
                $value,
            );
        }
    };

    ($value:ident in $start:expr => exclusive $end:expr) => {
        if !($start..$end).contains(&$value) {
            panic!(
                concat!(stringify!($value), " must be in the range {}..{} (was {})"),
                $start,
                $end,
                $value,
            );
        }
    };

    ($value:ident in $start:expr => $end:expr, given $($conditional:ident),+ $(,)?) => {
        if !($start..=$end).contains(&$value) {
            panic!(
                concat!(stringify!($value), " must be in the range {}..={} given{} (was {})"),
                $start,
                $end,
                &format_conditional!($($conditional),+),
                $value,
            );
        };
    };
}

/// The `Date` struct and its associated `impl`s.
mod date;
/// The `DateTime` struct and its associated `impl`s.
mod date_time;
/// The `Duration` struct and its associated `impl`s.
mod duration;
/// The `Instant` struct and its associated `impl`s.
#[cfg(feature = "std")]
mod instant;
/// A collection of traits extending built-in numerical types.
mod numerical_traits;
/// The `OffsetDateTime` struct and its associated `impl`s.
mod offset_date_time;
/// Ensure certain methods are present on all types.
mod shim;
/// The `Sign` struct and its associated `impl`s.
mod sign;
/// The `Time` struct and its associated `impl`s.
mod time;
/// The `UtcOffset` struct and its associated `impl`s.
mod utc_offset;
/// Days of the week.
mod weekday;

pub use self::time::Time;
use core::fmt;
pub use date::{days_in_year, is_leap_year, weeks_in_year, Date};
pub use date_time::DateTime;
pub use duration::Duration;
#[cfg(feature = "std")]
pub use instant::Instant;
pub use numerical_traits::NumericalDuration;
pub use offset_date_time::OffsetDateTime;
pub(crate) use shim::NumberExt;
pub use sign::Sign;
pub use utc_offset::UtcOffset;
pub use weekday::Weekday;

/// A collection of traits (and possibly types, enums, etc.) that are useful to
/// import. Unlike the standard library, this must be explicitly included.
///
/// ```rust,no_run
/// use time::prelude::*;
/// ```
///
/// The prelude may grow in minor releases. Any removals will only occur in
/// major releases.
pub mod prelude {
    pub use crate::NumericalDuration;
}

/// An error type indicating that a conversion failed because the target type
/// could not store the initial value.
///
/// ```rust
/// # use time::{Duration, OutOfRangeError};
/// # use core::time::Duration as StdDuration;
/// # use core::{any::Any, convert::TryFrom};
/// // "Construct" an `OutOfRangeError`.
/// let error = StdDuration::try_from(Duration::seconds(-1)).unwrap_err();
/// assert!(Any::is::<OutOfRangeError>(&error));
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct OutOfRangeError {
    /// Include zero-sized field so users can't construct this explicitly. This
    /// ensures forwards-compatibility, as anyone matching on this type has to
    /// explicitly discard the fields.
    unused: (),
}

impl OutOfRangeError {
    /// Create an new `OutOfRangeError`.
    pub(crate) const fn new() -> Self {
        Self { unused: () }
    }
}

impl fmt::Display for OutOfRangeError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::fmt::Result {
        f.write_str("Source value is out of range for the target type")
    }
}

#[cfg(feature = "std")]
impl std::error::Error for OutOfRangeError {}

// For some back-compatibility, we're also implementing some deprecated types.

#[cfg(feature = "std")]
#[allow(clippy::missing_docs_in_private_items)]
#[deprecated(since = "0.2.0", note = "Use `Instant`")]
pub type PreciseTime = Instant;

#[cfg(feature = "std")]
#[allow(clippy::missing_docs_in_private_items)]
#[deprecated(since = "0.2.0", note = "Use `Instant`")]
pub type SteadyTime = Instant;
<|endoftext|>


<commit_before>#![feature(io)]
#![feature(path)]
#![feature(fs)]
#![feature(collections)]
#![feature(core)]

use std::fs::{File};
use std::string::String;
use std::str::StrExt;
use std::path::AsPath;
use std::error::FromError;
use std::io::{Read, BufReader, Write};
use std::vec::Vec;
use std::num::ParseIntError;
use std::mem;

pub enum Error {
    IO,
    Parse,
    DataType,
    FieldType,
    Malformed,
    NotImplemented
}

impl FromError<std::io::Error> for Error {
    fn from_error(_: std::io::Error) -> Error {
        Error::IO
    }
}

impl FromError<ParseIntError> for Error {
    fn from_error(_: ParseIntError) -> Error {
        Error::Parse
    }
}

pub enum DataType {
    XDRFloat,
    FloatLE,
}

impl DataType {
    fn from_str(s: &str) -> Result<DataType, Error> {
        match s {
            "float_le" => Ok(DataType::FloatLE),
//            "xdr_float" => Ok(DataType::XDRFloat),
            _ => Err(Error::DataType)
        }
    }
}

pub enum FieldType {
    Uniform
}

impl FieldType {
    fn from_str(s: &str) -> Result<FieldType, Error> {
        match s {
            "uniform" => Ok(FieldType::Uniform),
            _ => Err(Error::FieldType)
        }
    }
}

pub struct AVSFile<'a> {
    pub ndim: usize,
    pub sizes: Vec<usize>,
    pub data_type: DataType,
    pub field_type: FieldType,
    reader: Box<Read + 'a>
}

impl<'a> AVSFile<'a> {
    pub fn write<W: Write, T>(
                writer: &mut W, ndim: usize, dims: &[usize], data: &[T])
                    -> Result<(), Error> {
        // header
        try!(writer.write_fmt(format_args!("# AVS FLD file (written by avsfldrs github.com/greyhill/avsfldrs)\n")));
        try!(writer.write_fmt(format_args!("ndim={}\n", ndim)));
        try!(writer.write_fmt(format_args!("veclen=1\n")));
        try!(writer.write_fmt(format_args!("nspace={}\n", ndim)));
        try!(writer.write_fmt(format_args!("field=uniform\n")));
        try!(writer.write_fmt(format_args!("data=float_le\n"))); // TODO
        for (id, size) in dims.iter().enumerate() {
            try!(writer.write_fmt(format_args!("dim{}={}\n", id+1, size)));
        }
        try!(writer.write_fmt(format_args!("{}{}", 12 as char, 12 as char)));
        let b: &[u8] = unsafe {
            std::slice::from_raw_parts(data.as_ptr() as *const u8,
                                       data.len()*mem::size_of::<T>())
        };
        try!(writer.write_all(b));
        Ok(())
    }

    pub fn read<T>(self: &mut Self) -> Result<Box<[T]>, Error> {
        let size = self.sizes.iter().fold(1 as usize, |l, r| l * *r);
        let mut buf_u8 = Vec::<u8>::with_capacity(mem::size_of::<T>()*size);
        try!(self.reader.read_to_end(&mut buf_u8));
        let buf: Vec<T> = unsafe { mem::transmute(buf_u8) };
        Ok(buf.into_boxed_slice())
    }

    pub fn open<P: AsPath>(path: &P) -> Result<AVSFile, Error> {
        let mut reader = BufReader::new(try!(File::open(path)));

        let mut ndim: Option<usize> = None;
        let mut sizes = Vec::<Option<usize>>::new();
        let mut data_type: Option<DataType> = None;
        let mut field_type: Option<FieldType> = None;
        let mut external: Option<String> = None;

        let mut line = String::new();
        let mut last_char: u8 = 0;
        loop {
            let mut new_char_buf: [u8;1] = [ 0u8 ];
            try!(reader.read(&mut new_char_buf));

            // break on two chr 14s
            let new_char = new_char_buf[0];
            if (new_char, last_char) == (12u8, 12u8) {
                break;
            }
            last_char = new_char;

            line.push(new_char as char);

            // new line; process the line and discard
            if new_char == 10 {
                let tokens: Vec<&str> = line.split('=')
                    .map(|s| s.trim()).collect();
                match &tokens[..] {
                    ["ndim", s] => {
                        let nd = try!(s.parse::<usize>());
                        ndim = Some(nd);
                        for _ in 0..nd {
                            sizes.push(None);
                        }
                    },
                    ["dim1", s] => sizes[0] = Some(try!(s.parse::<usize>())),
                    ["dim2", s] => sizes[1] = Some(try!(s.parse::<usize>())),
                    ["dim3", s] => sizes[2] = Some(try!(s.parse::<usize>())),
                    ["dim4", s] => sizes[2] = Some(try!(s.parse::<usize>())),
                    ["dim5", s] => sizes[2] = Some(try!(s.parse::<usize>())),
                    ["dim6", s] => sizes[2] = Some(try!(s.parse::<usize>())),
                    ["dim7", s] => sizes[2] = Some(try!(s.parse::<usize>())),
                    ["data", s] =>
                        data_type = Some(try!(DataType::from_str(s))),
                    ["field", s] =>
                        field_type = Some(try!(FieldType::from_str(s))),
                    ["variable 1 file", s] =>
                        external = Some(String::from_str(s)),
                    _ => {}
                }
            }
            // hack?  code smell?  need borrow in previous block to expire
            if new_char == 10 {
                line.clear();
            }
        }

        match external {
            None => {
                let mut tr = AVSFile {
                    ndim: try!(ndim.ok_or(Error::Malformed)),
                    sizes: Vec::<usize>::new(),
                    data_type: try!(data_type.ok_or(Error::Malformed)),
                    field_type: try!(field_type.ok_or(Error::Malformed)),
                    reader: Box::new(reader),
                };
                for idx in 0..ndim.unwrap() {
                    tr.sizes.push(
                        try!(sizes[idx].ok_or(Error::Malformed)));
                }
                Ok(tr)
            },
            Some(path) => {
                let new_reader = BufReader::new(try!(File::open(&path)));
                let mut tr = AVSFile {
                    ndim: try!(ndim.ok_or(Error::Malformed)),
                    sizes: Vec::<usize>::new(),
                    data_type: try!(data_type.ok_or(Error::Malformed)),
                    field_type: try!(field_type.ok_or(Error::Malformed)),
                    reader: Box::new(new_reader),
                };
                for idx in 0..ndim.unwrap() {
                    tr.sizes.push(
                        try!(sizes[idx].ok_or(Error::Malformed)));
                }
                Ok(tr)
            },
        }
    }
}

<commit_msg>return a vec from read(), not a boxed array<commit_after>#![feature(io)]
#![feature(path)]
#![feature(fs)]
#![feature(collections)]
#![feature(core)]

use std::fs::{File};
use std::string::String;
use std::str::StrExt;
use std::path::AsPath;
use std::error::FromError;
use std::io::{Read, BufReader, Write};
use std::vec::Vec;
use std::num::ParseIntError;
use std::mem;

#[derive(Debug)]
pub enum Error {
    IO,
    Parse,
    DataType,
    FieldType,
    Malformed,
    NotImplemented
}

impl FromError<std::io::Error> for Error {
    fn from_error(_: std::io::Error) -> Error {
        Error::IO
    }
}

impl FromError<ParseIntError> for Error {
    fn from_error(_: ParseIntError) -> Error {
        Error::Parse
    }
}

#[derive(Debug)]
pub enum DataType {
    XDRFloat,
    FloatLE,
}

impl DataType {
    fn from_str(s: &str) -> Result<DataType, Error> {
        match s {
            "float_le" => Ok(DataType::FloatLE),
//            "xdr_float" => Ok(DataType::XDRFloat),
            _ => Err(Error::DataType)
        }
    }
}

#[derive(Debug)]
pub enum FieldType {
    Uniform
}

impl FieldType {
    fn from_str(s: &str) -> Result<FieldType, Error> {
        match s {
            "uniform" => Ok(FieldType::Uniform),
            _ => Err(Error::FieldType)
        }
    }
}

pub struct AVSFile<'a> {
    pub ndim: usize,
    pub sizes: Vec<usize>,
    pub data_type: DataType,
    pub field_type: FieldType,
    reader: Box<Read + 'a>
}

impl<'a> AVSFile<'a> {
    pub fn write<W: Write, T>(
                writer: &mut W, ndim: usize, dims: &[usize], data: &[T])
                    -> Result<(), Error> {
        // header
        try!(writer.write_fmt(format_args!("# AVS FLD file (written by avsfldrs github.com/greyhill/avsfldrs)\n")));
        try!(writer.write_fmt(format_args!("ndim={}\n", ndim)));
        try!(writer.write_fmt(format_args!("veclen=1\n")));
        try!(writer.write_fmt(format_args!("nspace={}\n", ndim)));
        try!(writer.write_fmt(format_args!("field=uniform\n")));
        try!(writer.write_fmt(format_args!("data=float_le\n"))); // TODO
        for (id, size) in dims.iter().enumerate() {
            try!(writer.write_fmt(format_args!("dim{}={}\n", id+1, size)));
        }
        try!(writer.write_fmt(format_args!("{}{}", 12 as char, 12 as char)));
        let b: &[u8] = unsafe {
            std::slice::from_raw_parts(data.as_ptr() as *const u8,
                                       data.len()*mem::size_of::<T>())
        };
        try!(writer.write_all(b));
        Ok(())
    }

    pub fn read<T>(self: &mut Self) -> Result<Vec<T>, Error> {
        let size = self.sizes.iter().fold(1 as usize, |l, r| l * *r);
        let mut buf_u8 = Vec::<u8>::with_capacity(mem::size_of::<T>()*size);
        try!(self.reader.read_to_end(&mut buf_u8));
        let buf: Vec<T> = unsafe { mem::transmute(buf_u8) };
        Ok(buf)
    }

    pub fn open<P: AsPath>(path: &P) -> Result<AVSFile, Error> {
        let mut reader = BufReader::new(try!(File::open(path)));

        let mut ndim: Option<usize> = None;
        let mut sizes = Vec::<Option<usize>>::new();
        let mut data_type: Option<DataType> = None;
        let mut field_type: Option<FieldType> = None;
        let mut external: Option<String> = None;

        let mut line = String::new();
        let mut last_char: u8 = 0;
        loop {
            let mut new_char_buf: [u8;1] = [ 0u8 ];
            try!(reader.read(&mut new_char_buf));

            // break on two chr 14s
            let new_char = new_char_buf[0];
            if (new_char, last_char) == (12u8, 12u8) {
                break;
            }
            last_char = new_char;

            line.push(new_char as char);

            // new line; process the line and discard
            if new_char == 10 {
                let tokens: Vec<&str> = line.split('=')
                    .map(|s| s.trim()).collect();
                match &tokens[..] {
                    ["ndim", s] => {
                        let nd = try!(s.parse::<usize>());
                        ndim = Some(nd);
                        for _ in 0..nd {
                            sizes.push(None);
                        }
                    },
                    ["dim1", s] => sizes[0] = Some(try!(s.parse::<usize>())),
                    ["dim2", s] => sizes[1] = Some(try!(s.parse::<usize>())),
                    ["dim3", s] => sizes[2] = Some(try!(s.parse::<usize>())),
                    ["dim4", s] => sizes[2] = Some(try!(s.parse::<usize>())),
                    ["dim5", s] => sizes[2] = Some(try!(s.parse::<usize>())),
                    ["dim6", s] => sizes[2] = Some(try!(s.parse::<usize>())),
                    ["dim7", s] => sizes[2] = Some(try!(s.parse::<usize>())),
                    ["data", s] =>
                        data_type = Some(try!(DataType::from_str(s))),
                    ["field", s] =>
                        field_type = Some(try!(FieldType::from_str(s))),
                    ["variable 1 file", s] =>
                        external = Some(String::from_str(s)),
                    _ => {}
                }
            }
            // hack?  code smell?  need borrow in previous block to expire
            if new_char == 10 {
                line.clear();
            }
        }

        match external {
            None => {
                let mut tr = AVSFile {
                    ndim: try!(ndim.ok_or(Error::Malformed)),
                    sizes: Vec::<usize>::new(),
                    data_type: try!(data_type.ok_or(Error::Malformed)),
                    field_type: try!(field_type.ok_or(Error::Malformed)),
                    reader: Box::new(reader),
                };
                for idx in 0..ndim.unwrap() {
                    tr.sizes.push(
                        try!(sizes[idx].ok_or(Error::Malformed)));
                }
                Ok(tr)
            },
            Some(path) => {
                let new_reader = BufReader::new(try!(File::open(&path)));
                let mut tr = AVSFile {
                    ndim: try!(ndim.ok_or(Error::Malformed)),
                    sizes: Vec::<usize>::new(),
                    data_type: try!(data_type.ok_or(Error::Malformed)),
                    field_type: try!(field_type.ok_or(Error::Malformed)),
                    reader: Box::new(new_reader),
                };
                for idx in 0..ndim.unwrap() {
                    tr.sizes.push(
                        try!(sizes[idx].ok_or(Error::Malformed)));
                }
                Ok(tr)
            },
        }
    }
}

<|endoftext|>


<commit_before>extern crate base64;
extern crate chrono;
extern crate futures;
extern crate hyper;
extern crate hyper_tls;
extern crate jsonwebtoken as jwt;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate openssl;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate tokio_core;
extern crate url;

mod auth;
mod client;
pub mod svc;

pub use client::{GoogleCloudClient, Hub};
pub use client::{Error, ApiError, ErrorDetails, Result};
<commit_msg>expose auth token<commit_after>extern crate base64;
extern crate chrono;
extern crate futures;
extern crate hyper;
extern crate hyper_tls;
extern crate jsonwebtoken as jwt;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate openssl;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate tokio_core;
extern crate url;

mod auth;
mod client;
pub mod svc;

pub use client::{GoogleCloudClient, Hub};
pub use client::{Error, ApiError, ErrorDetails, Result};
pub use auth::Token as BearerToken;
<|endoftext|>


<commit_before>#![crate_name = "neovim"]
#![crate_type = "lib"]
#![crate_type = "rlib"]
#![allow(raw_pointer_derive)]

extern crate libc;

use std::ffi::CString;
use std::fmt;
use std::string::String;
use std::vec::Vec;

#[cfg(target_os="macos")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    #[link(name = "iconv")]
    extern{}
}

#[cfg(target_os="linux")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

#[cfg(target_os="windows")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

mod ffi;

pub enum Object {
    Buffer(ffi::C_Buffer),
    Window(ffi::C_Window),
    Tabpage(ffi::C_Tabpage),
    Boolean(ffi::C_Boolean),
    Integer(ffi::C_Integer),
    Float(ffi::C_Float),
    String(String),
    Array(ffi::C_Array),
    Dictionary(ffi::C_Dictionary),
}

impl fmt::Show for Object {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Object::Buffer(ref obj) => write!(f, "Buffer({:?})", obj),
            Object::Window(ref obj) => write!(f, "Window({:?})", obj),
            Object::Tabpage(ref obj) => write!(f, "Tabpage({:?})", obj),
            Object::Boolean(ref obj) => write!(f, "Boolean({:?})", obj),
            Object::Integer(ref obj) => write!(f, "Integer({:?})", obj),
            Object::Float(ref obj) => write!(f, "Float({:?})", obj),
            Object::String(ref obj) => write!(f, "String({:?})", obj),
            Object::Array(ref obj) => {
                write!(f, "Array(").ok();
                for i in range(0, obj.size) {
                    let inner_obj_opt = unsafe { c_object_to_object(obj.items.offset(i as isize)) };
                    if let Some(inner_obj) = inner_obj_opt {
                        write!(f, "{:?}", inner_obj).ok();
                        if i + 1 < obj.size {
                            write!(f, ", ").ok();
                        }
                    } else {
                        write!(f, "Nil ").ok();
                    }
                }
                write!(f, ")")
            },
            Object::Dictionary(ref obj) => write!(f, "Dictionary(Length: {:?})", obj.size),
        }
    }
}

unsafe fn c_object_to_object(obj: *mut ffi::C_Object) -> Option<Object> {
    match (*obj).object_type {
        ffi::ObjectType::BufferType =>
            Some(Object::Buffer((*(obj as *mut ffi::C_Object_Buffer)).data)),
        ffi::ObjectType::WindowType =>
            Some(Object::Window((*(obj as *mut ffi::C_Object_Window)).data)),
        ffi::ObjectType::TabpageType =>
            Some(Object::Tabpage((*(obj as *mut ffi::C_Object_Tabpage)).data)),
        ffi::ObjectType::NilType =>
            None,
        ffi::ObjectType::BooleanType =>
            Some(Object::Boolean((*(obj as *mut ffi::C_Object_Boolean)).data)),
        ffi::ObjectType::IntegerType =>
            Some(Object::Integer((*(obj as *mut ffi::C_Object_Integer)).data)),
        ffi::ObjectType::FloatType =>
            Some(Object::Float((*(obj as *mut ffi::C_Object_Float)).data)),
        ffi::ObjectType::StringType => {
            let vim_str: ffi::C_String = (*(obj as *mut ffi::C_Object_String)).data;
            let v = Vec::from_raw_buf(vim_str.data as *const u8, vim_str.size as usize);
            Some(Object::String(String::from_utf8_unchecked(v)))
        },
        ffi::ObjectType::ArrayType =>
            Some(Object::Array((*(obj as *mut ffi::C_Object_Array)).data)),
        ffi::ObjectType::DictionaryType =>
            Some(Object::Dictionary((*(obj as *mut ffi::C_Object_Dictionary)).data)),
    }
}

pub fn main_setup(args: Vec<String>) -> i32 {
    let v: Vec<CString> = args.iter().map(|s| CString::from_slice(s.as_bytes())).collect();
    let vp: Vec<*const ffi::c_char> = v.iter().map(|s| s.as_ptr()).collect();
    let p_vp: *const *const ffi::c_char = vp.as_ptr();

    unsafe { ffi::nvim_main_setup(vp.len() as i32, p_vp) }
}

pub fn main_loop() -> i32 {
    unsafe { ffi::nvim_main_loop() }
}

pub fn channel_from_fds(read_fd: i32, write_fd: i32) -> u64 {
    unsafe { ffi::channel_from_fds(read_fd, write_fd) }
}

pub fn serialize_message(id: u64, method: &'static str, args: &Array) -> String {
    unsafe {
        let buf = ffi::vim_msgpack_new();
        let vim_str = ffi::C_String {data: method.as_ptr() as *const i8, size: method.len() as u64};
        ffi::vim_serialize_request(id, vim_str, args.unwrap_value(), buf);
        let v = Vec::from_raw_buf((*buf).data as *const u8, (*buf).size as usize);
        ffi::vim_msgpack_free(buf);
        String::from_utf8_unchecked(v)
    }
}

pub fn deserialize_message(message: &String) -> Array {
    unsafe {
        let s = ffi::C_String {
            data: message.as_slice().as_ptr() as *const i8,
            size: message.len() as u64
        };
        let mut arr_raw = ffi::C_Array {
            items: ::std::ptr::null_mut(),
            size: 0,
            capacity: 0,
        };
        ffi::vim_msgpack_parse(s, &mut arr_raw);
        Array::wrap_value(arr_raw)
    }
}

pub struct Array {
    value: ffi::C_Array
}

impl Array {
    pub fn new() -> Array {
        Array {
            value: ffi::C_Array {
                items: ::std::ptr::null_mut(),
                size: 0,
                capacity: 0,
            }
        }
    }

    pub fn add_buffer(&mut self, val: ffi::C_Buffer) {
        unsafe { ffi::vim_array_add_buffer(val, &mut self.value) }
    }

    pub fn add_window(&mut self, val: ffi::C_Window) {
        unsafe { ffi::vim_array_add_window(val, &mut self.value) }
    }

    pub fn add_tabpage(&mut self, val: ffi::C_Tabpage) {
        unsafe { ffi::vim_array_add_tabpage(val, &mut self.value) }
    }

    pub fn add_nil(&mut self) {
        unsafe { ffi::vim_array_add_nil(&mut self.value) }
    }

    pub fn add_boolean(&mut self, val: ffi::C_Boolean) {
        unsafe { ffi::vim_array_add_boolean(val, &mut self.value) }
    }

    pub fn add_integer(&mut self, val: ffi::C_Integer) {
        unsafe { ffi::vim_array_add_integer(val, &mut self.value) }
    }

    pub fn add_float(&mut self, val: ffi::C_Float) {
        unsafe { ffi::vim_array_add_float(val, &mut self.value) }
    }

    pub fn add_string(&mut self, val: &str) {
        unsafe {
            // we need to copy the string into memory not managed by Rust,
            // so api_free_array can clear it
            let ptr = ffi::malloc(val.len() as u64);
            ::std::ptr::copy_memory(ptr, val.as_ptr() as *const ffi::c_void, val.len());
            let vim_str = ffi::C_String {data: ptr as *const i8, size: val.len() as u64};
            ffi::vim_array_add_string(vim_str, &mut self.value)
        }
    }

    pub fn add_array(&mut self, val: &Array) {
        unsafe { ffi::vim_array_add_array(val.unwrap_value(), &mut self.value) }
    }

    pub fn add_dictionary(&mut self, val: ffi::C_Dictionary) {
        unsafe { ffi::vim_array_add_dictionary(val, &mut self.value) }
    }

    pub fn get(&self, index: u64) -> Option<Object> {
        if index >= self.len() || index < 0 {
            return None;
        }
        unsafe { c_object_to_object(self.value.items.offset(index as isize)) }
    }

    pub fn len(&self) -> u64 {
        self.value.size
    }

    #[doc(hidden)]
    pub fn unwrap_value(&self) -> ffi::C_Array {
        self.value
    }

    #[doc(hidden)]
    pub fn wrap_value(c_array: ffi::C_Array) -> Array {
        Array {
            value: c_array
        }
    }
}

impl Drop for Array {
    fn drop(&mut self) {
        unsafe { ffi::api_free_array(self.value) };
    }
}

impl fmt::Show for Array {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Array(").ok();
        for i in range(0, self.len()) {
            if let Some(obj) = self.get(i) {
                write!(f, "{:?}", obj).ok();
            } else {
                write!(f, "Nil").ok();
            }
            if i + 1 < self.len() {
                write!(f, ", ").ok();
            }
        }
        write!(f, ")")
    }
}

#[test]
fn test_request() {
    let mut args = Array::new();
    args.add_integer(80);
    args.add_integer(24);
    args.add_string("hello");

    let msg = serialize_message(1, "attach_ui", &args);
    let arr = deserialize_message(&msg);
    println!("LENGTH: {}", arr.len());
    for i in range(0, arr.len()) {
        println!("{:?}", arr.get(i));
    }
}
<commit_msg>Reduce size of unsafe block<commit_after>#![crate_name = "neovim"]
#![crate_type = "lib"]
#![crate_type = "rlib"]
#![allow(raw_pointer_derive)]

extern crate libc;

use std::ffi::CString;
use std::fmt;
use std::string::String;
use std::vec::Vec;

#[cfg(target_os="macos")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    #[link(name = "iconv")]
    extern{}
}

#[cfg(target_os="linux")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

#[cfg(target_os="windows")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

mod ffi;

pub enum Object {
    Buffer(ffi::C_Buffer),
    Window(ffi::C_Window),
    Tabpage(ffi::C_Tabpage),
    Boolean(ffi::C_Boolean),
    Integer(ffi::C_Integer),
    Float(ffi::C_Float),
    String(String),
    Array(ffi::C_Array),
    Dictionary(ffi::C_Dictionary),
}

impl fmt::Show for Object {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Object::Buffer(ref obj) => write!(f, "Buffer({:?})", obj),
            Object::Window(ref obj) => write!(f, "Window({:?})", obj),
            Object::Tabpage(ref obj) => write!(f, "Tabpage({:?})", obj),
            Object::Boolean(ref obj) => write!(f, "Boolean({:?})", obj),
            Object::Integer(ref obj) => write!(f, "Integer({:?})", obj),
            Object::Float(ref obj) => write!(f, "Float({:?})", obj),
            Object::String(ref obj) => write!(f, "String({:?})", obj),
            Object::Array(ref obj) => {
                write!(f, "Array(").ok();
                for i in range(0, obj.size) {
                    let inner_obj_opt = unsafe { c_object_to_object(obj.items.offset(i as isize)) };
                    if let Some(inner_obj) = inner_obj_opt {
                        write!(f, "{:?}", inner_obj).ok();
                        if i + 1 < obj.size {
                            write!(f, ", ").ok();
                        }
                    } else {
                        write!(f, "Nil ").ok();
                    }
                }
                write!(f, ")")
            },
            Object::Dictionary(ref obj) => write!(f, "Dictionary(Length: {:?})", obj.size),
        }
    }
}

unsafe fn c_object_to_object(obj: *mut ffi::C_Object) -> Option<Object> {
    match (*obj).object_type {
        ffi::ObjectType::BufferType =>
            Some(Object::Buffer((*(obj as *mut ffi::C_Object_Buffer)).data)),
        ffi::ObjectType::WindowType =>
            Some(Object::Window((*(obj as *mut ffi::C_Object_Window)).data)),
        ffi::ObjectType::TabpageType =>
            Some(Object::Tabpage((*(obj as *mut ffi::C_Object_Tabpage)).data)),
        ffi::ObjectType::NilType =>
            None,
        ffi::ObjectType::BooleanType =>
            Some(Object::Boolean((*(obj as *mut ffi::C_Object_Boolean)).data)),
        ffi::ObjectType::IntegerType =>
            Some(Object::Integer((*(obj as *mut ffi::C_Object_Integer)).data)),
        ffi::ObjectType::FloatType =>
            Some(Object::Float((*(obj as *mut ffi::C_Object_Float)).data)),
        ffi::ObjectType::StringType => {
            let vim_str: ffi::C_String = (*(obj as *mut ffi::C_Object_String)).data;
            let v = Vec::from_raw_buf(vim_str.data as *const u8, vim_str.size as usize);
            Some(Object::String(String::from_utf8_unchecked(v)))
        },
        ffi::ObjectType::ArrayType =>
            Some(Object::Array((*(obj as *mut ffi::C_Object_Array)).data)),
        ffi::ObjectType::DictionaryType =>
            Some(Object::Dictionary((*(obj as *mut ffi::C_Object_Dictionary)).data)),
    }
}

pub fn main_setup(args: Vec<String>) -> i32 {
    let v: Vec<CString> = args.iter().map(|s| CString::from_slice(s.as_bytes())).collect();
    let vp: Vec<*const ffi::c_char> = v.iter().map(|s| s.as_ptr()).collect();
    let p_vp: *const *const ffi::c_char = vp.as_ptr();

    unsafe { ffi::nvim_main_setup(vp.len() as i32, p_vp) }
}

pub fn main_loop() -> i32 {
    unsafe { ffi::nvim_main_loop() }
}

pub fn channel_from_fds(read_fd: i32, write_fd: i32) -> u64 {
    unsafe { ffi::channel_from_fds(read_fd, write_fd) }
}

pub fn serialize_message(id: u64, method: &'static str, args: &Array) -> String {
    unsafe {
        let buf = ffi::vim_msgpack_new();
        let vim_str = ffi::C_String {data: method.as_ptr() as *const i8, size: method.len() as u64};
        ffi::vim_serialize_request(id, vim_str, args.unwrap_value(), buf);
        let v = Vec::from_raw_buf((*buf).data as *const u8, (*buf).size as usize);
        ffi::vim_msgpack_free(buf);
        String::from_utf8_unchecked(v)
    }
}

pub fn deserialize_message(message: &String) -> Array {
    let s = ffi::C_String {
        data: message.as_slice().as_ptr() as *const i8,
        size: message.len() as u64
    };
    let mut arr_raw = ffi::C_Array {
        items: ::std::ptr::null_mut(),
        size: 0,
        capacity: 0,
    };
    unsafe { ffi::vim_msgpack_parse(s, &mut arr_raw) };
    Array::wrap_value(arr_raw)
}

pub struct Array {
    value: ffi::C_Array
}

impl Array {
    pub fn new() -> Array {
        Array {
            value: ffi::C_Array {
                items: ::std::ptr::null_mut(),
                size: 0,
                capacity: 0,
            }
        }
    }

    pub fn add_buffer(&mut self, val: ffi::C_Buffer) {
        unsafe { ffi::vim_array_add_buffer(val, &mut self.value) }
    }

    pub fn add_window(&mut self, val: ffi::C_Window) {
        unsafe { ffi::vim_array_add_window(val, &mut self.value) }
    }

    pub fn add_tabpage(&mut self, val: ffi::C_Tabpage) {
        unsafe { ffi::vim_array_add_tabpage(val, &mut self.value) }
    }

    pub fn add_nil(&mut self) {
        unsafe { ffi::vim_array_add_nil(&mut self.value) }
    }

    pub fn add_boolean(&mut self, val: ffi::C_Boolean) {
        unsafe { ffi::vim_array_add_boolean(val, &mut self.value) }
    }

    pub fn add_integer(&mut self, val: ffi::C_Integer) {
        unsafe { ffi::vim_array_add_integer(val, &mut self.value) }
    }

    pub fn add_float(&mut self, val: ffi::C_Float) {
        unsafe { ffi::vim_array_add_float(val, &mut self.value) }
    }

    pub fn add_string(&mut self, val: &str) {
        unsafe {
            // we need to copy the string into memory not managed by Rust,
            // so api_free_array can clear it
            let ptr = ffi::malloc(val.len() as u64);
            ::std::ptr::copy_memory(ptr, val.as_ptr() as *const ffi::c_void, val.len());
            let vim_str = ffi::C_String {data: ptr as *const i8, size: val.len() as u64};
            ffi::vim_array_add_string(vim_str, &mut self.value)
        }
    }

    pub fn add_array(&mut self, val: &Array) {
        unsafe { ffi::vim_array_add_array(val.unwrap_value(), &mut self.value) }
    }

    pub fn add_dictionary(&mut self, val: ffi::C_Dictionary) {
        unsafe { ffi::vim_array_add_dictionary(val, &mut self.value) }
    }

    pub fn get(&self, index: u64) -> Option<Object> {
        if index >= self.len() || index < 0 {
            return None;
        }
        unsafe { c_object_to_object(self.value.items.offset(index as isize)) }
    }

    pub fn len(&self) -> u64 {
        self.value.size
    }

    #[doc(hidden)]
    pub fn unwrap_value(&self) -> ffi::C_Array {
        self.value
    }

    #[doc(hidden)]
    pub fn wrap_value(c_array: ffi::C_Array) -> Array {
        Array {
            value: c_array
        }
    }
}

impl Drop for Array {
    fn drop(&mut self) {
        unsafe { ffi::api_free_array(self.value) };
    }
}

impl fmt::Show for Array {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Array(").ok();
        for i in range(0, self.len()) {
            if let Some(obj) = self.get(i) {
                write!(f, "{:?}", obj).ok();
            } else {
                write!(f, "Nil").ok();
            }
            if i + 1 < self.len() {
                write!(f, ", ").ok();
            }
        }
        write!(f, ")")
    }
}

#[test]
fn test_request() {
    let mut args = Array::new();
    args.add_integer(80);
    args.add_integer(24);
    args.add_string("hello");

    let msg = serialize_message(1, "attach_ui", &args);
    let arr = deserialize_message(&msg);
    println!("LENGTH: {}", arr.len());
    for i in range(0, arr.len()) {
        println!("{:?}", arr.get(i));
    }
}
<|endoftext|>


<commit_before><commit_msg>Simplify run; we can use for loops with Fn now<commit_after><|endoftext|>


<commit_before><commit_msg>Issue 33 test case<commit_after>// issue #33: it prints this line and then hangs on the next one, hang time increases super-linearly with line length
impl ApplicationPreferenceseeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee {
}
<|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before><commit_msg>Add level filter test<commit_after>#[macro_use]
extern crate log;
extern crate simple_write_logger as logger;

use std::env::temp_dir;
use std::fs::{File, remove_file};
use std::io::{Read, stderr, stdout};

#[test]
fn level_filter() {
    let mut t = temp_dir();
    t.push("simple_write_logger.txt");
    let temp = t.to_str().unwrap();

    {
        let file = File::create(temp);
        assert!(file.is_ok());

        let writer = vec![logger::Writer(Box::new(file.unwrap()))];
        assert!(logger::init(writer, log::LogLevel::Info).is_ok());
    }

    debug!("DEBUG");

    {
        let file = File::open(temp);
        assert!(file.is_ok());

        let expect = "";
        let mut file_str = String::new();
        let _ = file.unwrap().read_to_string(&mut file_str);
        assert_eq!(file_str, expect);
    }

    assert!(remove_file(temp).is_ok());
}
<|endoftext|>


<commit_before><commit_msg>Add Cuboid and ::closest_interior_point<commit_after><|endoftext|>


<commit_before><commit_msg>argh, forgot to commit this<commit_after>use std::{ptr, slice};
use std::marker::PhantomData;
use std::mem;
use std;

#[repr(C)]
#[allow(raw_pointer_derive)]
#[derive(Copy, Clone)]
pub struct Buf<'a> {
    ptr: *mut u8,
    len: usize,
    marker: PhantomData<&'a ()>
}

impl<'a> Buf<'a> {
    pub unsafe fn uninitialized<'b>() -> Buf<'b> {
        Buf {
            ptr: mem::uninitialized(),
            len: mem::uninitialized(),
            marker: PhantomData
        }
    }

    pub fn wrap(s: &'a str) -> Buf<'a> {
        Buf {
            ptr: s.as_ptr() as *mut u8,
            len: s.len(),
            marker: PhantomData,
        }
    }

    // FIXME: this is not legit; can't use unchecked without making this method unsafe
    pub fn as_str(self) -> Option<&'a str> {
        if self.ptr == ptr::null_mut() {
            return None;
        }

        unsafe {
            let s = slice::from_raw_parts(self.ptr as *const u8, self.len);
            Some(std::str::from_utf8_unchecked(s))
        }
    }

    pub fn as_slice(&self) -> Option<&'a [u8]> {
        if self.ptr.is_null() {
            return None;
        }

        unsafe {
            Some(slice::from_raw_parts(self.ptr, self.len))
        }
    }

    pub fn as_mut_slice(&mut self) -> Option<&'a mut [u8]> {
        if self.ptr.is_null() {
            return None;
        }

        unsafe {
            Some(slice::from_raw_parts_mut(self.ptr, self.len))
        }
    }

    pub fn len(&self) -> usize {
        self.len
    }

    pub unsafe fn set_len(&mut self, len: usize) {
        self.len = len;
    }
}
<|endoftext|>


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

//! Library used by tidy and other tools
//!
//! This library contains the tidy lints and exposes it
//! to be used by tools.

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

use std::fs;

use std::path::Path;

macro_rules! t {
    ($e:expr, $p:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed on {} with {}", stringify!($e), ($p).display(), e),
    });

    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {}", stringify!($e), e),
    })
}

macro_rules! tidy_error {
    ($bad:expr, $fmt:expr, $($arg:tt)*) => ({
        *$bad = true;
        eprint!("tidy error: ");
        eprintln!($fmt, $($arg)*);
    });
}

pub mod bins;
pub mod style;
pub mod errors;
pub mod features;
pub mod cargo;
pub mod pal;
pub mod deps;
pub mod extdeps;
pub mod ui_tests;
pub mod unstable_book;
pub mod libcoretest;

fn filter_dirs(path: &Path) -> bool {
    let skip = [
        "src/dlmalloc",
        "src/jemalloc",
        "src/llvm",
        "src/llvm-emscripten",
        "src/libbacktrace",
        "src/libcompiler_builtins",
        "src/librustc_data_structures/owning_ref",
        "src/compiler-rt",
        "src/liblibc",
        "src/vendor",
        "src/rt/hoedown",
        "src/tools/cargo",
        "src/tools/clang",
        "src/tools/rls",
        "src/tools/clippy",
        "src/tools/rust-installer",
        "src/tools/rustfmt",
        "src/tools/miri",
        "src/tools/lld",
        "src/tools/lldb",
        "src/target",
        "src/stdsimd",
    ];
    skip.iter().any(|p| path.ends_with(p))
}

fn walk_many(paths: &[&Path], skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&Path)) {
    for path in paths {
        walk(path, skip, f);
    }
}

fn walk(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&Path)) {
    if let Ok(dir) = fs::read_dir(path) {
        for entry in dir {
            let entry = t!(entry);
            let kind = t!(entry.file_type());
            let path = entry.path();
            if kind.is_dir() {
                if !skip(&path) {
                    walk(&path, skip, f);
                }
            } else {
                f(&path);
            }
        }
    }
}
<commit_msg>ignore target folders<commit_after>// Copyright 2017 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.

//! Library used by tidy and other tools
//!
//! This library contains the tidy lints and exposes it
//! to be used by tools.

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

use std::fs;

use std::path::Path;

macro_rules! t {
    ($e:expr, $p:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed on {} with {}", stringify!($e), ($p).display(), e),
    });

    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {}", stringify!($e), e),
    })
}

macro_rules! tidy_error {
    ($bad:expr, $fmt:expr, $($arg:tt)*) => ({
        *$bad = true;
        eprint!("tidy error: ");
        eprintln!($fmt, $($arg)*);
    });
}

pub mod bins;
pub mod style;
pub mod errors;
pub mod features;
pub mod cargo;
pub mod pal;
pub mod deps;
pub mod extdeps;
pub mod ui_tests;
pub mod unstable_book;
pub mod libcoretest;

fn filter_dirs(path: &Path) -> bool {
    let skip = [
        "src/dlmalloc",
        "src/jemalloc",
        "src/llvm",
        "src/llvm-emscripten",
        "src/libbacktrace",
        "src/libcompiler_builtins",
        "src/librustc_data_structures/owning_ref",
        "src/compiler-rt",
        "src/liblibc",
        "src/vendor",
        "src/rt/hoedown",
        "src/tools/cargo",
        "src/tools/clang",
        "src/tools/rls",
        "src/tools/clippy",
        "src/tools/rust-installer",
        "src/tools/rustfmt",
        "src/tools/miri",
        "src/tools/lld",
        "src/tools/lldb",
        "src/target",
        "src/stdsimd",
        "target",
    ];
    skip.iter().any(|p| path.ends_with(p))
}

fn walk_many(paths: &[&Path], skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&Path)) {
    for path in paths {
        walk(path, skip, f);
    }
}

fn walk(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&Path)) {
    if let Ok(dir) = fs::read_dir(path) {
        for entry in dir {
            let entry = t!(entry);
            let kind = t!(entry.file_type());
            let path = entry.path();
            if kind.is_dir() {
                if !skip(&path) {
                    walk(&path, skip, f);
                }
            } else {
                f(&path);
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add support for fetching segments<commit_after>use resources::enums::ResourceState;
use resources::enums::ActivityType;
use error::Result;
use http;
use accesstoken::AccessToken;

/// A specific section(s) of road.
///
/// Segments are available in Summary and Detail versions.
#[derive(Debug, RustcDecodable)]
pub struct Segment {
    id: u32,
    resource_state: ResourceState,
    name: String,
    activity_type: ActivityType,
    distance: f32,
    average_grade: f32,
    maximum_grade: f32,
    elevation_high: f32,
    elevation_low: f32,
    start_latlng: Vec<f32>,
    end_latlng: Vec<f32>,
    climb_category: u8,
    city: String,
    state: String,
    country: String,
    private: bool,

    // Detail Attributes
    created_at: Option<String>,
    updated_at: Option<String>,
    total_elevation_gain: Option<f32>,
    // map: Option<Map>,
    effort_count: Option<u32>,
    athlete_count: Option<u32>,
    star_count: Option<u32>,
    hazardous: Option<bool>

}

impl Segment {
    pub fn get(token: &AccessToken, id: u32) -> Result<Segment> {
        let url = format!("https://www.strava.com/api/v3/segments/{}?access_token={}",
                          id, token.get());
        Ok(try!(http::get::<Segment>(&url[..])))
    }
}

#[cfg(feature = "api_test")]
#[cfg(test)]
mod api_tests {
    use super::Segment;
    use accesstoken::AccessToken;

    #[test]
    fn get_segment() {
        let token = AccessToken::new_from_env().unwrap();
        let segment = Segment::get(&token, 646257).unwrap();

        println!("{:?}", segment);
    }
}
<|endoftext|>