<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_fail
/// # #![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`. For more information, see
/// `std::io`.
#[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
///
/// ```
/// 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>Remove bad reference to std::io<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_fail
/// # #![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
///
/// ```
/// 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 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![no_std]
#![crate_name = "unwind"]
#![crate_type = "rlib"]
#![unstable(feature = "panic_unwind", issue = "32837")]
#![deny(warnings)]

#![feature(cfg_target_vendor)]
#![feature(link_cfg)]
#![feature(staged_api)]
#![feature(unwind_attributes)]
#![feature(static_nobundle)]

#![cfg_attr(not(target_env = "msvc"), feature(libc))]

#[cfg(not(target_env = "msvc"))]
extern crate libc;

#[cfg(not(target_env = "msvc"))]
mod libunwind;
#[cfg(not(target_env = "msvc"))]
pub use libunwind::*;

#[cfg(target_env = "musl")]
#[link(name = "unwind", kind = "static-nobundle", cfg(target_feature = "crt-static"))]
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
extern {}
<commit_msg>Do not assume libunwind.a is available<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![no_std]
#![crate_name = "unwind"]
#![crate_type = "rlib"]
#![unstable(feature = "panic_unwind", issue = "32837")]
#![deny(warnings)]

#![feature(cfg_target_vendor)]
#![feature(link_cfg)]
#![feature(staged_api)]
#![feature(unwind_attributes)]
#![feature(static_nobundle)]

#![cfg_attr(not(target_env = "msvc"), feature(libc))]

#[cfg(not(target_env = "msvc"))]
extern crate libc;

#[cfg(not(target_env = "msvc"))]
mod libunwind;
#[cfg(not(target_env = "msvc"))]
pub use libunwind::*;

#[cfg(all(target_env = "musl", not(target_arch = "mips")))]
#[link(name = "unwind", kind = "static", cfg(target_feature = "crt-static"))]
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
extern {}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>We need std::env to parse command line arguments.<commit_after>use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    println!("{:?}", args);
}
<|endoftext|>


<commit_before>//
// Sysinfo
//
// Copyright (c) 2015 Guillaume Gomez
//

use std::collections::HashMap;
use std::fmt;
use std::fs::File;
use std::path::{Path, PathBuf};

use libc::{c_int, gid_t, kill, uid_t};

use crate::{DiskUsage, Pid, ProcessExt, Signal};

/// Enum describing the different status of a process.
#[derive(Clone, Copy, Debug)]
pub enum ProcessStatus {
    /// Waiting in uninterruptible disk sleep.
    Idle,
    /// Running.
    Run,
    /// Sleeping in an interruptible waiting.
    Sleep,
    /// Stopped (on a signal) or (before Linux 2.6.33) trace stopped.
    Stop,
    /// Zombie.
    Zombie,
    /// Tracing stop (Linux 2.6.33 onward).
    Tracing,
    /// Dead.
    Dead,
    /// Wakekill (Linux 2.6.33 to 3.13 only).
    Wakekill,
    /// Waking (Linux 2.6.33 to 3.13 only).
    Waking,
    /// Parked (Linux 3.9 to 3.13 only).
    Parked,
    /// Unknown.
    Unknown(u32),
}

impl From<u32> for ProcessStatus {
    fn from(status: u32) -> ProcessStatus {
        match status {
            1 => ProcessStatus::Idle,
            2 => ProcessStatus::Run,
            3 => ProcessStatus::Sleep,
            4 => ProcessStatus::Stop,
            5 => ProcessStatus::Zombie,
            x => ProcessStatus::Unknown(x),
        }
    }
}

impl From<char> for ProcessStatus {
    fn from(status: char) -> ProcessStatus {
        match status {
            'R' => ProcessStatus::Run,
            'S' => ProcessStatus::Sleep,
            'D' => ProcessStatus::Idle,
            'Z' => ProcessStatus::Zombie,
            'T' => ProcessStatus::Stop,
            't' => ProcessStatus::Tracing,
            'X' | 'x' => ProcessStatus::Dead,
            'K' => ProcessStatus::Wakekill,
            'W' => ProcessStatus::Waking,
            'P' => ProcessStatus::Parked,
            x => ProcessStatus::Unknown(x as u32),
        }
    }
}

impl ProcessStatus {
    /// Used to display `ProcessStatus`.
    pub fn as_str(&self) -> &str {
        match *self {
            ProcessStatus::Idle => "Idle",
            ProcessStatus::Run => "Runnable",
            ProcessStatus::Sleep => "Sleeping",
            ProcessStatus::Stop => "Stopped",
            ProcessStatus::Zombie => "Zombie",
            ProcessStatus::Tracing => "Tracing",
            ProcessStatus::Dead => "Dead",
            ProcessStatus::Wakekill => "Wakekill",
            ProcessStatus::Waking => "Waking",
            ProcessStatus::Parked => "Parked",
            ProcessStatus::Unknown(_) => "Unknown",
        }
    }
}

impl fmt::Display for ProcessStatus {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.as_str())
    }
}

/// Struct containing a process' information.
pub struct Process {
    pub(crate) name: String,
    pub(crate) cmd: Vec<String>,
    pub(crate) exe: PathBuf,
    pub(crate) pid: Pid,
    parent: Option<Pid>,
    pub(crate) environ: Vec<String>,
    pub(crate) cwd: PathBuf,
    pub(crate) root: PathBuf,
    pub(crate) memory: u64,
    pub(crate) virtual_memory: u64,
    utime: u64,
    stime: u64,
    old_utime: u64,
    old_stime: u64,
    start_time: u64,
    updated: bool,
    cpu_usage: f32,
    /// User id of the process owner.
    pub uid: uid_t,
    /// Group id of the process owner.
    pub gid: gid_t,
    pub(crate) status: ProcessStatus,
    /// Tasks run by this process.
    pub tasks: HashMap<Pid, Process>,
    pub(crate) stat_file: Option<File>,
    old_read_bytes: u64,
    old_written_bytes: u64,
    read_bytes: u64,
    written_bytes: u64,
}

