<commit_before>#![crate_type = "lib"]
#![crate_name = "gst"]

pub use self::appsink::AppSink;
pub use self::appsrc::AppSrc;
pub use self::sample::Sample;
pub use self::caps::Caps;
pub use self::buffer::Buffer;
pub use self::mapinfo::MapInfo;
pub use self::mapinfo::Map;
pub use self::element::Element;
pub use self::bus::Bus;
pub use self::bin::Bin;
pub use self::pipeline::Pipeline;
pub use self::playbin::PlayBin;
pub use self::message::Message;
pub use self::mainloop::MainLoop;
pub use self::error::Error;
pub use self::error::Result;
pub use self::videoframe::VideoFrame;
pub use self::videoframe::VideoPlane;
pub use self::videoframe::VideoComponent;
pub use self::videoinfo::VideoInfo;
pub use self::buffer_pool::BufferPool;
pub use self::pad::Pad;
pub use self::structure::Structure;
pub use self::iterator::Iter;
pub use self::reference::Ref;
pub use self::miniobject::MiniObject;
pub use self::object::Object;

use ffi::*;
use std::ptr;
use std::mem;
use std::ffi::CString;
use std::str;
use std::ffi::CStr;

#[macro_use] mod util;
pub mod ffi;

/// Easy way for applications to extract samples from a pipeline.
pub mod appsink;

/// Easy way for applications to inject buffers into a pipeline.
mod appsrc;
mod sample;
mod caps;
mod buffer;
mod element;
pub mod bus;
mod bin;
mod pipeline;
mod playbin;
mod message;
pub mod mainloop;
mod error;
mod videoframe;
mod videoinfo;
mod mapinfo;
mod buffer_pool;
mod pad;
mod structure;
mod iterator;
mod reference;
mod miniobject;
mod object;

#[cfg(target_os="linux")]
mod link_linux;
#[cfg(target_os="macos")]
mod link_osx;
#[cfg(target_os="windows")]
mod link_windows;

pub fn init(){
    unsafe{
        gst_init(ptr::null::<i32>() as *mut i32, ptr::null_mut::<i8>() as *mut *mut *mut i8);
    }
}

pub fn filename_to_uri(filename: &str) -> Result<String>{
    let cfilename = CString::new(filename).unwrap();
    unsafe{
        if gst_uri_is_valid(cfilename.as_ptr())==1{
            return Ok(filename.to_string())
        }
        let err: *mut GError = ptr::null_mut();
        let c_uri = gst_filename_to_uri(cfilename.as_ptr(), mem::transmute(&err));
        if err != ptr::null_mut(){
            Err(Error::new(0, 0, from_c_str!(mem::transmute((*err).message))))
        }else{
            let uri = from_c_str!(mem::transmute(c_uri)).to_string();
            g_free(mem::transmute(c_uri));
            Ok(uri)
        }
    }
}

pub fn uri_get_protocol(uri: &str) -> Result<String>{
    let curi = CString::new(uri).unwrap();
    unsafe{
        if gst_uri_is_valid(curi.as_ptr())==1{
            Ok(from_c_str!(mem::transmute(gst_uri_get_protocol(curi.as_ptr()))).to_string())
        }else{
            Err(Error::new(0,0,"not a valid URI"))
        }
    }
}

pub trait Transfer<PtrType=GstElement>{
    /// Consumes the current object and transfers ownership of the raw pointer
    /// Used to transfer ownership to ffi functions, should be used when an ffi
    /// function expects full transfer of an object to avoid the original object
    /// to be unreferenced in the process
    unsafe fn transfer(self) -> *mut PtrType;
}

pub trait FromGValue{
    fn from_gvalue(value: &GValue) -> Option<Self> where Self:Sized;
}
<commit_msg>fix compilation on arm architecture<commit_after>#![crate_type = "lib"]
#![crate_name = "gst"]

pub use self::appsink::AppSink;
pub use self::appsrc::AppSrc;
pub use self::sample::Sample;
pub use self::caps::Caps;
pub use self::buffer::Buffer;
pub use self::mapinfo::MapInfo;
pub use self::mapinfo::Map;
pub use self::element::Element;
pub use self::bus::Bus;
pub use self::bin::Bin;
pub use self::pipeline::Pipeline;
pub use self::playbin::PlayBin;
pub use self::message::Message;
pub use self::mainloop::MainLoop;
pub use self::error::Error;
pub use self::error::Result;
pub use self::videoframe::VideoFrame;
pub use self::videoframe::VideoPlane;
pub use self::videoframe::VideoComponent;
pub use self::videoinfo::VideoInfo;
pub use self::buffer_pool::BufferPool;
pub use self::pad::Pad;
pub use self::structure::Structure;
pub use self::iterator::Iter;
pub use self::reference::Ref;
pub use self::miniobject::MiniObject;
pub use self::object::Object;

use ffi::*;
use std::ptr;
use std::mem;
use std::ffi::CString;
use std::str;
use std::ffi::CStr;
use std::os::raw::c_char;

#[macro_use] mod util;
pub mod ffi;

/// Easy way for applications to extract samples from a pipeline.
pub mod appsink;

/// Easy way for applications to inject buffers into a pipeline.
mod appsrc;
mod sample;
mod caps;
mod buffer;
mod element;
pub mod bus;
mod bin;
mod pipeline;
mod playbin;
mod message;
pub mod mainloop;
mod error;
mod videoframe;
mod videoinfo;
mod mapinfo;
mod buffer_pool;
mod pad;
mod structure;
mod iterator;
mod reference;
mod miniobject;
mod object;

#[cfg(target_os="linux")]
mod link_linux;
#[cfg(target_os="macos")]
mod link_osx;
#[cfg(target_os="windows")]
mod link_windows;

pub fn init(){
    unsafe{
        gst_init(ptr::null::<i32>() as *mut i32, ptr::null_mut::<c_char>() as *mut *mut *mut c_char);
    }
}

pub fn filename_to_uri(filename: &str) -> Result<String>{
    let cfilename = CString::new(filename).unwrap();
    unsafe{
        if gst_uri_is_valid(cfilename.as_ptr())==1{
            return Ok(filename.to_string())
        }
        let err: *mut GError = ptr::null_mut();
        let c_uri = gst_filename_to_uri(cfilename.as_ptr(), mem::transmute(&err));
        if err != ptr::null_mut(){
            Err(Error::new(0, 0, from_c_str!(mem::transmute((*err).message))))
        }else{
            let uri = from_c_str!(mem::transmute(c_uri)).to_string();
            g_free(mem::transmute(c_uri));
            Ok(uri)
        }
    }
}

pub fn uri_get_protocol(uri: &str) -> Result<String>{
    let curi = CString::new(uri).unwrap();
    unsafe{
        if gst_uri_is_valid(curi.as_ptr())==1{
            Ok(from_c_str!(mem::transmute(gst_uri_get_protocol(curi.as_ptr()))).to_string())
        }else{
            Err(Error::new(0,0,"not a valid URI"))
        }
    }
}

pub trait Transfer<PtrType=GstElement>{
    /// Consumes the current object and transfers ownership of the raw pointer
    /// Used to transfer ownership to ffi functions, should be used when an ffi
    /// function expects full transfer of an object to avoid the original object
    /// to be unreferenced in the process
    unsafe fn transfer(self) -> *mut PtrType;
}

pub trait FromGValue{
    fn from_gvalue(value: &GValue) -> Option<Self> where Self:Sized;
}
<|endoftext|>


<commit_before>//! Json String Literal Generator
//!
//! Write json with Rust syntax instead of hard to read inline strings.
//! This crate doesn't evaluate any expressions, it just converts a Rust _token tree_ into a
//! minified json string.
//!
//! # Usage
//!
//! This crate is on [crates.io](https://crates.io/crates/json_str).
//!
//! There are two ways to reference `json_str` in your projects, depending on whether you're on
//! the `stable`/`beta` or `nightly` channels.
//!
//! ## Stable
//!
//! To get started, add `json_str` to your `Cargo.toml`:
//!
//! ```ignore
//! [dependencies]
//! json_str = "*"
//! ```
//!
//! And reference it in your crate root:
//!
//! ```ignore
//! #[macro_use]
//! extern crate json_str;
//! ```
//!
//! ## Nightly
//!
//! To get started, add `json_str` to your `Cargo.toml`:
//!
//! ```ignore
//! [dependencies]
//! json_str = { version = "*", features = "nightly" }
//! ```
//!
//! And reference it in your crate root:
//!
//! ```ignore
//! #![feature(plugin)]
//! #![plugin(json_str)]
//! ```
//!
//! If you're on the `nightly` channel, it's better to use the above `plugin` version with the `nightly`
//! feature because the conversion and sanitisation takes place at compile-time instead of runtime,
//! saving precious runtime cycles.
//!
//! ## Examples
//!
//! The `json_str!` macro will take an inline token tree and return a sanitised json `String`:
//!
//! ```
//! # #![feature(plugin)]
//! # #![plugin(json_str)]
//! # fn main() {
//! let json = json_str!({
//! 	"query": {
//! 		"filtered": {
//! 			"query": {
//! 				"match_all": {}
//! 			},
//! 			"filter": {
//! 				"geo_distance": {
//! 					"distance": "20km",
//! 					"location": {
//! 						"lat": 37.776,
//! 						"lon": -122.41
//! 					}
//! 				}
//! 			}
//! 		}
//! 	}
//! });
//! # }
//! ```
//!
//! This will also work for unquoted keys for something a bit more `rusty`:
//!
//! ```
//! # #![feature(plugin)]
//! # #![plugin(json_str)]
//! # fn main() {
//! let json = json_str!({
//! 	query: {
//! 		filtered: {
//! 			query: {
//! 				match_all: {}
//! 			},
//! 			filter: {
//! 				geo_distance: {
//! 					distance: "20km",
//! 					location: {
//! 						lat: 37.776,
//! 						lon: -122.41
//! 					}
//! 				}
//! 			}
//! 		}
//! 	}
//! });
//! # }
//! ```
//!
//! On `nightly`, there's an additional plugin called `json_lit` that returns a `&'satic str`
//! instead of a `String`, so you can avoid allocating each time. The syntax is otherwise the same
//! as `json_str`:
//!
//! ```
//! # #![feature(plugin)]
//! # #![plugin(json_str)]
//! # fn main() {
//! let json = json_lit!({
//! 	"query": {
//! 		"filtered": {
//! 			"query": {
//! 				"match_all": {}
//! 			},
//! 			"filter": {
//! 				"geo_distance": {
//! 					"distance": "20km",
//! 					"location": {
//! 						"lat": 37.776,
//! 						"lon": -122.41
//! 					}
//! 				}
//! 			}
//! 		}
//! 	}
//! });
//! # }
//! ```
//!
//! For json values that can't be fully determined at compile-time,
//! use [json_macros](https://github.com/tomjakubowski/json_macros) instead.

#![doc(html_root_url = "http://kodraus.github.io/rustdoc/json_str/")]
#![cfg_attr(feature = "nightly", crate_type="dylib")]
#![cfg_attr(feature = "nightly", feature(plugin_registrar, rustc_private, quote, plugin, stmt_expr_attributes))]

#[doc(hidden)]
pub mod parse;

