<commit_before>#![crate_id = "base58"]
#![crate_type = "rlib"]
#![license = "Apache License, Version 2.0"]
#![deny(missing_doc)]

//! Rust-Base58 provides functions to encode and decode base58 values.

static BASE_256:u16 = 256;
static BASE_58:u16 = 58;

/// Encode a String into base58 String.
///
/// ```rust{.example}
/// extern crate base58;
/// use base58::encode_base58;
///
/// fn main() {
///   let encoded = encode_base58(String::from_str("azerty"));
///   println!("encoded: {}",encoded); // will print "encoded: qYPmmAqv"
/// }
/// ```
pub fn encode_base58 (input: String) -> String {
  let mut copied = input.into_bytes();
  let mut output:Vec<u8> = Vec::with_capacity(copied.len() * 138 / 100 + 1);
  let len = copied.len();

  if len == 0 {
    return String::new();
  }

  let mut count = 0;
  while count < len {
    let modulo = divide_by_58(&mut copied, count);
    let letter = from_alphabet(modulo);
    output.push(letter);

    if *copied.get(count) == 0 {
      count += 1;
    }
  }

  output.reverse();

  match String::from_utf8(output) {
    Ok(result) => result,
    Err(e) => fail!(e)
  }
}

/// Give the letter from the base58 alphabet
fn from_alphabet(position: u16) -> u8 {
  "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".char_at(position as uint) as u8
}

/// This function make the division by 256 of a big number stored in a Vec
/// and returns the modulo of the division.
/// The given Vec is modified and becomes the result of the division.
fn divide_by_58(input: &mut Vec<u8>, start: uint) -> u16 {
  let mut remainder = 0;

  for x in input.mut_iter().skip(start) {
    let num_base256: u16 = (*x as u16) & 0xFF;
    let temp = remainder * BASE_256 + num_base256;
    *x = (temp / BASE_58) as u8;
    remainder = temp % BASE_58;
  }

  remainder
}

/// This function make the division by 58 of a big number stored in a Vec
/// and returns the modulo of the division.
/// The given Vec is modified and becomes the result of the division.
fn divide_by_256(input: &mut Vec<u8>, start: uint) -> u16 {
  let mut remainder = 0;

  for x in input.mut_iter().skip(start) {
    let num_base58: u16 = (*x as u16) & 0xFF;
    let temp = remainder * BASE_58 + num_base58;
    *x = (temp / BASE_256) as u8;
    remainder = temp % BASE_256;
  }

  remainder
}

#[cfg(test)]
mod tests {

  use super::divide_by_256;
  use super::divide_by_58;

	/* Divisions by 256 */

  #[test]
  fn should_divide_zero_by_58_without_modulo() {
    // Given
    let mut input = vec!(0u8, 0, 0, 0);

    // When
    let modulo = divide_by_58(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 0);
    assert_eq!(*input.get(1), 0);
    assert_eq!(*input.get(2), 0);
    assert_eq!(*input.get(3), 0);
    assert_eq!(modulo, 0);
  }

  #[test]
  fn should_divide_100_43_by_58_with_modulo_7() {
    // Given
    let mut input = vec!(100u8, 43);

    // When
    let modulo = divide_by_58(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 1);
    assert_eq!(*input.get(1), 186);
    assert_eq!(modulo, 7);
  }

	/* Divisions by 58 */

  #[test]
  fn should_divide_zero_by_256_without_modulo() {
    // Given
    let mut input = vec!(0u8, 0, 0, 0);

    // When
    let modulo = divide_by_256(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 0);
    assert_eq!(*input.get(1), 0);
    assert_eq!(*input.get(2), 0);
    assert_eq!(*input.get(3), 0);
    assert_eq!(modulo, 0);
  }

  #[test]
  fn should_divide_100_43_by_256_with_modulo_228() {
    // Given
    let mut input = vec!(13u8, 12, 88);

    // When
    let modulo = divide_by_256(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 0);
    assert_eq!(*input.get(1), 2);
    assert_eq!(*input.get(2), 57);
    assert_eq!(modulo, 228);
  }

}
<commit_msg>Add index_of_letter function<commit_after>#![crate_id = "base58"]
#![crate_type = "rlib"]
#![license = "Apache License, Version 2.0"]
#![deny(missing_doc)]

//! Rust-Base58 provides functions to encode and decode base58 values.

static BASE_256:u16 = 256;
static BASE_58:u16 = 58;

/// Encode a String into base58 String.
///
/// ```rust{.example}
/// extern crate base58;
/// use base58::encode_base58;
///
/// fn main() {
///   let encoded = encode_base58(String::from_str("azerty"));
///   println!("encoded: {}",encoded); // will print "encoded: qYPmmAqv"
/// }
/// ```
pub fn encode_base58 (input: String) -> String {
  let mut copied = input.into_bytes();
  let mut output:Vec<u8> = Vec::with_capacity(copied.len() * 138 / 100 + 1);
  let len = copied.len();

  if len == 0 {
    return String::new();
  }

  let mut count = 0;
  while count < len {
    let modulo = divide_by_58(&mut copied, count);
    let letter = from_alphabet(modulo);
    output.push(letter);

    if *copied.get(count) == 0 {
      count += 1;
    }
  }

  output.reverse();

  match String::from_utf8(output) {
    Ok(result) => result,
    Err(e) => fail!(e)
  }
}

/// Give the letter from the base58 alphabet
fn from_alphabet(position: u16) -> u8 {
  "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".char_at(position as uint) as u8
}

/// Give the index of a letter in the alphabet
fn index_of_letter(letter: char) -> Option<uint> {
  "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".find(letter)
}

/// This function make the division by 256 of a big number stored in a Vec
/// and returns the modulo of the division.
/// The given Vec is modified and becomes the result of the division.
fn divide_by_58(input: &mut Vec<u8>, start: uint) -> u16 {
  let mut remainder = 0;

  for x in input.mut_iter().skip(start) {
    let num_base256: u16 = (*x as u16) & 0xFF;
    let temp = remainder * BASE_256 + num_base256;
    *x = (temp / BASE_58) as u8;
    remainder = temp % BASE_58;
  }

  remainder
}

/// This function make the division by 58 of a big number stored in a Vec
/// and returns the modulo of the division.
/// The given Vec is modified and becomes the result of the division.
fn divide_by_256(input: &mut Vec<u8>, start: uint) -> u16 {
  let mut remainder = 0;

  for x in input.mut_iter().skip(start) {
    let num_base58: u16 = (*x as u16) & 0xFF;
    let temp = remainder * BASE_58 + num_base58;
    *x = (temp / BASE_256) as u8;
    remainder = temp % BASE_256;
  }

  remainder
}

#[cfg(test)]
mod tests {

  use super::divide_by_256;
  use super::divide_by_58;
  use super::from_alphabet;
  use super::index_of_letter;

  /* Divisions by 256 */

  #[test]
  fn should_divide_zero_by_58_without_modulo() {
    // Given
    let mut input = vec!(0u8, 0, 0, 0);

    // When
    let modulo = divide_by_58(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 0);
    assert_eq!(*input.get(1), 0);
    assert_eq!(*input.get(2), 0);
    assert_eq!(*input.get(3), 0);
    assert_eq!(modulo, 0);
  }

  #[test]
  fn should_divide_100_43_by_58_with_modulo_7() {
    // Given
    let mut input = vec!(100u8, 43);

    // When
    let modulo = divide_by_58(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 1);
    assert_eq!(*input.get(1), 186);
    assert_eq!(modulo, 7);
  }

  /* Divisions by 58 */

  #[test]
  fn should_divide_zero_by_256_without_modulo() {
    // Given
    let mut input = vec!(0u8, 0, 0, 0);

    // When
    let modulo = divide_by_256(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 0);
    assert_eq!(*input.get(1), 0);
    assert_eq!(*input.get(2), 0);
    assert_eq!(*input.get(3), 0);
    assert_eq!(modulo, 0);
  }

  #[test]
  fn should_divide_100_43_by_256_with_modulo_228() {
    // Given
    let mut input = vec!(13u8, 12, 88);

    // When
    let modulo = divide_by_256(&mut input, 0);

    // Then
    assert_eq!(*input.get(0), 0);
    assert_eq!(*input.get(1), 2);
    assert_eq!(*input.get(2), 57);
    assert_eq!(modulo, 228);
  }

  #[test]
  fn should_find_right_letters_from_alphabet() {
    // Given

    // When
    let letter_1 = from_alphabet(0);
    let letter_A = from_alphabet(9);

    // Then
    assert_eq!(letter_1, 49u8);
    assert_eq!(letter_A, 65u8);
  }

  #[test]
  fn should_find_right_index_into_alphabet() {
    // Given

    // When
    let index_1 = index_of_letter('1').unwrap_or(255);
    let index_A = index_of_letter('A').unwrap_or(255);

    // Then
    assert_eq!(index_1, 0);
    assert_eq!(index_A, 9);
  }

}
<|endoftext|>


<commit_before>/*!
Rust bindings to the [sodium library](https://github.com/jedisct1/libsodium).

Sodium is a portable implementation of Dan Bernsteins [NaCl: Networking and
Cryptography library](http://nacl.cr.yp.to)

For most users, if you want public-key (asymmetric) cryptography you should use
the functions in `crypto::asymmetricbox` for encryption/decryption.

If you want secret-key (symmetric) cryptography you should be using the
functions in `crypto::secretbox` for encryption/decryption.

For public-key signatures you should use the functions in `crypto::sign` for
signature creation and verification.

Unless you know what you're doing you most certainly don't want to use the
functions in `crypto::scalarmult`, `crypto::stream`, `crypto::auth` and
`crypto::onetimeauth`.

## Thread Safety
All functions in this library are thread-safe provided that the `init()`
function has been called during program execution.

If `init()` hasn't been called then all functions except the random-number
generation functions and the key-generation functions are thread-safe.

# Public-key cryptography
 `crypto::asymmetricbox`

 `crypto::sign`

# Secret-key cryptography
 `crypto::secretbox`

 `crypto::stream`

 `crypto::auth`

 `crypto::onetimeauth`

# Low-level functions
 `crypto::hash`

 `crypto::verify`

 `crypto::shorthash`
 */
#![crate_name = "sodiumoxide"]
#![crate_type = "lib"]
#![warn(missing_docs)]
#![warn(non_upper_case_globals)]
#![warn(non_camel_case_types)]
#![warn(unused_qualifications)]
#![feature(collections, core)]

/* workaround: the rust compiler doesn't recognize
   the features old_io, old_path, and test yet, still it warns
   about using them */
#![allow(unused_features)]
#![feature(test)]

extern crate libsodium_sys as ffi;
extern crate libc;

/**
 * `init()` initializes the sodium library and chooses faster versions of
 * the primitives if possible. `init()` also makes the random number generation
 * functions (`gen_key`, `gen_keypair`, `gen_nonce`, `randombytes`, `randombytes_into`)
 * thread-safe
 */
pub fn init() -> bool {
    unsafe {
        ffi::sodium_init() == 0
    }
}

#[macro_use]
mod utils;

pub mod randombytes;

/**
 * Cryptographic functions
 */
pub mod crypto {
    pub mod asymmetricbox;
    pub mod sign;
    pub mod scalarmult;
    pub mod auth;
    pub mod hash;
    pub mod secretbox;
    pub mod onetimeauth;
    pub mod stream;
    pub mod shorthash;
    pub mod verify;
}