impl ProcessExt for Process {
    fn new(pid: Pid, parent: Option<Pid>, start_time: u64) -> Process {
        Process {
            name: String::with_capacity(20),
            pid,
            parent,
            cmd: Vec::with_capacity(2),
            environ: Vec::with_capacity(10),
            exe: PathBuf::new(),
            cwd: PathBuf::new(),
            root: PathBuf::new(),
            memory: 0,
            virtual_memory: 0,
            cpu_usage: 0.,
            utime: 0,
            stime: 0,
            old_utime: 0,
            old_stime: 0,
            updated: true,
            start_time,
            uid: 0,
            gid: 0,
            status: ProcessStatus::Unknown(0),
            tasks: if pid == 0 {
                HashMap::with_capacity(1000)
            } else {
                HashMap::new()
            },
            stat_file: None,
            old_read_bytes: 0,
            old_written_bytes: 0,
            read_bytes: 0,
            written_bytes: 0,
        }
    }

    fn kill(&self, signal: Signal) -> bool {
        unsafe { kill(self.pid, signal as c_int) == 0 }
    }

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

    fn cmd(&self) -> &[String] {
        &self.cmd
    }

    fn exe(&self) -> &Path {
        self.exe.as_path()
    }

    fn pid(&self) -> Pid {
        self.pid
    }

    fn environ(&self) -> &[String] {
        &self.environ
    }

    fn cwd(&self) -> &Path {
        self.cwd.as_path()
    }

    fn root(&self) -> &Path {
        self.root.as_path()
    }

    fn memory(&self) -> u64 {
        self.memory
    }

    fn virtual_memory(&self) -> u64 {
        self.virtual_memory
    }

    fn parent(&self) -> Option<Pid> {
        self.parent
    }

    /// Returns the status of the processus (idle, run, zombie, etc). `None` means that
    /// `sysinfo` doesn't have enough rights to get this information.
    fn status(&self) -> ProcessStatus {
        self.status
    }

    fn start_time(&self) -> u64 {
        self.start_time
    }

    fn cpu_usage(&self) -> f32 {
        self.cpu_usage
    }

    fn disk_usage(&self) -> DiskUsage {
        DiskUsage {
            written_bytes: self.written_bytes - self.old_written_bytes,
            total_written_bytes: self.written_bytes,
            read_bytes: self.read_bytes - self.old_read_bytes,
            total_read_bytes: self.read_bytes,
        }
    }
}

impl Drop for Process {
    fn drop(&mut self) {
        if self.stat_file.is_some() {
            if let Ok(ref mut x) = unsafe { crate::sys::system::REMAINING_FILES.lock() } {
                **x += 1;
            }
        }
    }
}

pub fn compute_cpu_usage(p: &mut Process, nb_processors: u64, total_time: f32) {
    p.cpu_usage =
        ((p.utime - p.old_utime + p.stime - p.old_stime) * nb_processors * 100) as f32 / total_time;
    p.updated = false;
}

pub fn set_time(p: &mut Process, utime: u64, stime: u64) {
    p.old_utime = p.utime;
    p.old_stime = p.stime;
    p.utime = utime;
    p.stime = stime;
    p.updated = true;
}

pub fn has_been_updated(p: &Process) -> bool {
    p.updated
}

pub(crate) fn update_process_disk_activity(p: &mut Process, path: &Path) {
    let mut path = PathBuf::from(path);
    path.push("io");
    let data = match super::system::get_all_data(&path, 16_384) {
        Ok(d) => d,
        Err(_) => return,
    };
    let mut done = 0;
    for line in data.split('\n') {
        let mut parts = line.split(": ");
        match parts.next() {
            Some("read_bytes") => {
                p.old_read_bytes = p.read_bytes;
                p.read_bytes = parts
                    .next()
                    .and_then(|x| x.parse::<u64>().ok())
                    .unwrap_or(p.old_read_bytes);
            }
            Some("write_bytes") => {
                p.old_written_bytes = p.written_bytes;
                p.written_bytes = parts
                    .next()
                    .and_then(|x| x.parse::<u64>().ok())
                    .unwrap_or(p.old_written_bytes);
            }
            _ => continue,
        }
        done += 1;
        if done > 1 {
            // No need to continue the reading.
            break;
        }
    }
}
<commit_msg>linux: process: Check for old values before updating cpu_usage<commit_after>//
// Sysinfo
//
// Copyright (c) 2015 Guillaume Gomez
//

use std::collections::HashMap;
use std::fmt;
use std::fs::File;
use std::path::{Path, PathBuf};

use libc::{c_int, gid_t, kill, uid_t};

use crate::{DiskUsage, Pid, ProcessExt, Signal};

/// Enum describing the different status of a process.
#[derive(Clone, Copy, Debug)]
pub enum ProcessStatus {
    /// Waiting in uninterruptible disk sleep.
    Idle,
    /// Running.
    Run,
    /// Sleeping in an interruptible waiting.
    Sleep,
    /// Stopped (on a signal) or (before Linux 2.6.33) trace stopped.
    Stop,
    /// Zombie.
    Zombie,
    /// Tracing stop (Linux 2.6.33 onward).
    Tracing,
    /// Dead.
    Dead,
    /// Wakekill (Linux 2.6.33 to 3.13 only).
    Wakekill,
    /// Waking (Linux 2.6.33 to 3.13 only).
    Waking,
    /// Parked (Linux 3.9 to 3.13 only).
    Parked,
    /// Unknown.
    Unknown(u32),
}