#[cfg(feature = "nightly")]
include!("lib.rs.in");

#[cfg_attr(not(feature = "nightly"), macro_export)]
#[cfg(not(feature = "nightly"))]
macro_rules! json_str {
	($j:tt) => ({
		let json_raw = stringify!($j);
		let mut json = String::with_capacity(json_raw.len());
		$crate::parse::sanitise(json_raw.as_bytes(), &mut json);

		json
	})
}
<commit_msg>Fix minor typo.<commit_after>//! Json String Literal Generator
//!
//! Write json with Rust syntax instead of hard to read inline strings.
//! This crate doesn't evaluate any expressions, it just converts a Rust _token tree_ into a
//! minified json string.
//!
//! # Usage
//!
//! This crate is on [crates.io](https://crates.io/crates/json_str).
//!
//! There are two ways to reference `json_str` in your projects, depending on whether you're on
//! the `stable`/`beta` or `nightly` channels.
//!
//! ## Stable
//!
//! To get started, add `json_str` to your `Cargo.toml`:
//!
//! ```ignore
//! [dependencies]
//! json_str = "*"
//! ```
//!
//! And reference it in your crate root:
//!
//! ```ignore
//! #[macro_use]
//! extern crate json_str;
//! ```
//!
//! ## Nightly
//!
//! To get started, add `json_str` to your `Cargo.toml`:
//!
//! ```ignore
//! [dependencies]
//! json_str = { version = "*", features = "nightly" }
//! ```
//!
//! And reference it in your crate root:
//!
//! ```ignore
//! #![feature(plugin)]
//! #![plugin(json_str)]
//! ```
//!
//! If you're on the `nightly` channel, it's better to use the above `plugin` version with the `nightly`
//! feature because the conversion and sanitisation takes place at compile-time instead of runtime,
//! saving precious runtime cycles.
//!
//! ## Examples
//!
//! The `json_str!` macro will take an inline token tree and return a sanitised json `String`:
//!
//! ```
//! # #![feature(plugin)]
//! # #![plugin(json_str)]
//! # fn main() {
//! let json = json_str!({
//! 	"query": {
//! 		"filtered": {
//! 			"query": {
//! 				"match_all": {}
//! 			},
//! 			"filter": {
//! 				"geo_distance": {
//! 					"distance": "20km",
//! 					"location": {
//! 						"lat": 37.776,
//! 						"lon": -122.41
//! 					}
//! 				}
//! 			}
//! 		}
//! 	}
//! });
//! # }
//! ```
//!
//! This will also work for unquoted keys for something a bit more `rusty`:
//!
//! ```
//! # #![feature(plugin)]
//! # #![plugin(json_str)]
//! # fn main() {
//! let json = json_str!({
//! 	query: {
//! 		filtered: {
//! 			query: {
//! 				match_all: {}
//! 			},
//! 			filter: {
//! 				geo_distance: {
//! 					distance: "20km",
//! 					location: {
//! 						lat: 37.776,
//! 						lon: -122.41
//! 					}
//! 				}
//! 			}
//! 		}
//! 	}
//! });
//! # }
//! ```
//!
//! On `nightly`, there's an additional plugin called `json_lit` that returns a `&'static str`
//! instead of a `String`, so you can avoid allocating each time. The syntax is otherwise the same
//! as `json_str`:
//!
//! ```
//! # #![feature(plugin)]
//! # #![plugin(json_str)]
//! # fn main() {
//! let json = json_lit!({
//! 	"query": {
//! 		"filtered": {
//! 			"query": {
//! 				"match_all": {}
//! 			},
//! 			"filter": {
//! 				"geo_distance": {
//! 					"distance": "20km",
//! 					"location": {
//! 						"lat": 37.776,
//! 						"lon": -122.41
//! 					}
//! 				}
//! 			}
//! 		}
//! 	}
//! });
//! # }
//! ```
//!
//! For json values that can't be fully determined at compile-time,
//! use [json_macros](https://github.com/tomjakubowski/json_macros) instead.

#![doc(html_root_url = "http://kodraus.github.io/rustdoc/json_str/")]
#![cfg_attr(feature = "nightly", crate_type="dylib")]
#![cfg_attr(feature = "nightly", feature(plugin_registrar, rustc_private, quote, plugin, stmt_expr_attributes))]

#[doc(hidden)]
pub mod parse;

#[cfg(feature = "nightly")]
include!("lib.rs.in");

#[cfg_attr(not(feature = "nightly"), macro_export)]
#[cfg(not(feature = "nightly"))]
macro_rules! json_str {
	($j:tt) => ({
		let json_raw = stringify!($j);
		let mut json = String::with_capacity(json_raw.len());
		$crate::parse::sanitise(json_raw.as_bytes(), &mut json);

		json
	})
}
<|endoftext|>


<commit_before>// #![feature(plugin, custom_attribute)]
// #![plugin(c_import)]

#![cfg_attr(feature="clippy", warn(cast_possible_truncation))]
#![cfg_attr(feature="clippy", warn(cast_possible_wrap))]
#![cfg_attr(feature="clippy", warn(cast_precision_loss))]
#![cfg_attr(feature="clippy", warn(cast_sign_loss))]
#![cfg_attr(feature="clippy", warn(enum_glob_use))]
#![cfg_attr(feature="clippy", warn(mut_mut))]
#![cfg_attr(feature="clippy", warn(mutex_integer))]
#![cfg_attr(feature="clippy", warn(non_ascii_literal))]
#![cfg_attr(feature="clippy", warn(nonminimal_bool))]
#![cfg_attr(feature="clippy", warn(option_unwrap_used))]
#![cfg_attr(feature="clippy", warn(result_unwrap_used))]
#![cfg_attr(feature="clippy", warn(single_match_else))]
#![cfg_attr(feature="clippy", warn(string_add))]
#![cfg_attr(feature="clippy", warn(string_add_assign))]
#![cfg_attr(feature="clippy", warn(unicode_not_nfc))]
#![cfg_attr(feature="clippy", warn(wrong_pub_self_convention))]

#![deny(missing_docs)]
#![deny(warnings)]

//! Message Passing Interface bindings for Rust
//!
//! The [Message Passing Interface][MPI] (MPI) is a specification for a
//! message-passing style concurrency library. Implementations of MPI are often used to structure
//! parallel computation on High Performance Computing systems. The MPI specification describes
//! bindings for the C programming language (and through it C++) as well as for the Fortran
//! programming language. This library tries to bridge the gap into a more rustic world.
//!
//! [MPI]: http://www.mpi-forum.org
//!
//! # Usage
//!
//! Add the `mpi` crate as a dependency in your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! mpi = { git = "https://github.com/bsteinb/rsmpi.git", tag = "0.4.0" }
//! ```
//!
//! Then use it in your program like this:
//!
//! ```no_run
//! extern crate mpi;
//!
//! use mpi::traits::*;
//!
//! fn main() {
//!     let universe = mpi::initialize().unwrap();
//!     let world = universe.world();
//!     let size = world.size();
//!     let rank = world.rank();
//!
//!     if size != 2 {
//!         panic!("Size of MPI_COMM_WORLD must be 2, but is {}!", size);
//!      }
//!
//!     match rank {
//!         0 => {
//!             let msg = vec![4.0f64, 8.0, 15.0];
//!             world.process_at_rank(rank + 1).send(&msg[..]);
//!         }
//!         1 => {
//!             let (msg, status) = world.any_process().receive_vec::<f64>();
//!             println!("Process {} got message {:?}.\nStatus is: {:?}", rank, msg, status);
//!         }
//!         _ => unreachable!()
//!     }
//! }
//! ```
//!
//! # Features
//!
//! The bindings follow the MPI 3.1 specification.
//!
//! Currently supported:
//!
//! - **Groups, Contexts, Communicators**:
//!   - Group and (Intra-)Communicator management from section 6 is mostly complete.
//!   - no Inter-Communicators
//!   - no process topologies
//! - **Point to point communication**:
//!   - standard, buffered, synchronous and ready mode send in blocking and non-blocking variants
//!   - receive in blocking and non-blocking variants
//!   - send-receive
//!   - probe
//!   - matched probe/receive
//! - **Collective communication**:
//!   - barrier
//!   - broadcast
//!   - (all) gather
//!   - scatter
//!   - all to all
//!   - varying counts operations
//!   - reductions/scans
//!   - blocking and non-blocking variants
//! - **Datatypes**: Bridging between Rust types and MPI basic types as well as custom MPI datatypes
//! which can act as views into buffers.
//!
//! Not supported (yet):
//!
//! - Process management
//! - One-sided communication (RMA)
//! - MPI parallel I/O
//! - A million small things
//!
//! The sub-modules contain a more detailed description of which features are and are not
//! supported.
//!
//! # Further Reading
//!
//! While every publicly defined item in this crate should have some documentation attached to it,
//! most of the descriptions are quite terse for now and to the uninitiated will only make sense in
//! combination with the [MPI specification][MPIspec].
//!
//! [MPIspec]: http://www.mpi-forum.org/docs/docs.html

use std::mem;
use std::string::FromUtf8Error;
use std::os::raw::{c_char, c_int};

extern crate conv;

use conv::ConvUtil;

/// The raw C language MPI API
///
/// Documented in the [Message Passing Interface specification][spec]
///
/// [spec]: http://www.mpi-forum.org/docs/docs.html
#[allow(missing_docs, dead_code, non_snake_case, non_camel_case_types)]
pub mod ffi;

pub mod collective;
pub mod datatype;
pub mod point_to_point;
pub mod raw;
pub mod request;
pub mod topology;

/// Re-exports all traits.
pub mod traits {
    pub use collective::traits::*;
    pub use datatype::traits::*;
    pub use point_to_point::traits::*;
    pub use raw::traits::*;
    pub use request::traits::*;
    pub use topology::traits::*;
}

#[doc(inline)]
pub use topology::{initialize, initialize_with_threading, Threading};

use ffi::MPI_Aint;

/// Encodes error values returned by MPI functions.
pub type Error = c_int;
/// Encodes number of values in multi-value messages.
pub type Count = c_int;
/// Can be used to tag messages on the sender side and match on the receiver side.
pub type Tag = c_int;
/// An address in memory
pub type Address = MPI_Aint;

/// Identifies the version of the MPI standard implemented by the library.
///
/// Returns a tuple of `(version, subversion)`, e.g. `(3, 0)`.
///
/// Can be called without initializing MPI.
pub fn get_version() -> (c_int, c_int) {
    let mut version: c_int = unsafe { mem::uninitialized() };
    let mut subversion: c_int = unsafe { mem::uninitialized() };
    unsafe {
        ffi::MPI_Get_version(&mut version, &mut subversion);
    }
    (version, subversion)
}

/// Describes the version of the MPI library itself.
///
/// Can return an `Err` if the description of the MPI library is not a UTF-8 string.
///
/// Can be called without initializing MPI.
pub fn get_library_version() -> Result<String, FromUtf8Error> {
    let bufsize = ffi::RSMPI_MAX_LIBRARY_VERSION_STRING.value_as().expect(
        &format!("MPI_MAX_LIBRARY_SIZE ({}) cannot be expressed as a usize.",
            ffi::RSMPI_MAX_LIBRARY_VERSION_STRING)
        );
    let mut buf = vec![0u8; bufsize];
    let mut len: c_int = 0;

    unsafe {
        ffi::MPI_Get_library_version(buf.as_mut_ptr() as *mut c_char, &mut len);
    }
    buf.truncate(len.value_as().expect(&format!("Length of library version string ({}) cannot \
                                                 be expressed as a usize.",
                                                len)));
    String::from_utf8(buf)
}
<commit_msg>chore: enable more built-in lints<commit_after>// #![feature(plugin, custom_attribute)]
// #![plugin(c_import)]

