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

//! Standard library macros
//!
//! This modules contains a set of macros which are exported from the standard
//! library. Each macro is available for use when linking against the standard
//! library.

#![unstable(feature = "std_misc")]

/// The entry point for panic of Rust tasks.
///
/// This macro is used to inject panic into a Rust task, causing the task to
/// unwind and panic entirely. Each task's panic can be reaped as the
/// `Box<Any>` type, and the single-argument form of the `panic!` macro will be
/// the value which is transmitted.
///
/// The multi-argument form of this macro panics with a string and has the
/// `format!` syntax for building a string.
///
/// # Examples
///
/// ```should_panic
/// # #![allow(unreachable_code)]
/// panic!();
/// panic!("this is a terrible mistake!");
/// panic!(4); // panic with the value of 4 to be collected elsewhere
/// panic!("this is a {} {message}", "fancy", message = "message");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! panic {
    () => ({
        panic!("explicit panic")
    });
    ($msg:expr) => ({
        $crate::rt::begin_unwind($msg, {
            // static requires less code at runtime, more constant data
            static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize);
            &_FILE_LINE
        })
    });
    ($fmt:expr, $($arg:tt)+) => ({
        $crate::rt::begin_unwind_fmt(format_args!($fmt, $($arg)+), {
            // The leading _'s are to avoid dead code warnings if this is
            // used inside a dead function. Just `#[allow(dead_code)]` is
            // insufficient, since the user may have
            // `#[forbid(dead_code)]` and which cannot be overridden.
            static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize);
            &_FILE_LINE
        })
    });
}

/// Macro for printing to the standard output.
///
/// Equivalent to the `println!` macro except that a newline is not printed at
/// the end of the message.
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable]
macro_rules! print {
    ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
}

/// Macro for printing to the standard output.
///
/// Use the `format!` syntax to write data to the standard output.
/// See `std::fmt` for more information.
///
/// # Examples
///
/// ```
/// println!("hello there!");
/// println!("format {} arguments", "some");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! println {
    ($fmt:expr) => (print!(concat!($fmt, "\n")));
    ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}

/// Helper macro for unwrapping `Result` values while returning early with an
/// error if the value of the expression is `Err`.
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! try {
    ($expr:expr) => (match $expr {
        $crate::result::Result::Ok(val) => val,
        $crate::result::Result::Err(err) => {
            return $crate::result::Result::Err($crate::error::FromError::from_error(err))
        }
    })
}

/// A macro to select an event from a number of receivers.
///
/// This macro is used to wait for the first event to occur on a number of
/// receivers. It places no restrictions on the types of receivers given to
/// this macro, this can be viewed as a heterogeneous select.
///
/// # Examples
///
/// ```
/// # #![feature(std_misc)]
/// use std::thread;
/// use std::sync::mpsc;
///
/// // two placeholder functions for now
/// fn long_running_task() {}
/// fn calculate_the_answer() -> u32 { 42 }
///
/// let (tx1, rx1) = mpsc::channel();
/// let (tx2, rx2) = mpsc::channel();
///
/// thread::spawn(move|| { long_running_task(); tx1.send(()).unwrap(); });
/// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
///
/// select! (
///     _ = rx1.recv() => println!("the long running task finished first"),
///     answer = rx2.recv() => {
///         println!("the answer was: {}", answer.unwrap());
///     }
/// )
/// ```
///
/// For more information about select, see the `std::sync::mpsc::Select` structure.
#[macro_export]
#[unstable(feature = "std_misc")]
macro_rules! select {
    (
        $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
    ) => ({
        use $crate::sync::mpsc::Select;
        let sel = Select::new();
        $( let mut $rx = sel.handle(&$rx); )+
        unsafe {
            $( $rx.add(); )+
        }
        let ret = sel.wait();
        $( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
        { unreachable!() }
    })
}

// When testing the standard library, we link to the liblog crate to get the
// logging macros. In doing so, the liblog crate was linked against the real
// version of libstd, and uses a different std::fmt module than the test crate
// uses. To get around this difference, we redefine the log!() macro here to be
// just a dumb version of what it should be.
#[cfg(test)]
macro_rules! log {
    ($lvl:expr, $($args:tt)*) => (
        if log_enabled!($lvl) { println!($($args)*) }
    )
}

/// Built-in macros to the compiler itself.
///
/// These macros do not have any corresponding definition with a `macro_rules!`
/// macro, but are documented here. Their implementations can be found hardcoded
/// into libsyntax itself.
#[cfg(dox)]
pub mod builtin {
    /// The core macro for formatted string creation & output.
    ///
    /// This macro produces a value of type `fmt::Arguments`. This value can be
    /// passed to the functions in `std::fmt` for performing useful functions.
    /// All other formatting macros (`format!`, `write!`, `println!`, etc) are
    /// proxied through this one.
    ///
    /// For more information, see the documentation in `std::fmt`.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::fmt;
    ///
    /// let s = fmt::format(format_args!("hello {}", "world"));
    /// assert_eq!(s, format!("hello {}", "world"));
    ///
    /// ```
    #[macro_export]
    macro_rules! format_args { ($fmt:expr, $($args:tt)*) => ({
        /* compiler built-in */
    }) }

    /// Inspect an environment variable at compile time.
    ///
    /// This macro will expand to the value of the named environment variable at
    /// compile time, yielding an expression of type `&'static str`.
    ///
    /// If the environment variable is not defined, then a compilation error
    /// will be emitted.  To not emit a compile error, use the `option_env!`
    /// macro instead.
    ///
    /// # Examples
    ///
    /// ```
    /// let path: &'static str = env!("PATH");
    /// println!("the $PATH variable at the time of compiling was: {}", path);
    /// ```
    #[macro_export]
    macro_rules! env { ($name:expr) => ({ /* compiler built-in */ }) }

    /// Optionally inspect an environment variable at compile time.
    ///
    /// If the named environment variable is present at compile time, this will
    /// expand into an expression of type `Option<&'static str>` whose value is
    /// `Some` of the value of the environment variable. If the environment
    /// variable is not present, then this will expand to `None`.
    ///
    /// A compile time error is never emitted when using this macro regardless
    /// of whether the environment variable is present or not.
    ///
    /// # Examples
    ///
    /// ```
    /// let key: Option<&'static str> = option_env!("SECRET_KEY");
    /// println!("the secret key might be: {:?}", key);
    /// ```
    #[macro_export]
    macro_rules! option_env { ($name:expr) => ({ /* compiler built-in */ }) }

    /// Concatenate identifiers into one identifier.
    ///
    /// This macro takes any number of comma-separated identifiers, and
    /// concatenates them all into one, yielding an expression which is a new
    /// identifier. Note that hygiene makes it such that this macro cannot
    /// capture local variables, and macros are only allowed in item,
    /// statement or expression position, meaning this macro may be difficult to
    /// use in some situations.
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(concat_idents)]
    ///
    /// # fn main() {
    /// fn foobar() -> u32 { 23 }
    ///
    /// let f = concat_idents!(foo, bar);
    /// println!("{}", f());
    /// # }
    /// ```
    #[macro_export]
    macro_rules! concat_idents {
        ($($e:ident),*) => ({ /* compiler built-in */ })
    }

    /// Concatenates literals into a static string slice.
    ///
    /// This macro takes any number of comma-separated literals, yielding an
    /// expression of type `&'static str` which represents all of the literals
    /// concatenated left-to-right.
    ///
    /// Integer and floating point literals are stringified in order to be
    /// concatenated.
    ///
    /// # Examples
    ///
    /// ```
    /// let s = concat!("test", 10, 'b', true);
    /// assert_eq!(s, "test10btrue");
    /// ```
    #[macro_export]
    macro_rules! concat { ($($e:expr),*) => ({ /* compiler built-in */ }) }

    /// A macro which expands to the line number on which it was invoked.
    ///
    /// The expanded expression has type `usize`, and the returned line is not
    /// the invocation of the `line!()` macro itself, but rather the first macro
    /// invocation leading up to the invocation of the `line!()` macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let current_line = line!();
    /// println!("defined on line: {}", current_line);
    /// ```
    #[macro_export]
    macro_rules! line { () => ({ /* compiler built-in */ }) }

    /// A macro which expands to the column number on which it was invoked.
    ///
    /// The expanded expression has type `usize`, and the returned column is not
    /// the invocation of the `column!()` macro itself, but rather the first macro
    /// invocation leading up to the invocation of the `column!()` macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let current_col = column!();
    /// println!("defined on column: {}", current_col);
    /// ```
    #[macro_export]
    macro_rules! column { () => ({ /* compiler built-in */ }) }

    /// A macro which expands to the file name from which it was invoked.
    ///
    /// The expanded expression has type `&'static str`, and the returned file
    /// is not the invocation of the `file!()` macro itself, but rather the
    /// first macro invocation leading up to the invocation of the `file!()`
    /// macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let this_file = file!();
    /// println!("defined in file: {}", this_file);
    /// ```
    #[macro_export]
    macro_rules! file { () => ({ /* compiler built-in */ }) }

    /// A macro which stringifies its argument.
    ///
    /// This macro will yield an expression of type `&'static str` which is the
    /// stringification of all the tokens passed to the macro. No restrictions
    /// are placed on the syntax of the macro invocation itself.
    ///
    /// # Examples
    ///
    /// ```
    /// let one_plus_one = stringify!(1 + 1);
    /// assert_eq!(one_plus_one, "1 + 1");
    /// ```
    #[macro_export]
    macro_rules! stringify { ($t:tt) => ({ /* compiler built-in */ }) }

    /// Includes a utf8-encoded file as a string.
    ///
    /// This macro will yield an expression of type `&'static str` which is the
    /// contents of the filename specified. The file is located relative to the
    /// current file (similarly to how modules are found),
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let secret_key = include_str!("secret-key.ascii");
    /// ```
    #[macro_export]
    macro_rules! include_str { ($file:expr) => ({ /* compiler built-in */ }) }

    /// Includes a file as a byte slice.
    ///
    /// This macro will yield an expression of type `&'static [u8]` which is
    /// the contents of the filename specified. The file is located relative to
    /// the current file (similarly to how modules are found),
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let secret_key = include_bytes!("secret-key.bin");
    /// ```
    #[macro_export]
    macro_rules! include_bytes { ($file:expr) => ({ /* compiler built-in */ }) }

    /// Expands to a string that represents the current module path.
    ///
    /// The current module path can be thought of as the hierarchy of modules
    /// leading back up to the crate root. The first component of the path
    /// returned is the name of the crate currently being compiled.
    ///
    /// # Examples
    ///
    /// ```
    /// mod test {
    ///     pub fn foo() {
    ///         assert!(module_path!().ends_with("test"));
    ///     }
    /// }
    ///
    /// test::foo();
    /// ```
    #[macro_export]
    macro_rules! module_path { () => ({ /* compiler built-in */ }) }

    /// Boolean evaluation of configuration flags.
    ///
    /// In addition to the `#[cfg]` attribute, this macro is provided to allow
    /// boolean expression evaluation of configuration flags. This frequently
    /// leads to less duplicated code.
    ///
    /// The syntax given to this macro is the same syntax as the `cfg`
    /// attribute.
    ///
    /// # Examples
    ///
    /// ```
    /// let my_directory = if cfg!(windows) {
    ///     "windows-specific-directory"
    /// } else {
    ///     "unix-directory"
    /// };
    /// ```
    #[macro_export]
    macro_rules! cfg { ($cfg:tt) => ({ /* compiler built-in */ }) }

    /// Parse the current given file as an expression.
    ///
    /// This is generally a bad idea, because it's going to behave unhygenically.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// fn foo() {
    ///     include!("/path/to/a/file")
    /// }
    /// ```
    #[macro_export]
    macro_rules! include { ($cfg:tt) => ({ /* compiler built-in */ }) }
}
<commit_msg>std: Add a note about the print! macro and output buffering<commit_after>// Copyright 2014 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.