<commit_msg>Remove unsupported features, #51<commit_after>/*!
Rust bindings to the [sodium library](https://github.com/jedisct1/libsodium).

Sodium is a portable implementation of Dan Bernsteins [NaCl: Networking and
Cryptography library](http://nacl.cr.yp.to)

For most users, if you want public-key (asymmetric) cryptography you should use
the functions in `crypto::asymmetricbox` for encryption/decryption.

If you want secret-key (symmetric) cryptography you should be using the
functions in `crypto::secretbox` for encryption/decryption.

For public-key signatures you should use the functions in `crypto::sign` for
signature creation and verification.

Unless you know what you're doing you most certainly don't want to use the
functions in `crypto::scalarmult`, `crypto::stream`, `crypto::auth` and
`crypto::onetimeauth`.

## Thread Safety
All functions in this library are thread-safe provided that the `init()`
function has been called during program execution.

If `init()` hasn't been called then all functions except the random-number
generation functions and the key-generation functions are thread-safe.

# Public-key cryptography
 `crypto::asymmetricbox`

 `crypto::sign`

# Secret-key cryptography
 `crypto::secretbox`

 `crypto::stream`

 `crypto::auth`

 `crypto::onetimeauth`

# Low-level functions
 `crypto::hash`

 `crypto::verify`

 `crypto::shorthash`
 */
#![crate_name = "sodiumoxide"]
#![crate_type = "lib"]
#![warn(missing_docs)]
#![warn(non_upper_case_globals)]
#![warn(non_camel_case_types)]
#![warn(unused_qualifications)]

extern crate libsodium_sys as ffi;
extern crate libc;

/**
 * `init()` initializes the sodium library and chooses faster versions of
 * the primitives if possible. `init()` also makes the random number generation
 * functions (`gen_key`, `gen_keypair`, `gen_nonce`, `randombytes`, `randombytes_into`)
 * thread-safe
 */
pub fn init() -> bool {
    unsafe {
        ffi::sodium_init() == 0
    }
}

#[macro_use]
mod utils;

pub mod randombytes;

/**
 * Cryptographic functions
 */
pub mod crypto {
    pub mod asymmetricbox;
    pub mod sign;
    pub mod scalarmult;
    pub mod auth;
    pub mod hash;
    pub mod secretbox;
    pub mod onetimeauth;
    pub mod stream;
    pub mod shorthash;
    pub mod verify;
}

<|endoftext|>


<commit_before>#![no_std]

extern crate abs;
extern crate from_primitive;
extern crate max;
extern crate min;
extern crate one;
extern crate round;
extern crate signum;
extern crate sqrt;
extern crate trig;
extern crate zero;

use core::ops::*;

pub use abs::Abs;
pub use from_primitive::FromPrimitive;
pub use max::Max;
pub use min::Min;
pub use one::One;
pub use round::Round;
pub use signum::Signum;
pub use sqrt::Sqrt;
pub use trig::Trig;
pub use zero::Zero;

pub trait Num:
    Copy + One + Zero + Sqrt
    + Min + Max + Signum
    + Abs
    + FromPrimitive
    + Trig
    + PartialEq
    + PartialOrd
    + Round

    + Add<Self, Output = Self>
    + Mul<Self, Output = Self>
    + Sub<Self, Output = Self>
    + Div<Self, Output = Self>
    + Rem<Self, Output = Self>
    + Neg<Output = Self> {}

impl<T> Num for T where T:
    Copy + One + Zero + Sqrt
    + Min + Max + Signum
    + Abs
    + FromPrimitive
    + Trig
    + PartialEq
    + PartialOrd
    + Round

    + Add<T, Output = T>
    + Mul<T, Output = T>
    + Sub<T, Output = T>
    + Div<T, Output = T>
    + Rem<T, Output = T>
    + Neg<Output = T> {}
<commit_msg>added ToString trait<commit_after>#![feature(collections)]
#![no_std]

extern crate collections;

extern crate abs;
extern crate from_primitive;
extern crate max;
extern crate min;
extern crate one;
extern crate round;
extern crate signum;
extern crate sqrt;
extern crate trig;
extern crate zero;

use collections::string::ToString;
use core::ops::*;

pub use abs::Abs;
pub use from_primitive::FromPrimitive;
pub use max::Max;
pub use min::Min;
pub use one::One;
pub use round::Round;
pub use signum::Signum;
pub use sqrt::Sqrt;
pub use trig::Trig;
pub use zero::Zero;

pub trait Num:
    Copy + One + Zero + Sqrt
    + Min + Max + Signum
    + Abs
    + FromPrimitive
    + Trig
    + PartialEq
    + PartialOrd
    + Round
    + ToString

    + Add<Self, Output = Self>
    + Mul<Self, Output = Self>
    + Sub<Self, Output = Self>
    + Div<Self, Output = Self>
    + Rem<Self, Output = Self>
    + Neg<Output = Self> {}

impl<T> Num for T where T:
    Copy + One + Zero + Sqrt
    + Min + Max + Signum
    + Abs
    + FromPrimitive
    + Trig
    + PartialEq
    + PartialOrd
    + Round
    + ToString

    + Add<T, Output = T>
    + Mul<T, Output = T>
    + Sub<T, Output = T>
    + Div<T, Output = T>
    + Rem<T, Output = T>
    + Neg<Output = T> {}
<|endoftext|>


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

//! # LLDB
//!
//! This crate provides a safe binding to the public API for [LLDB], the
//! debugger provided by the [LLVM project]. LLDB provides a modern, high
//! performance debugger framework and is the default debugger for macOS
//! and iOS.
//!
//! ## Installation
//!
//! This crate works with Cargo and is on [crates.io].
//! Add it to your `Cargo.toml` like so:
//!
//! ```toml
//! lldb = "0.0.7"
//! ```
//!
//! ### macOS Installation Notes
//!
//! On macOS, this library relies upon being able to find
//! the `LLDB.framework` that is provided by Xcode.app.
//!
//! In your own application, you will need to configure the
//! `@rpath` for your execuable to point to the location
//! of the `LLDB.framework` that you are using. Doing this
//! automatically is not currently supported by Cargo.
//!
//! For testing, you can use the version provided by
//! Xcode.app by setting an environment variable:
//!
//! ```shell
//! export DYLD_FRAMEWORK_PATH=/Applications/Xcode.app/Contents/SharedFrameworks
//! ```
//!
//! ### Linux Installation Notes
//!
//! Install the `lldb` and `lldb-dev` packages for your platform so that
//! you have both LLDB itself installed as well as the headers and
//! other support files required.
//!
//! ### Windows Installation Notes
//!
//! Support for building this has not yet been provided for Windows.
//! Contributions are welcome!
//!
//! ## Usage
//!
//! The primary entry point is [`SBDebugger`]. This will be how you
//! create a debug target and begin the actually interesting stuff.
//!
//! ## Important Classes
//!
//! The LLDB API provides many structs and a wide range of functionality. Some of the
//! most common usages will involve these structs and their corresponding methods:
//!
//! * [`SBDebugger`]: Manages the entire debug experience and creates [`SBTarget`]s.
//! * [`SBTarget`]: The target program running under the debugger.
//! * [`SBProcess`]: The process associated with the target program.
//! * [`SBThread`]: A thread of execution. [`SBProcess`] contains
//!   [`SBThread`]s.
//! * [`SBFrame`]: One of the stack frames associated with
//!   a thread. [`SBThread`] contains [`SBFrame`]s.
//! * [`SBSymbolContext`]: A container that stores various debugger
//!   related info.
//! * [`SBValue`]: The value of a variable, a register, or an
//!   expression.
//! * [`SBModule`]: An executable image and its associated object
//!   and symbol files.  [`SBTarget`] contains [`SBModule`]s.
//! * [`SBBreakpoint`]: A logical breakpoint and its associated
//!   settings. [`SBTarget`] contains [`SBBreakpoint`]s.
//! * [`SBSymbol`]: The symbol possibly associated with a stack frame.
//! * [`SBCompileUnit`]: A compilation unit, or compiled source file.
//! * [`SBFunction`]: A generic function, which can be inlined or not.
//! * [`SBBlock`]: A lexical block. [`SBFunction`] contains [`SBBlock`]s.
//! * [`SBLineEntry`]: Specifies an association with a contiguous range of
//!   instructions and a source file location. [`SBCompileUnit`] contains
//!   [`SBLineEntry`]s.
//!
//! ## Support and Maintenance
//!
//! I am developing this library largely on my own so far. I am able
//! to offer support and maintenance, but would very much appreciate
//! donations via [Patreon](https://patreon.com/endoli). I can also
//! provide commercial support, so feel free to
//! [contact me](mailto:bruce.mitchener@gmail.com).
//!
//! [LLDB]: http://lldb.llvm.org/
//! [LLVM project]: http://llvm.org/
//! [crates.io]: https://crates.io/crates/lldb
//! [`SBDebugger`]: struct.SBDebugger.html
//! [`SBTarget`]: struct.SBTarget.html
//! [`SBProcess`]: struct.SBProcess.html
//! [`SBThread`]: struct.SBThread.html
//! [`SBFrame`]: struct.SBFrame.html
//! [`SBSymbolContext`]: struct.SBSymbolContext.html
//! [`SBValue`]: struct.SBValue.html
//! [`SBModule`]: struct.SBModule.html
//! [`SBBreakpoint`]: struct.SBBreakpoint.html
//! [`SBSymbol`]: struct.SBSymbol.html
//! [`SBCompileUnit`]: struct.SBCompileUnit.html
//! [`SBFunction`]: struct.SBFunction.html
//! [`SBBlock`]: struct.SBBlock.html
//! [`SBLineEntry`]: struct.SBLineEntry.html

#![warn(missing_docs)]
#![deny(trivial_numeric_casts, unstable_features,
        unused_import_braces, unused_qualifications)]

extern crate lldb_sys as sys;

#[cfg(feature = "graphql")]
#[macro_use]
extern crate juniper;

pub use sys::{lldb_addr_t, lldb_offset_t, lldb_pid_t, lldb_tid_t, lldb_user_id_t};

pub use sys::{AccessType, AddressClass, BasicType, BreakpointEventType, ByteOrder,
              CommandArgumentType, CommandFlags, ConnectionStatus, DescriptionLevel,
              DynamicValueType, EmulateInstructionOptions, Encoding, ErrorType,
              ExpressionEvaluationPhase, ExpressionResults, FilePermissions, Format,
              FrameComparison, FunctionNameType, GdbSignal, InputReaderAction,
              InputReaderGranularity, InstrumentationRuntimeType, LanguageType, LaunchFlags,
              MatchType, MemberFunctionKind, PathType, Permissions, QueueItemKind, QueueKind,
              RegisterKind, ReturnStatus, RunMode, ScriptLanguage, SectionType, StateType,
              StopReason, SymbolContextItem, SymbolType, TemplateArgumentKind, TypeClass,
              TypeFlags, TypeOptions, TypeSummaryCapping, ValueType, WatchpointEventType,
              WatchpointKind};

mod address;
mod attachinfo;
mod block;
mod breakpoint;
mod breakpointlist;
mod breakpointlocation;
mod broadcaster;
mod compileunit;
mod data;
mod debugger;
mod error;
mod event;
mod expressionoptions;
mod filespec;
mod filespeclist;
mod frame;
mod function;
mod instruction;
mod instructionlist;
mod launchinfo;
mod lineentry;
mod listener;
mod module;
mod modulespec;
mod platform;
mod process;
mod queue;
mod queueitem;
mod section;
mod stream;
mod stringlist;
mod structureddata;
mod symbol;
mod symbolcontext;
mod target;
mod thread;
mod types;
mod typelist;
mod value;
mod valuelist;
mod variablesoptions;
mod watchpoint;