#![deny(missing_docs)]

#![warn(missing_copy_implementations)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
// This has false positives on #[macro_use],
// see https://github.com/rust-lang/rust/issues/30849
// #![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_qualifications)]
#![deny(warnings)]

#![cfg_attr(feature="clippy", warn(cast_possible_truncation))]
#![cfg_attr(feature="clippy", warn(cast_possible_wrap))]
#![cfg_attr(feature="clippy", warn(cast_precision_loss))]
#![cfg_attr(feature="clippy", warn(cast_sign_loss))]
#![cfg_attr(feature="clippy", warn(enum_glob_use))]
#![cfg_attr(feature="clippy", warn(mut_mut))]
#![cfg_attr(feature="clippy", warn(mutex_integer))]
#![cfg_attr(feature="clippy", warn(non_ascii_literal))]
#![cfg_attr(feature="clippy", warn(nonminimal_bool))]
#![cfg_attr(feature="clippy", warn(option_unwrap_used))]
#![cfg_attr(feature="clippy", warn(result_unwrap_used))]
#![cfg_attr(feature="clippy", warn(single_match_else))]
#![cfg_attr(feature="clippy", warn(string_add))]
#![cfg_attr(feature="clippy", warn(string_add_assign))]
#![cfg_attr(feature="clippy", warn(unicode_not_nfc))]
#![cfg_attr(feature="clippy", warn(wrong_pub_self_convention))]

//! Message Passing Interface bindings for Rust
//!
//! The [Message Passing Interface][MPI] (MPI) is a specification for a
//! message-passing style concurrency library. Implementations of MPI are often used to structure
//! parallel computation on High Performance Computing systems. The MPI specification describes
//! bindings for the C programming language (and through it C++) as well as for the Fortran
//! programming language. This library tries to bridge the gap into a more rustic world.
//!
//! [MPI]: http://www.mpi-forum.org
//!
//! # Usage
//!
//! Add the `mpi` crate as a dependency in your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! mpi = { git = "https://github.com/bsteinb/rsmpi.git", tag = "0.4.0" }
//! ```
//!
//! Then use it in your program like this:
//!
//! ```no_run
//! extern crate mpi;
//!
//! use mpi::traits::*;
//!
//! fn main() {
//!     let universe = mpi::initialize().unwrap();
//!     let world = universe.world();
//!     let size = world.size();
//!     let rank = world.rank();
//!
//!     if size != 2 {
//!         panic!("Size of MPI_COMM_WORLD must be 2, but is {}!", size);
//!      }
//!
//!     match rank {
//!         0 => {
//!             let msg = vec![4.0f64, 8.0, 15.0];
//!             world.process_at_rank(rank + 1).send(&msg[..]);
//!         }
//!         1 => {
//!             let (msg, status) = world.any_process().receive_vec::<f64>();
//!             println!("Process {} got message {:?}.\nStatus is: {:?}", rank, msg, status);
//!         }
//!         _ => unreachable!()
//!     }
//! }
//! ```
//!
//! # Features
//!
//! The bindings follow the MPI 3.1 specification.
//!
//! Currently supported:
//!
//! - **Groups, Contexts, Communicators**:
//!   - Group and (Intra-)Communicator management from section 6 is mostly complete.
//!   - no Inter-Communicators
//!   - no process topologies
//! - **Point to point communication**:
//!   - standard, buffered, synchronous and ready mode send in blocking and non-blocking variants
//!   - receive in blocking and non-blocking variants
//!   - send-receive
//!   - probe
//!   - matched probe/receive
//! - **Collective communication**:
//!   - barrier
//!   - broadcast
//!   - (all) gather
//!   - scatter
//!   - all to all
//!   - varying counts operations
//!   - reductions/scans
//!   - blocking and non-blocking variants
//! - **Datatypes**: Bridging between Rust types and MPI basic types as well as custom MPI datatypes
//! which can act as views into buffers.
//!
//! Not supported (yet):
//!
//! - Process management
//! - One-sided communication (RMA)
//! - MPI parallel I/O
//! - A million small things
//!
//! The sub-modules contain a more detailed description of which features are and are not
//! supported.
//!
//! # Further Reading
//!
//! While every publicly defined item in this crate should have some documentation attached to it,
//! most of the descriptions are quite terse for now and to the uninitiated will only make sense in
//! combination with the [MPI specification][MPIspec].
//!
//! [MPIspec]: http://www.mpi-forum.org/docs/docs.html

use std::mem;
use std::string::FromUtf8Error;
use std::os::raw::{c_char, c_int};

extern crate conv;

use conv::ConvUtil;

/// The raw C language MPI API
///
/// Documented in the [Message Passing Interface specification][spec]
///
/// [spec]: http://www.mpi-forum.org/docs/docs.html
#[allow(missing_docs, dead_code, non_snake_case, non_camel_case_types)]
pub mod ffi;

pub mod collective;
pub mod datatype;
pub mod point_to_point;
pub mod raw;
pub mod request;
pub mod topology;

/// Re-exports all traits.
pub mod traits {
    pub use collective::traits::*;
    pub use datatype::traits::*;
    pub use point_to_point::traits::*;
    pub use raw::traits::*;
    pub use request::traits::*;
    pub use topology::traits::*;
}

#[doc(inline)]
pub use topology::{initialize, initialize_with_threading, Threading};

use ffi::MPI_Aint;

/// Encodes error values returned by MPI functions.
pub type Error = c_int;
/// Encodes number of values in multi-value messages.
pub type Count = c_int;
/// Can be used to tag messages on the sender side and match on the receiver side.
pub type Tag = c_int;
/// An address in memory
pub type Address = MPI_Aint;

/// Identifies the version of the MPI standard implemented by the library.
///
/// Returns a tuple of `(version, subversion)`, e.g. `(3, 0)`.
///
/// Can be called without initializing MPI.
pub fn get_version() -> (c_int, c_int) {
    let mut version: c_int = unsafe { mem::uninitialized() };
    let mut subversion: c_int = unsafe { mem::uninitialized() };
    unsafe {
        ffi::MPI_Get_version(&mut version, &mut subversion);
    }
    (version, subversion)
}

/// Describes the version of the MPI library itself.
///
/// Can return an `Err` if the description of the MPI library is not a UTF-8 string.
///
/// Can be called without initializing MPI.
pub fn get_library_version() -> Result<String, FromUtf8Error> {
    let bufsize = ffi::RSMPI_MAX_LIBRARY_VERSION_STRING.value_as().expect(
        &format!("MPI_MAX_LIBRARY_SIZE ({}) cannot be expressed as a usize.",
            ffi::RSMPI_MAX_LIBRARY_VERSION_STRING)
        );
    let mut buf = vec![0u8; bufsize];
    let mut len: c_int = 0;

    unsafe {
        ffi::MPI_Get_library_version(buf.as_mut_ptr() as *mut c_char, &mut len);
    }
    buf.truncate(len.value_as().expect(&format!("Length of library version string ({}) cannot \
                                                 be expressed as a usize.",
                                                len)));
    String::from_utf8(buf)
}
<|endoftext|>


<commit_before>//#![warn(missing_doc)]
#![forbid(non_camel_case_types)]
#![allow(unstable)]

//! This crate currently provides almost XML 1.0/1.1-compliant pull parser.

extern crate core;

#[macro_use]
extern crate bitflags;

pub use reader::EventReader;

pub mod macros;
pub mod name;
pub mod attribute;
pub mod common;
pub mod escape;
pub mod namespace;
pub mod reader;
pub mod writer;
pub mod util;
<commit_msg>Opt-in to Rust features<commit_after>//#![warn(missing_doc)]
#![forbid(non_camel_case_types)]
#![feature(collections,core,hash,io)]

//! This crate currently provides almost XML 1.0/1.1-compliant pull parser.

extern crate core;

#[macro_use]
extern crate bitflags;

pub use reader::EventReader;

pub mod macros;
pub mod name;
pub mod attribute;
pub mod common;
pub mod escape;
pub mod namespace;
pub mod reader;
pub mod writer;
pub mod util;
<|endoftext|>


<commit_before>//! A crate for parsing and using JSON pointers, as specified in [RFC 6901](https://tools.ietf.org/html/rfc6901).
//!
//! [![Build Status](https://travis-ci.org/remexre/json-pointer.svg?branch=master)](https://travis-ci.org/remexre/json-pointer)
//! [![crates.io](https://img.shields.io/crates/v/json-pointer.svg)](https://crates.io/crates/json-pointer)
//! [![Documentation](https://docs.rs/json-pointer/badge.svg)](https://docs.rs/json-pointer)
//!
//! ## Creating a JSON Pointer
//!
//! JSON pointers can be created with a literal `[&str]`, or parsed from a `String`.
//!
//! ```rust
//! extern crate json_pointer;
//! #[macro_use]
//! extern crate serde_json;
//!
//! use json_pointer::JsonPointer;
//!
//! fn main() {
//!     let from_strs = JsonPointer::new([
//!         "foo",
//!         "bar",
//!     ]);
//!     let parsed = "/foo/bar".parse::<JsonPointer<_, _>>().unwrap();
//!
//!     assert_eq!(from_strs.to_string(), parsed.to_string());
//! }
//! ```
//!
//! ## Using a JSON Pointer
//!
//! The `JsonPointer` type provides `.get()` and `.get_mut()`, to get references
//! and mutable references to the appropriate value, respectively.
//!
//! ```rust
//! extern crate json_pointer;
//! #[macro_use]
//! extern crate serde_json;
//!
//! use json_pointer::JsonPointer;
//!
//! fn main() {
//!     let ptr = "/foo/bar".parse::<JsonPointer<_, _>>().unwrap();
//!
//!     let document = json!({
//!         "foo": {
//!             "bar": 0,
//!             "baz": 1,
//!         },
//!         "quux": "xyzzy"
//!     });
//!
//!     let indexed = ptr.get(&document).unwrap();
//!
//!     assert_eq!(indexed, &json!(0));
//! }
//! ```
//!
//! ## URI Fragment Identifier Representation
//!
//! JSON Pointers can be embedded in the fragment portion of a URI. This is the
//! reason why most JSON pointer libraries require a `#` character at the beginning
//! of a JSON pointer. The crate will detect the leading `#` as an indicator to
//! parse in URI Fragment Identifier Representation. Note that this means that this
//! crate does not support parsing full URIs.
//!
//! ```rust
//! extern crate json_pointer;
//! #[macro_use]
//! extern crate serde_json;
//!
//! use json_pointer::JsonPointer;
//!
//! fn main() {
//!     let str_ptr = "/f%o".parse::<JsonPointer<_, _>>().unwrap();
//!     let uri_ptr = "#/f%25o".parse::<JsonPointer<_, _>>().unwrap();
//!
//!     assert_eq!(str_ptr, uri_ptr);
//! }
//! ```