impl From<u32> for ProcessStatus {
    fn from(status: u32) -> ProcessStatus {
        match status {
            1 => ProcessStatus::Idle,
            2 => ProcessStatus::Run,
            3 => ProcessStatus::Sleep,
            4 => ProcessStatus::Stop,
            5 => ProcessStatus::Zombie,
            x => ProcessStatus::Unknown(x),
        }
    }
}

impl From<char> for ProcessStatus {
    fn from(status: char) -> ProcessStatus {
        match status {
            'R' => ProcessStatus::Run,
            'S' => ProcessStatus::Sleep,
            'D' => ProcessStatus::Idle,
            'Z' => ProcessStatus::Zombie,
            'T' => ProcessStatus::Stop,
            't' => ProcessStatus::Tracing,
            'X' | 'x' => ProcessStatus::Dead,
            'K' => ProcessStatus::Wakekill,
            'W' => ProcessStatus::Waking,
            'P' => ProcessStatus::Parked,
            x => ProcessStatus::Unknown(x as u32),
        }
    }
}

impl ProcessStatus {
    /// Used to display `ProcessStatus`.
    pub fn as_str(&self) -> &str {
        match *self {
            ProcessStatus::Idle => "Idle",
            ProcessStatus::Run => "Runnable",
            ProcessStatus::Sleep => "Sleeping",
            ProcessStatus::Stop => "Stopped",
            ProcessStatus::Zombie => "Zombie",
            ProcessStatus::Tracing => "Tracing",
            ProcessStatus::Dead => "Dead",
            ProcessStatus::Wakekill => "Wakekill",
            ProcessStatus::Waking => "Waking",
            ProcessStatus::Parked => "Parked",
            ProcessStatus::Unknown(_) => "Unknown",
        }
    }
}

impl fmt::Display for ProcessStatus {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.as_str())
    }
}

/// Struct containing a process' information.
pub struct Process {
    pub(crate) name: String,
    pub(crate) cmd: Vec<String>,
    pub(crate) exe: PathBuf,
    pub(crate) pid: Pid,
    parent: Option<Pid>,
    pub(crate) environ: Vec<String>,
    pub(crate) cwd: PathBuf,
    pub(crate) root: PathBuf,
    pub(crate) memory: u64,
    pub(crate) virtual_memory: u64,
    utime: u64,
    stime: u64,
    old_utime: u64,
    old_stime: u64,
    start_time: u64,
    updated: bool,
    cpu_usage: f32,
    /// User id of the process owner.
    pub uid: uid_t,
    /// Group id of the process owner.
    pub gid: gid_t,
    pub(crate) status: ProcessStatus,
    /// Tasks run by this process.
    pub tasks: HashMap<Pid, Process>,
    pub(crate) stat_file: Option<File>,
    old_read_bytes: u64,
    old_written_bytes: u64,
    read_bytes: u64,
    written_bytes: u64,
}

impl ProcessExt for Process {
    fn new(pid: Pid, parent: Option<Pid>, start_time: u64) -> Process {
        Process {
            name: String::with_capacity(20),
            pid,
            parent,
            cmd: Vec::with_capacity(2),
            environ: Vec::with_capacity(10),
            exe: PathBuf::new(),
            cwd: PathBuf::new(),
            root: PathBuf::new(),
            memory: 0,
            virtual_memory: 0,
            cpu_usage: 0.,
            utime: 0,
            stime: 0,
            old_utime: 0,
            old_stime: 0,
            updated: true,
            start_time,
            uid: 0,
            gid: 0,
            status: ProcessStatus::Unknown(0),
            tasks: if pid == 0 {
                HashMap::with_capacity(1000)
            } else {
                HashMap::new()
            },
            stat_file: None,
            old_read_bytes: 0,
            old_written_bytes: 0,
            read_bytes: 0,
            written_bytes: 0,
        }
    }

    fn kill(&self, signal: Signal) -> bool {
        unsafe { kill(self.pid, signal as c_int) == 0 }
    }

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

    fn cmd(&self) -> &[String] {
        &self.cmd
    }

    fn exe(&self) -> &Path {
        self.exe.as_path()
    }

    fn pid(&self) -> Pid {
        self.pid
    }

    fn environ(&self) -> &[String] {
        &self.environ
    }

    fn cwd(&self) -> &Path {
        self.cwd.as_path()
    }

    fn root(&self) -> &Path {
        self.root.as_path()
    }

    fn memory(&self) -> u64 {
        self.memory
    }

    fn virtual_memory(&self) -> u64 {
        self.virtual_memory
    }

    fn parent(&self) -> Option<Pid> {
        self.parent
    }

    /// Returns the status of the processus (idle, run, zombie, etc). `None` means that
    /// `sysinfo` doesn't have enough rights to get this information.
    fn status(&self) -> ProcessStatus {
        self.status
    }

    fn start_time(&self) -> u64 {
        self.start_time
    }

    fn cpu_usage(&self) -> f32 {
        self.cpu_usage
    }

    fn disk_usage(&self) -> DiskUsage {
        DiskUsage {
            written_bytes: self.written_bytes - self.old_written_bytes,
            total_written_bytes: self.written_bytes,
            read_bytes: self.read_bytes - self.old_read_bytes,
            total_read_bytes: self.read_bytes,
        }
    }
}

impl Drop for Process {
    fn drop(&mut self) {
        if self.stat_file.is_some() {
            if let Ok(ref mut x) = unsafe { crate::sys::system::REMAINING_FILES.lock() } {
                **x += 1;
            }
        }
    }
}

pub fn compute_cpu_usage(p: &mut Process, nb_processors: u64, total_time: f32) {
    // First time updating the values without reference, wait for a second cycle to update cpu_usage
    if p.old_utime == 0 && p.old_stime == 0 {
        return;
    }

    p.cpu_usage =
        ((p.utime - p.old_utime + p.stime - p.old_stime) * nb_processors * 100) as f32 / total_time;
    p.updated = false;
}