pub use self::address::SBAddress;
pub use self::attachinfo::SBAttachInfo;
pub use self::block::SBBlock;
pub use self::breakpoint::{SBBreakpoint, SBBreakpointLocationIter};
pub use self::breakpointlist::{SBBreakpointList, SBBreakpointListIter};
pub use self::breakpointlocation::SBBreakpointLocation;
pub use self::broadcaster::SBBroadcaster;
pub use self::compileunit::SBCompileUnit;
pub use self::data::SBData;
pub use self::debugger::{SBDebugger, SBDebuggerTargetIter};
pub use self::error::SBError;
pub use self::event::SBEvent;
pub use self::expressionoptions::SBExpressionOptions;
pub use self::filespec::SBFileSpec;
pub use self::filespeclist::{SBFileSpecList, SBFileSpecListIter};
pub use self::frame::SBFrame;
pub use self::function::SBFunction;
pub use self::instruction::SBInstruction;
pub use self::instructionlist::{SBInstructionList, SBInstructionListIter};
pub use self::launchinfo::SBLaunchInfo;
pub use self::lineentry::SBLineEntry;
pub use self::listener::SBListener;
pub use self::module::{SBModule, SBModuleSectionIter};
pub use self::modulespec::SBModuleSpec;
pub use self::platform::SBPlatform;
pub use self::process::{SBProcess, SBProcessEvent, SBProcessEventRestartedReasonIter,
                        SBProcessQueueIter, SBProcessThreadIter};
pub use self::queue::{SBQueue, SBQueueQueueItemIter, SBQueueThreadIter};
pub use self::queueitem::SBQueueItem;
pub use self::section::{SBSection, SBSectionSubSectionIter};
pub use self::stream::SBStream;
pub use self::stringlist::{SBStringList, SBStringListIter};
pub use self::structureddata::SBStructuredData;
pub use self::symbol::SBSymbol;
pub use self::symbolcontext::SBSymbolContext;
pub use self::target::{SBTarget, SBTargetBreakpointIter, SBTargetEvent, SBTargetEventModuleIter,
                       SBTargetModuleIter, SBTargetWatchpointIter};
pub use self::thread::{SBThread, SBThreadEvent, SBThreadFrameIter};
pub use self::types::SBType;
pub use self::typelist::{SBTypeList, SBTypeListIter};
pub use self::value::SBValue;
pub use self::valuelist::{SBValueList, SBValueListIter};
pub use self::variablesoptions::SBVariablesOptions;
pub use self::watchpoint::SBWatchpoint;

/// Which syntax should be used in disassembly?
///
/// On x86, there are 2 syntaxes used for disassembly. Other
/// architectures need not be concerned by this and can just
/// use `DisassemblyFlavor::Default` all the time.
#[derive(Clone, Copy, Debug)]
pub enum DisassemblyFlavor {
    /// The primary syntax used by the GNU Assembler and in the
    /// Linux world.
    ///
    /// AT&T syntax:
    ///
    /// * Operations has a suffix, indicating the operand size.
    /// * Prefixes registers with `%` and immediate values with `$`.
    /// * Orders operands with source first, then destination.
    /// * Memory operands are somewhat complicated.
    ///
    /// For example:
    ///
    /// ```asm
    /// movb $0x05, %al
    /// ```
    ///
    /// This syntax is described in detail in [GAS Syntax].
    ///
    /// [GAS Syntax]: https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax
    ATT,
    /// The default syntax.
    Default,
    /// The primary syntax used on Windows.
    ///
    /// This differs from AT&T syntax in that:
    ///
    /// * Operations are not suffixed.
    /// * Registers are not prefixed with `%`, immediate values have a suffix.
    /// * Operands are ordered so that the destination is first, then the source.
    ///
    /// For example:
    ///
    /// ```asm
    /// mov al, 05h
    /// ```
    ///
    Intel,
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<commit_msg>Fix typo ('execuable' -> 'executable').<commit_after>// 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.

//! # LLDB
//!
//! This crate provides a safe binding to the public API for [LLDB], the
//! debugger provided by the [LLVM project]. LLDB provides a modern, high
//! performance debugger framework and is the default debugger for macOS
//! and iOS.
//!
//! ## Installation
//!
//! This crate works with Cargo and is on [crates.io].
//! Add it to your `Cargo.toml` like so:
//!
//! ```toml
//! lldb = "0.0.7"
//! ```
//!
//! ### macOS Installation Notes
//!
//! On macOS, this library relies upon being able to find
//! the `LLDB.framework` that is provided by Xcode.app.
//!
//! In your own application, you will need to configure the
//! `@rpath` for your executable to point to the location
//! of the `LLDB.framework` that you are using. Doing this
//! automatically is not currently supported by Cargo.
//!
//! For testing, you can use the version provided by
//! Xcode.app by setting an environment variable:
//!
//! ```shell
//! export DYLD_FRAMEWORK_PATH=/Applications/Xcode.app/Contents/SharedFrameworks
//! ```
//!
//! ### Linux Installation Notes
//!
//! Install the `lldb` and `lldb-dev` packages for your platform so that
//! you have both LLDB itself installed as well as the headers and
//! other support files required.
//!
//! ### Windows Installation Notes
//!
//! Support for building this has not yet been provided for Windows.
//! Contributions are welcome!
//!
//! ## Usage
//!
//! The primary entry point is [`SBDebugger`]. This will be how you
//! create a debug target and begin the actually interesting stuff.
//!
//! ## Important Classes
//!
//! The LLDB API provides many structs and a wide range of functionality. Some of the
//! most common usages will involve these structs and their corresponding methods:
//!
//! * [`SBDebugger`]: Manages the entire debug experience and creates [`SBTarget`]s.
//! * [`SBTarget`]: The target program running under the debugger.
//! * [`SBProcess`]: The process associated with the target program.
//! * [`SBThread`]: A thread of execution. [`SBProcess`] contains
//!   [`SBThread`]s.
//! * [`SBFrame`]: One of the stack frames associated with
//!   a thread. [`SBThread`] contains [`SBFrame`]s.
//! * [`SBSymbolContext`]: A container that stores various debugger
//!   related info.
//! * [`SBValue`]: The value of a variable, a register, or an
//!   expression.
//! * [`SBModule`]: An executable image and its associated object
//!   and symbol files.  [`SBTarget`] contains [`SBModule`]s.
//! * [`SBBreakpoint`]: A logical breakpoint and its associated
//!   settings. [`SBTarget`] contains [`SBBreakpoint`]s.
//! * [`SBSymbol`]: The symbol possibly associated with a stack frame.
//! * [`SBCompileUnit`]: A compilation unit, or compiled source file.
//! * [`SBFunction`]: A generic function, which can be inlined or not.
//! * [`SBBlock`]: A lexical block. [`SBFunction`] contains [`SBBlock`]s.
//! * [`SBLineEntry`]: Specifies an association with a contiguous range of
//!   instructions and a source file location. [`SBCompileUnit`] contains
//!   [`SBLineEntry`]s.
//!
//! ## Support and Maintenance
//!
//! I am developing this library largely on my own so far. I am able
//! to offer support and maintenance, but would very much appreciate
//! donations via [Patreon](https://patreon.com/endoli). I can also
//! provide commercial support, so feel free to
//! [contact me](mailto:bruce.mitchener@gmail.com).
//!
//! [LLDB]: http://lldb.llvm.org/
//! [LLVM project]: http://llvm.org/
//! [crates.io]: https://crates.io/crates/lldb
//! [`SBDebugger`]: struct.SBDebugger.html
//! [`SBTarget`]: struct.SBTarget.html
//! [`SBProcess`]: struct.SBProcess.html
//! [`SBThread`]: struct.SBThread.html
//! [`SBFrame`]: struct.SBFrame.html
//! [`SBSymbolContext`]: struct.SBSymbolContext.html
//! [`SBValue`]: struct.SBValue.html
//! [`SBModule`]: struct.SBModule.html
//! [`SBBreakpoint`]: struct.SBBreakpoint.html
//! [`SBSymbol`]: struct.SBSymbol.html
//! [`SBCompileUnit`]: struct.SBCompileUnit.html
//! [`SBFunction`]: struct.SBFunction.html
//! [`SBBlock`]: struct.SBBlock.html
//! [`SBLineEntry`]: struct.SBLineEntry.html

#![warn(missing_docs)]
#![deny(trivial_numeric_casts, unstable_features,
        unused_import_braces, unused_qualifications)]

extern crate lldb_sys as sys;

#[cfg(feature = "graphql")]
#[macro_use]
extern crate juniper;

pub use sys::{lldb_addr_t, lldb_offset_t, lldb_pid_t, lldb_tid_t, lldb_user_id_t};

pub use sys::{AccessType, AddressClass, BasicType, BreakpointEventType, ByteOrder,
              CommandArgumentType, CommandFlags, ConnectionStatus, DescriptionLevel,
              DynamicValueType, EmulateInstructionOptions, Encoding, ErrorType,
              ExpressionEvaluationPhase, ExpressionResults, FilePermissions, Format,
              FrameComparison, FunctionNameType, GdbSignal, InputReaderAction,
              InputReaderGranularity, InstrumentationRuntimeType, LanguageType, LaunchFlags,
              MatchType, MemberFunctionKind, PathType, Permissions, QueueItemKind, QueueKind,
              RegisterKind, ReturnStatus, RunMode, ScriptLanguage, SectionType, StateType,
              StopReason, SymbolContextItem, SymbolType, TemplateArgumentKind, TypeClass,
              TypeFlags, TypeOptions, TypeSummaryCapping, ValueType, WatchpointEventType,
              WatchpointKind};

mod address;
mod attachinfo;
mod block;
mod breakpoint;
mod breakpointlist;
mod breakpointlocation;
mod broadcaster;
mod compileunit;
mod data;
mod debugger;
mod error;
mod event;
mod expressionoptions;
mod filespec;
mod filespeclist;
mod frame;
mod function;
mod instruction;
mod instructionlist;
mod launchinfo;
mod lineentry;
mod listener;
mod module;
mod modulespec;
mod platform;
mod process;
mod queue;
mod queueitem;
mod section;
mod stream;
mod stringlist;
mod structureddata;
mod symbol;
mod symbolcontext;
mod target;
mod thread;
mod types;
mod typelist;
mod value;
mod valuelist;
mod variablesoptions;
mod watchpoint;

pub use self::address::SBAddress;
pub use self::attachinfo::SBAttachInfo;
pub use self::block::SBBlock;
pub use self::breakpoint::{SBBreakpoint, SBBreakpointLocationIter};
pub use self::breakpointlist::{SBBreakpointList, SBBreakpointListIter};
pub use self::breakpointlocation::SBBreakpointLocation;
pub use self::broadcaster::SBBroadcaster;
pub use self::compileunit::SBCompileUnit;
pub use self::data::SBData;
pub use self::debugger::{SBDebugger, SBDebuggerTargetIter};
pub use self::error::SBError;
pub use self::event::SBEvent;
pub use self::expressionoptions::SBExpressionOptions;
pub use self::filespec::SBFileSpec;
pub use self::filespeclist::{SBFileSpecList, SBFileSpecListIter};
pub use self::frame::SBFrame;
pub use self::function::SBFunction;
pub use self::instruction::SBInstruction;
pub use self::instructionlist::{SBInstructionList, SBInstructionListIter};
pub use self::launchinfo::SBLaunchInfo;
pub use self::lineentry::SBLineEntry;
pub use self::listener::SBListener;
pub use self::module::{SBModule, SBModuleSectionIter};
pub use self::modulespec::SBModuleSpec;
pub use self::platform::SBPlatform;
pub use self::process::{SBProcess, SBProcessEvent, SBProcessEventRestartedReasonIter,
                        SBProcessQueueIter, SBProcessThreadIter};