#![deny(missing_docs)]

extern crate serde_json;

mod parser;
mod ptr;

pub use parser::ParseError;
pub use ptr::IndexError;
pub use ptr::JsonPointer;
<commit_msg>Removes unneeded imports from doc tests.<commit_after>//! A crate for parsing and using JSON pointers, as specified in [RFC 6901](https://tools.ietf.org/html/rfc6901).
//!
//! [![Build Status](https://travis-ci.org/remexre/json-pointer.svg?branch=master)](https://travis-ci.org/remexre/json-pointer)
//! [![crates.io](https://img.shields.io/crates/v/json-pointer.svg)](https://crates.io/crates/json-pointer)
//! [![Documentation](https://docs.rs/json-pointer/badge.svg)](https://docs.rs/json-pointer)
//!
//! ## Creating a JSON Pointer
//!
//! JSON pointers can be created with a literal `[&str]`, or parsed from a `String`.
//!
//! ```rust
//! extern crate json_pointer;
//!
//! use json_pointer::JsonPointer;
//!
//! fn main() {
//!     let from_strs = JsonPointer::new([
//!         "foo",
//!         "bar",
//!     ]);
//!     let parsed = "/foo/bar".parse::<JsonPointer<_, _>>().unwrap();
//!
//!     assert_eq!(from_strs.to_string(), parsed.to_string());
//! }
//! ```
//!
//! ## Using a JSON Pointer
//!
//! The `JsonPointer` type provides `.get()` and `.get_mut()`, to get references
//! and mutable references to the appropriate value, respectively.
//!
//! ```rust
//! extern crate json_pointer;
//! #[macro_use]
//! extern crate serde_json;
//!
//! use json_pointer::JsonPointer;
//!
//! fn main() {
//!     let ptr = "/foo/bar".parse::<JsonPointer<_, _>>().unwrap();
//!
//!     let document = json!({
//!         "foo": {
//!             "bar": 0,
//!             "baz": 1,
//!         },
//!         "quux": "xyzzy"
//!     });
//!
//!     let indexed = ptr.get(&document).unwrap();
//!
//!     assert_eq!(indexed, &json!(0));
//! }
//! ```
//!
//! ## URI Fragment Identifier Representation
//!
//! JSON Pointers can be embedded in the fragment portion of a URI. This is the
//! reason why most JSON pointer libraries require a `#` character at the beginning
//! of a JSON pointer. The crate will detect the leading `#` as an indicator to
//! parse in URI Fragment Identifier Representation. Note that this means that this
//! crate does not support parsing full URIs.
//!
//! ```rust
//! extern crate json_pointer;
//!
//! use json_pointer::JsonPointer;
//!
//! fn main() {
//!     let str_ptr = "/f%o".parse::<JsonPointer<_, _>>().unwrap();
//!     let uri_ptr = "#/f%25o".parse::<JsonPointer<_, _>>().unwrap();
//!
//!     assert_eq!(str_ptr, uri_ptr);
//! }
//! ```

#![deny(missing_docs)]

extern crate serde_json;

mod parser;
mod ptr;

pub use parser::ParseError;
pub use ptr::IndexError;
pub use ptr::JsonPointer;
<|endoftext|>


<commit_before>use std::mem;
use std::convert::From;

#[derive(Debug, Eq, PartialEq)]
pub struct U32b([u8; 4]);

impl<'a> From<&'a [u8]> for U32b {
    fn from(a: &[u8]) -> U32b {
        assert!(a.len() == 4);
        U32b([a[0], a[1], a[2], a[3]])
    }
}

#[inline(always)]
pub fn pack_native_u32(n: u32) -> U32b {
    U32b(unsafe { mem::transmute(n) })
}

#[inline(always)]
pub fn unpack_native_u32(bytes: U32b) -> u32 {
    match bytes {
        U32b(b) => unsafe { mem::transmute(b) }
    }
}

#[cfg(target_endian = "little")]
pub fn pack_le_u32(n: u32) -> U32b {
    pack_native_u32(n)
}

#[cfg(target_endian = "little")]
pub fn unpack_le_u32(bytes: U32b) -> u32 {
    unpack_native_u32(bytes)
}

#[cfg(target_endian = "big")]
pub fn pack_le_u32(n: u32) -> U32b {
    pack_native_u32(n.swap_bytes())
}

#[cfg(target_endian = "big")]
fn unpack_le_u32(bytes: U32b) -> u32 {
    unpack_native_u32(bytes).swap_bytes()
}

#[test]
fn test_pack() {
    assert_eq!(U32b([123, 0, 0, 0]), pack_le_u32(123));
}

#[test]
fn test_unpack() {
    assert_eq!(123, unpack_le_u32(U32b([123, 0, 0, 0])));

    let b = [123, 0, 0, 0, 0u8];
    assert_eq!(123, unpack_le_u32(U32b::from(&b[0..4])));
}
<commit_msg>Implement AsRef<commit_after>use std::mem;
use std::convert::From;
use std::convert::AsRef;

#[derive(Debug, Eq, PartialEq)]
pub struct U32b([u8; 4]);

impl<'a> From<&'a [u8]> for U32b {
    fn from(a: &[u8]) -> U32b {
        assert!(a.len() == 4);
        U32b([a[0], a[1], a[2], a[3]])
    }
}

impl AsRef<[u8]> for U32b {
    fn as_ref(&self) -> &[u8] {
        &self.0[..]
    }
}

#[inline(always)]
pub fn pack_native_u32(n: u32) -> U32b {
    U32b(unsafe { mem::transmute(n) })
}

#[inline(always)]
pub fn unpack_native_u32(bytes: U32b) -> u32 {
    match bytes {
        U32b(b) => unsafe { mem::transmute(b) }
    }
}

#[cfg(target_endian = "little")]
pub fn pack_le_u32(n: u32) -> U32b {
    pack_native_u32(n)
}

#[cfg(target_endian = "little")]
pub fn unpack_le_u32(bytes: U32b) -> u32 {
    unpack_native_u32(bytes)
}

#[cfg(target_endian = "big")]
pub fn pack_le_u32(n: u32) -> U32b {
    pack_native_u32(n.swap_bytes())
}

#[cfg(target_endian = "big")]
fn unpack_le_u32(bytes: U32b) -> u32 {
    unpack_native_u32(bytes).swap_bytes()
}

#[test]
fn test_pack() {
    assert_eq!(U32b([123, 0, 0, 0]), pack_le_u32(123));
}

#[test]
fn test_unpack() {
    assert_eq!(123, unpack_le_u32(U32b([123, 0, 0, 0])));

    let b = [123, 0, 0, 0, 0u8];
    assert_eq!(123, unpack_le_u32(U32b::from(&b[0..4])));
}
<|endoftext|>


<commit_before>extern crate libc;

use libc::{c_void, c_int, c_char, pid_t, ssize_t};

#[allow(non_camel_case_types)]
enum _cap_struct{}

#[allow(non_camel_case_types)]
type cap_t = *mut _cap_struct;

#[allow(non_camel_case_types)]
type cap_value_t = isize;

#[allow(non_camel_case_types)]
enum cap_flag_t {
    CAP_EFFECTIVE=0,
    CAP_PERMITTED=1,
    CAP_INHERITABLE=2
}

#[allow(non_camel_case_types)]
enum cap_flag_value_t {
    CAP_CLEAR=0,
    CAP_SET=1
}

/*
 * TODO
enum capabilities {
    CAP_CHOWN=0,
    CAP_DAC_OVERRIDE
}
*/

#[link(name="cap")]
extern "C" {

    /* libcap/cap_alloc.c */
    fn cap_init() -> cap_t;
	fn cap_free(ptr: *mut c_void) -> c_int;
	fn cap_dup(cap: cap_t) -> cap_t;

    /* libcap/cap_flag.c */
    fn cap_get_flag(c: cap_t, vt: cap_value_t,
                    ft: cap_flag_t,
                    val: *mut cap_flag_value_t) -> c_int;

    fn cap_set_flag(c: cap_t, f: cap_flag_t,
                    ncap: c_int,
                    caps: *const cap_value_t,
                    val: cap_flag_value_t) -> c_int;

    fn cap_clear(c: cap_t) -> c_int;
    fn cap_clear_flag(c: cap_t, flag: cap_flag_t) -> c_int;

    /* libcap/cap_file.c */
    fn cap_get_fd(fd: c_int) -> cap_t;
    fn cap_get_file(filename: *const c_char) -> cap_t;
    fn cap_set_fd(fd: c_int, cap: cap_t) -> c_int;
    fn cap_set_file(filename: *const c_char, cap: cap_t) -> c_int;

    /* libcap/cap_proc.c */
    fn cap_get_proc() -> cap_t;
    fn cap_get_pid(pid: pid_t) -> cap_t;
    fn cap_set_proc(cap: cap_t) -> c_int;
    fn cap_get_bound(vt: cap_value_t) -> c_int;
    fn cap_drop_bound(vt: cap_value_t) -> c_int;

    /* libcap/cap_extint.c */
    fn cap_size(cap: cap_t) -> ssize_t;
    fn cap_copy_ext(ptr: *mut c_void, cap: cap_t, size: ssize_t) -> ssize_t;
    fn cap_copy_int(ptr: *const c_void) -> cap_t;
    fn cap_compare(a: cap_t, b: cap_t) -> c_int;

}

#[test]
fn test_basic(){
	unsafe {
		let c = cap_init();
		cap_free(c);
	}
}
<commit_msg>Add capability definitions<commit_after>extern crate libc;

use libc::{c_void, c_int, c_char, pid_t, ssize_t};

#[allow(non_camel_case_types)]
type cap_t = *mut c_void;

#[allow(non_camel_case_types)]
type cap_value_t = isize;

#[allow(non_camel_case_types)]
#[repr(C)]
enum cap_flag_t {
    CAP_EFFECTIVE=0,
    CAP_PERMITTED=1,
    CAP_INHERITABLE=2
}

#[allow(non_camel_case_types)]
#[repr(C)]
enum cap_flag_value_t {
    CAP_CLEAR=0,
    CAP_SET=1
}

#[link(name="cap")]
extern "C" {

    /* libcap/cap_alloc.c */
    fn cap_init() -> cap_t;
	fn cap_free(ptr: *mut c_void) -> c_int;
	fn cap_dup(cap: cap_t) -> cap_t;

    /* libcap/cap_flag.c */
    fn cap_get_flag(c: cap_t, vt: cap_value_t,
                    ft: cap_flag_t,
                    val: *mut cap_flag_value_t) -> c_int;

    fn cap_set_flag(c: cap_t, f: cap_flag_t,
                    ncap: c_int,
                    caps: *const cap_value_t,
                    val: cap_flag_value_t) -> c_int;

    fn cap_clear(c: cap_t) -> c_int;
    fn cap_clear_flag(c: cap_t, flag: cap_flag_t) -> c_int;

    /* libcap/cap_file.c */
    fn cap_get_fd(fd: c_int) -> cap_t;
    fn cap_get_file(filename: *const c_char) -> cap_t;
    fn cap_set_fd(fd: c_int, cap: cap_t) -> c_int;
    fn cap_set_file(filename: *const c_char, cap: cap_t) -> c_int;

    /* libcap/cap_proc.c */
    fn cap_get_proc() -> cap_t;
    fn cap_get_pid(pid: pid_t) -> cap_t;
    fn cap_set_proc(cap: cap_t) -> c_int;
    fn cap_get_bound(vt: cap_value_t) -> c_int;
    fn cap_drop_bound(vt: cap_value_t) -> c_int;

    /* libcap/cap_extint.c */
    fn cap_size(cap: cap_t) -> ssize_t;
    fn cap_copy_ext(ptr: *mut c_void, cap: cap_t, size: ssize_t) -> ssize_t;
    fn cap_copy_int(ptr: *const c_void) -> cap_t;
    fn cap_compare(a: cap_t, b: cap_t) -> c_int;

}