//! Standard library macros
//!
//! This modules contains a set of macros which are exported from the standard
//! library. Each macro is available for use when linking against the standard
//! library.

#![unstable(feature = "std_misc")]

/// The entry point for panic of Rust tasks.
///
/// This macro is used to inject panic into a Rust task, causing the task to
/// unwind and panic entirely. Each task's panic can be reaped as the
/// `Box<Any>` type, and the single-argument form of the `panic!` macro will be
/// the value which is transmitted.
///
/// The multi-argument form of this macro panics with a string and has the
/// `format!` syntax for building a string.
///
/// # Examples
///
/// ```should_panic
/// # #![allow(unreachable_code)]
/// panic!();
/// panic!("this is a terrible mistake!");
/// panic!(4); // panic with the value of 4 to be collected elsewhere
/// panic!("this is a {} {message}", "fancy", message = "message");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! panic {
    () => ({
        panic!("explicit panic")
    });
    ($msg:expr) => ({
        $crate::rt::begin_unwind($msg, {
            // static requires less code at runtime, more constant data
            static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize);
            &_FILE_LINE
        })
    });
    ($fmt:expr, $($arg:tt)+) => ({
        $crate::rt::begin_unwind_fmt(format_args!($fmt, $($arg)+), {
            // The leading _'s are to avoid dead code warnings if this is
            // used inside a dead function. Just `#[allow(dead_code)]` is
            // insufficient, since the user may have
            // `#[forbid(dead_code)]` and which cannot be overridden.
            static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize);
            &_FILE_LINE
        })
    });
}

/// Macro for printing to the standard output.
///
/// Equivalent to the `println!` macro except that a newline is not printed at
/// the end of the message.
///
/// Note that stdout is frequently line-buffered by default so it may be
/// necessary to use `io::stdout().flush()` to ensure the output is emitted
/// immediately.
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable]
macro_rules! print {
    ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
}

/// Macro for printing to the standard output.
///
/// Use the `format!` syntax to write data to the standard output.
/// See `std::fmt` for more information.
///
/// # Examples
///
/// ```
/// println!("hello there!");
/// println!("format {} arguments", "some");
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! println {
    ($fmt:expr) => (print!(concat!($fmt, "\n")));
    ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}

/// Helper macro for unwrapping `Result` values while returning early with an
/// error if the value of the expression is `Err`.
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! try {
    ($expr:expr) => (match $expr {
        $crate::result::Result::Ok(val) => val,
        $crate::result::Result::Err(err) => {
            return $crate::result::Result::Err($crate::error::FromError::from_error(err))
        }
    })
}

/// A macro to select an event from a number of receivers.
///
/// This macro is used to wait for the first event to occur on a number of
/// receivers. It places no restrictions on the types of receivers given to
/// this macro, this can be viewed as a heterogeneous select.
///
/// # Examples
///
/// ```
/// # #![feature(std_misc)]
/// use std::thread;
/// use std::sync::mpsc;
///
/// // two placeholder functions for now
/// fn long_running_task() {}
/// fn calculate_the_answer() -> u32 { 42 }
///
/// let (tx1, rx1) = mpsc::channel();
/// let (tx2, rx2) = mpsc::channel();
///
/// thread::spawn(move|| { long_running_task(); tx1.send(()).unwrap(); });
/// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
///
/// select! (
///     _ = rx1.recv() => println!("the long running task finished first"),
///     answer = rx2.recv() => {
///         println!("the answer was: {}", answer.unwrap());
///     }
/// )
/// ```
///
/// For more information about select, see the `std::sync::mpsc::Select` structure.
#[macro_export]
#[unstable(feature = "std_misc")]
macro_rules! select {
    (
        $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
    ) => ({
        use $crate::sync::mpsc::Select;
        let sel = Select::new();
        $( let mut $rx = sel.handle(&$rx); )+
        unsafe {
            $( $rx.add(); )+
        }
        let ret = sel.wait();
        $( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
        { unreachable!() }
    })
}

// When testing the standard library, we link to the liblog crate to get the
// logging macros. In doing so, the liblog crate was linked against the real
// version of libstd, and uses a different std::fmt module than the test crate
// uses. To get around this difference, we redefine the log!() macro here to be
// just a dumb version of what it should be.
#[cfg(test)]
macro_rules! log {
    ($lvl:expr, $($args:tt)*) => (
        if log_enabled!($lvl) { println!($($args)*) }
    )
}

/// Built-in macros to the compiler itself.
///
/// These macros do not have any corresponding definition with a `macro_rules!`
/// macro, but are documented here. Their implementations can be found hardcoded
/// into libsyntax itself.
#[cfg(dox)]
pub mod builtin {
    /// The core macro for formatted string creation & output.
    ///
    /// This macro produces a value of type `fmt::Arguments`. This value can be
    /// passed to the functions in `std::fmt` for performing useful functions.
    /// All other formatting macros (`format!`, `write!`, `println!`, etc) are
    /// proxied through this one.
    ///
    /// For more information, see the documentation in `std::fmt`.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::fmt;
    ///
    /// let s = fmt::format(format_args!("hello {}", "world"));
    /// assert_eq!(s, format!("hello {}", "world"));
    ///
    /// ```
    #[macro_export]
    macro_rules! format_args { ($fmt:expr, $($args:tt)*) => ({
        /* compiler built-in */
    }) }

    /// Inspect an environment variable at compile time.
    ///
    /// This macro will expand to the value of the named environment variable at
    /// compile time, yielding an expression of type `&'static str`.
    ///
    /// If the environment variable is not defined, then a compilation error
    /// will be emitted.  To not emit a compile error, use the `option_env!`
    /// macro instead.
    ///
    /// # Examples
    ///
    /// ```
    /// let path: &'static str = env!("PATH");
    /// println!("the $PATH variable at the time of compiling was: {}", path);
    /// ```
    #[macro_export]
    macro_rules! env { ($name:expr) => ({ /* compiler built-in */ }) }

    /// Optionally inspect an environment variable at compile time.
    ///
    /// If the named environment variable is present at compile time, this will
    /// expand into an expression of type `Option<&'static str>` whose value is
    /// `Some` of the value of the environment variable. If the environment
    /// variable is not present, then this will expand to `None`.
    ///
    /// A compile time error is never emitted when using this macro regardless
    /// of whether the environment variable is present or not.
    ///
    /// # Examples
    ///
    /// ```
    /// let key: Option<&'static str> = option_env!("SECRET_KEY");
    /// println!("the secret key might be: {:?}", key);
    /// ```
    #[macro_export]
    macro_rules! option_env { ($name:expr) => ({ /* compiler built-in */ }) }

    /// Concatenate identifiers into one identifier.
    ///
    /// This macro takes any number of comma-separated identifiers, and
    /// concatenates them all into one, yielding an expression which is a new
    /// identifier. Note that hygiene makes it such that this macro cannot
    /// capture local variables, and macros are only allowed in item,
    /// statement or expression position, meaning this macro may be difficult to
    /// use in some situations.
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(concat_idents)]
    ///
    /// # fn main() {
    /// fn foobar() -> u32 { 23 }
    ///
    /// let f = concat_idents!(foo, bar);
    /// println!("{}", f());
    /// # }
    /// ```
    #[macro_export]
    macro_rules! concat_idents {
        ($($e:ident),*) => ({ /* compiler built-in */ })
    }

    /// Concatenates literals into a static string slice.
    ///
    /// This macro takes any number of comma-separated literals, yielding an
    /// expression of type `&'static str` which represents all of the literals
    /// concatenated left-to-right.
    ///
    /// Integer and floating point literals are stringified in order to be
    /// concatenated.
    ///
    /// # Examples
    ///
    /// ```
    /// let s = concat!("test", 10, 'b', true);
    /// assert_eq!(s, "test10btrue");
    /// ```
    #[macro_export]
    macro_rules! concat { ($($e:expr),*) => ({ /* compiler built-in */ }) }

    /// A macro which expands to the line number on which it was invoked.
    ///
    /// The expanded expression has type `usize`, and the returned line is not
    /// the invocation of the `line!()` macro itself, but rather the first macro
    /// invocation leading up to the invocation of the `line!()` macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let current_line = line!();
    /// println!("defined on line: {}", current_line);
    /// ```
    #[macro_export]
    macro_rules! line { () => ({ /* compiler built-in */ }) }

    /// A macro which expands to the column number on which it was invoked.
    ///
    /// The expanded expression has type `usize`, and the returned column is not
    /// the invocation of the `column!()` macro itself, but rather the first macro
    /// invocation leading up to the invocation of the `column!()` macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let current_col = column!();
    /// println!("defined on column: {}", current_col);
    /// ```
    #[macro_export]
    macro_rules! column { () => ({ /* compiler built-in */ }) }

    /// A macro which expands to the file name from which it was invoked.
    ///
    /// The expanded expression has type `&'static str`, and the returned file
    /// is not the invocation of the `file!()` macro itself, but rather the
    /// first macro invocation leading up to the invocation of the `file!()`
    /// macro.
    ///
    /// # Examples
    ///
    /// ```
    /// let this_file = file!();
    /// println!("defined in file: {}", this_file);
    /// ```
    #[macro_export]
    macro_rules! file { () => ({ /* compiler built-in */ }) }

    /// A macro which stringifies its argument.
    ///
    /// This macro will yield an expression of type `&'static str` which is the
    /// stringification of all the tokens passed to the macro. No restrictions
    /// are placed on the syntax of the macro invocation itself.
    ///
    /// # Examples
    ///
    /// ```
    /// let one_plus_one = stringify!(1 + 1);
    /// assert_eq!(one_plus_one, "1 + 1");
    /// ```
    #[macro_export]
    macro_rules! stringify { ($t:tt) => ({ /* compiler built-in */ }) }

    /// Includes a utf8-encoded file as a string.
    ///
    /// This macro will yield an expression of type `&'static str` which is the
    /// contents of the filename specified. The file is located relative to the
    /// current file (similarly to how modules are found),
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let secret_key = include_str!("secret-key.ascii");
    /// ```
    #[macro_export]
    macro_rules! include_str { ($file:expr) => ({ /* compiler built-in */ }) }

    /// Includes a file as a byte slice.
    ///
    /// This macro will yield an expression of type `&'static [u8]` which is
    /// the contents of the filename specified. The file is located relative to
    /// the current file (similarly to how modules are found),
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let secret_key = include_bytes!("secret-key.bin");
    /// ```
    #[macro_export]
    macro_rules! include_bytes { ($file:expr) => ({ /* compiler built-in */ }) }

    /// Expands to a string that represents the current module path.
    ///
    /// The current module path can be thought of as the hierarchy of modules
    /// leading back up to the crate root. The first component of the path
    /// returned is the name of the crate currently being compiled.
    ///
    /// # Examples
    ///
    /// ```
    /// mod test {
    ///     pub fn foo() {
    ///         assert!(module_path!().ends_with("test"));
    ///     }
    /// }
    ///
    /// test::foo();
    /// ```
    #[macro_export]
    macro_rules! module_path { () => ({ /* compiler built-in */ }) }

    /// Boolean evaluation of configuration flags.
    ///
    /// In addition to the `#[cfg]` attribute, this macro is provided to allow
    /// boolean expression evaluation of configuration flags. This frequently
    /// leads to less duplicated code.
    ///
    /// The syntax given to this macro is the same syntax as the `cfg`
    /// attribute.
    ///
    /// # Examples
    ///
    /// ```
    /// let my_directory = if cfg!(windows) {
    ///     "windows-specific-directory"
    /// } else {
    ///     "unix-directory"
    /// };
    /// ```
    #[macro_export]
    macro_rules! cfg { ($cfg:tt) => ({ /* compiler built-in */ }) }

    /// Parse the current given file as an expression.
    ///
    /// This is generally a bad idea, because it's going to behave unhygenically.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// fn foo() {
    ///     include!("/path/to/a/file")
    /// }
    /// ```
    #[macro_export]
    macro_rules! include { ($cfg:tt) => ({ /* compiler built-in */ }) }
}
<|endoftext|>


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