pub use self::queue::{SBQueue, SBQueueQueueItemIter, SBQueueThreadIter};
pub use self::queueitem::SBQueueItem;
pub use self::section::{SBSection, SBSectionSubSectionIter};
pub use self::stream::SBStream;
pub use self::stringlist::{SBStringList, SBStringListIter};
pub use self::structureddata::SBStructuredData;
pub use self::symbol::SBSymbol;
pub use self::symbolcontext::SBSymbolContext;
pub use self::target::{SBTarget, SBTargetBreakpointIter, SBTargetEvent, SBTargetEventModuleIter,
                       SBTargetModuleIter, SBTargetWatchpointIter};
pub use self::thread::{SBThread, SBThreadEvent, SBThreadFrameIter};
pub use self::types::SBType;
pub use self::typelist::{SBTypeList, SBTypeListIter};
pub use self::value::SBValue;
pub use self::valuelist::{SBValueList, SBValueListIter};
pub use self::variablesoptions::SBVariablesOptions;
pub use self::watchpoint::SBWatchpoint;

/// Which syntax should be used in disassembly?
///
/// On x86, there are 2 syntaxes used for disassembly. Other
/// architectures need not be concerned by this and can just
/// use `DisassemblyFlavor::Default` all the time.
#[derive(Clone, Copy, Debug)]
pub enum DisassemblyFlavor {
    /// The primary syntax used by the GNU Assembler and in the
    /// Linux world.
    ///
    /// AT&T syntax:
    ///
    /// * Operations has a suffix, indicating the operand size.
    /// * Prefixes registers with `%` and immediate values with `$`.
    /// * Orders operands with source first, then destination.
    /// * Memory operands are somewhat complicated.
    ///
    /// For example:
    ///
    /// ```asm
    /// movb $0x05, %al
    /// ```
    ///
    /// This syntax is described in detail in [GAS Syntax].
    ///
    /// [GAS Syntax]: https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax
    ATT,
    /// The default syntax.
    Default,
    /// The primary syntax used on Windows.
    ///
    /// This differs from AT&T syntax in that:
    ///
    /// * Operations are not suffixed.
    /// * Registers are not prefixed with `%`, immediate values have a suffix.
    /// * Operands are ordered so that the destination is first, then the source.
    ///
    /// For example:
    ///
    /// ```asm
    /// mov al, 05h
    /// ```
    ///
    Intel,
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<|endoftext|>


<commit_before>//! Infinity for types without infinite values
//!
//! Infinitable introduces the notion of "infinity" and "negative infinity"
//! to numeric types, such as integers, that do not have infinite values.
//!
//! A representation of infinity is useful for graph algorithms such as
//! Dijkstra's algorithm, as well as for representing a graph with an
//! adjacency matrix.
//!
//! # Basic Usage
//!
//! ```
//! use infinitable::Infinitable;
//!
//! let finite = Infinitable::Finite(5);
//! let infinity = Infinitable::Infinity;
//! let negative_infinity = Infinitable::NegativeInfinity;
//!
//! assert!(finite < infinity);
//! assert!(finite > negative_infinity);
//! ```

use std::cmp::Ordering;
use std::ops::Neg;
use std::fmt;
use std::fmt::{Display,Formatter};

/// An "infinitable" value, one that can be either finite or infinite
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Infinitable<T> {
	/// A finite value `T`
	Finite(T),
	/// Positive infinity, which compares greater than all finite values
	Infinity,
	/// Negative infinity, which compares less than all finite values
	NegativeInfinity,
}

impl<T> Infinitable<T> {
	/// Returns `true` if the value is `Finite`.
	///
	/// # Examples
	///
	/// ```
	/// use infinitable::Infinitable;
	///
	/// let finite = Infinitable::Finite(5);
	/// assert!(finite.is_finite());
	/// ```
	pub fn is_finite(&self) -> bool {
		match self {
			&Infinitable::Finite(_) => true,
			_ => false,
		}
	}

	/// Converts from an `Infinitable<T>` to an `Option<T>`.
	///
	/// Converts `self` into an `Option<T>` possibly containing a finite value,
	/// consuming `self`.
	///
	/// # Examples
	///
	/// ```
	/// use infinitable::Infinitable;
	///
	/// let finite = Infinitable::Finite(5);
	/// assert_eq!(Some(5), finite.finite());
	/// let infinite: Infinitable<i32> = Infinitable::Infinity;
	/// assert_eq!(None, infinite.finite());
	/// ```
	pub fn finite(self) -> Option<T> {
		match self {
			Infinitable::Finite(x) => Some(x),
			_ => None,
		}
	}
}

impl<T> From<T> for Infinitable<T> {
	fn from(value: T) -> Infinitable<T> {
		Infinitable::Finite(value)
	}
}

impl<T> PartialOrd for Infinitable<T> where T: PartialOrd {
	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
		match (self, other) {
			(&Infinitable::Infinity, &Infinitable::Infinity)
			| (&Infinitable::NegativeInfinity, &Infinitable::NegativeInfinity)
				=> Some(Ordering::Equal),
			(&Infinitable::Infinity, _)
			| (_, &Infinitable::NegativeInfinity)
				=> Some(Ordering::Greater),
			(&Infinitable::NegativeInfinity, _)
			| (_, &Infinitable::Infinity)
				=> Some(Ordering::Less),
			(&Infinitable::Finite(ref x), &Infinitable::Finite(ref y))
				=> x.partial_cmp(y),
		}
	}
}

impl<T> Ord for Infinitable<T> where T: Ord {
	fn cmp(&self, other: &Self) -> Ordering {
		match (self, other) {
			(&Infinitable::Finite(ref x), &Infinitable::Finite(ref y))
				=> x.cmp(y),
			(..)
				=> self.partial_cmp(other).unwrap(),
		}
	}
}

impl<T> Neg for Infinitable<T> where T: Neg {
	type Output = Infinitable<T::Output>;

	fn neg(self) -> Infinitable<T::Output> {
		match self {
			Infinitable::Finite(x) => Infinitable::Finite(-x),
			Infinitable::Infinity => Infinitable::NegativeInfinity,
			Infinitable::NegativeInfinity => Infinitable::Infinity,
		}
	}
}

impl<T> Display for Infinitable<T> where T: Display {
	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
		match self {
			&Infinitable::Finite(ref x) => write!(f, "{}", x),
			&Infinitable::Infinity => write!(f, "inf"),
			&Infinitable::NegativeInfinity => write!(f, "-inf"),
		}
	}
}
<commit_msg>Derive Hash trait<commit_after>//! Infinity for types without infinite values
//!
//! Infinitable introduces the notion of "infinity" and "negative infinity"
//! to numeric types, such as integers, that do not have infinite values.
//!
//! A representation of infinity is useful for graph algorithms such as
//! Dijkstra's algorithm, as well as for representing a graph with an
//! adjacency matrix.
//!
//! # Basic Usage
//!
//! ```
//! use infinitable::Infinitable;
//!
//! let finite = Infinitable::Finite(5);
//! let infinity = Infinitable::Infinity;
//! let negative_infinity = Infinitable::NegativeInfinity;
//!
//! assert!(finite < infinity);
//! assert!(finite > negative_infinity);
//! ```

use std::cmp::Ordering;
use std::ops::Neg;
use std::fmt;
use std::fmt::{Display,Formatter};

/// An "infinitable" value, one that can be either finite or infinite
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Infinitable<T> {
	/// A finite value `T`
	Finite(T),
	/// Positive infinity, which compares greater than all finite values
	Infinity,
	/// Negative infinity, which compares less than all finite values
	NegativeInfinity,
}

impl<T> Infinitable<T> {
	/// Returns `true` if the value is `Finite`.
	///
	/// # Examples
	///
	/// ```
	/// use infinitable::Infinitable;
	///
	/// let finite = Infinitable::Finite(5);
	/// assert!(finite.is_finite());
	/// ```
	pub fn is_finite(&self) -> bool {
		match self {
			&Infinitable::Finite(_) => true,
			_ => false,
		}
	}

	/// Converts from an `Infinitable<T>` to an `Option<T>`.
	///
	/// Converts `self` into an `Option<T>` possibly containing a finite value,
	/// consuming `self`.
	///
	/// # Examples
	///
	/// ```
	/// use infinitable::Infinitable;
	///
	/// let finite = Infinitable::Finite(5);
	/// assert_eq!(Some(5), finite.finite());
	/// let infinite: Infinitable<i32> = Infinitable::Infinity;
	/// assert_eq!(None, infinite.finite());
	/// ```
	pub fn finite(self) -> Option<T> {
		match self {
			Infinitable::Finite(x) => Some(x),
			_ => None,
		}
	}
}

impl<T> From<T> for Infinitable<T> {
	fn from(value: T) -> Infinitable<T> {
		Infinitable::Finite(value)
	}
}

impl<T> PartialOrd for Infinitable<T> where T: PartialOrd {
	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
		match (self, other) {
			(&Infinitable::Infinity, &Infinitable::Infinity)
			| (&Infinitable::NegativeInfinity, &Infinitable::NegativeInfinity)
				=> Some(Ordering::Equal),
			(&Infinitable::Infinity, _)
			| (_, &Infinitable::NegativeInfinity)
				=> Some(Ordering::Greater),
			(&Infinitable::NegativeInfinity, _)
			| (_, &Infinitable::Infinity)
				=> Some(Ordering::Less),
			(&Infinitable::Finite(ref x), &Infinitable::Finite(ref y))
				=> x.partial_cmp(y),
		}
	}
}

impl<T> Ord for Infinitable<T> where T: Ord {
	fn cmp(&self, other: &Self) -> Ordering {
		match (self, other) {
			(&Infinitable::Finite(ref x), &Infinitable::Finite(ref y))
				=> x.cmp(y),
			(..)
				=> self.partial_cmp(other).unwrap(),
		}
	}
}

impl<T> Neg for Infinitable<T> where T: Neg {
	type Output = Infinitable<T::Output>;

	fn neg(self) -> Infinitable<T::Output> {
		match self {
			Infinitable::Finite(x) => Infinitable::Finite(-x),
			Infinitable::Infinity => Infinitable::NegativeInfinity,
			Infinitable::NegativeInfinity => Infinitable::Infinity,
		}
	}
}

impl<T> Display for Infinitable<T> where T: Display {
	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
		match self {
			&Infinitable::Finite(ref x) => write!(f, "{}", x),
			&Infinitable::Infinity => write!(f, "inf"),
			&Infinitable::NegativeInfinity => write!(f, "-inf"),
		}
	}
}
<|endoftext|>


<commit_before>pub mod ui {
    extern crate term;
    use net;

    pub fn update(state: net::State) {
        match state {
            net::State::Online  => online(),
            net::State::Offline => offline()
        }
    }

    pub fn online() {
        let mut t = term::stdout().unwrap();
        t.fg(term::color::GREEN).unwrap();
        writeln!(t, "Online").unwrap();
        t.reset();
    }
    pub fn offline() {
        let mut t = term::stdout().unwrap();
        t.fg(term::color::RED).unwrap();
        writeln!(t, "Offline").unwrap();
        t.reset();
    }
    pub fn clear_screen() {
        println!("\x1b[2J\x1b[1;1H");
    }
}

pub mod net {
    extern crate curl;
    extern crate url;
    use self::curl::http;
    use std::env;
    use self::
    url::Url;