// Capability descriptions taken from:
//  https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h

/// In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this
/// overrides the restriction of changing file ownership and group
/// ownership.
pub const CAP_CHOWN: isize = 0;

/// Override all DAC access, including ACL execute access if
/// [_POSIX_ACL] is defined. Excluding DAC access covered by
/// CAP_LINUX_IMMUTABLE.
pub const CAP_DAC_OVERRIDE: isize = 1;

/// Overrides all DAC restrictions regarding read and search on files
/// and directories, including ACL restrictions if [_POSIX_ACL] is
/// defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE.
pub const CAP_DAC_READ_SEARCH: isize = 2;

/// Overrides all restrictions about allowed operations on files, where
/// file owner ID must be equal to the user ID, except where CAP_FSETID
/// is applicable. It doesn't override MAC and DAC restrictions.
pub const CAP_FOWNER: isize = 3;

/// Overrides the following restrictions that the effective user ID
/// shall match the file owner ID when setting the S_ISUID and S_ISGID
/// bits on that file; that the effective group ID (or one of the
/// supplementary group IDs) shall match the file owner ID when setting
/// the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are
/// cleared on successful return from chown(2) (not implemented).
pub const CAP_FSETID: isize = 4;

/// Overrides the restriction that the real or effective user ID of a
/// process sending a signal must match the real or effective user ID
/// of the process receiving the signal.
pub const CAP_KILL: isize = 5;

/// - Allows setgid(2) manipulation
/// - Allows setgroups(2) manipulation
/// - Allows forged gids on socket credentials passing.
pub const CAP_SETGID: isize = 6;

/// - Allows set*uid(2) manipulation (including fsuid).
/// - Allows forged pids on socket credentials passing.
pub const CAP_SETUID: isize = 7;

/// - Without VFS support for capabilities:
///   * Transfer any capability in your permitted set to any pid,
///     remove any capability in your permitted set from any pid.
/// - With VFS support for capabilities (neither of above, but)
///   * Add any capability from current's capability bounding set
///     to the current process' inheritable set.
///   * Allow taking bits out of capability bounding set
///   * Allow modification of the securebits for a process
pub const CAP_SETPCAP: isize = 8;

/// Allow modification of S_IMMUTABLE and S_APPEND file attributes
pub const CAP_LINUX_IMMUTABLE: isize = 9;

/// - Allows binding to TCP/UDP sockets below 1024,
/// - Allows binding to ATM VCIs below 32
pub const CAP_NET_BIND_SERVICE: isize = 10;

/// Allows broadcasting, listen to multicast
pub const CAP_NET_BROADCAST: isize = 11;

/// - Allow interface configuration
/// - Allow administration of IP firewall, masquerading and accounting
/// - Allow setting debug option on sockets
/// - Allow modification of routing tables
/// - Allow setting arbitrary process / process group ownership on sockets
/// - Allow binding to any address for transparent proxying (also via NET_RAW)
/// - Allow setting TOS (type of service)
/// - Allow setting promiscuous mode
/// - Allow clearing driver statistics
/// - Allow multicasting
/// - Allow read/write of device-specific registers
/// - Allow activation of ATM control sockets
pub const CAP_NET_ADMIN: isize = 12;

/// - Allow use of RAW sockets
/// - Allow use of PACKET sockets
/// - Allow binding to any address for transparent proxying (also via NET_ADMIN)
pub const CAP_NET_RAW: isize = 13;

/// - Allow locking of shared memory segments
/// - Allow mlock and mlockall (which doesn't really have anything to do with IPC)
pub const CAP_IPC_LOCK: isize = 14;

/// Override IPC ownership checks
pub const CAP_IPC_OWNER: isize = 15;

/// Insert and remove kernel modules - modify kernel without limit
pub const CAP_SYS_MODULE: isize = 16;

/// - Allow ioperm/iopl access
/// - Allow sending USB messages to any device via /proc/bus/usb
pub const CAP_SYS_RAWIO: isize = 17;

/// Allow the use of chroot
pub const CAP_SYS_CHROOT: isize = 18;

/// Allow ptrace() of any process
pub const CAP_SYS_PTRACE: isize = 19;

/// Allow configuration of process accounting
pub const CAP_SYS_PACCT: isize = 20;

/// - Allow configuration of the secure attention key
/// - Allow administration of the random device
/// - Allow examination and configuration of disk quotas
/// - Allow setting the domainname
/// - Allow setting the hostname
/// - Allow calling bdflush()
/// - Allow mount() and umount(), setting up new smb connection
/// - Allow some autofs root ioctls
/// - Allow nfsservctl
/// - Allow VM86_REQUEST_IRQ
/// - Allow to read/write pci config on alpha
/// - Allow irix_prctl on mips (setstacksize)
/// - Allow flushing all cache on m68k (sys_cacheflush)
/// - Allow removing semaphores
/// - Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores
///   and shared memory
/// - Allow locking/unlocking of shared memory segment
/// - Allow turning swap on/off
/// - Allow forged pids on socket credentials passing
/// - Allow setting readahead and flushing buffers on block devices
/// - Allow setting geometry in floppy driver
/// - Allow turning DMA on/off in xd driver
/// - Allow administration of md devices (mostly the above, but some
///   extra ioctls)
/// - Allow tuning the ide driver
/// - Allow access to the nvram device
/// - Allow administration of apm_bios, serial and bttv (TV) device
/// - Allow manufacturer commands in isdn CAPI support driver
/// - Allow reading non-standardized portions of pci configuration space
/// - Allow DDI debug ioctl on sbpcd driver
/// - Allow setting up serial ports
/// - Allow sending raw qic-117 commands
/// - Allow enabling/disabling tagged queuing on SCSI controllers and sending
///   arbitrary SCSI commands
/// - Allow setting encryption key on loopback filesystem
/// - Allow setting zone reclaim policy
pub const CAP_SYS_ADMIN: isize = 21;

/// Allow use of reboot()
pub const CAP_SYS_BOOT: isize = 22;

/// - Allow raising priority and setting priority on other (different
///   UID) processes
/// - Allow use of FIFO and round-robin (realtime) scheduling on own
///   processes and setting the scheduling algorithm used by another
///   process.
/// - Allow setting cpu affinity on other processes
pub const CAP_SYS_NICE: isize = 23;

/// - Override resource limits. Set resource limits.
/// - Override quota limits.
/// - Override reserved space on ext2 filesystem
/// - Modify data journaling mode on ext3 filesystem (uses journaling
///   resources)
/// - **NOTE**: *ext2 honors fsuid when checking for resource overrides, so
///   you can override using fsuid too.*
/// - Override size restrictions on IPC message queues
/// - Allow more than 64hz interrupts from the real-time clock
/// - Override max number of consoles on console allocation
/// - Override max number of keymaps
pub const CAP_SYS_RESOURCE: isize = 24;

/// - Allow manipulation of system clock
/// - Allow irix_stime on mips
/// - Allow setting the real-time clock
pub const CAP_SYS_TIME: isize = 25;

/// - Allow configuration of tty devices
/// - Allow vhangup() of tty
pub const CAP_SYS_TTY_CONFIG: isize = 26;

/// Allow the privileged aspects of mknod()
pub const CAP_MKNOD: isize = 27;

/// Allow taking of leases on files
pub const CAP_LEASE: isize = 28;

/// Allow writing the audit log via unicast netlink socket
pub const CAP_AUDIT_WRITE: isize = 29;

/// Allow configurationof audit via unicast netlink socket
pub const CAP_AUDIT_CONTROL: isize = 30;

/// Set file capabilities
pub const CAP_SETFCAP: isize = 31;

/// Override MAC access.
/// The base kernel enforces no MAC policy.
/// An LSM may enforce a MAC policy, and if it does and it chooses
/// to implement capability based overrides of that policy, this is
/// the capability it should use to do so.
pub const CAP_MAC_OVERRIDE: isize = 32;

/// Allow MAC configuration or state changes.
/// The base kernel requires no MAC configuration.
/// An LSM may enforce a MAC policy, and if it does and it chooses
/// to implement capability based checks on modifications to that
/// policy or the data required to maintain it, this is the
/// capability it should use to do so.
pub const CAP_MAC_ADMIN: isize = 33;

/// Allow configuring the kernel's syslog (printk behaviour)
pub const CAP_SYSLOG: isize = 34;

/// Allow triggering something that will wake the system
pub const CAP_WAKE_ALARM: isize = 35;

/// Allow preventing system suspends
pub const CAP_BLOCK_SUSPEND: isize = 36;

/// Allow reading the audit log via multicast netlink socket
pub const CAP_AUDIT_READ: isize = 37;

const CAP_LAST_CAP: isize = CAP_AUDIT_READ;
pub fn cap_valid(x: isize) -> bool { x >= 0 && x <= CAP_LAST_CAP }

<|endoftext|>


<commit_before>
pub extern crate crypto;

use crypto::digest::Digest;

pub trait Hashable {
    fn to_bytes(&self) -> &[u8];
}

impl Hashable for String {
    fn to_bytes(&self) -> &[u8] {
        return self.as_bytes();
    }
}

impl Hashable for str {
    fn to_bytes(&self) -> &[u8] {
        return self.as_bytes();
    }
}

#[derive(Clone)]
enum Tree<T> where T: Hashable + Clone {
    Leaf {
        hash: Vec<u8>,
        value: T
    },

    Node {
        hash: Vec<u8>,
        left: Box<Tree<T>>,
        right: Box<Tree<T>>
    }
}

impl <T> Tree<T> where T: Hashable + Clone {
    fn get_hash<'a>(&'a self) -> &'a Vec<u8> {
        match *self {
            Tree::Leaf { ref hash, value: _ }          => hash,
            Tree::Node { ref hash, left: _, right: _ } => hash
        }
    }
}

pub struct MerkleTree<D, T> where D: Digest + Clone, T: Hashable + Clone {
    digest: D,
    tree: Tree<T>
}

impl <T> Tree<T> where T: Hashable + Clone {

}

fn make_hash<D, T>(mut digest: D, bytes: &[u8]) -> Vec<u8> where D: Digest {
    let mut hash = Vec::with_capacity(digest.output_bytes());
    digest.reset();
    digest.input(bytes);
    digest.result(hash.as_mut_slice());
    digest.reset();
    return hash;
}

fn combine_hashes<D>(mut digest: D, left: &[u8], right: &[u8]) -> Vec<u8> where D: Digest {
    let mut hash = Vec::with_capacity(digest.output_bytes());
    digest.reset();
    digest.input(left);
    digest.input(right);
    digest.result(hash.as_mut_slice());
    digest.reset();
    return hash;
}