use core::prelude::*;
use core::to_bytes;
use core::to_str::ToStr;

#[deriving(Eq)]
pub enum Abi {
    // NB: This ordering MUST match the AbiDatas array below.
    // (This is ensured by the test indices_are_correct().)

    // Single platform ABIs come first (`for_arch()` relies on this)
    Cdecl,
    Stdcall,
    Fastcall,
    Aapcs,

    // Multiplatform ABIs second
    Rust,
    C,
    RustIntrinsic,
}

#[deriving(Eq)]
pub enum Architecture {
    // NB. You cannot change the ordering of these
    // constants without adjusting IntelBits below.
    // (This is ensured by the test indices_are_correct().)
    X86,
    X86_64,
    Arm,
    Mips
}

static IntelBits: u32 = (1 << (X86 as uint)) | (1 << (X86_64 as uint));
static ArmBits: u32 = (1 << (Arm as uint));

struct AbiData {
    abi: Abi,

    // Name of this ABI as we like it called.
    name: &'static str,

    // Is it specific to a platform? If so, which one?  Also, what is
    // the name that LLVM gives it (in case we disagree)
    abi_arch: AbiArchitecture
}

enum AbiArchitecture {
    RustArch,   // Not a real ABI (e.g., intrinsic)
    AllArch,    // An ABI that specifies cross-platform defaults (e.g., "C")
    Archs(u32)  // Multiple architectures (bitset)
}

#[auto_encode]
#[auto_decode]
#[deriving(Eq)]
pub struct AbiSet {
    priv bits: u32   // each bit represents one of the abis below
}

static AbiDatas: &'static [AbiData] = &[
    // Platform-specific ABIs
    AbiData {abi: Cdecl, name: "cdecl", abi_arch: Archs(IntelBits)},
    AbiData {abi: Stdcall, name: "stdcall", abi_arch: Archs(IntelBits)},
    AbiData {abi: Fastcall, name:"fastcall", abi_arch: Archs(IntelBits)},
    AbiData {abi: Aapcs, name: "aapcs", abi_arch: Archs(ArmBits)},

    // Cross-platform ABIs
    //
    // NB: Do not adjust this ordering without
    // adjusting the indices below.
    AbiData {abi: Rust, name: "Rust", abi_arch: RustArch},
    AbiData {abi: C, name: "C", abi_arch: AllArch},
    AbiData {abi: RustIntrinsic, name: "rust-intrinsic", abi_arch: RustArch},
];

fn each_abi(op: &fn(abi: Abi) -> bool) {
    /*!
     *
     * Iterates through each of the defined ABIs.
     */

    for AbiDatas.each |abi_data| {
        if !op(abi_data.abi) {
            return;
        }
    }
}

pub fn lookup(name: &str) -> Option<Abi> {
    /*!
     *
     * Returns the ABI with the given name (if any).
     */

    for each_abi |abi| {
        if name == abi.data().name {
            return Some(abi);
        }
    }
    return None;
}

pub fn all_names() -> ~[&'static str] {
    AbiDatas.map(|d| d.name)
}

pub impl Abi {
    #[inline]
    fn index(&self) -> uint {
        *self as uint
    }

    #[inline]
    fn data(&self) -> &'static AbiData {
        &AbiDatas[self.index()]
    }

    fn name(&self) -> &'static str {
        self.data().name
    }
}

impl Architecture {
    fn bit(&self) -> u32 {
        1 << (*self as u32)
    }
}

pub impl AbiSet {
    fn from(abi: Abi) -> AbiSet {
        AbiSet { bits: (1 << abi.index()) }
    }

    #[inline]
    fn Rust() -> AbiSet {
        AbiSet::from(Rust)
    }

    #[inline]
    fn C() -> AbiSet {
        AbiSet::from(C)
    }

    #[inline]
    fn Intrinsic() -> AbiSet {
        AbiSet::from(RustIntrinsic)
    }

    fn default() -> AbiSet {
        AbiSet::C()
    }

    fn empty() -> AbiSet {
        AbiSet { bits: 0 }
    }

    #[inline]
    fn is_rust(&self) -> bool {
        self.bits == 1 << Rust.index()
    }

    #[inline]
    fn is_c(&self) -> bool {
        self.bits == 1 << C.index()
    }

    #[inline]
    fn is_intrinsic(&self) -> bool {
        self.bits == 1 << RustIntrinsic.index()
    }

    fn contains(&self, abi: Abi) -> bool {
        (self.bits & (1 << abi.index())) != 0
    }

    fn subset_of(&self, other_abi_set: AbiSet) -> bool {
        (self.bits & other_abi_set.bits) == self.bits
    }

    fn add(&mut self, abi: Abi) {
        self.bits |= (1 << abi.index());
    }

    fn each(&self, op: &fn(abi: Abi) -> bool) {
        for each_abi |abi| {
            if self.contains(abi) {
                if !op(abi) {
                    return;
                }
            }
        }
    }

    fn is_empty(&self) -> bool {
        self.bits == 0
    }

    fn for_arch(&self, arch: Architecture) -> Option<Abi> {
        // NB---Single platform ABIs come first
        for self.each |abi| {
            let data = abi.data();
            match data.abi_arch {
                Archs(a) if (a & arch.bit()) != 0 => { return Some(abi); }
                Archs(_) => { }
                RustArch | AllArch => { return Some(abi); }
            }
        }

        None
    }

    fn check_valid(&self) -> Option<(Abi, Abi)> {
        let mut abis = ~[];
        for self.each |abi| { abis.push(abi); }

        for abis.eachi |i, abi| {
            let data = abi.data();
            for abis.slice(0, i).each |other_abi| {
                let other_data = other_abi.data();
                debug!("abis=(%?,%?) datas=(%?,%?)",
                       abi, data.abi_arch,
                       other_abi, other_data.abi_arch);
                match (&data.abi_arch, &other_data.abi_arch) {
                    (&AllArch, &AllArch) => {
                        // Two cross-architecture ABIs
                        return Some((*abi, *other_abi));
                    }
                    (_, &RustArch) |
                    (&RustArch, _) => {
                        // Cannot combine Rust or Rust-Intrinsic with
                        // anything else.
                        return Some((*abi, *other_abi));
                    }
                    (&Archs(is), &Archs(js)) if (is & js) != 0 => {
                        // Two ABIs for same architecture
                        return Some((*abi, *other_abi));
                    }
                    _ => {}
                }
            }
        }

        return None;
    }
}

impl to_bytes::IterBytes for Abi {
    fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
        self.index().iter_bytes(lsb0, f)
    }
}

impl to_bytes::IterBytes for AbiSet {
    fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
        self.bits.iter_bytes(lsb0, f)
    }
}

impl ToStr for Abi {
    fn to_str(&self) -> ~str {
        self.data().name.to_str()
    }
}

impl ToStr for AbiSet {
    fn to_str(&self) -> ~str {
        unsafe { // so we can push to strs.
            let mut strs = ~[];
            for self.each |abi| {
                strs.push(abi.data().name);
            }
            fmt!("\"%s\"", str::connect_slices(strs, " "))
        }
    }
}

#[test]
fn lookup_Rust() {
    let abi = lookup("Rust");
    assert!(abi.is_some() && abi.get().data().name == "Rust");
}

#[test]
fn lookup_cdecl() {
    let abi = lookup("cdecl");
    assert!(abi.is_some() && abi.get().data().name == "cdecl");
}

#[test]
fn lookup_baz() {
    let abi = lookup("baz");
    assert!(abi.is_none());
}

#[cfg(test)]
fn cannot_combine(n: Abi, m: Abi) {
    let mut set = AbiSet::empty();
    set.add(n);
    set.add(m);
    match set.check_valid() {
        Some((a, b)) => {
            assert!((n == a && m == b) ||
                         (m == a && n == b));
        }
        None => {
            fail!(~"Invalid match not detected");
        }
    }
}

#[cfg(test)]
fn can_combine(n: Abi, m: Abi) {
    let mut set = AbiSet::empty();
    set.add(n);
    set.add(m);
    match set.check_valid() {
        Some((_, _)) => {
            fail!(~"Valid match declared invalid");
        }
        None => {}
    }
}

#[test]
fn cannot_combine_cdecl_and_stdcall() {
    cannot_combine(Cdecl, Stdcall);
}

#[test]
fn cannot_combine_c_and_rust() {
    cannot_combine(C, Rust);
}

#[test]
fn cannot_combine_rust_and_cdecl() {
    cannot_combine(Rust, Cdecl);
}

#[test]
fn cannot_combine_rust_intrinsic_and_cdecl() {
    cannot_combine(RustIntrinsic, Cdecl);
}

#[test]
fn can_combine_c_and_stdcall() {
    can_combine(C, Stdcall);
}

#[test]
fn can_combine_aapcs_and_stdcall() {
    can_combine(Aapcs, Stdcall);
}

#[test]
fn abi_to_str_stdcall_aaps() {
    let mut set = AbiSet::empty();
    set.add(Aapcs);
    set.add(Stdcall);
    assert!(set.to_str() == ~"\"stdcall aapcs\"");
}

#[test]
fn abi_to_str_c_aaps() {
    let mut set = AbiSet::empty();
    set.add(Aapcs);
    set.add(C);
    debug!("set = %s", set.to_str());
    assert!(set.to_str() == ~"\"aapcs C\"");
}