    pub enum State { Online, Offline }
    pub fn is_online() -> State {

        // Going full on rust here. Thanks @skade! :D
        let env_var = env::var_os("ONLINE_CHECK_HOST");

        let url = match env_var {
            Some(ref val) => val.to_str().unwrap(),
            None => "http://duckduckgo.com/"
        };

        let check_target = match Url::parse(url) {
            Ok(v) => v,
            Err(e) => panic!("Sorry, URL {:?} is broken because of a {:?} error.", url, e)
        };

        let resp = http::handle()
            .get(&check_target)
            .exec();

        match resp {
            Ok(r) => State::Online,
            Err(e) => State::Offline
        }
    }

}
<commit_msg>Refactor almost duplicate online / offline fn().<commit_after>pub mod ui {
    extern crate term;
    use net;

    pub fn update(state: net::State) {
        match state {
            net::State::Online  => redraw("Online",  term::color::GREEN),
            net::State::Offline => redraw("Offline", term::color::RED)
        }

        fn redraw(text: &str, color: u16) {
            let mut t = term::stdout().unwrap();
            t.fg(color).unwrap();
            writeln!(t, "{:?}", text).unwrap();
            t.reset();
        };
    }

    pub fn clear_screen() {
        println!("\x1b[2J\x1b[1;1H");
    }
}

pub mod net {
    extern crate curl;
    extern crate url;
    use self::curl::http;
    use std::env;
    use self::
    url::Url;

    pub enum State { Online, Offline }
    pub fn is_online() -> State {

        // Going full on rust here. Thanks @skade! :D
        let env_var = env::var_os("ONLINE_CHECK_HOST");

        let url = match env_var {
            Some(ref val) => val.to_str().unwrap(),
            None => "http://duckduckgo.com/"
        };

        let check_target = match Url::parse(url) {
            Ok(v) => v,
            Err(e) => panic!("Sorry, URL {:?} is broken because of a {:?} error.", url, e)
        };

        let resp = http::handle()
            .get(&check_target)
            .exec();

        match resp {
            Ok(r) => State::Online,
            Err(e) => State::Offline
        }
    }

}
<|endoftext|>


<commit_before>// Many of my decisions were based off the following document
// https://web.archive.org/web/20140727185616/http://algs4.cs.princeton.edu/33balanced/

// TODO:
// Collection trait
// convert this to Key/Value K/V

use Direction::{Left, Middle, Right, Leaf};
use InsertResult::{Fit, Split};

/// SplitNode
enum SplitNode<V: Ord> {
    Four(V, V, V, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>),
    LeafFour(V, V, V),
}

impl <V: Ord> SplitNode<V> {
    fn to_two(self) -> Two<V> {
        match self {
            SplitNode::LeafFour(v1, v2, v3) =>
                Two(v2,
                    box Node::LeafTwo(LeafTwo(v1)),
                    box Node::LeafTwo(LeafTwo(v3))),
            SplitNode::Four(v1, v2, v3, n1, n2, n3, n4) =>
                Two(v2,
                    box Node::Two(Two(v1, n1, n2)),
                    box Node::Two(Two(v3, n3, n4))),
        }
    }
}

/// InsertResult
enum InsertResult<V: Ord> {
    Fit(Node<V>),
    Split(SplitNode<V>),
}

/// Direction
enum Direction {
    Left,
    Middle,
    Right,
    Leaf,
}