pub fn set_time(p: &mut Process, utime: u64, stime: u64) {
    p.old_utime = p.utime;
    p.old_stime = p.stime;
    p.utime = utime;
    p.stime = stime;
    p.updated = true;
}

pub fn has_been_updated(p: &Process) -> bool {
    p.updated
}

pub(crate) fn update_process_disk_activity(p: &mut Process, path: &Path) {
    let mut path = PathBuf::from(path);
    path.push("io");
    let data = match super::system::get_all_data(&path, 16_384) {
        Ok(d) => d,
        Err(_) => return,
    };
    let mut done = 0;
    for line in data.split('\n') {
        let mut parts = line.split(": ");
        match parts.next() {
            Some("read_bytes") => {
                p.old_read_bytes = p.read_bytes;
                p.read_bytes = parts
                    .next()
                    .and_then(|x| x.parse::<u64>().ok())
                    .unwrap_or(p.old_read_bytes);
            }
            Some("write_bytes") => {
                p.old_written_bytes = p.written_bytes;
                p.written_bytes = parts
                    .next()
                    .and_then(|x| x.parse::<u64>().ok())
                    .unwrap_or(p.old_written_bytes);
            }
            _ => continue,
        }
        done += 1;
        if done > 1 {
            // No need to continue the reading.
            break;
        }
    }
}
<|endoftext|>


<commit_before>extern crate libc;

use std::ffi::{
    CStr,
    CString,
};
use ffi::{
    memcached,
    memcached_add,
    memcached_exist,
    memcached_flush,
    memcached_free,
    memcached_get,
    memcached_last_error,
    memcached_replace,
    memcached_return_t,
    memcached_set,
    memcached_st,
};
use error::{
    MemcacheError,
    MemcacheResult,
};
use connectable::Connectable;

enum StoreCommand {
    ADD,
    REPLACE,
    SET,
}

//#[derive(Debug)]
pub struct Memcache {
    c_st: *const memcached_st,
}

impl Drop for Memcache {
    fn drop(&mut self) {
        unsafe {
            memcached_free(self.c_st);
        }
    }
}

impl Memcache {
    pub fn connect(connectable: &Connectable) -> MemcacheResult<Memcache> {
        let s = connectable.get_connection_str();
        let cstring = CString::new(s).unwrap();
        let s_len = cstring.to_bytes().len();
        unsafe {
            let c_st = memcached(cstring.as_ptr(), s_len as u64);
            if c_st.is_null() {
                let error_code = memcached_last_error(c_st);
                return Err(MemcacheError::new(error_code));
            }
            return Ok(Memcache{ c_st: c_st });
        }
    }

    /// Flush all the data on memcached after `expiration`.
    ///
    /// If `expiration` is 0, flush data immediatly.
    pub fn flush(&self, expiration: libc::time_t) -> MemcacheResult<()> {
        let r = unsafe{ memcached_flush(self.c_st, expiration) };
        match r {
            memcached_return_t::MEMCACHED_SUCCESS => {
                return Ok(());
            }
            _ => {
                return Err(MemcacheError::new(r));
            }
        }
    }

    /// Determin weather a key is exist on memcached.
    pub fn exist(&self, key: &str) -> MemcacheResult<bool> {
        let key = CString::new(key).unwrap();
        let key_length = key.as_bytes().len();
        let ret = unsafe{
            memcached_exist(self.c_st, key.as_ptr(), key_length as u64)
        };
        match ret {
            memcached_return_t::MEMCACHED_SUCCESS => Ok(true),
            memcached_return_t::MEMCACHED_NOTFOUND => Ok(false),
            _ => Err(MemcacheError::new(ret)),
        }
    }

    fn store_raw(&self, command: StoreCommand, key: &str, value: &[u8], expiration: libc::time_t, flags: u32) -> MemcacheResult<()> {
        // TODO: raise if key containes NULL
        let key = CString::new(key).unwrap();
        let key_length = key.as_bytes().len();
        let value_length = value.len();
        let value = unsafe { CString::from_vec_unchecked(value.to_vec()) };

        let store_func = match command {
            StoreCommand::SET => memcached_set,
            StoreCommand::ADD => memcached_add,
            StoreCommand::REPLACE => memcached_replace,
        };

        let r = unsafe {
            store_func(self.c_st, key.as_ptr(), key_length as u64, value.as_ptr(), value_length as u64, expiration, flags)
        };
        match r {
            memcached_return_t::MEMCACHED_SUCCESS => {
                return Ok(());
            }
            _ => {
                return Err(MemcacheError::new(r));
            }
        }
    }

    /// Set bytes data to memcached.
    pub fn set_raw(&self, key: &str, value: &[u8], expiration: libc::time_t, flags: u32) -> MemcacheResult<()> {
        return self.store_raw(StoreCommand::SET, key, value, expiration, flags);
    }

    /// Set bytes data to memcached only if the key is **not** existed.
    pub fn add_raw(&self, key: &str, value: &[u8], expiration: libc::time_t, flags: u32) -> MemcacheResult<()> {
        return self.store_raw(StoreCommand::ADD, key, value, expiration, flags);
    }

    /// Set bytes data to memcached only if the key is existed.
    pub fn replace_raw(&self, key: &str, value: &[u8], expiration: libc::time_t, flags: u32) -> MemcacheResult<()> {
        return self.store_raw(StoreCommand::REPLACE, key, value, expiration, flags);
    }