#[test]
fn abi_to_str_rust() {
    let mut set = AbiSet::empty();
    set.add(Rust);
    debug!("set = %s", set.to_str());
    assert!(set.to_str() == ~"\"Rust\"");
}

#[test]
fn indices_are_correct() {
    for AbiDatas.eachi |i, abi_data| {
        assert!(i == abi_data.abi.index());
    }

    let bits = 1 << (X86 as u32);
    let bits = bits | 1 << (X86_64 as u32);
    assert!(IntelBits == bits);

    let bits = 1 << (Arm as u32);
    assert!(ArmBits == bits);
}

#[cfg(test)]
fn check_arch(abis: &[Abi], arch: Architecture, expect: Option<Abi>) {
    let mut set = AbiSet::empty();
    for abis.each |&abi| {
        set.add(abi);
    }
    let r = set.for_arch(arch);
    assert!(r == expect);
}

#[test]
fn pick_multiplatform() {
    check_arch([C, Cdecl], X86, Some(Cdecl));
    check_arch([C, Cdecl], X86_64, Some(Cdecl));
    check_arch([C, Cdecl], Arm, Some(C));
}

#[test]
fn pick_uniplatform() {
    check_arch([Stdcall], X86, Some(Stdcall));
    check_arch([Stdcall], Arm, None);
}
<commit_msg>syntax: remove unnecessary unsafe blocks/functions<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::prelude::*;
use core::to_bytes;
use core::to_str::ToStr;

#[deriving(Eq)]
pub enum Abi {
    // NB: This ordering MUST match the AbiDatas array below.
    // (This is ensured by the test indices_are_correct().)

    // Single platform ABIs come first (`for_arch()` relies on this)
    Cdecl,
    Stdcall,
    Fastcall,
    Aapcs,

    // Multiplatform ABIs second
    Rust,
    C,
    RustIntrinsic,
}

#[deriving(Eq)]
pub enum Architecture {
    // NB. You cannot change the ordering of these
    // constants without adjusting IntelBits below.
    // (This is ensured by the test indices_are_correct().)
    X86,
    X86_64,
    Arm,
    Mips
}

static IntelBits: u32 = (1 << (X86 as uint)) | (1 << (X86_64 as uint));
static ArmBits: u32 = (1 << (Arm as uint));

struct AbiData {
    abi: Abi,

    // Name of this ABI as we like it called.
    name: &'static str,

    // Is it specific to a platform? If so, which one?  Also, what is
    // the name that LLVM gives it (in case we disagree)
    abi_arch: AbiArchitecture
}

enum AbiArchitecture {
    RustArch,   // Not a real ABI (e.g., intrinsic)
    AllArch,    // An ABI that specifies cross-platform defaults (e.g., "C")
    Archs(u32)  // Multiple architectures (bitset)
}

#[auto_encode]
#[auto_decode]
#[deriving(Eq)]
pub struct AbiSet {
    priv bits: u32   // each bit represents one of the abis below
}

static AbiDatas: &'static [AbiData] = &[
    // Platform-specific ABIs
    AbiData {abi: Cdecl, name: "cdecl", abi_arch: Archs(IntelBits)},
    AbiData {abi: Stdcall, name: "stdcall", abi_arch: Archs(IntelBits)},
    AbiData {abi: Fastcall, name:"fastcall", abi_arch: Archs(IntelBits)},
    AbiData {abi: Aapcs, name: "aapcs", abi_arch: Archs(ArmBits)},

    // Cross-platform ABIs
    //
    // NB: Do not adjust this ordering without
    // adjusting the indices below.
    AbiData {abi: Rust, name: "Rust", abi_arch: RustArch},
    AbiData {abi: C, name: "C", abi_arch: AllArch},
    AbiData {abi: RustIntrinsic, name: "rust-intrinsic", abi_arch: RustArch},
];

fn each_abi(op: &fn(abi: Abi) -> bool) {
    /*!
     *
     * Iterates through each of the defined ABIs.
     */

    for AbiDatas.each |abi_data| {
        if !op(abi_data.abi) {
            return;
        }
    }
}

pub fn lookup(name: &str) -> Option<Abi> {
    /*!
     *
     * Returns the ABI with the given name (if any).
     */

    for each_abi |abi| {
        if name == abi.data().name {
            return Some(abi);
        }
    }
    return None;
}

pub fn all_names() -> ~[&'static str] {
    AbiDatas.map(|d| d.name)
}

pub impl Abi {
    #[inline]
    fn index(&self) -> uint {
        *self as uint
    }

    #[inline]
    fn data(&self) -> &'static AbiData {
        &AbiDatas[self.index()]
    }

    fn name(&self) -> &'static str {
        self.data().name
    }
}

impl Architecture {
    fn bit(&self) -> u32 {
        1 << (*self as u32)
    }
}

pub impl AbiSet {
    fn from(abi: Abi) -> AbiSet {
        AbiSet { bits: (1 << abi.index()) }
    }

    #[inline]
    fn Rust() -> AbiSet {
        AbiSet::from(Rust)
    }

    #[inline]
    fn C() -> AbiSet {
        AbiSet::from(C)
    }

    #[inline]
    fn Intrinsic() -> AbiSet {
        AbiSet::from(RustIntrinsic)
    }

    fn default() -> AbiSet {
        AbiSet::C()
    }

    fn empty() -> AbiSet {
        AbiSet { bits: 0 }
    }

    #[inline]
    fn is_rust(&self) -> bool {
        self.bits == 1 << Rust.index()
    }

    #[inline]
    fn is_c(&self) -> bool {
        self.bits == 1 << C.index()
    }

    #[inline]
    fn is_intrinsic(&self) -> bool {
        self.bits == 1 << RustIntrinsic.index()
    }

    fn contains(&self, abi: Abi) -> bool {
        (self.bits & (1 << abi.index())) != 0
    }

    fn subset_of(&self, other_abi_set: AbiSet) -> bool {
        (self.bits & other_abi_set.bits) == self.bits
    }

    fn add(&mut self, abi: Abi) {
        self.bits |= (1 << abi.index());
    }

    fn each(&self, op: &fn(abi: Abi) -> bool) {
        for each_abi |abi| {
            if self.contains(abi) {
                if !op(abi) {
                    return;
                }
            }
        }
    }

    fn is_empty(&self) -> bool {
        self.bits == 0
    }

    fn for_arch(&self, arch: Architecture) -> Option<Abi> {
        // NB---Single platform ABIs come first
        for self.each |abi| {
            let data = abi.data();
            match data.abi_arch {
                Archs(a) if (a & arch.bit()) != 0 => { return Some(abi); }
                Archs(_) => { }
                RustArch | AllArch => { return Some(abi); }
            }
        }

        None
    }

    fn check_valid(&self) -> Option<(Abi, Abi)> {
        let mut abis = ~[];
        for self.each |abi| { abis.push(abi); }

        for abis.eachi |i, abi| {
            let data = abi.data();
            for abis.slice(0, i).each |other_abi| {
                let other_data = other_abi.data();
                debug!("abis=(%?,%?) datas=(%?,%?)",
                       abi, data.abi_arch,
                       other_abi, other_data.abi_arch);
                match (&data.abi_arch, &other_data.abi_arch) {
                    (&AllArch, &AllArch) => {
                        // Two cross-architecture ABIs
                        return Some((*abi, *other_abi));
                    }
                    (_, &RustArch) |
                    (&RustArch, _) => {
                        // Cannot combine Rust or Rust-Intrinsic with
                        // anything else.
                        return Some((*abi, *other_abi));
                    }
                    (&Archs(is), &Archs(js)) if (is & js) != 0 => {
                        // Two ABIs for same architecture
                        return Some((*abi, *other_abi));
                    }
                    _ => {}
                }
            }
        }

        return None;
    }
}

impl to_bytes::IterBytes for Abi {
    fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
        self.index().iter_bytes(lsb0, f)
    }
}

impl to_bytes::IterBytes for AbiSet {
    fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
        self.bits.iter_bytes(lsb0, f)
    }
}

impl ToStr for Abi {
    fn to_str(&self) -> ~str {
        self.data().name.to_str()
    }
}

impl ToStr for AbiSet {
    fn to_str(&self) -> ~str {
        let mut strs = ~[];
        for self.each |abi| {
            strs.push(abi.data().name);
        }
        fmt!("\"%s\"", str::connect_slices(strs, " "))
    }
}

#[test]
fn lookup_Rust() {
    let abi = lookup("Rust");
    assert!(abi.is_some() && abi.get().data().name == "Rust");
}

#[test]
fn lookup_cdecl() {
    let abi = lookup("cdecl");
    assert!(abi.is_some() && abi.get().data().name == "cdecl");
}

#[test]
fn lookup_baz() {
    let abi = lookup("baz");
    assert!(abi.is_none());
}

#[cfg(test)]
fn cannot_combine(n: Abi, m: Abi) {
    let mut set = AbiSet::empty();
    set.add(n);
    set.add(m);
    match set.check_valid() {
        Some((a, b)) => {
            assert!((n == a && m == b) ||
                         (m == a && n == b));
        }
        None => {
            fail!(~"Invalid match not detected");
        }
    }
}

#[cfg(test)]
fn can_combine(n: Abi, m: Abi) {
    let mut set = AbiSet::empty();
    set.add(n);
    set.add(m);
    match set.check_valid() {
        Some((_, _)) => {
            fail!(~"Valid match declared invalid");
        }
        None => {}
    }
}

#[test]
fn cannot_combine_cdecl_and_stdcall() {
    cannot_combine(Cdecl, Stdcall);
}

#[test]
fn cannot_combine_c_and_rust() {
    cannot_combine(C, Rust);
}

#[test]
fn cannot_combine_rust_and_cdecl() {
    cannot_combine(Rust, Cdecl);
}

#[test]
fn cannot_combine_rust_intrinsic_and_cdecl() {
    cannot_combine(RustIntrinsic, Cdecl);
}

#[test]
fn can_combine_c_and_stdcall() {
    can_combine(C, Stdcall);
}

#[test]
fn can_combine_aapcs_and_stdcall() {
    can_combine(Aapcs, Stdcall);
}

#[test]
fn abi_to_str_stdcall_aaps() {
    let mut set = AbiSet::empty();
    set.add(Aapcs);
    set.add(Stdcall);
    assert!(set.to_str() == ~"\"stdcall aapcs\"");
}

#[test]
fn abi_to_str_c_aaps() {
    let mut set = AbiSet::empty();
    set.add(Aapcs);
    set.add(C);
    debug!("set = %s", set.to_str());
    assert!(set.to_str() == ~"\"aapcs C\"");
}

#[test]
fn abi_to_str_rust() {
    let mut set = AbiSet::empty();
    set.add(Rust);
    debug!("set = %s", set.to_str());
    assert!(set.to_str() == ~"\"Rust\"");
}

#[test]
fn indices_are_correct() {
    for AbiDatas.eachi |i, abi_data| {
        assert!(i == abi_data.abi.index());
    }

    let bits = 1 << (X86 as u32);
    let bits = bits | 1 << (X86_64 as u32);
    assert!(IntelBits == bits);

    let bits = 1 << (Arm as u32);
    assert!(ArmBits == bits);
}