/// Two
pub struct Two<V: Ord>(pub V, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: Ord> Two<V> {
    fn as_node(self) -> Node<V> { Node::Two(self) }

    fn to_three(self, other_value: V, other_node: Box<Node<V>>) -> Three<V> {
        let Two(self_value, self_left, self_middle) = self;
        if self_value > other_value {
            Three(other_value, self_value, other_node, self_left, self_middle)
        } else {
            Three(self_value, other_value, self_left, self_middle, other_node)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let &Two(ref self_value, _, _) = self;
        *self_value == *value
    }
}

/// Three
pub struct Three<V: Ord>(pub V, pub V, pub Box<Node<V>>, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: Ord> Three<V> {
    fn as_node(self) -> Node<V> { Node::Three(self) }

    fn to_split_node(self, other_value: V, other_node: Box<Node<V>>) -> SplitNode<V> {
        let Three(self_value1, self_value2, self_left, self_middle, self_right) = self;
        if other_value < self_value1 {
            SplitNode::Four(other_value, self_value1, self_value2, other_node, self_left, self_middle, self_right)
        } else {
            SplitNode::Four(self_value1, self_value2, other_value, self_left, self_middle, self_right, other_node)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let Three(ref self_value1, ref self_value2, _, _, _) = *self;
        *self_value1 == *value || *self_value2 == *value
    }
}

/// LeafTwo
pub struct LeafTwo<V: Ord>(pub V);

impl <V: Ord> LeafTwo<V> {
    fn to_three(self, other_value: V) -> LeafThree<V> {
        let LeafTwo(self_value) = self;
        if self_value > other_value {
            LeafThree(other_value, self_value)
        } else {
            LeafThree(self_value, other_value)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let &LeafTwo(ref self_value) = self;
        *self_value == *value
    }
}

/// LeafThree
pub struct LeafThree<V: Ord>(pub V, pub V);

impl <V: Ord> LeafThree<V> {
    fn as_node(self) -> Node<V> { Node::LeafThree(self) }

    fn to_split_node(self, value: V) -> SplitNode<V> {
        let LeafThree(value1, value2) = self;
        if value > value2      { SplitNode::LeafFour(value1, value2, value) }
        else if value < value1 { SplitNode::LeafFour(value, value1, value2) }
        else                   { SplitNode::LeafFour(value1, value, value2) }
    }

    fn has_value(&self, value: &V) -> bool {
        let &LeafThree(ref self_value1, ref self_value2) = self;
        *self_value1 == *value || *self_value2 == *value
    }
}

/// Node
pub enum Node<V: Ord> {
    LeafTwo(LeafTwo<V>),
    LeafThree(LeafThree<V>),
    Two(Two<V>),
    Three(Three<V>),
}

impl <V: Ord> Node<V> {
    fn next_direction(&self, to_insert: &V) -> Direction {
        match *self {
            Node::Two(Two(ref value, _, _)) =>
                if to_insert < value { Left }
                else                 { Middle },
            Node::Three(Three(ref value1, ref value2, _, _, _)) =>
                if      to_insert < value1 { Left }
                else if to_insert > value2 { Right }
                else                       { Middle },
            _ => Leaf,
        }
    }

    fn has_value(&self, value: &V) -> bool {
        match *self {
            Node::LeafTwo(ref n)   => n.has_value(value),
            Node::LeafThree(ref n) => n.has_value(value),
            Node::Two(ref n)       => n.has_value(value),
            Node::Three(ref n)     => n.has_value(value),
        }
    }

    fn insert(self, to_insert: V) -> InsertResult<V> {
        // If value is already in this node, we're done (prevent duplicates)
        if self.has_value(&to_insert) { return Fit(self); }

        let next_direction = self.next_direction(&to_insert);

        match self {
            // Insert if leaf TwoNode
            Node::LeafTwo(leaf_two) => {
                let three_node = leaf_two.to_three(to_insert);
                Fit(three_node.as_node())
            },

            // Split if leaf ThreeNode
            Node::LeafThree(leaf_three) => {
                let split_node = leaf_three.to_split_node(to_insert);
                Split(split_node)
            },

            // Recurse down if internal Node and handle results
            Node::Two(Two(value, box left, box middle)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node) = match next_direction {
                    Left => (left, middle),
                    Middle => (middle, left),
                    _ => panic!(""),
                };

                // Recurse, save the result of the insert
                let insert_result = next_node.insert(to_insert);

                // Handle the result of the insert
                let new_node = match insert_result {
                    Fit(returned_node) =>
                        match next_direction {
                            Left =>   Two(value, box returned_node, box other_node),
                            Middle => Two(value, box other_node, box returned_node),
                            _ => panic!(""),
                        }.as_node(),
                    Split(split_node) => split_node.to_two().to_three(value, box other_node).as_node(),
                };

                Fit(new_node)
            },

            // Recurse down if internal Node and handle results
            Node::Three(Three(value1, value2, left, middle, right)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node1, other_node2) = match next_direction {
                    Left => (left, middle, right),
                    Middle => (middle, left, right),
                    Right => (right, left, middle),
                    _ => panic!(""),
                };

                let insert_result = next_node.insert(to_insert);

                match insert_result {
                    Fit(returned_node) => {
                        let three = match next_direction {
                            Left =>   Three(value1, value2, box returned_node, other_node1, other_node2),
                            Middle => Three(value1, value2, other_node1, box returned_node, other_node2),
                            Right =>  Three(value1, value2, other_node1, other_node2, box returned_node),
                            _ => panic!(""),
                        };
                        Fit(three.as_node())
                    },
                    Split(split_node) => {
                        let two = split_node.to_two();
                        let new_node = match next_direction {
                            Left =>   two.to_three(value1, other_node1).to_split_node(value2, other_node2),
                            Middle => two.to_three(value1, other_node1).to_split_node(value2, other_node2),
                            Right =>  two.to_three(value2, other_node2).to_split_node(value1, other_node1),
                            _ => panic!(""),
                        };
                        Split(new_node)
                    }
                }
            }
        }
    }
}

/// TTTree
pub struct TTTree<V: Ord> {
    pub root: Option<Node<V>>,
}

impl <V: Ord> TTTree<V> {
    pub fn new() -> TTTree<V> {
        TTTree { root: None }
    }

    pub fn insert(&mut self, value: V) -> () {
        let root: Option<Node<V>> = self.root.take();
        let new_root: Node<V> = match root {
            None => Node::LeafTwo(LeafTwo(value)),
            Some(root) => {
                let result = root.insert(value);
                match result {
                    Fit(node) => node,
                    Split(split_node) => split_node.to_two().as_node(),
                }
            }
        };
        self.root = Some(new_root);
    }
}
<commit_msg>Move TODO to GitHub issues<commit_after>// Many of my decisions were based off the following document
// https://web.archive.org/web/20140727185616/http://algs4.cs.princeton.edu/33balanced/

use Direction::{Left, Middle, Right, Leaf};
use InsertResult::{Fit, Split};

/// SplitNode
enum SplitNode<V: Ord> {
    Four(V, V, V, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>),
    LeafFour(V, V, V),
}

impl <V: Ord> SplitNode<V> {
    fn to_two(self) -> Two<V> {
        match self {
            SplitNode::LeafFour(v1, v2, v3) =>
                Two(v2,
                    box Node::LeafTwo(LeafTwo(v1)),
                    box Node::LeafTwo(LeafTwo(v3))),
            SplitNode::Four(v1, v2, v3, n1, n2, n3, n4) =>
                Two(v2,
                    box Node::Two(Two(v1, n1, n2)),
                    box Node::Two(Two(v3, n3, n4))),
        }
    }
}

/// InsertResult
enum InsertResult<V: Ord> {
    Fit(Node<V>),
    Split(SplitNode<V>),
}

/// Direction
enum Direction {
    Left,
    Middle,
    Right,
    Leaf,
}

/// Two
pub struct Two<V: Ord>(pub V, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: Ord> Two<V> {
    fn as_node(self) -> Node<V> { Node::Two(self) }

    fn to_three(self, other_value: V, other_node: Box<Node<V>>) -> Three<V> {
        let Two(self_value, self_left, self_middle) = self;
        if self_value > other_value {
            Three(other_value, self_value, other_node, self_left, self_middle)
        } else {
            Three(self_value, other_value, self_left, self_middle, other_node)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let &Two(ref self_value, _, _) = self;
        *self_value == *value
    }
}

/// Three
pub struct Three<V: Ord>(pub V, pub V, pub Box<Node<V>>, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: Ord> Three<V> {
    fn as_node(self) -> Node<V> { Node::Three(self) }

    fn to_split_node(self, other_value: V, other_node: Box<Node<V>>) -> SplitNode<V> {
        let Three(self_value1, self_value2, self_left, self_middle, self_right) = self;
        if other_value < self_value1 {
            SplitNode::Four(other_value, self_value1, self_value2, other_node, self_left, self_middle, self_right)
        } else {
            SplitNode::Four(self_value1, self_value2, other_value, self_left, self_middle, self_right, other_node)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let Three(ref self_value1, ref self_value2, _, _, _) = *self;
        *self_value1 == *value || *self_value2 == *value
    }
}

/// LeafTwo
pub struct LeafTwo<V: Ord>(pub V);

impl <V: Ord> LeafTwo<V> {
    fn to_three(self, other_value: V) -> LeafThree<V> {
        let LeafTwo(self_value) = self;
        if self_value > other_value {
            LeafThree(other_value, self_value)
        } else {
            LeafThree(self_value, other_value)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let &LeafTwo(ref self_value) = self;
        *self_value == *value
    }
}

/// LeafThree
pub struct LeafThree<V: Ord>(pub V, pub V);

impl <V: Ord> LeafThree<V> {
    fn as_node(self) -> Node<V> { Node::LeafThree(self) }

    fn to_split_node(self, value: V) -> SplitNode<V> {
        let LeafThree(value1, value2) = self;
        if value > value2      { SplitNode::LeafFour(value1, value2, value) }
        else if value < value1 { SplitNode::LeafFour(value, value1, value2) }
        else                   { SplitNode::LeafFour(value1, value, value2) }
    }

    fn has_value(&self, value: &V) -> bool {
        let &LeafThree(ref self_value1, ref self_value2) = self;
        *self_value1 == *value || *self_value2 == *value
    }
}

/// Node
pub enum Node<V: Ord> {
    LeafTwo(LeafTwo<V>),
    LeafThree(LeafThree<V>),
    Two(Two<V>),
    Three(Three<V>),
}

impl <V: Ord> Node<V> {
    fn next_direction(&self, to_insert: &V) -> Direction {
        match *self {
            Node::Two(Two(ref value, _, _)) =>
                if to_insert < value { Left }
                else                 { Middle },
            Node::Three(Three(ref value1, ref value2, _, _, _)) =>
                if      to_insert < value1 { Left }
                else if to_insert > value2 { Right }
                else                       { Middle },
            _ => Leaf,
        }
    }

    fn has_value(&self, value: &V) -> bool {
        match *self {
            Node::LeafTwo(ref n)   => n.has_value(value),
            Node::LeafThree(ref n) => n.has_value(value),
            Node::Two(ref n)       => n.has_value(value),
            Node::Three(ref n)     => n.has_value(value),
        }
    }

    fn insert(self, to_insert: V) -> InsertResult<V> {
        // If value is already in this node, we're done (prevent duplicates)
        if self.has_value(&to_insert) { return Fit(self); }

        let next_direction = self.next_direction(&to_insert);

        match self {
            // Insert if leaf TwoNode
            Node::LeafTwo(leaf_two) => {
                let three_node = leaf_two.to_three(to_insert);
                Fit(three_node.as_node())
            },

            // Split if leaf ThreeNode
            Node::LeafThree(leaf_three) => {
                let split_node = leaf_three.to_split_node(to_insert);
                Split(split_node)
            },

            // Recurse down if internal Node and handle results
            Node::Two(Two(value, box left, box middle)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node) = match next_direction {
                    Left => (left, middle),
                    Middle => (middle, left),
                    _ => panic!(""),
                };

                // Recurse, save the result of the insert
                let insert_result = next_node.insert(to_insert);

                // Handle the result of the insert
                let new_node = match insert_result {
                    Fit(returned_node) =>
                        match next_direction {
                            Left =>   Two(value, box returned_node, box other_node),
                            Middle => Two(value, box other_node, box returned_node),
                            _ => panic!(""),
                        }.as_node(),
                    Split(split_node) => split_node.to_two().to_three(value, box other_node).as_node(),
                };

                Fit(new_node)
            },

            // Recurse down if internal Node and handle results
            Node::Three(Three(value1, value2, left, middle, right)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node1, other_node2) = match next_direction {
                    Left => (left, middle, right),
                    Middle => (middle, left, right),
                    Right => (right, left, middle),
                    _ => panic!(""),
                };

                let insert_result = next_node.insert(to_insert);

                match insert_result {
                    Fit(returned_node) => {
                        let three = match next_direction {
                            Left =>   Three(value1, value2, box returned_node, other_node1, other_node2),
                            Middle => Three(value1, value2, other_node1, box returned_node, other_node2),
                            Right =>  Three(value1, value2, other_node1, other_node2, box returned_node),
                            _ => panic!(""),
                        };
                        Fit(three.as_node())
                    },
                    Split(split_node) => {
                        let two = split_node.to_two();
                        let new_node = match next_direction {
                            Left =>   two.to_three(value1, other_node1).to_split_node(value2, other_node2),
                            Middle => two.to_three(value1, other_node1).to_split_node(value2, other_node2),
                            Right =>  two.to_three(value2, other_node2).to_split_node(value1, other_node1),
                            _ => panic!(""),
                        };
                        Split(new_node)
                    }
                }
            }
        }
    }
}

/// TTTree
pub struct TTTree<V: Ord> {
    pub root: Option<Node<V>>,
}

impl <V: Ord> TTTree<V> {
    pub fn new() -> TTTree<V> {
        TTTree { root: None }
    }

    pub fn insert(&mut self, value: V) -> () {
        let root: Option<Node<V>> = self.root.take();
        let new_root: Node<V> = match root {
            None => Node::LeafTwo(LeafTwo(value)),
            Some(root) => {
                let result = root.insert(value);
                match result {
                    Fit(node) => node,
                    Split(split_node) => split_node.to_two().as_node(),
                }
            }
        };
        self.root = Some(new_root);
    }
}
<|endoftext|>


<commit_before>//! A macro for defining `#[cfg]` if-else statements.
//!
//! The macro provided by this crate, `cfg_if`, is similar to the `if/elif` C
//! preprocessor macro by allowing definition of a cascade of `#[cfg]` cases,
//! emitting the implementation which matches first.
//!
//! This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
//! without having to rewrite each clause multiple times.
//!
//! # Example
//!
//! ```
//! #[macro_use]
//! extern crate cfg_if;
//!
//! cfg_if! {
//!     if #[cfg(unix)] {
//!         fn foo() { /* unix specific functionality */ }
//!     } else if #[cfg(target_pointer_width = "32")] {
//!         fn foo() { /* non-unix, 32-bit functionality */ }
//!     } else {
//!         fn foo() { /* fallback implementation */ }
//!     }
//! }
//!
//! # fn main() {}
//! ```

#![no_std]

#![doc(html_root_url = "https://docs.rs/cfg-if")]
#![deny(missing_docs)]
#![cfg_attr(test, deny(warnings))]

#[macro_export(local_inner_macros)]
macro_rules! cfg_if {
    // match if/else chains with a final `else`
    ($(
        if #[cfg($($meta:meta),*)] { $($it:item)* }
    ) else * else {
        $($it2:item)*
    }) => {
        cfg_if! {
            @__items
            () ;
            $( ( ($($meta),*) ($($it)*) ), )*
            ( () ($($it2)*) ),
        }
    };

    // match if/else chains lacking a final `else`
    (
        if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
        $(
            else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
        )*
    ) => {
        cfg_if! {
            @__items
            () ;
            ( ($($i_met),*) ($($i_it)*) ),
            $( ( ($($e_met),*) ($($e_it)*) ), )*
            ( () () ),
        }
    };

    // Internal and recursive macro to emit all the items
    //
    // Collects all the negated cfgs in a list at the beginning and after the
    // semicolon is all the remaining items
    (@__items ($($not:meta,)*) ; ) => {};
    (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
        // Emit all items within one block, applying an approprate #[cfg]. The
        // #[cfg] will require all `$m` matchers specified and must also negate
        // all previous matchers.
        cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }

        // Recurse to emit all other items in `$rest`, and when we do so add all
        // our `$m` matchers to the list of `$not` matchers as future emissions
        // will have to negate everything we just matched as well.
        cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
    };

    // Internal macro to Apply a cfg attribute to a list of items
    (@__apply $m:meta, $($it:item)*) => {
        $(#[$m] $it)*
    };
}

#[cfg(test)]
mod tests {
    cfg_if! {
        if #[cfg(test)] {
            use core::option::Option as Option2;
            fn works1() -> Option2<u32> { Some(1) }
        } else {
            fn works1() -> Option<u32> { None }
        }
    }

    cfg_if! {
        if #[cfg(foo)] {
            fn works2() -> bool { false }
        } else if #[cfg(test)] {
            fn works2() -> bool { true }
        } else {
            fn works2() -> bool { false }
        }
    }

    cfg_if! {
        if #[cfg(foo)] {
            fn works3() -> bool { false }
        } else {
            fn works3() -> bool { true }
        }
    }

    cfg_if! {
        if #[cfg(test)] {
            use core::option::Option as Option3;
            fn works4() -> Option3<u32> { Some(1) }
        }
    }

    cfg_if! {
        if #[cfg(foo)] {
            fn works5() -> bool { false }
        } else if #[cfg(test)] {
            fn works5() -> bool { true }
        }
    }

    #[test]
    fn it_works() {
        assert!(works1().is_some());
        assert!(works2());
        assert!(works3());
        assert!(works4().is_some());
        assert!(works5());
    }
}
<commit_msg>Document macro<commit_after>//! A macro for defining `#[cfg]` if-else statements.
//!
//! The macro provided by this crate, `cfg_if`, is similar to the `if/elif` C
//! preprocessor macro by allowing definition of a cascade of `#[cfg]` cases,
//! emitting the implementation which matches first.
//!
//! This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
//! without having to rewrite each clause multiple times.
//!
//! # Example
//!
//! ```
//! #[macro_use]
//! extern crate cfg_if;
//!
//! cfg_if! {
//!     if #[cfg(unix)] {
//!         fn foo() { /* unix specific functionality */ }
//!     } else if #[cfg(target_pointer_width = "32")] {
//!         fn foo() { /* non-unix, 32-bit functionality */ }
//!     } else {
//!         fn foo() { /* fallback implementation */ }
//!     }
//! }
//!
//! # fn main() {}
//! ```

#![no_std]

#![doc(html_root_url = "https://docs.rs/cfg-if")]
#![deny(missing_docs)]
#![cfg_attr(test, deny(warnings))]

/// The main macro provided by this crate. See crate documentation for more
/// information.
#[macro_export(local_inner_macros)]
macro_rules! cfg_if {
    // match if/else chains with a final `else`
    ($(
        if #[cfg($($meta:meta),*)] { $($it:item)* }
    ) else * else {
        $($it2:item)*
    }) => {
        cfg_if! {
            @__items
            () ;
            $( ( ($($meta),*) ($($it)*) ), )*
            ( () ($($it2)*) ),
        }
    };

    // match if/else chains lacking a final `else`
    (
        if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
        $(
            else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
        )*
    ) => {
        cfg_if! {
            @__items
            () ;
            ( ($($i_met),*) ($($i_it)*) ),
            $( ( ($($e_met),*) ($($e_it)*) ), )*
            ( () () ),
        }
    };

    // Internal and recursive macro to emit all the items
    //
    // Collects all the negated cfgs in a list at the beginning and after the
    // semicolon is all the remaining items
    (@__items ($($not:meta,)*) ; ) => {};
    (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
        // Emit all items within one block, applying an approprate #[cfg]. The
        // #[cfg] will require all `$m` matchers specified and must also negate
        // all previous matchers.
        cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }

        // Recurse to emit all other items in `$rest`, and when we do so add all
        // our `$m` matchers to the list of `$not` matchers as future emissions
        // will have to negate everything we just matched as well.
        cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
    };

    // Internal macro to Apply a cfg attribute to a list of items
    (@__apply $m:meta, $($it:item)*) => {
        $(#[$m] $it)*
    };
}