    /// Get bytes data from memcached.
    pub fn get_raw(&self, key: &str) -> MemcacheResult<(Vec<u8>, u32)> {
        // TODO: raise if key containes NULL
        let key = CString::new(key).unwrap();
        let key_length = key.as_bytes().len();

        let mut value_length: libc::size_t = 0;
        let value_length_ptr: *mut libc::size_t = &mut value_length;

        let mut flags: libc::uint32_t = 0;
        let flags_ptr: *mut libc::uint32_t = &mut flags;

        let mut ret: memcached_return_t = memcached_return_t::MEMCACHED_FAILURE;
        let ret_ptr: *mut memcached_return_t = &mut ret;

        let raw_value: *const libc::c_char = unsafe {
            memcached_get(self.c_st, key.as_ptr(), key_length as u64, value_length_ptr, flags_ptr, ret_ptr)
        };

        // println!("value: {:?}, error: {:?}, value_length: {:?}", r, error_ptr, value_length_ptr);
        match ret {
            memcached_return_t::MEMCACHED_SUCCESS => {
                unsafe {
                    let value_c_str = CStr::from_ptr(raw_value);
                    let value = value_c_str.to_bytes().to_vec(); // TODO: here have a memory copy
                    libc::free(raw_value as *mut libc::c_void);
                    return Ok((value, flags));
                }
            }
            _ => Err(MemcacheError::new(ret))
        }
    }
}
<commit_msg>add more docs<commit_after>extern crate libc;

use std::ffi::{
    CStr,
    CString,
};
use ffi::{
    memcached,
    memcached_add,
    memcached_exist,
    memcached_flush,
    memcached_free,
    memcached_get,
    memcached_last_error,
    memcached_replace,
    memcached_return_t,
    memcached_set,
    memcached_st,
};
use error::{
    MemcacheError,
    MemcacheResult,
};
use connectable::Connectable;

enum StoreCommand {
    ADD,
    REPLACE,
    SET,
}

//#[derive(Debug)]
pub struct Memcache {
    c_st: *const memcached_st,
}

impl Drop for Memcache {
    fn drop(&mut self) {
        unsafe {
            memcached_free(self.c_st);
        }
    }
}

impl Memcache {
    pub fn connect(connectable: &Connectable) -> MemcacheResult<Memcache> {
        let s = connectable.get_connection_str();
        let cstring = CString::new(s).unwrap();
        let s_len = cstring.to_bytes().len();
        unsafe {
            let c_st = memcached(cstring.as_ptr(), s_len as u64);
            if c_st.is_null() {
                let error_code = memcached_last_error(c_st);
                return Err(MemcacheError::new(error_code));
            }
            return Ok(Memcache{ c_st: c_st });
        }
    }

    /// Flush all the data on memcached after `expiration`.
    ///
    /// If `expiration` is 0, flush data immediatly.
    ///
    /// # Examples
    ///
    /// ```
    /// let mc = memcache::connect(&("localhost", 2333)).unwrap();
    /// mc.flush(0);
    /// ```
    pub fn flush(&self, expiration: libc::time_t) -> MemcacheResult<()> {
        let r = unsafe{ memcached_flush(self.c_st, expiration) };
        match r {
            memcached_return_t::MEMCACHED_SUCCESS => {
                return Ok(());
            }
            _ => {
                return Err(MemcacheError::new(r));
            }
        }
    }

    /// Determin weather a key is exist on memcached.
    pub fn exist(&self, key: &str) -> MemcacheResult<bool> {
        let key = CString::new(key).unwrap();
        let key_length = key.as_bytes().len();
        let ret = unsafe{
            memcached_exist(self.c_st, key.as_ptr(), key_length as u64)
        };
        match ret {
            memcached_return_t::MEMCACHED_SUCCESS => Ok(true),
            memcached_return_t::MEMCACHED_NOTFOUND => Ok(false),
            _ => Err(MemcacheError::new(ret)),
        }
    }

    fn store_raw(&self, command: StoreCommand, key: &str, value: &[u8], expiration: libc::time_t, flags: u32) -> MemcacheResult<()> {
        // TODO: raise if key containes NULL
        let key = CString::new(key).unwrap();
        let key_length = key.as_bytes().len();
        let value_length = value.len();
        let value = unsafe { CString::from_vec_unchecked(value.to_vec()) };

        let store_func = match command {
            StoreCommand::SET => memcached_set,
            StoreCommand::ADD => memcached_add,
            StoreCommand::REPLACE => memcached_replace,
        };

        let r = unsafe {
            store_func(self.c_st, key.as_ptr(), key_length as u64, value.as_ptr(), value_length as u64, expiration, flags)
        };
        match r {
            memcached_return_t::MEMCACHED_SUCCESS => {
                return Ok(());
            }
            _ => {
                return Err(MemcacheError::new(r));
            }
        }
    }

    /// Set bytes data to memcached.
    pub fn set_raw(&self, key: &str, value: &[u8], expiration: libc::time_t, flags: u32) -> MemcacheResult<()> {
        return self.store_raw(StoreCommand::SET, key, value, expiration, flags);
    }

    /// Set bytes data to memcached only if the key is **not** existed.
    pub fn add_raw(&self, key: &str, value: &[u8], expiration: libc::time_t, flags: u32) -> MemcacheResult<()> {
        return self.store_raw(StoreCommand::ADD, key, value, expiration, flags);
    }

    /// Set bytes data to memcached only if the key is existed.
    pub fn replace_raw(&self, key: &str, value: &[u8], expiration: libc::time_t, flags: u32) -> MemcacheResult<()> {
        return self.store_raw(StoreCommand::REPLACE, key, value, expiration, flags);
    }