#[cfg(test)]
fn check_arch(abis: &[Abi], arch: Architecture, expect: Option<Abi>) {
    let mut set = AbiSet::empty();
    for abis.each |&abi| {
        set.add(abi);
    }
    let r = set.for_arch(arch);
    assert!(r == expect);
}

#[test]
fn pick_multiplatform() {
    check_arch([C, Cdecl], X86, Some(Cdecl));
    check_arch([C, Cdecl], X86_64, Some(Cdecl));
    check_arch([C, Cdecl], Arm, Some(C));
}

#[test]
fn pick_uniplatform() {
    check_arch([Stdcall], X86, Some(Stdcall));
    check_arch([Stdcall], Arm, None);
}
<|endoftext|>


<commit_before>#![allow(non_snake_case)]

use std::str::from_utf8;

use rustc_serialize::json;
use curl::http;

pub const SESSION_TTL: &'static str = "15s";

#[derive(RustcDecodable, RustcEncodable, Debug)]
pub struct SessionCreate {
    Name: String,
    TTL: String
}

#[derive(RustcDecodable, RustcEncodable, Debug)]
pub struct SessionID {
    ID: String
}

pub struct Session {
    endpoint: String
}

impl Session {
    pub fn new(address: &str) ->  Session {
        Session {
            endpoint: format!("http://{}/v1/session", address)
        }
    }

    pub fn create(&self, name: String) -> Option<String> {
        let url = format!("{}/create", self.endpoint);
        let session = SessionCreate {
            Name: name,
            TTL: self::SESSION_TTL.to_owned()
        };
        let json_str = json::encode(&session).unwrap();

        let resp = http::handle()
            .put(url, &json_str)
            .content_type("application/json")
            .exec().unwrap();
        if resp.get_code() != 200 {
            panic!("Consul: Error creating a session! Response: {}", resp);
        }
        let result = from_utf8(resp.get_body()).unwrap();
        let json_data = match json::Json::from_str(result) {
            Ok(value) => value,
            Err(err) => panic!("consul: Could not convert to json: {:?}. Err: {}", result, err)
        };
        super::get_string(&json_data, &["ID"])
    }

    pub fn renew(&self, session_id: &String) -> bool {
        for _ in 0..10 {
            let url = format!("{}/renew/{}", self.endpoint, session_id);
            let resp = http::handle()
                .put(url, "")
                .content_type("application/json")
                .exec().unwrap();
            if resp.get_code() != 200 {
                println!("Could not renew ession: {}, returned HTTP code: {:?}", session_id, resp.get_code());
                return false;
            }
            else {
                return true;
            }
        }
        false
    }

    pub fn end(&self, session_id: &String) {
        let url = format!("{}/destroy/{}", self.endpoint, session_id);
        let resp = http::handle()
            .put(url, "")
            .content_type("application/json")
            .exec().unwrap();
        if resp.get_code() != 200 {
            panic!("Cound not destroy session: {}", session_id);
        }

    }

}
<commit_msg>Retry session renewal 10 times<commit_after>#![allow(non_snake_case)]

use std::str::from_utf8;
use std::thread;
use std::time::Duration;

use rustc_serialize::json;
use curl::http;

pub const SESSION_TTL: &'static str = "15s";

#[derive(RustcDecodable, RustcEncodable, Debug)]
pub struct SessionCreate {
    Name: String,
    TTL: String
}

#[derive(RustcDecodable, RustcEncodable, Debug)]
pub struct SessionID {
    ID: String
}

pub struct Session {
    endpoint: String
}

impl Session {
    pub fn new(address: &str) ->  Session {
        Session {
            endpoint: format!("http://{}/v1/session", address)
        }
    }

    pub fn create(&self, name: String) -> Option<String> {
        let url = format!("{}/create", self.endpoint);
        let session = SessionCreate {
            Name: name,
            TTL: self::SESSION_TTL.to_owned()
        };
        let json_str = json::encode(&session).unwrap();

        let resp = http::handle()
            .put(url, &json_str)
            .content_type("application/json")
            .exec().unwrap();
        if resp.get_code() != 200 {
            panic!("Consul: Error creating a session! Response: {}", resp);
        }
        let result = from_utf8(resp.get_body()).unwrap();
        let json_data = match json::Json::from_str(result) {
            Ok(value) => value,
            Err(err) => panic!("consul: Could not convert to json: {:?}. Err: {}", result, err)
        };
        super::get_string(&json_data, &["ID"])
    }

    pub fn renew(&self, session_id: &String) -> bool {
        for _ in 0..10 {
            let url = format!("{}/renew/{}", self.endpoint, session_id);
            let resp = http::handle()
                .put(url, "")
                .content_type("application/json")
                .exec().unwrap();
            if resp.get_code() != 200 {
                println!("Could not renew session: {}, returned HTTP code: {:?}. Sleeping for 2 seconds", session_id, resp.get_code());
                thread::sleep(Duration::from_millis(2000u64));
            }
            else {
                return true;
            }
        }
        false
    }

    pub fn end(&self, session_id: &String) {
        let url = format!("{}/destroy/{}", self.endpoint, session_id);
        let resp = http::handle()
            .put(url, "")
            .content_type("application/json")
            .exec().unwrap();
        if resp.get_code() != 200 {
            panic!("Cound not destroy session: {}", session_id);
        }

    }

}
<|endoftext|>


<commit_before>pub fn encode(timeseconds: i32, precision: i32) -> String {
    // Fill me in!
    "abcdef1234".to_string()
}

pub fn decode(timehash: &str) -> i32 {
    // Fill me in!
    1
}
<commit_msg>WIP, starting to port the decode function and supporting code.<commit_after>use std::collections::HashMap;

static base32: &'static str = "01abcdef";
static before: &'static str = "f01abcde";
static after: &'static str = "1abcdef0";

// I think maybe this should be called once and then we just hard-code
// the resulting maps since they don't need to be computed on the fly every time
fn create_decode_map() -> HashMap<char, usize> {
    let mut _decode_map: HashMap<char, usize> = HashMap::new();
    let mut neighbor_map = HashMap::new();

    for i in 0..base32.len() {
        let b32_char = base32.chars().nth(i).unwrap();
        println!("{} is {:?}", i, b32_char);
        _decode_map.insert(b32_char, i);
        neighbor_map.insert(b32_char, (before.chars().nth(i).unwrap(), after.chars().nth(i).unwrap()));
    }
    println!("map1: {:?}", _decode_map);
    println!("map2: {:?}", neighbor_map);
    return _decode_map;
}

#[cfg(test)]
mod tests {
    #[test]
    fn timehash_decode_map() {
        use super::*;
        create_decode_map();
    }
}

pub fn encode(timeseconds: i32, precision: i32) -> String {
    // Fill me in!
    "abcdef1234".to_string()
}

pub fn decode(timehash: &str) -> i32 {
    let epoch_begin: f64 = 0.0;
    let epoch_end: f64 = 4039372800.0;
    let time_error: f64 = (epoch_begin + epoch_end) / 2.0;

    for c in timehash.chars() {

    }
    1
}
<|endoftext|>


<commit_before>#![allow(
    clippy::cast_sign_loss,
    clippy::default_trait_access,
    clippy::doc_markdown,
    clippy::enum_glob_use,
    clippy::filter_map,
    clippy::if_same_then_else,
    clippy::inherent_to_string,
    clippy::items_after_statements,
    clippy::large_enum_variant,
    clippy::match_bool,
    clippy::match_same_arms,
    clippy::module_name_repetitions,
    clippy::needless_pass_by_value,
    clippy::new_without_default,
    clippy::nonminimal_bool,
    clippy::option_if_let_else,
    clippy::or_fun_call,
    clippy::redundant_else,
    clippy::shadow_unrelated,
    clippy::similar_names,
    clippy::single_match,
    clippy::single_match_else,
    clippy::too_many_arguments,
    clippy::too_many_lines,
    clippy::toplevel_ref_arg,
    clippy::useless_let_if_seq,
    // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6983
    clippy::wrong_self_convention
)]

extern crate proc_macro;

mod derive;
mod expand;
mod generics;
mod syntax;
mod type_id;

#[cfg(feature = "experimental")]
mod clang;
#[cfg(feature = "experimental")]
mod load;

use crate::syntax::file::Module;
use crate::syntax::namespace::Namespace;
use crate::syntax::qualified::QualifiedName;
use crate::type_id::Crate;
use proc_macro::TokenStream;
use syn::parse::{Parse, ParseStream, Parser, Result};
use syn::parse_macro_input;

/// `#[cxx::bridge] mod ffi { ... }`
///
/// Refer to the crate-level documentation for the explanation of how this macro
/// is intended to be used.
///
/// The only additional thing to note here is namespace support — if the
/// types and functions on the `extern "C++"` side of our bridge are in a
/// namespace, specify that namespace as an argument of the cxx::bridge
/// attribute macro.
///
/// ```
/// #[cxx::bridge(namespace = "mycompany::rust")]
/// # mod ffi {}
/// ```
///
/// The types and functions from the `extern "Rust"` side of the bridge will be
/// placed into that same namespace in the generated C++ code.
#[proc_macro_attribute]
pub fn bridge(args: TokenStream, input: TokenStream) -> TokenStream {
    let _ = syntax::error::ERRORS;

    let namespace = match Namespace::parse_bridge_attr_namespace.parse(args) {
        Ok(namespace) => namespace,
        Err(err) => return err.to_compile_error().into(),
    };
    let mut ffi = parse_macro_input!(input as Module);
    ffi.namespace = namespace;

    expand::bridge(ffi)
        .unwrap_or_else(|err| err.to_compile_error())
        .into()
}

#[doc(hidden)]
#[proc_macro]
pub fn type_id(input: TokenStream) -> TokenStream {
    struct TypeId {
        krate: Crate,
        path: QualifiedName,
    }

    impl Parse for TypeId {
        fn parse(input: ParseStream) -> Result<Self> {
            let krate = input.parse().map(Crate::DollarCrate)?;
            let path = QualifiedName::parse_quoted_or_unquoted(input)?;
            Ok(TypeId { krate, path })
        }
    }

    let arg = parse_macro_input!(input as TypeId);
    type_id::expand(arg.krate, arg.path).into()
}
<commit_msg>Remove ignore of deleted filter_map clippy lint<commit_after>#![allow(
    clippy::cast_sign_loss,
    clippy::default_trait_access,
    clippy::doc_markdown,
    clippy::enum_glob_use,
    clippy::if_same_then_else,
    clippy::inherent_to_string,
    clippy::items_after_statements,
    clippy::large_enum_variant,
    clippy::match_bool,
    clippy::match_same_arms,
    clippy::module_name_repetitions,
    clippy::needless_pass_by_value,
    clippy::new_without_default,
    clippy::nonminimal_bool,
    clippy::option_if_let_else,
    clippy::or_fun_call,
    clippy::redundant_else,
    clippy::shadow_unrelated,
    clippy::similar_names,
    clippy::single_match,
    clippy::single_match_else,
    clippy::too_many_arguments,
    clippy::too_many_lines,
    clippy::toplevel_ref_arg,
    clippy::useless_let_if_seq,
    // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6983
    clippy::wrong_self_convention
)]