fn make_leaf<D, T>(digest: D, value: T) -> Tree<T> where D: Digest, T: Hashable + Clone {
    return Tree::Leaf {
        hash: make_hash::<D, T>(digest, value.to_bytes()),
        value: value
    };
}

impl <D, T> MerkleTree<D, T> where D: Digest + Clone, T: Hashable + Clone {

    // TODO: Don't clone all the things
    pub fn from_vec(digest: D, values: Vec<T>) -> MerkleTree<D, T> {
        if values.is_empty() {
            panic!("Cannot build a Merkle tree from an empty vector.");
        }

        let mut cur: Vec<_> =
            values.iter()
                  .map(|v| make_leaf::<D, T>(digest.clone(), v.clone()))
                  .collect();

        while cur.len() > 1 {
            cur = cur.chunks(2).map(|chunk|
                if chunk.len() == 1 {
                    chunk[0].clone()
                } else {
                    let left:  Tree<T> = chunk[0].clone();
                    let right: Tree<T> = chunk[1].clone();

                    let combined_hash = combine_hashes::<D>(
                        digest.clone(),
                        left.get_hash().as_slice(),
                        right.get_hash().as_slice()
                    );

                    Tree::Node {
                       hash: combined_hash,
                       left: Box::new(left),
                       right: Box::new(right)
                    }
                }
            ).collect();
        }

        return MerkleTree {
            digest: digest.clone(),
            tree: cur[0].clone()
        };

    }

}

#[cfg(test)]
use crypto::sha3::Sha3;

#[test]
fn test_stuff() {
}

#[cfg(test)]
pub mod tests;
<commit_msg>Rewrite MerkleTree::from_vec without iterators, to avoid having to copy the whole world.<commit_after>
#![allow(dead_code)]

pub extern crate crypto;

use crypto::digest::Digest;

pub trait Hashable {
    fn to_bytes(&self) -> &[u8];
}

impl Hashable for String {
    fn to_bytes(&self) -> &[u8] {
        return self.as_bytes();
    }
}

fn make_hash<D, T>(digest: &mut D, bytes: &[u8]) -> Vec<u8> where D: Digest {
    let mut hash = vec![0; digest.output_bytes()];

    digest.reset();
    digest.input(bytes);
    digest.result(&mut hash);
    digest.reset();

    hash
}

fn combine_hashes<D>(digest: &mut D, left: &[u8], right: &[u8]) -> Vec<u8> where D: Digest {
    let mut hash = vec![0; digest.output_bytes()];

    digest.reset();
    digest.input(left);
    digest.input(right);
    digest.result(&mut hash);
    digest.reset();

    hash
}

enum Tree<T> {
    Leaf {
        hash: Vec<u8>,
        value: T
    },

    Node {
        hash: Vec<u8>,
        left: Box<Tree<T>>,
        right: Box<Tree<T>>
    }
}

impl <T> Tree<T> where T: Hashable {

    fn new(hash: Vec<u8>, value: T) -> Self {
        Tree::Leaf {
            hash: hash,
            value: value
        }
    }

    fn get_hash(&self) -> &Vec<u8> {
        match *self {
            Tree::Leaf { ref hash, value: _ }          => hash,
            Tree::Node { ref hash, left: _, right: _ } => hash
        }
    }
}

fn make_leaf<D, T>(digest: &mut D, value: T) -> Tree<T> where D: Digest, T: Hashable {
    let hash = make_hash::<D, T>(digest, value.to_bytes());
    Tree::new(hash, value)
}

pub struct MerkleTree<D, T> where D: Digest, T: Hashable {
    digest: D,
    tree: Tree<T>
}

impl <D, T> MerkleTree<D, T> where D: Digest, T: Hashable {

    pub fn from_vec(mut digest: D, values: Vec<T>) -> Self {
        if values.is_empty() {
            panic!("Cannot build a Merkle tree from an empty vector.");
        }

        let len = values.len();
        let mut cur = Vec::with_capacity(len);

        for v in values {
            let leaf = make_leaf(&mut digest, v);
            cur.push(leaf);
        }

        while cur.len() > 1 {
            let mut next = Vec::with_capacity(len);

            while cur.len() > 0 {
                if cur.len() == 1 {
                    next.push(cur.remove(0));
                }
                else {
                    let left  = cur.remove(0);
                    let right = cur.remove(0);

                    let combined_hash = combine_hashes::<D>(
                        &mut digest,
                        left.get_hash().as_slice(),
                        right.get_hash().as_slice()
                    );

                    let node = Tree::Node {
                       hash: combined_hash,
                       left: Box::new(left),
                       right: Box::new(right)
                    };

                    next.push(node);
                }
            }

            cur = next;
        }

        let tree = cur.remove(0);

        MerkleTree {
            digest: digest,
            tree: tree
        }
    }

}

#[cfg(test)]
use crypto::sha3::Sha3;

#[test]
fn test_stuff() {
}

#[cfg(test)]
pub mod tests;
<|endoftext|>


<commit_before>#![feature(read_exact)]

mod ntr_sender;
use ntr_sender::NtrSender;

extern crate byteorder;
extern crate time;
extern crate regex;

use byteorder::{ByteOrder, LittleEndian};
use time::{Duration, PreciseTime};
use regex::Regex;

use std::mem;
use std::io;
use std::io::prelude::*;
use std::net::TcpStream;
use std::thread;
use std::sync::{Arc, Mutex};
use std::sync::mpsc;
use std::sync::mpsc::Receiver;

pub struct Ntr {
    ntr_sender: Arc<Mutex<NtrSender>>,
    mem_read_rx: Receiver<Vec<u8>>,
    get_pid_rx: Receiver<String>,
}
impl Ntr {
    pub fn connect(addr: &str) -> io::Result<Self> {
        let mut tcp_stream = try!(TcpStream::connect(&(addr.to_owned() + ":8000") as &str));
        let (mem_read_tx, mem_read_rx) = mpsc::channel();
        let (get_pid_tx, get_pid_rx) = mpsc::channel();

        let ntr_sender = Arc::new(Mutex::new(NtrSender::new(tcp_stream.try_clone().unwrap())));

        // spawn heartbeat thread
        {
            let ntr_sender = ntr_sender.clone();
            thread::spawn(move || {
                let one_second = Duration::seconds(1);
                let mut heartbeat_sent_time = PreciseTime::now();
                loop {
                    let mut ntr_sender = ntr_sender.lock().unwrap();
                    if heartbeat_sent_time.to(PreciseTime::now()) >= one_second
                     && ntr_sender.is_heartbeat_sendable() {
                        ntr_sender.send_heartbeat_packet().unwrap();
                        heartbeat_sent_time = PreciseTime::now();
                        ntr_sender.set_is_heartbeat_sendable(false);
                    }
                    mem::drop(ntr_sender);
                    thread::sleep_ms(500);
                }
            });
        }

        // spawn receiver thread
        {
            let ntr_sender = ntr_sender.clone();
            thread::spawn(move || {
                let mut buf = [0u8; 84];
                loop {
                    tcp_stream.read_exact(&mut buf).unwrap();
                    let cmd = LittleEndian::read_u32(&buf[12..16]);
                    let data_len = LittleEndian::read_u32(&buf[80..84]) as usize;

                    if data_len != 0 {
                        let mut data_buf = vec![0u8; data_len];
                        tcp_stream.read_exact(&mut data_buf[0..data_len]).unwrap();
                        if cmd == 0 {
                            ntr_sender.lock().unwrap().set_is_heartbeat_sendable(true);

                            let msg = String::from_utf8(data_buf).unwrap();
                            if let Some(_) = msg.find("end of process list.") {
                                get_pid_tx.send(msg).unwrap();
                            }
                        } else if cmd == 9 {
                            mem_read_tx.send(data_buf).unwrap();
                        }
                    }
                }
            });
        }

        Ok(Ntr {
            ntr_sender: ntr_sender,
            mem_read_rx: mem_read_rx,
            get_pid_rx: get_pid_rx,
        })
    }

    pub fn get_pid(&mut self, tid: u64) -> Option<u32> {
        self.ntr_sender.lock().unwrap().send_list_process_packet().unwrap();
        let msg = self.get_pid_rx.recv().unwrap();
        let cap = Regex::new(&(r"pid: 0x(\d{8}), pname:[^,]*, tid: ".to_owned() + &format!("{:016x}", tid)))
            .unwrap()
            .captures(&msg);
        match cap {
            Some(x) => Some(u32::from_str_radix(x.at(1).unwrap(), 16).unwrap()),
            None => None,
        }
    }

    pub fn mem_read(&mut self, addr: u32, size: u32, pid: u32) -> Result<Vec<u8>, ()> {
        try!(self.ntr_sender.lock().unwrap().send_mem_read_packet(addr, size, pid).map_err(|_x| ()));
        self.mem_read_rx.recv().map_err(|_x| ())
    }

    pub fn mem_write(&mut self, addr: u32, data: &Vec<u8>, pid: u32) -> io::Result<usize> {
        self.ntr_sender.lock().unwrap().send_mem_write_packet(addr, pid, data)
    }
}<commit_msg>Improve IO error handling.<commit_after>#![feature(read_exact)]

mod ntr_sender;
use ntr_sender::NtrSender;

extern crate byteorder;
extern crate time;
extern crate regex;

use byteorder::{ByteOrder, LittleEndian};
use time::{Duration, PreciseTime};
use regex::Regex;

use std::error::Error;
use std::mem;
use std::io;
use std::io::prelude::*;
use std::net::TcpStream;
use std::thread;
use std::sync::{Arc, Mutex};
use std::sync::mpsc;
use std::sync::mpsc::Receiver;

pub struct Ntr {
    ntr_sender: Arc<Mutex<NtrSender>>,
    mem_read_rx: Receiver<Vec<u8>>,
    get_pid_rx: Receiver<String>,
}
impl Ntr {
    pub fn connect(addr: &str) -> io::Result<Self> {
        let mut tcp_stream = try!(TcpStream::connect(&(addr.to_owned() + ":8000") as &str));
        let (mem_read_tx, mem_read_rx) = mpsc::channel();
        let (get_pid_tx, get_pid_rx) = mpsc::channel();

        let ntr_sender = Arc::new(Mutex::new(NtrSender::new(try!(tcp_stream.try_clone()))));

        // spawn heartbeat thread
        {
            let ntr_sender = ntr_sender.clone();
            thread::spawn(move || {
                let one_second = Duration::seconds(1);
                let mut heartbeat_sent_time = PreciseTime::now();
                loop {
                    let mut ntr_sender = ntr_sender.lock().unwrap();
                    if heartbeat_sent_time.to(PreciseTime::now()) >= one_second
                     && ntr_sender.is_heartbeat_sendable() {
                        ntr_sender.send_heartbeat_packet().unwrap();
                        heartbeat_sent_time = PreciseTime::now();
                        ntr_sender.set_is_heartbeat_sendable(false);
                    }
                    mem::drop(ntr_sender);
                    thread::sleep_ms(500);
                }
            });
        }

        // spawn receiver thread
        {
            let ntr_sender = ntr_sender.clone();
            thread::spawn(move || {
                let mut buf = [0u8; 84];
                loop {
                    tcp_stream.read_exact(&mut buf).unwrap();
                    let cmd = LittleEndian::read_u32(&buf[12..16]);
                    let data_len = LittleEndian::read_u32(&buf[80..84]) as usize;

                    if data_len != 0 {
                        let mut data_buf = vec![0u8; data_len];
                        tcp_stream.read_exact(&mut data_buf[0..data_len]).unwrap();
                        if cmd == 0 {
                            ntr_sender.lock().unwrap().set_is_heartbeat_sendable(true);

                            let msg = String::from_utf8(data_buf).unwrap();
                            if let Some(_) = msg.find("end of process list.") {
                                get_pid_tx.send(msg).unwrap();
                            }
                        } else if cmd == 9 {
                            mem_read_tx.send(data_buf).unwrap();
                        }
                    }
                }
            });
        }

        Ok(Ntr {
            ntr_sender: ntr_sender,
            mem_read_rx: mem_read_rx,
            get_pid_rx: get_pid_rx,
        })
    }