    /// Get bytes data from memcached.
    pub fn get_raw(&self, key: &str) -> MemcacheResult<(Vec<u8>, u32)> {
        // TODO: raise if key containes NULL
        let key = CString::new(key).unwrap();
        let key_length = key.as_bytes().len();

        let mut value_length: libc::size_t = 0;
        let value_length_ptr: *mut libc::size_t = &mut value_length;

        let mut flags: libc::uint32_t = 0;
        let flags_ptr: *mut libc::uint32_t = &mut flags;

        let mut ret: memcached_return_t = memcached_return_t::MEMCACHED_FAILURE;
        let ret_ptr: *mut memcached_return_t = &mut ret;

        let raw_value: *const libc::c_char = unsafe {
            memcached_get(self.c_st, key.as_ptr(), key_length as u64, value_length_ptr, flags_ptr, ret_ptr)
        };

        // println!("value: {:?}, error: {:?}, value_length: {:?}", r, error_ptr, value_length_ptr);
        match ret {
            memcached_return_t::MEMCACHED_SUCCESS => {
                unsafe {
                    let value_c_str = CStr::from_ptr(raw_value);
                    let value = value_c_str.to_bytes().to_vec(); // TODO: here have a memory copy
                    libc::free(raw_value as *mut libc::c_void);
                    return Ok((value, flags));
                }
            }
            _ => Err(MemcacheError::new(ret))
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Calc start of a backspace delete interval

use view::View;

use xi_rope::tree::Cursor;
use xi_rope::rope::Rope;

use config::BufferItems;
use selection::SelRegion;
use xi_unicode::*;

pub fn offset_for_delete_backwards(view: &View, region: &SelRegion, text: &Rope, config: &BufferItems) -> usize {
    if !region.is_caret() {
        region.min()
    } else {
        if preceded_by_spaces
            && config.translate_tabs_to_spaces
            && config.use_tab_stops {
            // backspace deletes max(1, tab_size) contiguous spaces
            let (_, c) = view.offset_to_line_col(&text, region.start);

            let tab_off = c % config.tab_size;
            let tab_size = config.tab_size;
            let tab_size = if tab_off == 0 { tab_size } else { tab_off };
            let tab_start = region.start.saturating_sub(tab_size);
            let preceded_by_spaces = region.start > 0 &&
                (tab_start..region.start).all(|i| text.byte_at(i) == b' ');
            tab_start
        } else {
            #[derive(PartialEq)]
            enum State {
                Start,
                Lf,
                BeforeKeycap,
                BeforeVsAndKeycap,
                BeforeEmojiModifier,
                BeforeVSAndEmojiModifier,
                BeforeVS,
                BeforeEmoji,
                BeforeZwj,
                BeforeVSAndZWJ,
                OddNumberedRIS,
                EvenNumberedRIS,
                InTagSequence,
                Finished
            };
            let mut state = State::Start;
            let mut tmp_offset = region.end;

            let mut delete_code_point_count = 0;
            let mut last_seen_vs_code_point_count = 0;

            while state != State::Finished && tmp_offset > 0 {
                let mut cursor = Cursor::new(&text, tmp_offset);
                let code_point = cursor.prev_codepoint().unwrap_or('0');

                tmp_offset = text.prev_codepoint_offset(tmp_offset).unwrap_or(0);

                match state {
                    State::Start => {
                        delete_code_point_count = 1;
                        if code_point == '\n' {
                            state = State::Lf;
                        } else if is_variation_selector(code_point) {
                            state = State::BeforeVS;
                        } else if code_point.is_regional_indicator_symbol() {
                            state = State::OddNumberedRIS;
                        } else if code_point.is_emoji_modifier() {
                            state = State::BeforeEmojiModifier;
                        } else if code_point.is_emoji_combining_enclosing_keycap() {
                            state = State::BeforeKeycap;
                        } else if code_point.is_emoji() {
                            state = State::BeforeEmoji;
                        } else if code_point.is_emoji_cancel_tag() {
                            state = State::InTagSequence;
                        } else {
                            state = State::Finished;
                        }
                    }
                    State::Lf => {
                        if code_point == '\r' {
                            delete_code_point_count += 1;
                        }
                        state = State::Finished;
                    }
                    State::OddNumberedRIS => {
                        if code_point.is_regional_indicator_symbol() {
                            delete_code_point_count += 1;
                            state = State::EvenNumberedRIS
                        } else {
                            state = State::Finished
                        }
                    }
                    State::EvenNumberedRIS => {
                        if code_point.is_regional_indicator_symbol() {
                            delete_code_point_count -= 1;
                            state = State::OddNumberedRIS;
                        } else {
                            state = State::Finished;
                        }
                    }
                    State::BeforeKeycap => {
                        if is_variation_selector(code_point) {
                            last_seen_vs_code_point_count = 1;
                            state = State::BeforeVsAndKeycap;
                        } else {
                            if is_keycap_base(code_point) {
                                delete_code_point_count += 1;
                            }
                            state = State::Finished;
                        }
                    }
                    State::BeforeVsAndKeycap => {
                        if is_keycap_base(code_point) {
                            delete_code_point_count += last_seen_vs_code_point_count + 1;
                        }
                        state = State::Finished;
                    }
                    State::BeforeEmojiModifier => {
                        if is_variation_selector(code_point) {
                            last_seen_vs_code_point_count = 1;
                            state = State::BeforeVSAndEmojiModifier;
                        } else {
                            if code_point.is_emoji_modifier_base() {
                                delete_code_point_count += 1;
                            }
                            state = State::Finished;
                        }
                    }
                    State::BeforeVSAndEmojiModifier => {
                        if code_point.is_emoji_modifier_base() {
                            delete_code_point_count += last_seen_vs_code_point_count + 1;
                        }
                        state = State::Finished;
                    }
                    State::BeforeVS => {
                        if code_point.is_emoji() {
                            delete_code_point_count += 1;
                            state = State::BeforeEmoji;
                        } else {
                            if !is_variation_selector(code_point) { //TODO: UCharacter.getCombiningClass(codePoint) == 0
                                delete_code_point_count += 1;
                            }
                            state = State::Finished;
                        }
                    }
                    State::BeforeEmoji => {
                        if code_point.is_zwj() {
                            state = State::BeforeZwj;
                        } else {
                            state = State::Finished;
                        }
                    }
                    State::BeforeZwj => {
                        if code_point.is_emoji() {
                            delete_code_point_count += 2;
                            state = if code_point.is_emoji_modifier() { State::BeforeEmojiModifier } else { State::BeforeEmoji };
                        } else if is_variation_selector(code_point) {
                            last_seen_vs_code_point_count = 1;
                            state = State::BeforeVSAndZWJ;
                        } else {
                            state = State::Finished;
                        }
                    }
                    State::BeforeVSAndZWJ => {
                        if code_point.is_emoji() {
                            delete_code_point_count += last_seen_vs_code_point_count + 2;
                            last_seen_vs_code_point_count = 0;
                            state = State::BeforeEmoji;
                        } else {
                            state = State::Finished;
                        }
                    }
                    State::InTagSequence => {
                        if code_point.is_tag_spec_char() {
                            delete_code_point_count += 1;
                        } else if code_point.is_emoji() {
                            delete_code_point_count += 1;
                            state = State::Finished;
                        } else {
                            delete_code_point_count = 1;
                            state = State::Finished;
                        }
                    }
                    State::Finished => {
                        break;
                    }
                }
            }

            let mut start = region.end;
            while delete_code_point_count > 0 {
                start = text.prev_codepoint_offset(start).unwrap_or(0);
                delete_code_point_count -= 1;
            }
            start
        }
    }
}<commit_msg>Fix cannot find  bug<commit_after>// Copyright 2018 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Calc start of a backspace delete interval

use view::View;

use xi_rope::tree::Cursor;
use xi_rope::rope::Rope;

use config::BufferItems;
use selection::SelRegion;
use xi_unicode::*;

pub fn offset_for_delete_backwards(view: &View, region: &SelRegion, text: &Rope, config: &BufferItems) -> usize {
    if !region.is_caret() {
        region.min()
    } else {
        // backspace deletes max(1, tab_size) contiguous spaces
        let (_, c) = view.offset_to_line_col(&text, region.start);

        let tab_off = c % config.tab_size;
        let tab_size = config.tab_size;
        let tab_size = if tab_off == 0 { tab_size } else { tab_off };
        let tab_start = region.start.saturating_sub(tab_size);
        let preceded_by_spaces = region.start > 0 &&
            (tab_start..region.start).all(|i| text.byte_at(i) == b' ');
        if preceded_by_spaces
            && config.translate_tabs_to_spaces
            && config.use_tab_stops {
            tab_start
        } else {
            #[derive(PartialEq)]
            enum State {
                Start,
                Lf,
                BeforeKeycap,
                BeforeVsAndKeycap,
                BeforeEmojiModifier,
                BeforeVSAndEmojiModifier,
                BeforeVS,
                BeforeEmoji,
                BeforeZwj,
                BeforeVSAndZWJ,
                OddNumberedRIS,
                EvenNumberedRIS,
                InTagSequence,
                Finished
            };
            let mut state = State::Start;
            let mut tmp_offset = region.end;

            let mut delete_code_point_count = 0;
            let mut last_seen_vs_code_point_count = 0;

            while state != State::Finished && tmp_offset > 0 {
                let mut cursor = Cursor::new(&text, tmp_offset);
                let code_point = cursor.prev_codepoint().unwrap_or('0');

                tmp_offset = text.prev_codepoint_offset(tmp_offset).unwrap_or(0);

                match state {
                    State::Start => {
                        delete_code_point_count = 1;
                        if code_point == '\n' {
                            state = State::Lf;
                        } else if is_variation_selector(code_point) {
                            state = State::BeforeVS;
                        } else if code_point.is_regional_indicator_symbol() {
                            state = State::OddNumberedRIS;
                        } else if code_point.is_emoji_modifier() {
                            state = State::BeforeEmojiModifier;
                        } else if code_point.is_emoji_combining_enclosing_keycap() {
                            state = State::BeforeKeycap;
                        } else if code_point.is_emoji() {
                            state = State::BeforeEmoji;
                        } else if code_point.is_emoji_cancel_tag() {
                            state = State::InTagSequence;
                        } else {
                            state = State::Finished;
                        }
                    }
                    State::Lf => {
                        if code_point == '\r' {
                            delete_code_point_count += 1;
                        }
                        state = State::Finished;
                    }
                    State::OddNumberedRIS => {
                        if code_point.is_regional_indicator_symbol() {
                            delete_code_point_count += 1;
                            state = State::EvenNumberedRIS
                        } else {
                            state = State::Finished
                        }
                    }
                    State::EvenNumberedRIS => {
                        if code_point.is_regional_indicator_symbol() {
                            delete_code_point_count -= 1;
                            state = State::OddNumberedRIS;
                        } else {
                            state = State::Finished;
                        }
                    }
                    State::BeforeKeycap => {
                        if is_variation_selector(code_point) {
                            last_seen_vs_code_point_count = 1;
                            state = State::BeforeVsAndKeycap;
                        } else {
                            if is_keycap_base(code_point) {
                                delete_code_point_count += 1;
                            }
                            state = State::Finished;
                        }
                    }
                    State::BeforeVsAndKeycap => {
                        if is_keycap_base(code_point) {
                            delete_code_point_count += last_seen_vs_code_point_count + 1;
                        }
                        state = State::Finished;
                    }
                    State::BeforeEmojiModifier => {
                        if is_variation_selector(code_point) {
                            last_seen_vs_code_point_count = 1;
                            state = State::BeforeVSAndEmojiModifier;
                        } else {
                            if code_point.is_emoji_modifier_base() {
                                delete_code_point_count += 1;
                            }
                            state = State::Finished;
                        }
                    }
                    State::BeforeVSAndEmojiModifier => {
                        if code_point.is_emoji_modifier_base() {
                            delete_code_point_count += last_seen_vs_code_point_count + 1;
                        }
                        state = State::Finished;
                    }
                    State::BeforeVS => {
                        if code_point.is_emoji() {
                            delete_code_point_count += 1;
                            state = State::BeforeEmoji;
                        } else {
                            if !is_variation_selector(code_point) { //TODO: UCharacter.getCombiningClass(codePoint) == 0
                                delete_code_point_count += 1;
                            }
                            state = State::Finished;
                        }
                    }
                    State::BeforeEmoji => {
                        if code_point.is_zwj() {
                            state = State::BeforeZwj;
                        } else {
                            state = State::Finished;
                        }
                    }
                    State::BeforeZwj => {
                        if code_point.is_emoji() {
                            delete_code_point_count += 2;
                            state = if code_point.is_emoji_modifier() { State::BeforeEmojiModifier } else { State::BeforeEmoji };
                        } else if is_variation_selector(code_point) {
                            last_seen_vs_code_point_count = 1;
                            state = State::BeforeVSAndZWJ;
                        } else {
                            state = State::Finished;
                        }
                    }
                    State::BeforeVSAndZWJ => {
                        if code_point.is_emoji() {
                            delete_code_point_count += last_seen_vs_code_point_count + 2;
                            last_seen_vs_code_point_count = 0;
                            state = State::BeforeEmoji;
                        } else {
                            state = State::Finished;
                        }
                    }
                    State::InTagSequence => {
                        if code_point.is_tag_spec_char() {
                            delete_code_point_count += 1;
                        } else if code_point.is_emoji() {
                            delete_code_point_count += 1;
                            state = State::Finished;
                        } else {
                            delete_code_point_count = 1;
                            state = State::Finished;
                        }
                    }
                    State::Finished => {
                        break;
                    }
                }
            }

            let mut start = region.end;
            while delete_code_point_count > 0 {
                start = text.prev_codepoint_offset(start).unwrap_or(0);
                delete_code_point_count -= 1;
            }
            start
        }
    }
}<|endoftext|>


<commit_before>use point::Point;
use ui_context::UIID;
use UiContext;
use graphics::math::Scalar;

/// A trait that indicates whether or not a widget
/// builder is positionable.
pub trait Positionable {
    fn point(self, pos: Point) -> Self;
    fn position(self, x: f64, y: f64) -> Self;
    fn down<C>(self, padding: f64, uic: &UiContext<C>) -> Self;
    fn up<C>(self, padding: f64, uic: &UiContext<C>) -> Self;
    fn left<C>(self, padding: f64, uic: &UiContext<C>) -> Self;
    fn right<C>(self, padding: f64, uic: &UiContext<C>) -> Self;
    fn down_from<C>(self, ui_id: UIID, padding: f64, uic: &UiContext<C>) -> Self;
    fn up_from<C>(self, ui_id: UIID, padding: f64, uic: &UiContext<C>) -> Self;
    fn left_from<C>(self, ui_id: UIID, padding: f64, uic: &UiContext<C>) -> Self;
    fn right_from<C>(self, ui_id: UIID, padding: f64, uic: &UiContext<C>) -> Self;
}

/// Position property.
#[derive(Copy, Clone)]
pub struct Position(pub [Scalar; 2]);

/*
impl<T> Positionable for T
    where
        (Position, T): Pair<Data = Position, Object = T> + SetAt
{

    #[inline]
    fn point(self, pos: Point) -> Self {
        self.set(Position(pos))
    }

    #[inline]
    fn position(self, x: f64, y: f64) -> Self {
        self.set(Position([x as Scalar, y as Scalar]))
    }

    #[inline]
    fn down<C>(self, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uic.get_prev_uiid()).down(padding);
        self.set(Position([x, y]))
    }
    #[inline]
    fn up<C>(self, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uic.get_prev_uiid()).up(padding);
        self.set(Position([x, y]))
    }
    #[inline]
    fn left<C>(self, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uic.get_prev_uiid()).left(padding);
        self.set(Position([x, y]))
    }
    #[inline]
    fn right<C>(self, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uic.get_prev_uiid()).right(padding);
        self.set(Position([x, y]))
    }

    #[inline]
    fn down_from<C>(self, uiid: u64, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uiid).down(padding);
        self.set(Position([x, y]))
    }
    #[inline]
    fn up_from<C>(self, uiid: u64, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uiid).up(padding);
        self.set(Position([x, y]))
    }
    #[inline]
    fn left_from<C>(self, uiid: u64, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uiid).left(padding);
        self.set(Position([x, y]))
    }
    #[inline]
    fn right_from<C>(self, uiid: u64, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uiid).right(padding);
        self.set(Position([x, y]))
    }
}
*/
<commit_msg>Made provided trait methods on `Positionable`<commit_after>use point::Point;
use ui_context::UIID;
use UiContext;
use graphics::math::Scalar;

/// A trait that indicates whether or not a widget
/// builder is positionable.
pub trait Positionable: Sized {
    fn point(self, pos: Point) -> Self;
    fn position(self, x: f64, y: f64) -> Self {
        self.point([x, y])
    }
    fn down<C>(self, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uic.get_prev_uiid()).down(padding);
        self.point([x, y])
    }
    fn up<C>(self, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uic.get_prev_uiid()).up(padding);
        self.point([x, y])
    }
    fn left<C>(self, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uic.get_prev_uiid()).left(padding);
        self.point([x, y])
    }
    fn right<C>(self, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(uic.get_prev_uiid()).right(padding);
        self.point([x, y])
    }
    fn down_from<C>(self, ui_id: UIID, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(ui_id).down(padding);
        self.point([x, y])
    }
    fn up_from<C>(self, ui_id: UIID, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(ui_id).up(padding);
        self.point([x, y])
    }
    fn left_from<C>(self, ui_id: UIID, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(ui_id).left(padding);
        self.point([x, y])
    }
    fn right_from<C>(self, ui_id: UIID, padding: f64, uic: &UiContext<C>) -> Self {
        let (x, y) = uic.get_placing(ui_id).right(padding);
        self.point([x, y])
    }
}

/// Position property.
#[derive(Copy, Clone)]
pub struct Position(pub [Scalar; 2]);
<|endoftext|>