extern crate proc_macro;

mod derive;
mod expand;
mod generics;
mod syntax;
mod type_id;

#[cfg(feature = "experimental")]
mod clang;
#[cfg(feature = "experimental")]
mod load;

use crate::syntax::file::Module;
use crate::syntax::namespace::Namespace;
use crate::syntax::qualified::QualifiedName;
use crate::type_id::Crate;
use proc_macro::TokenStream;
use syn::parse::{Parse, ParseStream, Parser, Result};
use syn::parse_macro_input;

/// `#[cxx::bridge] mod ffi { ... }`
///
/// Refer to the crate-level documentation for the explanation of how this macro
/// is intended to be used.
///
/// The only additional thing to note here is namespace support — if the
/// types and functions on the `extern "C++"` side of our bridge are in a
/// namespace, specify that namespace as an argument of the cxx::bridge
/// attribute macro.
///
/// ```
/// #[cxx::bridge(namespace = "mycompany::rust")]
/// # mod ffi {}
/// ```
///
/// The types and functions from the `extern "Rust"` side of the bridge will be
/// placed into that same namespace in the generated C++ code.
#[proc_macro_attribute]
pub fn bridge(args: TokenStream, input: TokenStream) -> TokenStream {
    let _ = syntax::error::ERRORS;

    let namespace = match Namespace::parse_bridge_attr_namespace.parse(args) {
        Ok(namespace) => namespace,
        Err(err) => return err.to_compile_error().into(),
    };
    let mut ffi = parse_macro_input!(input as Module);
    ffi.namespace = namespace;

    expand::bridge(ffi)
        .unwrap_or_else(|err| err.to_compile_error())
        .into()
}

#[doc(hidden)]
#[proc_macro]
pub fn type_id(input: TokenStream) -> TokenStream {
    struct TypeId {
        krate: Crate,
        path: QualifiedName,
    }

    impl Parse for TypeId {
        fn parse(input: ParseStream) -> Result<Self> {
            let krate = input.parse().map(Crate::DollarCrate)?;
            let path = QualifiedName::parse_quoted_or_unquoted(input)?;
            Ok(TypeId { krate, path })
        }
    }

    let arg = parse_macro_input!(input as TypeId);
    type_id::expand(arg.krate, arg.path).into()
}
<|endoftext|>


<commit_before>pub mod requests;
pub use requests::*;

pub use telegram_bot_raw::{Integer, Float, Request};
pub use telegram_bot_raw::{Update, UpdateKind};
pub use telegram_bot_raw::{User, Group, Supergroup, Channel, Chat};
pub use telegram_bot_raw::{Message, MessageKind, Forward, ForwardFrom};
pub use telegram_bot_raw::{MessageEntity, MessageEntityKind};
pub use telegram_bot_raw::{Audio, Document, PhotoSize, Sticker, Video, Voice};
pub use telegram_bot_raw::{Contact, Location, Venue, File};

pub use telegram_bot_raw::{ParseMode, ChatId, UserId, MessageId};
pub use telegram_bot_raw::{ReplyMarkup, InlineKeyboardMarkup, ReplyKeyboardMarkup};
pub use telegram_bot_raw::{ReplyKeyboardRemove, ForceReply};
pub use telegram_bot_raw::{ChatAction};
<commit_msg>feat: export KeyboardButton<commit_after>pub mod requests;
pub use requests::*;

pub use telegram_bot_raw::{Integer, Float, Request};
pub use telegram_bot_raw::{Update, UpdateKind};
pub use telegram_bot_raw::{User, Group, Supergroup, Channel, Chat};
pub use telegram_bot_raw::{Message, MessageKind, Forward, ForwardFrom};
pub use telegram_bot_raw::{MessageEntity, MessageEntityKind};
pub use telegram_bot_raw::{Audio, Document, PhotoSize, Sticker, Video, Voice};
pub use telegram_bot_raw::{Contact, Location, Venue, File};

pub use telegram_bot_raw::{ParseMode, ChatId, UserId, MessageId};
pub use telegram_bot_raw::{ReplyMarkup, InlineKeyboardMarkup, ReplyKeyboardMarkup, KeyboardButton};
pub use telegram_bot_raw::{ReplyKeyboardRemove, ForceReply};
pub use telegram_bot_raw::{ChatAction};
<|endoftext|>


<commit_before>#![feature(path_ext)]

extern crate bindgen;
extern crate pkg_config;

use std::env;
use std::fs::PathExt;
use std::path::Path;
use std::process::Command;

static VERSION: &'static str = "1.1.8"; // Should be the same as the version in the manifest

fn main() {
    let out_dir     = env::var("OUT_DIR").unwrap();
    let current_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let driver_path = format!(
        "mongo-c-driver-{}",
        VERSION
    );

    let libmongoc_path = Path::new(&out_dir).join("lib/libmongoc-1.0.a");
    if !libmongoc_path.exists() { // TODO: This should check if we're at the right version
        // Download and extract driver archive
        let url = format!(
            "https://github.com/mongodb/mongo-c-driver/releases/download/{}/mongo-c-driver-{}.tar.gz",
            VERSION,
            VERSION
        );
        assert!(Command::new("curl").arg("-O") // Save to disk
                                    .arg("-L") // Follow redirects
                                    .arg(url)
                                    .status()
                                    .unwrap()
                                    .success());

        let archive_name = format!(
            "mongo-c-driver-{}.tar.gz",
            VERSION
        );
        assert!(Command::new("tar").arg("xzf")
                                   .arg(&archive_name)
                                   .status()
                                   .unwrap()
                                   .success());

        // Configure and install
        assert!(Command::new("sh").arg("configure")
                          .arg("--enable-ssl=yes")
                          .arg("--enable-sasl=no")
                          .arg("--enable-static=yes")
                          .arg("--enable-shared=no")
                          .arg("--with-libbson=bundled")
                          .arg(format!("--prefix={}", &out_dir))
                          .current_dir(&driver_path)
                          .status()
                          .unwrap()
                          .success());
        assert!(Command::new("make").current_dir(&driver_path).status().unwrap().success());
        assert!(Command::new("make").arg("install").current_dir(&driver_path).status().unwrap().success());

        // Generate bindings
        let bindings_rs_path = Path::new(&current_dir).join("src/bindings.rs");
        let mongo_h_path     = Path::new(&current_dir).join(&driver_path).join("src/mongoc/mongoc.h");
        let bson_path        = Path::new(&current_dir).join(&driver_path).join("src/libbson/src/bson");
        bindgen::builder()
            .emit_builtins()
            .header(mongo_h_path.to_str().unwrap())
            .clang_arg(format!("-I{}", bson_path.to_str().unwrap()))
            .generate()
            .unwrap()
            .write_to_file(&bindings_rs_path)
            .unwrap();
    }

    // Output to Cargo
    println!("cargo:root={}", &out_dir);
    println!("cargo:libdir={}/lib", &out_dir);
    println!("cargo:include={}/include", &out_dir);
    println!("cargo:rustc-link-search={}/lib", &out_dir);
    println!("cargo:rustc-link-lib=static=bson-1.0");
    println!("cargo:rustc-link-lib=static=mongoc-1.0");

    for link_path in pkg_config::find_library("openssl").unwrap().link_paths.iter(){
        println!("cargo:rustc-link-search=framework={}", &link_path.display());
    }
}
<commit_msg>Add clang include dir detection and override<commit_after>#![feature(path_ext)]

extern crate bindgen;
extern crate pkg_config;

use std::env;
use std::fs::PathExt;
use std::path::Path;
use std::process::Command;

static VERSION: &'static str = "1.1.8"; // Should be the same as the version in the manifest

fn main() {
    let out_dir     = env::var("OUT_DIR").unwrap();
    let current_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let driver_path = format!(
        "mongo-c-driver-{}",
        VERSION
    );

    let libmongoc_path = Path::new(&out_dir).join("lib/libmongoc-1.0.a");
    if !libmongoc_path.exists() { // TODO: This should check if we're at the right version
        // Download and extract driver archive
        let url = format!(
            "https://github.com/mongodb/mongo-c-driver/releases/download/{}/mongo-c-driver-{}.tar.gz",
            VERSION,
            VERSION
        );
        assert!(Command::new("curl").arg("-O") // Save to disk
                                    .arg("-L") // Follow redirects
                                    .arg(url)
                                    .status()
                                    .unwrap()
                                    .success());

        let archive_name = format!(
            "mongo-c-driver-{}.tar.gz",
            VERSION
        );
        assert!(Command::new("tar").arg("xzf")
                                   .arg(&archive_name)
                                   .status()
                                   .unwrap()
                                   .success());

        // Configure and install
        assert!(Command::new("sh").arg("configure")
                          .arg("--enable-ssl=yes")
                          .arg("--enable-sasl=no")
                          .arg("--enable-static=yes")
                          .arg("--enable-shared=no")
                          .arg("--with-libbson=bundled")
                          .arg(format!("--prefix={}", &out_dir))
                          .current_dir(&driver_path)
                          .status()
                          .unwrap()
                          .success());
        assert!(Command::new("make").current_dir(&driver_path).status().unwrap().success());
        assert!(Command::new("make").arg("install").current_dir(&driver_path).status().unwrap().success());

        // Generate bindings
        let bindings_rs_path = Path::new(&current_dir).join("src/bindings.rs");
        let mongo_h_path     = Path::new(&current_dir).join(&driver_path).join("src/mongoc/mongoc.h");
        let bson_path        = Path::new(&current_dir).join(&driver_path).join("src/libbson/src/bson");
        let mongo_h_path_arg = mongo_h_path.to_str().unwrap();
        let bson_path_arg    = bson_path.to_str().unwrap();

        let mut builder = bindgen::builder();
        builder.emit_builtins();
        builder.header(mongo_h_path_arg);
        builder.clang_arg("-I".to_owned());
        builder.clang_arg(bson_path_arg);

        // Add clang include dir if it's detected by bindgen.
        if let Some(path) = bindgen::get_include_dir() {
            builder.clang_arg("-I".to_owned());
            builder.clang_arg(path);
        }

        // Add clang include dir from env var, use as a last resort
        // if include cannot be detected normally.
        if let Ok(path) = env::var("CLANG_INCLUDE_DIR") {
            builder.clang_arg("-I".to_owned());
            builder.clang_arg(path);
        }

        let binding = builder.generate().unwrap();
        binding.write_to_file(&bindings_rs_path).unwrap();
    }

    // Output to Cargo
    println!("cargo:root={}", &out_dir);
    println!("cargo:libdir={}/lib", &out_dir);
    println!("cargo:include={}/include", &out_dir);
    println!("cargo:rustc-link-search={}/lib", &out_dir);
    println!("cargo:rustc-link-lib=static=bson-1.0");
    println!("cargo:rustc-link-lib=static=mongoc-1.0");

    for link_path in pkg_config::find_library("openssl").unwrap().link_paths.iter(){
        println!("cargo:rustc-link-search=framework={}", &link_path.display());
    }
}
<|endoftext|>