    pub fn get_pid(&mut self, tid: u64) -> Result<Option<u32>, Box<Error>> {
        try!(self.ntr_sender.lock().unwrap().send_list_process_packet());
        let msg = self.get_pid_rx.recv().unwrap();
        let cap = Regex::new(
            &(r"pid: 0x(\d{8}), pname:[^,]*, tid: ".to_owned() + &format!("{:016x}", tid)))
                .unwrap()
                .captures(&msg);
        Ok(match cap {
            Some(x) => Some(u32::from_str_radix(x.at(1).unwrap(), 16).unwrap()),
            None => None,
        })
    }

    pub fn mem_read(&mut self, addr: u32, size: u32, pid: u32) -> Result<Vec<u8>, Box<Error>> {
        try!(self.ntr_sender.lock().unwrap().send_mem_read_packet(addr, size, pid));
        Ok(self.mem_read_rx.recv().unwrap())
    }

    pub fn mem_write(&mut self, addr: u32, data: &Vec<u8>, pid: u32) -> io::Result<usize> {
        self.ntr_sender.lock().unwrap().send_mem_write_packet(addr, pid, data)
    }
}<|endoftext|>


<commit_before>//! The enum `Either`.

use std::error::Error;
use std::fmt;
use std::io::{self, Write, Read, BufRead};
use std::convert::{AsRef, AsMut};
use std::ops::Deref;
use std::ops::DerefMut;

pub use Either::{Left, Right};

/// `Either` represents an alternative holding one value out of
/// either of the two possible values.
///
/// `Either` is a general purpose sum type of two parts. For representing
/// success or error, use the regular `Result<T, E>` instead.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Either<L, R> {
    /// A value of type `L`.
    Left(L),
    /// A value of type `R`.
    Right(R),
}

macro_rules! either {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref $inner) => $result,
            Either::Right(ref $inner) => $result,
        }
    )
}

macro_rules! either_mut {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref mut $inner) => $result,
            Either::Right(ref mut $inner) => $result,
        }
    )
}

/// Macro for unwrapping the left side of an `Either`, which fails early
/// with the opposite side. Can only be used in functions that return
/// `Either` because of the early return of `Right` that it provides.
///
/// See also `try_right!` for its dual, which applies the same just to the
/// right side.
///
/// # Example
///
/// ```
/// #[macro_use] extern crate either;
/// use either::{Either, Left, Right};
///
/// fn twice(wrapper: Either<u32, &str>) -> Either<u32, &str> {
///     let value = try_left!(wrapper);
///     Left(value * 2)
/// }
///
/// fn main() {
///     assert_eq!(twice(Left(2)), Left(4));
///     assert_eq!(twice(Right("ups")), Right("ups"));
/// }
/// ```
#[macro_export]
macro_rules! try_left {
    ($expr:expr) => (
        match $expr {
            $crate::Left(val) => val,
            $crate::Right(err) => return $crate::Right(::std::convert::From::from(err))
        }
    )
}

/// Dual to `try_left!`, see its documentation for more information.
#[macro_export]
macro_rules! try_right {
    ($expr:expr) => (
        match $expr {
            $crate::Left(err) => return $crate::Left(::std::convert::From::from(err)),
            $crate::Right(val) => val
        }
    )
}

impl<L, R> Either<L, R> {
    pub fn is_left(&self) -> bool {
        match *self {
            Left(_) => true,
            Right(_) => false,
        }
    }

    pub fn is_right(&self) -> bool {
        !self.is_left()
    }

    pub fn left(self) -> Option<L> {
        match self {
            Left(l) => Some(l),
            Right(_) => None,
        }
    }

    pub fn right(self) -> Option<R> {
        match self {
            Left(_) => None,
            Right(r) => Some(r),
        }
    }

    pub fn as_ref(&self) -> Either<&L, &R> {
        match *self {
            Left(ref inner) => Left(inner),
            Right(ref inner) => Right(inner),
        }
    }

    pub fn as_mut(&mut self) -> Either<&mut L, &mut R> {
        match *self {
            Left(ref mut inner) => Left(inner),
            Right(ref mut inner) => Right(inner),
        }
    }

    pub fn flip(self) -> Either<R, L> {
        match self {
            Left(l) => Right(l),
            Right(r) => Left(r),
        }
    }
}

/// Convert from `Result` to `Either` with `Ok => Right` and `Err => Left`.
impl<L, R> From<Result<R, L>> for Either<L, R> {
    fn from(r: Result<R, L>) -> Self {
        match r {
            Err(e) => Left(e),
            Ok(o) => Right(o),
        }
    }
}

/// Convert from `Either` to `Result` with `Right => Ok` and `Left => Err`.
impl<L, R> Into<Result<R, L>> for Either<L, R> {
    fn into(self) -> Result<R, L> {
        match self {
            Left(l) => Err(l),
            Right(r) => Ok(r),
        }
    }
}

/// `Either<L, R>` is an iterator if both `L` and `R` are iterators.
impl<L, R> Iterator for Either<L, R>
    where L: Iterator, R: Iterator<Item=L::Item>
{
    type Item = L::Item;

    fn next(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        either!(*self, inner => inner.size_hint())
    }
}

impl<L, R> DoubleEndedIterator for Either<L, R>
    where L: DoubleEndedIterator, R: DoubleEndedIterator<Item=L::Item>
{
    fn next_back(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next_back())
    }
}

impl<L, R> ExactSizeIterator for Either<L, R>
    where L: ExactSizeIterator, R: ExactSizeIterator<Item=L::Item>
{
}

/// `Either<L, R>` implements `Read` if both `L` and `R` do.
impl<L, R> Read for Either<L, R>
    where L: Read, R: Read
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read(buf))
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read_to_end(buf))
    }
}

impl<L, R> BufRead for Either<L, R>
    where L: BufRead, R: BufRead
{
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        either_mut!(*self, inner => inner.fill_buf())
    }

    fn consume(&mut self, amt: usize) {
        either_mut!(*self, inner => inner.consume(amt))
    }
}

/// `Either<L, R>` implements `Write` if both `L` and `R` do.
impl<L, R> Write for Either<L, R>
    where L: Write, R: Write
{
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.write(buf))
    }

    fn flush(&mut self) -> io::Result<()> {
        either_mut!(*self, inner => inner.flush())
    }
}

impl<L, R, Target> AsRef<Target> for Either<L, R>
    where L: AsRef<Target>, R: AsRef<Target>
{
    fn as_ref(&self) -> &Target {
        either!(*self, inner => inner.as_ref())
    }
}

impl<L, R, Target> AsMut<Target> for Either<L, R>
    where L: AsMut<Target>, R: AsMut<Target>
{
    fn as_mut(&mut self) -> &mut Target {
        either_mut!(*self, inner => inner.as_mut())
    }
}

impl<L, R> Deref for Either<L, R>
    where L: Deref, R: Deref<Target=L::Target>
{
    type Target = L::Target;

    fn deref(&self) -> &Self::Target {
        either!(*self, inner => &*inner)
    }
}

impl<L, R> DerefMut for Either<L, R>
    where L: DerefMut, R: DerefMut<Target=L::Target>
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        either_mut!(*self, inner => &mut *inner)
    }
}

/// `Either` implements `Error` if *both* `L` and `R` implement it.
impl<L, R> Error for Either<L, R>
    where L: Error, R: Error
{
    fn description(&self) -> &str {
        either!(*self, inner => inner.description())
    }

    fn cause(&self) -> Option<&Error> {
        either!(*self, inner => inner.cause())
    }
}

impl<L, R> fmt::Display for Either<L, R>
    where L: fmt::Display, R: fmt::Display
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        either!(*self, inner => inner.fmt(f))
    }
}

#[test]
fn basic() {
    let mut e = Left(2);
    let r = Right(2);
    assert_eq!(e, Left(2));
    e = r;
    assert_eq!(e, Right(2));
    assert_eq!(e.left(), None);
    assert_eq!(e.right(), Some(2));
    assert_eq!(e.as_ref().right(), Some(&2));
    assert_eq!(e.as_mut().right(), Some(&mut 2));
}

#[test]
fn macros() {
    fn a() -> Either<u32, u32> {
        let x: u32 = try_left!(Right(1337u32));
        Left(x * 2)
    }
    assert_eq!(a(), Right(1337));

    fn b() -> Either<String, &'static str> {
        Right(try_right!(Left("foo bar")))
    }
    assert_eq!(b(), Left(String::from("foo bar")));
}

#[test]
fn deref() {
    fn is_str(_: &str) {}
    let value: Either<String, &str> = Left(String::from("test"));
    is_str(&*value);
}

#[test]
fn iter() {
    let x = 3;
    let mut iter = match x {
        1...3 => Left(0..10),
        _ => Right(17..),
    };

    assert_eq!(iter.next(), Some(0));
    assert_eq!(iter.count(), 9);
}

#[test]
fn read_write() {
    use std::io;

    let use_stdio = false;
    let mockdata = [0xff; 256];

    let mut reader = if use_stdio {
        Left(io::stdin())
    } else {
        Right(&mockdata[..])
    };

    let mut buf = [0u8; 16];
    assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
    assert_eq!(&buf, &mockdata[..buf.len()]);

    let mut mockbuf = [0u8; 256];
    let mut writer = if use_stdio {
        Left(io::stdout())
    } else {
        Right(&mut mockbuf[..])
    };

    let buf = [1u8; 16];
    assert_eq!(writer.write(&buf).unwrap(), buf.len());
}

#[test]
fn error() {
    let invalid_utf8 = b"\xff";
    let res = || -> Result<_, Either<_, _>> {
        try!(::std::str::from_utf8(invalid_utf8).map_err(Left));
        try!("x".parse::<i32>().map_err(Right));
        Ok(())
    }();
    assert!(res.is_err());
    res.unwrap_err().description(); // make sure this can be called
}
<commit_msg>Documentation for Either methods<commit_after>//! The enum `Either`.

use std::error::Error;
use std::fmt;
use std::io::{self, Write, Read, BufRead};
use std::convert::{AsRef, AsMut};
use std::ops::Deref;
use std::ops::DerefMut;

pub use Either::{Left, Right};