#[cfg(test)]
mod tests {
    cfg_if! {
        if #[cfg(test)] {
            use core::option::Option as Option2;
            fn works1() -> Option2<u32> { Some(1) }
        } else {
            fn works1() -> Option<u32> { None }
        }
    }

    cfg_if! {
        if #[cfg(foo)] {
            fn works2() -> bool { false }
        } else if #[cfg(test)] {
            fn works2() -> bool { true }
        } else {
            fn works2() -> bool { false }
        }
    }

    cfg_if! {
        if #[cfg(foo)] {
            fn works3() -> bool { false }
        } else {
            fn works3() -> bool { true }
        }
    }

    cfg_if! {
        if #[cfg(test)] {
            use core::option::Option as Option3;
            fn works4() -> Option3<u32> { Some(1) }
        }
    }

    cfg_if! {
        if #[cfg(foo)] {
            fn works5() -> bool { false }
        } else if #[cfg(test)] {
            fn works5() -> bool { true }
        }
    }

    #[test]
    fn it_works() {
        assert!(works1().is_some());
        assert!(works2());
        assert!(works3());
        assert!(works4().is_some());
        assert!(works5());
    }
}
<|endoftext|>


<commit_before>//! Core I/O traits and combinators when working with Tokio.
//!
//! A description of the high-level I/O combinators can be [found online] in
//! addition to a description of the [low level details].
//!
//! [found online]: https://tokio.rs/docs/getting-started/core/
//! [low level details]: https://tokio.rs/docs/going-deeper/core-low-level/

#![deny(missing_docs)]
#![doc(html_root_url = "https://docs.rs/tokio-io/0.1")]

#[macro_use]
extern crate log;

#[macro_use]
extern crate futures;
extern crate bytes;

use std::io as std_io;
use std::io::Write;

use futures::{Async, Poll, BoxFuture};
use futures::stream::BoxStream;

use bytes::{Buf, BufMut};

/// A convenience typedef around a `Future` whose error component is `io::Error`
pub type IoFuture<T> = BoxFuture<T, std_io::Error>;

/// A convenience typedef around a `Stream` whose error component is `io::Error`
pub type IoStream<T> = BoxStream<T, std_io::Error>;

/// A convenience macro for working with `io::Result<T>` from the `Read` and
/// `Write` traits.
///
/// This macro takes `io::Result<T>` as input, and returns `T` as the output. If
/// the input type is of the `Err` variant, then `Poll::NotReady` is returned if
/// it indicates `WouldBlock` or otherwise `Err` is returned.
#[macro_export]
macro_rules! try_nb {
    ($e:expr) => (match $e {
        Ok(t) => t,
        Err(ref e) if e.kind() == ::std::io::ErrorKind::WouldBlock => {
            return Ok(::futures::Async::NotReady)
        }
        Err(e) => return Err(e.into()),
    })
}

pub mod io;
pub mod codec;

mod copy;
mod flush;
mod framed;
mod framed_read;
mod framed_write;
mod length_delimited;
mod lines;
mod read;
mod read_exact;
mod read_to_end;
mod read_until;
mod shutdown;
mod split;
mod window;
mod write_all;

use codec::{Decoder, Encoder, Framed};
use split::{ReadHalf, WriteHalf};

/// A trait for readable objects which operated in an asynchronous and
/// futures-aware fashion.
///
/// This trait inherits from `io::Read` and indicates as a marker that an I/O
/// object is **nonblocking**, meaning that it will return an error instead of
/// blocking when bytes are read. Specifically this means that the `read`
/// function for traits that implement this type can have a few return values:
///
/// * `Ok(n)` means that `n` bytes of data was immediately read and placed into
///   the output buffer, where `n` == 0 implies that EOF has been reached.
/// * `Err(e) if e.kind() == ErrorKind::WouldBlock` means that no data was read
///   into the buffer provided. The I/O object is not currently readable but may
///   become readable in the future. Most importantly, **the current future's
///   task is scheduled to get unparked when the object is readable**. This
///   means that like `Future::poll` you'll receive a notification when the I/O
///   object is readable again.
/// * `Err(e)` for other errors are standard I/O errors coming from the
///   underlying object.
///
/// This trait importantly means that the `read` method only works in the
/// context of a future's task. The object may panic if used outside of a task.
pub trait AsyncRead: std_io::Read {
    /// Prepares an uninitialized buffer to be safe to pass to `read`. Returns
    /// `true` if the supplied buffer was zeroed out.
    ///
    /// While it would be highly unusual, implementations of [`io::Read`] are
    /// able to read data from the buffer passed as an argument. Because of
    /// this, the buffer passed to [`io::Read`] must be initialized memory. In
    /// situations where large numbers of buffers are used, constantly having to
    /// zero out buffers can be expensive.
    ///
    /// This function does any necessary work to prepare an uninitialized buffer
    /// to be safe to pass to `read`. If `read` guarantees to never attempt read
    /// data out of the supplied buffer, then `prepare_uninitialized_buffer`
    /// doesn't need to do any work.
    ///
    /// If this function returns `true`, then the memory has been zeroed out.
    /// This allows implementations of `AsyncRead` which are composed of
    /// multiple sub implementations to efficiently implement
    /// `prepare_uninitialized_buffer`.
    ///
    /// This function is called from [`read_buf`].
    ///
    /// [`io::Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
    /// [`read_buf`]: #method.read_buf
    unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
        for i in 0..buf.len() {
            buf[i] = 0;
        }

        true
    }

    /// Pull some bytes from this source into the specified `Buf`, returning
    /// how many bytes were read.
    ///
    /// The `buf` provided will have bytes read into it and the internal cursor
    /// will be advanced if any bytes were read. Note that this method typically
    /// will not reallocate the buffer provided.
    fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, std_io::Error> {
        if !buf.has_remaining_mut() {
            return Ok(Async::Ready(0));
        }

        unsafe {
            let n = {
                let b = buf.bytes_mut();

                self.prepare_uninitialized_buffer(b);

                try_nb!(self.read(b))
            };

            buf.advance_mut(n);
            Ok(Async::Ready(n))
        }
    }

    /// Provides a `Stream` and `Sink` interface for reading and writing to this
    /// `Io` object, using `Decode` and `Encode` to read and write the raw data.
    ///
    /// Raw I/O objects work with byte sequences, but higher-level code usually
    /// wants to batch these into meaningful chunks, called "frames". This
    /// method layers framing on top of an I/O object, by using the `Codec`
    /// traits to handle encoding and decoding of messages frames. Note that
    /// the incoming and outgoing frame types may be distinct.
    ///
    /// This function returns a *single* object that is both `Stream` and
    /// `Sink`; grouping this into a single object is often useful for layering
    /// things like gzip or TLS, which require both read and write access to the
    /// underlying object.
    ///
    /// If you want to work more directly with the streams and sink, consider
    /// calling `split` on the `Framed` returned by this method, which will
    /// break them into separate objects, allowing them to interact more easily.
    fn framed<T: Encoder + Decoder>(self, codec: T) -> Framed<Self, T>
        where Self: AsyncWrite + Sized,
    {
        framed::framed(self, codec)
    }

    /// Helper method for splitting this read/write object into two halves.
    ///
    /// The two halves returned implement the `Read` and `Write` traits,
    /// respectively.
    fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>)
        where Self: AsyncWrite + Sized,
    {
        split::split(self)
    }
}

impl<T: ?Sized + AsyncRead> AsyncRead for Box<T> {
    unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
        (**self).prepare_uninitialized_buffer(buf)
    }
}

impl<'a, T: ?Sized + AsyncRead> AsyncRead for &'a mut T {
    unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
        (**self).prepare_uninitialized_buffer(buf)
    }
}

impl<'a> AsyncRead for &'a [u8] {
    unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool {
        false
    }
}

/// A trait for writable objects which operated in an asynchronous and
/// futures-aware fashion.
///
/// This trait inherits from `io::Write` and indicates that an I/O object is
/// **nonblocking**, meaning that it will return an error instead of blocking
/// when bytes are written. Specifically this means that the `write` function
/// for traits that implement this type can have a few return values:
///
/// * `Ok(n)` means that `n` bytes of data was immediately written .
/// * `Err(e) if e.kind() == ErrorKind::WouldBlock` means that no data was
///   written from the buffer provided. The I/O object is not currently
///   writable but may become writable in the future. Most importantly, **the
///   current future's task is scheduled to get unparked when the object is
///   readable**. This means that like `Future::poll` you'll receive a
///   notification when the I/O object is writable again.
/// * `Err(e)` for other errors are standard I/O errors coming from the
///   underlying object.
///
/// This trait importantly means that the `write` method only works in the
/// context of a future's task. The object may panic if used outside of a task.
pub trait AsyncWrite: std_io::Write {
    /// Initiates or attempts to shut down this writer, returning success when
    /// the I/O connection has completely shut down.
    ///
    /// This method is intended to be used for asynchronous shutdown of I/O
    /// connections. For example this is suitable for implementing shutdown of a
    /// TLS connection or calling `TcpStream::shutdown` on a proxied connection.
    ///
    /// This `shutdown` method is required by implementors of the
    /// `AsyncWrite` trait. Wrappers typically just want to proxy this call
    /// through to the wrapped type, and base types will typically implement
    /// shutdown logic here or just return `Ok(().into())`.
    ///
    /// # Return value
    ///
    /// This function returns a `Poll<(), io::Error>` classified as such:
    ///
    /// * `Ok(Async::Ready(()))` - indicates that the connection was
    ///   successfully shut down and is now safe to deallocate/drop/close
    ///   resources associated with it. This method means that the current task
    ///   will no longer receive any notifications due to this method and the
    ///   I/O object itself is likely no longer usable.
    ///
    /// * `Ok(Async::NotReady)` - indicates that shutdown is initiated but could
    ///   not complete just yet. This may mean that more I/O needs to happen to
    ///   continue this shutdown operation. The current task is scheduled to
    ///   receive a notification when it's otherwise ready to continue the
    ///   shutdown operation. When woken up this method should be called again.
    ///
    /// * `Err(e)` - indicates a fatal error has happened with shutdown,
    ///   indicating that the shutdown operation did not complete successfully.
    ///   This typically means that the I/O object is no longer usable.
    ///
    /// # Errors
    ///
    /// This function can return normal I/O errors through `Err`, described
    /// above. Additionally this method may also render the underlying
    /// `Write::write` method no longer usable (e.g. will return errors in the
    /// future). It's recommended that once `shutdown` is called the
    /// `write` method is no longer called.
    ///
    /// # Panics
    ///
    /// This function will panic if not called within the context of a future's
    /// task.
    fn shutdown(&mut self) -> Poll<(), std_io::Error>;

    /// Write a `Buf` into this value, returning how many bytes were written.
    ///
    /// Note that this method will advance the `buf` provided automatically by
    /// the number of bytes written.
    fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, std_io::Error> {
        if !buf.has_remaining() {
            return Ok(Async::Ready(0));
        }

        let n = try_nb!(self.write(buf.bytes()));
        buf.advance(n);
        Ok(Async::Ready(n))
    }
}

impl<T: ?Sized + AsyncWrite> AsyncWrite for Box<T> {
    fn shutdown(&mut self) -> Poll<(), std_io::Error> {
        (**self).shutdown()
    }
}
impl<'a, T: ?Sized + AsyncWrite> AsyncWrite for &'a mut T {
    fn shutdown(&mut self) -> Poll<(), std_io::Error> {
        (**self).shutdown()
    }
}

impl AsyncRead for std_io::Repeat {
    unsafe fn prepare_uninitialized_buffer(&self, _: &mut [u8]) -> bool {
        false
    }
}

impl AsyncWrite for std_io::Sink {
    fn shutdown(&mut self) -> Poll<(), std_io::Error> {
        Ok(().into())
    }
}