<commit_before>extern crate rustbox;
extern crate regex;

use std::error::Error;
use self::rustbox::{Color, RustBox, Key};
use self::rustbox::Event::KeyEvent;
use self::regex::Regex;

// Error

// Screen Status
pub enum Status {
    Selected(String),
    Escaped,
    Continue,
    Quit,
    Error,
}

trait PrintLine {
    fn print_line(&self, y: usize, item: &str, fg: Color, bg: Color);
}

impl PrintLine for RustBox {

    fn print_line(&self, y: usize, item: &str, fg: Color, bg: Color) {
        for x in 0..(self.width()) {
            let ch = item.chars().nth(x).unwrap_or(' ');
            self.print_char(x, y, rustbox::RB_NORMAL, fg, bg, ch);
        }
    }
}

pub struct Screen {
    lines: Vec<String>,
    prompt: String,
    y_offset: usize,
    filtered: Vec<String>,
    query: String,
    cursor: usize,
    // offset: usize,
    rustbox: RustBox
}

impl Screen {

    pub fn new() -> Screen {

        let rustbox = match RustBox::init(Default::default()) {
            Result::Ok(v) => v,
            Result::Err(e) => panic!("{}", e),
        };

        Screen {
            lines: vec!(),
            filtered: vec!(),
            prompt: "> ".to_owned(),
            y_offset: 1,
            query: String::new(),
            cursor: 0,
            // offset: 0,
            rustbox: rustbox
        }
    }

    pub fn update_screen(&mut self, lines: &Vec<String>) {
        self.cursor = 0;
        self.query = String::new();
        self.lines = lines.to_owned();
        self.filtered = self.lines.clone();
    }

    pub fn render(&self, item: &str) -> Status {

        self.rustbox.clear();
        self.rustbox.print_line(0, &format!("{0}", item), Color::Blue, Color::Black);
        self.rustbox.present();

        match self.rustbox.poll_event(false) {
            Ok(KeyEvent(Key::Char('q'))) => Status::Quit,
            _ => Status::Escaped
        }
    }

    pub fn select_line(&mut self) -> Status {

        loop {

            self.render_items();

            match self.rustbox.poll_event(false) {
                Err(err) => panic!("{:?}", err),
                Ok(event) => match self.handle_event(event) {
                    Ok(Status::Selected(s)) => return Status::Selected(s),
                    Ok(Status::Quit) => return Status::Quit,
                    _ => (),
                }
            }
        }
    }

    fn handle_event(&mut self, event: rustbox::Event) -> Result<Status, Box<Error>> {

        match event {
            KeyEvent(Key::Enter) => {
                Ok(Status::Selected(self.filtered[self.cursor].to_owned()))
            },
            KeyEvent(Key::Esc) => Ok(Status::Escaped),
            KeyEvent(Key::Up) | KeyEvent(Key::Ctrl('p')) => {
                self.cursor_up();
                Ok(Status::Continue)
            },
            KeyEvent(Key::Down) | KeyEvent(Key::Ctrl('n')) => {
                self.cursor_down();
                Ok(Status::Continue)
            },
            KeyEvent(Key::Char('q')) => {
                Ok(Status::Quit)
            },
            KeyEvent(Key::Backspace) => self.remove_query().and(Ok(Status::Continue)),
            KeyEvent(Key::Char(c)) => self.append_query(c).and(Ok(Status::Continue)),
            _ => Ok(Status::Continue),
        }
    }

    fn append_query(&mut self, c: char) -> Result<(), Box<Error>> {

        self.query.push(c);
        self.apply_filter()
    }

    fn remove_query(&mut self) -> Result<(), Box<Error>> {

        if self.query.is_empty() {
            return Ok(());
        }

        let idx = self.query.len() - 1;
        self.query.remove(idx);
        self.apply_filter()
    }

    fn apply_filter(&mut self) -> Result<(), Box<Error>> {
        self.filtered = if self.query.len() == 0 {
            self.lines.clone()
        } else {
            let re = try!(Regex::new(self.query.as_str()));
            self.lines.iter().filter(|&input| re.is_match(input)).cloned().collect()
        };

        self.cursor = 0;

        Ok(())
    }

    fn cursor_up(&mut self) {

        if self.cursor != 0 { self.cursor -= 1; }
    }

    fn cursor_down(&mut self) {

        self.cursor += 1;  // displayのサイズを考慮する必要がある
    }

    fn render_items(&self) {

        self.rustbox.clear();

        for(y, item) in self.filtered.iter().enumerate() {
            if y == self.cursor {
                self.rustbox.print_line(y + self.y_offset, &format!("[{0}]: {1}", y, &item), Color::Black, Color::Green);
            } else {
                self.rustbox.print_line(y + self.y_offset, &format!("[{0}]: {1}", y, &item), Color::Blue, Color::Black);
            }
        }

        // print query line and move the cursor to end.
        let query_str = format!("{}{}", self.prompt, self.query);
        self.rustbox.print_line(0, &query_str, Color::Green, Color::Black);
        self.rustbox.set_cursor(query_str.len() as isize, 0);
        self.rustbox.present();
    }

}

<commit_msg>Fix cursor down bug<commit_after>extern crate rustbox;
extern crate regex;

use std::cmp::min;
use std::error::Error;
use self::rustbox::{Color, RustBox, Key};
use self::rustbox::Event::KeyEvent;
use self::regex::Regex;

// Error

// Screen Status
pub enum Status {
    Selected(String),
    Escaped,
    Continue,
    Quit,
    Error,
}

trait PrintLine {
    fn print_line(&self, y: usize, item: &str, fg: Color, bg: Color);
}

impl PrintLine for RustBox {

    fn print_line(&self, y: usize, item: &str, fg: Color, bg: Color) {
        for x in 0..(self.width()) {
            let ch = item.chars().nth(x).unwrap_or(' ');
            self.print_char(x, y, rustbox::RB_NORMAL, fg, bg, ch);
        }
    }
}

pub struct Screen {
    lines: Vec<String>,
    prompt: String,
    y_offset: usize,
    filtered: Vec<String>,
    query: String,
    cursor: usize,
    // offset: usize,
    rustbox: RustBox
}

impl Screen {

    pub fn new() -> Screen {

        let rustbox = match RustBox::init(Default::default()) {
            Result::Ok(v) => v,
            Result::Err(e) => panic!("{}", e),
        };

        Screen {
            lines: vec!(),
            filtered: vec!(),
            prompt: "> ".to_owned(),
            y_offset: 1,
            query: String::new(),
            cursor: 0,
            // offset: 0,
            rustbox: rustbox
        }
    }

    pub fn update_screen(&mut self, lines: &Vec<String>) {
        self.cursor = 0;
        self.query = String::new();
        self.lines = lines.to_owned();
        self.filtered = self.lines.clone();
    }

    pub fn render(&self, item: &str) -> Status {

        self.rustbox.clear();
        self.rustbox.print_line(0, &format!("{0}", item), Color::Blue, Color::Black);
        self.rustbox.present();

        match self.rustbox.poll_event(false) {
            Ok(KeyEvent(Key::Char('q'))) => Status::Quit,
            _ => Status::Escaped
        }
    }

    pub fn select_line(&mut self) -> Status {

        loop {

            self.render_items();

            match self.rustbox.poll_event(false) {
                Err(err) => panic!("{:?}", err),
                Ok(event) => match self.handle_event(event) {
                    Ok(Status::Selected(s)) => return Status::Selected(s),
                    Ok(Status::Quit) => return Status::Quit,
                    _ => (),
                }
            }
        }
    }

    fn handle_event(&mut self, event: rustbox::Event) -> Result<Status, Box<Error>> {

        match event {
            KeyEvent(Key::Enter) => {
                Ok(Status::Selected(self.filtered[self.cursor].to_owned()))
            },
            KeyEvent(Key::Esc) => Ok(Status::Escaped),
            KeyEvent(Key::Up) | KeyEvent(Key::Ctrl('p')) => {
                self.cursor_up();
                Ok(Status::Continue)
            },
            KeyEvent(Key::Down) | KeyEvent(Key::Ctrl('n')) => {
                self.cursor_down();
                Ok(Status::Continue)
            },
            KeyEvent(Key::Char('q')) => {
                Ok(Status::Quit)
            },
            KeyEvent(Key::Backspace) => self.remove_query().and(Ok(Status::Continue)),
            KeyEvent(Key::Char(c)) => self.append_query(c).and(Ok(Status::Continue)),
            _ => Ok(Status::Continue),
        }
    }

    fn append_query(&mut self, c: char) -> Result<(), Box<Error>> {

        self.query.push(c);
        self.apply_filter()
    }

    fn remove_query(&mut self) -> Result<(), Box<Error>> {

        if self.query.is_empty() {
            return Ok(());
        }

        let idx = self.query.len() - 1;
        self.query.remove(idx);
        self.apply_filter()
    }

    fn apply_filter(&mut self) -> Result<(), Box<Error>> {
        self.filtered = if self.query.len() == 0 {
            self.lines.clone()
        } else {
            let re = try!(Regex::new(self.query.as_str()));
            self.lines.iter().filter(|&input| re.is_match(input)).cloned().collect()
        };

        self.cursor = 0;

        Ok(())
    }

    fn cursor_up(&mut self) {

        if self.cursor != 0 { self.cursor -= 1; }
    }

    fn cursor_down(&mut self) {

        let height = self.rustbox.height();

        self.cursor = min(
            (self.cursor + 1),
            min(
                (self.filtered.len() - 1),
                (height - 1)
            )
        );
    }

    fn render_items(&self) {

        self.rustbox.clear();

        for(y, item) in self.filtered.iter().enumerate() {
            if y == self.cursor {
                self.rustbox.print_line(y + self.y_offset, &format!("[{0}]: {1}", y, &item), Color::Black, Color::Green);
            } else {
                self.rustbox.print_line(y + self.y_offset, &format!("[{0}]: {1}", y, &item), Color::Blue, Color::Black);
            }
        }

        // print query line and move the cursor to end.
        let query_str = format!("{}{}", self.prompt, self.query);
        self.rustbox.print_line(0, &query_str, Color::Green, Color::Black);
        self.rustbox.set_cursor(query_str.len() as isize, 0);
        self.rustbox.present();
    }

}

<|endoftext|>


<commit_before>use super::coordinates::{CoordinateSystem, Point};

pub enum IndexType {
	Covariant,
	Contravariant
}

pub struct Tensor<T: CoordinateSystem> {
	rank: Vec<IndexType>,
	point: Point<T>,
	coords:	Vec<T::CoordType>
}<commit_msg>Changed Tensor into a trait<commit_after>use super::coordinates::{CoordinateSystem, Point};

pub enum IndexType {
	Covariant,
	Contravariant
}

pub trait Tensor<T: CoordinateSystem> {

	fn get_point(&self) -> &Point<T>;
	fn get_coord(&self, &[u8]) -> T::CoordType;
	fn get_rank(&self) -> Vec<IndexType>;

}<|endoftext|>


<commit_before>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::ops::Deref;
use {extensions, image, json, Gltf};

pub use json::texture::{MagFilter, MinFilter, WrappingMode};