/// `Either` represents an alternative holding one value out of
/// either of the two possible values.
///
/// `Either` is a general purpose sum type of two parts. For representing
/// success or error, use the regular `Result<T, E>` instead.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Either<L, R> {
    /// A value of type `L`.
    Left(L),
    /// A value of type `R`.
    Right(R),
}

macro_rules! either {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref $inner) => $result,
            Either::Right(ref $inner) => $result,
        }
    )
}

macro_rules! either_mut {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref mut $inner) => $result,
            Either::Right(ref mut $inner) => $result,
        }
    )
}

/// Macro for unwrapping the left side of an `Either`, which fails early
/// with the opposite side. Can only be used in functions that return
/// `Either` because of the early return of `Right` that it provides.
///
/// See also `try_right!` for its dual, which applies the same just to the
/// right side.
///
/// # Example
///
/// ```
/// #[macro_use] extern crate either;
/// use either::{Either, Left, Right};
///
/// fn twice(wrapper: Either<u32, &str>) -> Either<u32, &str> {
///     let value = try_left!(wrapper);
///     Left(value * 2)
/// }
///
/// fn main() {
///     assert_eq!(twice(Left(2)), Left(4));
///     assert_eq!(twice(Right("ups")), Right("ups"));
/// }
/// ```
#[macro_export]
macro_rules! try_left {
    ($expr:expr) => (
        match $expr {
            $crate::Left(val) => val,
            $crate::Right(err) => return $crate::Right(::std::convert::From::from(err))
        }
    )
}

/// Dual to `try_left!`, see its documentation for more information.
#[macro_export]
macro_rules! try_right {
    ($expr:expr) => (
        match $expr {
            $crate::Left(err) => return $crate::Left(::std::convert::From::from(err)),
            $crate::Right(val) => val
        }
    )
}

impl<L, R> Either<L, R> {
    /// Returns true if the value is `Left(L)`.
    ///
    /// # Examples
    ///
    /// ```
    /// use either::Either;
    ///
    /// let left: Either<_, ()> = Either::Left(123);
    /// assert_eq!(left.is_left(), true);
    ///
    /// let right: Either<(), _> = Either::Right("the right value");
    /// assert_eq!(right.is_left(), false);
    /// ```
    pub fn is_left(&self) -> bool {
        match *self {
            Left(_) => true,
            Right(_) => false,
        }
    }

    /// Returns true if the value is `Right(R)`.
    ///
    /// # Examples
    ///
    /// ```
    /// use either::Either;
    ///
    /// let left: Either<_, ()> = Either::Left(123);
    /// assert_eq!(left.is_right(), false);
    ///
    /// let right: Either<(), _> = Either::Right("the right value");
    /// assert_eq!(right.is_right(), true);
    /// ```
    pub fn is_right(&self) -> bool {
        !self.is_left()
    }

    /// Converts the left side of `Either<L, R>` to an `Option<L>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use either::Either;
    ///
    /// let left: Either<_, ()> = Either::Left("some value");
    /// assert_eq!(left.left(),  Some("some value"));
    ///
    /// let right: Either<(), _> = Either::Right(321);
    /// assert_eq!(right.left(), None);
    /// ```
    pub fn left(self) -> Option<L> {
        match self {
            Left(l) => Some(l),
            Right(_) => None,
        }
    }

    /// Converts the right side of `Either<L, R>` to an `Option<R>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use either::Either;
    ///
    /// let left: Either<_, ()> = Either::Left("some value");
    /// assert_eq!(left.right(),  None);
    ///
    /// let right: Either<(), _> = Either::Right(321);
    /// assert_eq!(right.right(), Some(321));
    /// ```
    pub fn right(self) -> Option<R> {
        match self {
            Left(_) => None,
            Right(r) => Some(r),
        }
    }

    /// Converts `Either<L, R>` to `Either<&L, &R>`.
    ///
    /// ```
    /// use either::Either;
    ///
    /// let left: Either<_, ()> = Either::Left("some value");
    /// assert_eq!(left.as_ref(), Either::Left(&"some value"));
    ///
    /// let right: Either<(), _> = Either::Right("some value");
    /// assert_eq!(right.as_ref(), Either::Right(&"some value"));
    /// ```
    pub fn as_ref(&self) -> Either<&L, &R> {
        match *self {
            Left(ref inner) => Left(inner),
            Right(ref inner) => Right(inner),
        }
    }

    /// Converts `Either<L, R>` to `Either<&mut L, &mut R>`.
    ///
    /// ```
    /// use either::Either;
    ///
    /// fn mutate(r: &mut Either<u32, u32>) {
    ///     match r.as_mut() {
    ///         Either::Left(&mut ref mut l) => *l = 314,
    ///         Either::Right(&mut ref mut r) => *r = 1,
    ///     }
    /// }
    ///
    /// let mut left = Either::Left(123);
    /// mutate(&mut left);
    /// assert_eq!(left, Either::Left(314));
    ///
    /// let mut right = Either::Right(123);
    /// mutate(&mut right);
    /// assert_eq!(right, Either::Right(1));
    /// ```
    pub fn as_mut(&mut self) -> Either<&mut L, &mut R> {
        match *self {
            Left(ref mut inner) => Left(inner),
            Right(ref mut inner) => Right(inner),
        }
    }

    /// Converts `Either<L, R>` to `Either<R, L>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use either::Either;
    ///
    /// let left: Either<_, ()> = Either::Left(123);
    /// assert_eq!(left.flip(), Either::Right(123));
    ///
    /// let right: Either<(), _> = Either::Right("some value");
    /// assert_eq!(right.flip(), Either::Left("some value"));
    /// ```
    pub fn flip(self) -> Either<R, L> {
        match self {
            Left(l) => Right(l),
            Right(r) => Left(r),
        }
    }
}

/// Convert from `Result` to `Either` with `Ok => Right` and `Err => Left`.
impl<L, R> From<Result<R, L>> for Either<L, R> {
    fn from(r: Result<R, L>) -> Self {
        match r {
            Err(e) => Left(e),
            Ok(o) => Right(o),
        }
    }
}

/// Convert from `Either` to `Result` with `Right => Ok` and `Left => Err`.
impl<L, R> Into<Result<R, L>> for Either<L, R> {
    fn into(self) -> Result<R, L> {
        match self {
            Left(l) => Err(l),
            Right(r) => Ok(r),
        }
    }
}

/// `Either<L, R>` is an iterator if both `L` and `R` are iterators.
impl<L, R> Iterator for Either<L, R>
    where L: Iterator, R: Iterator<Item=L::Item>
{
    type Item = L::Item;

    fn next(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        either!(*self, inner => inner.size_hint())
    }
}

impl<L, R> DoubleEndedIterator for Either<L, R>
    where L: DoubleEndedIterator, R: DoubleEndedIterator<Item=L::Item>
{
    fn next_back(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next_back())
    }
}

impl<L, R> ExactSizeIterator for Either<L, R>
    where L: ExactSizeIterator, R: ExactSizeIterator<Item=L::Item>
{
}

/// `Either<L, R>` implements `Read` if both `L` and `R` do.
impl<L, R> Read for Either<L, R>
    where L: Read, R: Read
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read(buf))
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read_to_end(buf))
    }
}

impl<L, R> BufRead for Either<L, R>
    where L: BufRead, R: BufRead
{
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        either_mut!(*self, inner => inner.fill_buf())
    }

    fn consume(&mut self, amt: usize) {
        either_mut!(*self, inner => inner.consume(amt))
    }
}

/// `Either<L, R>` implements `Write` if both `L` and `R` do.
impl<L, R> Write for Either<L, R>
    where L: Write, R: Write
{
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.write(buf))
    }

    fn flush(&mut self) -> io::Result<()> {
        either_mut!(*self, inner => inner.flush())
    }
}

impl<L, R, Target> AsRef<Target> for Either<L, R>
    where L: AsRef<Target>, R: AsRef<Target>
{
    fn as_ref(&self) -> &Target {
        either!(*self, inner => inner.as_ref())
    }
}

impl<L, R, Target> AsMut<Target> for Either<L, R>
    where L: AsMut<Target>, R: AsMut<Target>
{
    fn as_mut(&mut self) -> &mut Target {
        either_mut!(*self, inner => inner.as_mut())
    }
}

impl<L, R> Deref for Either<L, R>
    where L: Deref, R: Deref<Target=L::Target>
{
    type Target = L::Target;

    fn deref(&self) -> &Self::Target {
        either!(*self, inner => &*inner)
    }
}

impl<L, R> DerefMut for Either<L, R>
    where L: DerefMut, R: DerefMut<Target=L::Target>
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        either_mut!(*self, inner => &mut *inner)
    }
}

/// `Either` implements `Error` if *both* `L` and `R` implement it.
impl<L, R> Error for Either<L, R>
    where L: Error, R: Error
{
    fn description(&self) -> &str {
        either!(*self, inner => inner.description())
    }

    fn cause(&self) -> Option<&Error> {
        either!(*self, inner => inner.cause())
    }
}

impl<L, R> fmt::Display for Either<L, R>
    where L: fmt::Display, R: fmt::Display
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        either!(*self, inner => inner.fmt(f))
    }
}

#[test]
fn basic() {
    let mut e = Left(2);
    let r = Right(2);
    assert_eq!(e, Left(2));
    e = r;
    assert_eq!(e, Right(2));
    assert_eq!(e.left(), None);
    assert_eq!(e.right(), Some(2));
    assert_eq!(e.as_ref().right(), Some(&2));
    assert_eq!(e.as_mut().right(), Some(&mut 2));
}

#[test]
fn macros() {
    fn a() -> Either<u32, u32> {
        let x: u32 = try_left!(Right(1337u32));
        Left(x * 2)
    }
    assert_eq!(a(), Right(1337));

    fn b() -> Either<String, &'static str> {
        Right(try_right!(Left("foo bar")))
    }
    assert_eq!(b(), Left(String::from("foo bar")));
}

#[test]
fn deref() {
    fn is_str(_: &str) {}
    let value: Either<String, &str> = Left(String::from("test"));
    is_str(&*value);
}

#[test]
fn iter() {
    let x = 3;
    let mut iter = match x {
        1...3 => Left(0..10),
        _ => Right(17..),
    };

    assert_eq!(iter.next(), Some(0));
    assert_eq!(iter.count(), 9);
}

#[test]
fn read_write() {
    use std::io;

    let use_stdio = false;
    let mockdata = [0xff; 256];

    let mut reader = if use_stdio {
        Left(io::stdin())
    } else {
        Right(&mockdata[..])
    };

    let mut buf = [0u8; 16];
    assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
    assert_eq!(&buf, &mockdata[..buf.len()]);

    let mut mockbuf = [0u8; 256];
    let mut writer = if use_stdio {
        Left(io::stdout())
    } else {
        Right(&mut mockbuf[..])
    };

    let buf = [1u8; 16];
    assert_eq!(writer.write(&buf).unwrap(), buf.len());
}

#[test]
fn error() {
    let invalid_utf8 = b"\xff";
    let res = || -> Result<_, Either<_, _>> {
        try!(::std::str::from_utf8(invalid_utf8).map_err(Left));
        try!("x".parse::<i32>().map_err(Right));
        Ok(())
    }();
    assert!(res.is_err());
    res.unwrap_err().description(); // make sure this can be called
}
<|endoftext|>