// TODO: Implement `prepare_uninitialized_buffer` for `io::Take`.
// This is blocked on rust-lang/rust#27269
impl<T: AsyncRead> AsyncRead for std_io::Take<T> {
}

impl<T: AsyncWrite> AsyncWrite for std_io::BufWriter<T> {
    fn shutdown(&mut self) -> Poll<(), std_io::Error> {
        try_nb!(self.flush());
        self.get_mut().shutdown()
    }
}
<commit_msg>Add AsyncRead for std::io::BufReader<commit_after>//! Core I/O traits and combinators when working with Tokio.
//!
//! A description of the high-level I/O combinators can be [found online] in
//! addition to a description of the [low level details].
//!
//! [found online]: https://tokio.rs/docs/getting-started/core/
//! [low level details]: https://tokio.rs/docs/going-deeper/core-low-level/

#![deny(missing_docs)]
#![doc(html_root_url = "https://docs.rs/tokio-io/0.1")]

#[macro_use]
extern crate log;

#[macro_use]
extern crate futures;
extern crate bytes;

use std::io as std_io;
use std::io::Write;

use futures::{Async, Poll, BoxFuture};
use futures::stream::BoxStream;

use bytes::{Buf, BufMut};

/// A convenience typedef around a `Future` whose error component is `io::Error`
pub type IoFuture<T> = BoxFuture<T, std_io::Error>;

/// A convenience typedef around a `Stream` whose error component is `io::Error`
pub type IoStream<T> = BoxStream<T, std_io::Error>;

/// A convenience macro for working with `io::Result<T>` from the `Read` and
/// `Write` traits.
///
/// This macro takes `io::Result<T>` as input, and returns `T` as the output. If
/// the input type is of the `Err` variant, then `Poll::NotReady` is returned if
/// it indicates `WouldBlock` or otherwise `Err` is returned.
#[macro_export]
macro_rules! try_nb {
    ($e:expr) => (match $e {
        Ok(t) => t,
        Err(ref e) if e.kind() == ::std::io::ErrorKind::WouldBlock => {
            return Ok(::futures::Async::NotReady)
        }
        Err(e) => return Err(e.into()),
    })
}

pub mod io;
pub mod codec;

mod copy;
mod flush;
mod framed;
mod framed_read;
mod framed_write;
mod length_delimited;
mod lines;
mod read;
mod read_exact;
mod read_to_end;
mod read_until;
mod shutdown;
mod split;
mod window;
mod write_all;

use codec::{Decoder, Encoder, Framed};
use split::{ReadHalf, WriteHalf};

/// A trait for readable objects which operated in an asynchronous and
/// futures-aware fashion.
///
/// This trait inherits from `io::Read` and indicates as a marker that an I/O
/// object is **nonblocking**, meaning that it will return an error instead of
/// blocking when bytes are read. Specifically this means that the `read`
/// function for traits that implement this type can have a few return values:
///
/// * `Ok(n)` means that `n` bytes of data was immediately read and placed into
///   the output buffer, where `n` == 0 implies that EOF has been reached.
/// * `Err(e) if e.kind() == ErrorKind::WouldBlock` means that no data was read
///   into the buffer provided. The I/O object is not currently readable but may
///   become readable in the future. Most importantly, **the current future's
///   task is scheduled to get unparked when the object is readable**. This
///   means that like `Future::poll` you'll receive a notification when the I/O
///   object is readable again.
/// * `Err(e)` for other errors are standard I/O errors coming from the
///   underlying object.
///
/// This trait importantly means that the `read` method only works in the
/// context of a future's task. The object may panic if used outside of a task.
pub trait AsyncRead: std_io::Read {
    /// Prepares an uninitialized buffer to be safe to pass to `read`. Returns
    /// `true` if the supplied buffer was zeroed out.
    ///
    /// While it would be highly unusual, implementations of [`io::Read`] are
    /// able to read data from the buffer passed as an argument. Because of
    /// this, the buffer passed to [`io::Read`] must be initialized memory. In
    /// situations where large numbers of buffers are used, constantly having to
    /// zero out buffers can be expensive.
    ///
    /// This function does any necessary work to prepare an uninitialized buffer
    /// to be safe to pass to `read`. If `read` guarantees to never attempt read
    /// data out of the supplied buffer, then `prepare_uninitialized_buffer`
    /// doesn't need to do any work.
    ///
    /// If this function returns `true`, then the memory has been zeroed out.
    /// This allows implementations of `AsyncRead` which are composed of
    /// multiple sub implementations to efficiently implement
    /// `prepare_uninitialized_buffer`.
    ///
    /// This function is called from [`read_buf`].
    ///
    /// [`io::Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
    /// [`read_buf`]: #method.read_buf
    unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
        for i in 0..buf.len() {
            buf[i] = 0;
        }

        true
    }

    /// Pull some bytes from this source into the specified `Buf`, returning
    /// how many bytes were read.
    ///
    /// The `buf` provided will have bytes read into it and the internal cursor
    /// will be advanced if any bytes were read. Note that this method typically
    /// will not reallocate the buffer provided.
    fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, std_io::Error> {
        if !buf.has_remaining_mut() {
            return Ok(Async::Ready(0));
        }

        unsafe {
            let n = {
                let b = buf.bytes_mut();

                self.prepare_uninitialized_buffer(b);

                try_nb!(self.read(b))
            };

            buf.advance_mut(n);
            Ok(Async::Ready(n))
        }
    }

    /// Provides a `Stream` and `Sink` interface for reading and writing to this
    /// `Io` object, using `Decode` and `Encode` to read and write the raw data.
    ///
    /// Raw I/O objects work with byte sequences, but higher-level code usually
    /// wants to batch these into meaningful chunks, called "frames". This
    /// method layers framing on top of an I/O object, by using the `Codec`
    /// traits to handle encoding and decoding of messages frames. Note that
    /// the incoming and outgoing frame types may be distinct.
    ///
    /// This function returns a *single* object that is both `Stream` and
    /// `Sink`; grouping this into a single object is often useful for layering
    /// things like gzip or TLS, which require both read and write access to the
    /// underlying object.
    ///
    /// If you want to work more directly with the streams and sink, consider
    /// calling `split` on the `Framed` returned by this method, which will
    /// break them into separate objects, allowing them to interact more easily.
    fn framed<T: Encoder + Decoder>(self, codec: T) -> Framed<Self, T>
        where Self: AsyncWrite + Sized,
    {
        framed::framed(self, codec)
    }

    /// Helper method for splitting this read/write object into two halves.
    ///
    /// The two halves returned implement the `Read` and `Write` traits,
    /// respectively.
    fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>)
        where Self: AsyncWrite + Sized,
    {
        split::split(self)
    }
}

impl<T: ?Sized + AsyncRead> AsyncRead for Box<T> {
    unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
        (**self).prepare_uninitialized_buffer(buf)
    }
}

impl<'a, T: ?Sized + AsyncRead> AsyncRead for &'a mut T {
    unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
        (**self).prepare_uninitialized_buffer(buf)
    }
}

impl<'a> AsyncRead for &'a [u8] {
    unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool {
        false
    }
}

/// A trait for writable objects which operated in an asynchronous and
/// futures-aware fashion.
///
/// This trait inherits from `io::Write` and indicates that an I/O object is
/// **nonblocking**, meaning that it will return an error instead of blocking
/// when bytes are written. Specifically this means that the `write` function
/// for traits that implement this type can have a few return values:
///
/// * `Ok(n)` means that `n` bytes of data was immediately written .
/// * `Err(e) if e.kind() == ErrorKind::WouldBlock` means that no data was
///   written from the buffer provided. The I/O object is not currently
///   writable but may become writable in the future. Most importantly, **the
///   current future's task is scheduled to get unparked when the object is
///   readable**. This means that like `Future::poll` you'll receive a
///   notification when the I/O object is writable again.
/// * `Err(e)` for other errors are standard I/O errors coming from the
///   underlying object.
///
/// This trait importantly means that the `write` method only works in the
/// context of a future's task. The object may panic if used outside of a task.
pub trait AsyncWrite: std_io::Write {
    /// Initiates or attempts to shut down this writer, returning success when
    /// the I/O connection has completely shut down.
    ///
    /// This method is intended to be used for asynchronous shutdown of I/O
    /// connections. For example this is suitable for implementing shutdown of a
    /// TLS connection or calling `TcpStream::shutdown` on a proxied connection.
    ///
    /// This `shutdown` method is required by implementors of the
    /// `AsyncWrite` trait. Wrappers typically just want to proxy this call
    /// through to the wrapped type, and base types will typically implement
    /// shutdown logic here or just return `Ok(().into())`.
    ///
    /// # Return value
    ///
    /// This function returns a `Poll<(), io::Error>` classified as such:
    ///
    /// * `Ok(Async::Ready(()))` - indicates that the connection was
    ///   successfully shut down and is now safe to deallocate/drop/close
    ///   resources associated with it. This method means that the current task
    ///   will no longer receive any notifications due to this method and the
    ///   I/O object itself is likely no longer usable.
    ///
    /// * `Ok(Async::NotReady)` - indicates that shutdown is initiated but could
    ///   not complete just yet. This may mean that more I/O needs to happen to
    ///   continue this shutdown operation. The current task is scheduled to
    ///   receive a notification when it's otherwise ready to continue the
    ///   shutdown operation. When woken up this method should be called again.
    ///
    /// * `Err(e)` - indicates a fatal error has happened with shutdown,
    ///   indicating that the shutdown operation did not complete successfully.
    ///   This typically means that the I/O object is no longer usable.
    ///
    /// # Errors
    ///
    /// This function can return normal I/O errors through `Err`, described
    /// above. Additionally this method may also render the underlying
    /// `Write::write` method no longer usable (e.g. will return errors in the
    /// future). It's recommended that once `shutdown` is called the
    /// `write` method is no longer called.
    ///
    /// # Panics
    ///
    /// This function will panic if not called within the context of a future's
    /// task.
    fn shutdown(&mut self) -> Poll<(), std_io::Error>;

    /// Write a `Buf` into this value, returning how many bytes were written.
    ///
    /// Note that this method will advance the `buf` provided automatically by
    /// the number of bytes written.
    fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, std_io::Error> {
        if !buf.has_remaining() {
            return Ok(Async::Ready(0));
        }

        let n = try_nb!(self.write(buf.bytes()));
        buf.advance(n);
        Ok(Async::Ready(n))
    }
}

impl<T: ?Sized + AsyncWrite> AsyncWrite for Box<T> {
    fn shutdown(&mut self) -> Poll<(), std_io::Error> {
        (**self).shutdown()
    }
}
impl<'a, T: ?Sized + AsyncWrite> AsyncWrite for &'a mut T {
    fn shutdown(&mut self) -> Poll<(), std_io::Error> {
        (**self).shutdown()
    }
}

impl AsyncRead for std_io::Repeat {
    unsafe fn prepare_uninitialized_buffer(&self, _: &mut [u8]) -> bool {
        false
    }
}

impl AsyncWrite for std_io::Sink {
    fn shutdown(&mut self) -> Poll<(), std_io::Error> {
        Ok(().into())
    }
}

// TODO: Implement `prepare_uninitialized_buffer` for `io::Take`.
// This is blocked on rust-lang/rust#27269
impl<T: AsyncRead> AsyncRead for std_io::Take<T> {
}

impl<T: AsyncWrite> AsyncWrite for std_io::BufWriter<T> {
    fn shutdown(&mut self) -> Poll<(), std_io::Error> {
        try_nb!(self.flush());
        self.get_mut().shutdown()
    }
}

impl<T: AsyncRead> AsyncRead for std_io::BufReader<T> {
}
<|endoftext|>