lazy_static! {
    static ref DEFAULT_SAMPLER: json::texture::Sampler = Default::default();
}

/// A reference to a `Texture`.
#[derive(Clone, Debug)]
pub struct Info<'a> {
    /// The parent `Texture` struct.
    texture: Texture<'a>,

    /// The corresponding JSON struct.
    json: &'a json::texture::Info,
}

///  Texture sampler properties for filtering and wrapping modes.
#[derive(Clone, Debug)]
pub struct Sampler<'a> {
    /// The parent `Gltf` struct.
    #[allow(dead_code)]
    gltf: &'a Gltf,

    /// The corresponding JSON index - `None` when the default sampler.
    index: Option<usize>,

    /// The corresponding JSON struct.
    json: &'a json::texture::Sampler,
}

/// A texture and its sampler.
#[derive(Clone, Debug)]
pub struct Texture<'a> {
    /// The parent `Gltf` struct.
    gltf: &'a Gltf,

    /// The corresponding JSON index.
    index: usize,

    /// The corresponding JSON struct.
    json: &'a json::texture::Texture,
}

impl<'a> Sampler<'a> {
    /// Constructs a `Sampler`.
    pub fn new(
        gltf: &'a Gltf,
        index: usize,
        json: &'a json::texture::Sampler,
    ) -> Self {
        Self {
            gltf: gltf,
            index: Some(index),
            json: json,
        }
    }

    /// Constructs the default `Sampler`.
    pub fn default(gltf: &'a Gltf) -> Self {
        Self {
            gltf: gltf,
            index: None,
            json: &DEFAULT_SAMPLER,
        }
    }

    /// Returns the internal JSON index.
    pub fn index(&self) -> Option<usize> {
        self.index
    }

    /// Returns the internal JSON item.
    pub fn as_json(&self) ->  &json::texture::Sampler {
        self.json
    }

    /// Magnification filter.
    pub fn mag_filter(&self) -> Option<MagFilter> {
        self.json.mag_filter.map(|filter| filter.unwrap())
    }

    /// Minification filter.
    pub fn min_filter(&self) -> Option<MinFilter> {
        self.json.min_filter.map(|filter| filter.unwrap())
    }

    /// Optional user-defined name for this object.
    #[cfg(feature = "names")]
    pub fn name(&self) -> Option<&str> {
        self.json.name.as_ref().map(String::as_str)
    }

    /// `s` wrapping mode.
    pub fn wrap_s(&self) -> WrappingMode {
        self.json.wrap_s.unwrap()
    }

    /// `t` wrapping mode.
    pub fn wrap_t(&self) -> WrappingMode {
        self.json.wrap_t.unwrap()
    }

    /// Extension specific data.
    pub fn extensions(&self) -> extensions::texture::Sampler<'a> {
        extensions::texture::Sampler::new(
            self.gltf,
            &self.json.extensions,
        )
    }

    /// Optional application specific data.
    pub fn extras(&self) -> &json::Extras {
        &self.json.extras
    }
}

impl<'a> Texture<'a> {
    /// Constructs a `Texture`.
    pub fn new(
        gltf: &'a Gltf,
        index: usize,
        json: &'a json::texture::Texture,
    ) -> Self {
        Self {
            gltf: gltf,
            index: index,
            json: json,
        }
    }

    /// Returns the internal JSON index.
    pub fn index(&self) -> usize {
        self.index
    }

    /// Returns the internal JSON item.
    pub fn as_json(&self) ->  &json::texture::Texture {
        self.json
    }

    /// Optional user-defined name for this object.
    #[cfg(feature = "names")]
    pub fn name(&self) -> Option<&str> {
        self.json.name.as_ref().map(String::as_str)
    }

    /// The index of the sampler used by this texture.
    pub fn sampler(&self) -> Sampler<'a> {
        self.json.sampler
            .as_ref()
            .map(|index| self.gltf.samplers().nth(index.value() as usize).unwrap())
            .unwrap_or_else(|| Sampler::default(self.gltf))
    }

    /// The index of the image used by this texture.
    pub fn source(&self) -> image::Image<'a> {
        self.gltf.images().nth(self.json.source.value() as usize).unwrap()
    }

    /// Extension specific data.
    pub fn extensions(&self) -> extensions::texture::Texture<'a> {
        extensions::texture::Texture::new(
            self.gltf,
            &self.json.extensions,
        )
    }

    /// Optional application specific data.
    pub fn extras(&self) -> &json::Extras {
        &self.json.extras
    }
}

impl<'a> Info<'a> {
    /// Constructs a reference to a `Texture`.
    pub fn new(texture: Texture<'a>, json: &'a json::texture::Info) -> Self {
        Self {
            texture: texture,
            json: json,
        }
    }

    /// Returns the internal JSON item.
    pub fn as_json(&self) ->  &json::texture::Info {
        self.json
    }

    /// The set index of the texture's `TEXCOORD` attribute.
    pub fn tex_coord(&self) -> u32 {
        self.json.tex_coord
    }

    /// Extension specific data.
    pub fn extensions(&self) -> extensions::texture::Info<'a> {
        extensions::texture::Info::new(
            self.texture.clone(),
            &self.json.extensions,
        )
    }

    /// Optional application specific data.
    pub fn extras(&self) -> &json::Extras {
        &self.json.extras
    }
}

impl<'a> Deref for Info<'a> {
    type Target = Texture<'a>;
    fn deref(&self) -> &Self::Target {
        &self.texture
    }
}
<commit_msg>Update sampler docs<commit_after>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::ops::Deref;
use {extensions, image, json, Gltf};

pub use json::texture::{MagFilter, MinFilter, WrappingMode};

lazy_static! {
    static ref DEFAULT_SAMPLER: json::texture::Sampler = Default::default();
}

/// A reference to a `Texture`.
#[derive(Clone, Debug)]
pub struct Info<'a> {
    /// The parent `Texture` struct.
    texture: Texture<'a>,

    /// The corresponding JSON struct.
    json: &'a json::texture::Info,
}

///  Texture sampler properties for filtering and wrapping modes.
#[derive(Clone, Debug)]
pub struct Sampler<'a> {
    /// The parent `Gltf` struct.
    #[allow(dead_code)]
    gltf: &'a Gltf,

    /// The corresponding JSON index - `None` when the default sampler.
    index: Option<usize>,

    /// The corresponding JSON struct.
    json: &'a json::texture::Sampler,
}

/// A texture and its sampler.
#[derive(Clone, Debug)]
pub struct Texture<'a> {
    /// The parent `Gltf` struct.
    gltf: &'a Gltf,

    /// The corresponding JSON index.
    index: usize,

    /// The corresponding JSON struct.
    json: &'a json::texture::Texture,
}

impl<'a> Sampler<'a> {
    /// Constructs a `Sampler`.
    pub fn new(
        gltf: &'a Gltf,
        index: usize,
        json: &'a json::texture::Sampler,
    ) -> Self {
        Self {
            gltf: gltf,
            index: Some(index),
            json: json,
        }
    }

    /// Constructs the default `Sampler`.
    pub fn default(gltf: &'a Gltf) -> Self {
        Self {
            gltf: gltf,
            index: None,
            json: &DEFAULT_SAMPLER,
        }
    }

    /// Returns the internal JSON index if this `Sampler` was explicity defined.
    ///
    /// This function returns `None` if the `Sampler` is the default sampler.
    pub fn index(&self) -> Option<usize> {
        self.index
    }

    /// Returns the internal JSON item.
    pub fn as_json(&self) ->  &json::texture::Sampler {
        self.json
    }

    /// Magnification filter.
    pub fn mag_filter(&self) -> Option<MagFilter> {
        self.json.mag_filter.map(|filter| filter.unwrap())
    }

    /// Minification filter.
    pub fn min_filter(&self) -> Option<MinFilter> {
        self.json.min_filter.map(|filter| filter.unwrap())
    }

    /// Optional user-defined name for this object.
    #[cfg(feature = "names")]
    pub fn name(&self) -> Option<&str> {
        self.json.name.as_ref().map(String::as_str)
    }

    /// `s` wrapping mode.
    pub fn wrap_s(&self) -> WrappingMode {
        self.json.wrap_s.unwrap()
    }

    /// `t` wrapping mode.
    pub fn wrap_t(&self) -> WrappingMode {
        self.json.wrap_t.unwrap()
    }

    /// Extension specific data.
    pub fn extensions(&self) -> extensions::texture::Sampler<'a> {
        extensions::texture::Sampler::new(
            self.gltf,
            &self.json.extensions,
        )
    }

    /// Optional application specific data.
    pub fn extras(&self) -> &json::Extras {
        &self.json.extras
    }
}

impl<'a> Texture<'a> {
    /// Constructs a `Texture`.
    pub fn new(
        gltf: &'a Gltf,
        index: usize,
        json: &'a json::texture::Texture,
    ) -> Self {
        Self {
            gltf: gltf,
            index: index,
            json: json,
        }
    }

    /// Returns the internal JSON index.
    pub fn index(&self) -> usize {
        self.index
    }

    /// Returns the internal JSON item.
    pub fn as_json(&self) ->  &json::texture::Texture {
        self.json
    }

    /// Optional user-defined name for this object.
    #[cfg(feature = "names")]
    pub fn name(&self) -> Option<&str> {
        self.json.name.as_ref().map(String::as_str)
    }

    /// The index of the sampler used by this texture.
    pub fn sampler(&self) -> Sampler<'a> {
        self.json.sampler
            .as_ref()
            .map(|index| self.gltf.samplers().nth(index.value() as usize).unwrap())
            .unwrap_or_else(|| Sampler::default(self.gltf))
    }

    /// The index of the image used by this texture.
    pub fn source(&self) -> image::Image<'a> {
        self.gltf.images().nth(self.json.source.value() as usize).unwrap()
    }

    /// Extension specific data.
    pub fn extensions(&self) -> extensions::texture::Texture<'a> {
        extensions::texture::Texture::new(
            self.gltf,
            &self.json.extensions,
        )
    }

    /// Optional application specific data.
    pub fn extras(&self) -> &json::Extras {
        &self.json.extras
    }
}

impl<'a> Info<'a> {
    /// Constructs a reference to a `Texture`.
    pub fn new(texture: Texture<'a>, json: &'a json::texture::Info) -> Self {
        Self {
            texture: texture,
            json: json,
        }
    }

    /// Returns the internal JSON item.
    pub fn as_json(&self) ->  &json::texture::Info {
        self.json
    }

    /// The set index of the texture's `TEXCOORD` attribute.
    pub fn tex_coord(&self) -> u32 {
        self.json.tex_coord
    }

    /// Extension specific data.
    pub fn extensions(&self) -> extensions::texture::Info<'a> {
        extensions::texture::Info::new(
            self.texture.clone(),
            &self.json.extensions,
        )
    }

    /// Optional application specific data.
    pub fn extras(&self) -> &json::Extras {
        &self.json.extras
    }
}

impl<'a> Deref for Info<'a> {
    type Target = Texture<'a>;
    fn deref(&self) -> &Self::Target {
        &self.texture
    }
}
<|endoftext|>