<commit_before>#[macro_use]
extern crate mopa;
extern crate pulse;
extern crate threadpool;
extern crate fnv;

use std::any::TypeId;
use std::cell::RefCell;
use std::collections::HashMap;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
use mopa::Any;
use pulse::{Pulse, Signal};
use threadpool::ThreadPool;

pub use storage::{Storage, StorageBase, VecStorage, HashMapStorage};

mod storage;

/// Index generation. When a new entity is placed at the old index,
/// it bumps the generation by 1. This allows to avoid using components
/// from the entities that were deleted.
/// G<=0 - the entity of generation G is dead
/// G >0 - the entity of generation G is alive
pub type Generation = i32;
/// Index type is arbitrary. It doesn't show up in any interfaces.
/// Keeping it 32bit allows for a single 64bit word per entity.
pub type Index = u32;
/// Entity type, as seen by the user.
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct Entity(Index, Generation);

impl Entity {
    #[cfg(test)]
    /// Create a new entity (externally from ECS)
    pub fn new(index: u32, gen: i32) -> Entity {
        Entity(index, gen)
    }

    /// Get the index of the entity.
    pub fn get_id(&self) -> usize { self.0 as usize }
    /// Get the generation of the entity.
    pub fn get_gen(&self) -> Generation { self.1 }
}

/// A custom entity iterator. Needed because the world doesn't really store
/// entities directly, but rather has just a vector of Index -> Generation.
pub struct EntityIter<'a> {
    guard: RwLockReadGuard<'a, Vec<Generation>>,
    index: usize,
}

impl<'a> Iterator for EntityIter<'a> {
    type Item = Entity;
    fn next(&mut self) -> Option<Entity> {
        loop {
            match self.guard.get(self.index) {
                Some(&gen) if gen > 0 => {
                    let ent = Entity(self.index as Index, gen);
                    self.index += 1;
                    return Some(ent)
                },
                Some(_) => self.index += 1, // continue
                None => return None,
            }
        }
    }
}

/// Abstract component type. Doesn't have to be Copy or even Clone.
pub trait Component: Any + Sized {
    type Storage: Storage<Self> + Any + Send + Sync;
}

trait StorageLock: Any + Send + Sync {
    fn del_slice(&self, &[Entity]);
}

mopafy!(StorageLock);

impl<S: StorageBase + Any + Send + Sync> StorageLock for RwLock<S> {
    fn del_slice(&self, entities: &[Entity]) {
        let mut guard = self.write().unwrap();
        for &e in entities.iter() {
            guard.del(e);
        }
    }
}

/// The world struct contains all the data, which is entities and their components.
/// The methods are supposed to be valid for any context they are available in.
pub struct World {
    generations: RwLock<Vec<Generation>>,
    components: HashMap<TypeId, Box<StorageLock>>,
}

impl World {
    /// Create a new empty world.
    pub fn new() -> World {
        World {
            generations: RwLock::new(Vec::new()),
            components: HashMap::new(),
        }
    }
    /// Register a new component type.
    pub fn register<T: Component>(&mut self) {
        let any = RwLock::new(T::Storage::new());
        self.components.insert(TypeId::of::<T>(), Box::new(any));
    }
    /// Unregister a component type.
    pub fn unregister<T: Component>(&mut self) -> Option<T::Storage> {
        self.components.remove(&TypeId::of::<T>()).map(|boxed|
            match boxed.downcast::<RwLock<T::Storage>>() {
                Ok(b) => (*b).into_inner().unwrap(),
                Err(_) => panic!("Unable to downcast the storage type"),
            }
        )
    }
    fn lock<T: Component>(&self) -> &RwLock<T::Storage> {
        let boxed = self.components.get(&TypeId::of::<T>()).unwrap();
        boxed.downcast_ref().unwrap()
    }
    /// Lock a component for reading.
    pub fn read<'a, T: Component>(&'a self) -> RwLockReadGuard<'a, T::Storage> {
        self.lock::<T>().read().unwrap()
    }
    /// Lock a component for writing.
    pub fn write<'a, T: Component>(&'a self) -> RwLockWriteGuard<'a, T::Storage> {
        self.lock::<T>().write().unwrap()
    }
    /// Return the entity iterator.
    pub fn entities<'a>(&'a self) -> EntityIter<'a> {
        EntityIter {
            guard: self.generations.read().unwrap(),
            index: 0,
        }
    }
    fn find_next(&self, base: usize) -> Entity {
        let gens = self.generations.read().unwrap();
        match gens.iter().enumerate().skip(base).find(|&(_, g)| *g <= 0) {
            Some((id, gen)) => Entity(id as Index, 1 - gen),
            None => Entity(gens.len() as Index, 1),
        }
    }
}

/// World argument for a system closure.
pub struct WorldArg(Arc<World>, RefCell<Option<Pulse>>);

impl WorldArg {
    /// Borrows the world, allowing the system lock some components and get the entity
    /// iterator. Has to be called only once. Fires a pulse at the end.
    pub fn fetch<'a, U, F>(&'a self, f: F) -> U
        where F: FnOnce(&'a World) -> U
    {
        let pulse = self.1.borrow_mut().take().expect("fetch may only be called once.");
        let u = f(&self.0);
        pulse.pulse();
        u
    }
}

/// Helper builder for entities.
pub struct EntityBuilder<'a>(Entity, &'a World);

impl<'a> EntityBuilder<'a> {
    /// Add a component value to the new entity.
    pub fn with<T: Component>(self, value: T) -> EntityBuilder<'a> {
        self.1.write::<T>().insert(self.0, value);
        self
    }
    /// Finish entity construction.
    pub fn build(self) -> Entity {
        self.0
    }
}

struct Appendix {
    next: Entity,
    queue: Vec<Entity>,
}

pub struct Scheduler {
    world: Arc<World>,
    threads: ThreadPool,
    appendix: RwLock<Appendix>,
}

impl Scheduler {
    pub fn new(world: World, num_threads: usize) -> Scheduler {
        let next = Appendix {
            next: world.find_next(0),
            queue: Vec::new(),
        };
        Scheduler {
            world: Arc::new(world),
            threads: ThreadPool::new(num_threads),
            appendix: RwLock::new(next),
        }
    }
    pub fn get_world(&self) -> &World {
        //println!("{:?}", &*self.world.generations.read().unwrap());
        &self.world
    }
    pub fn run<F>(&mut self, functor: F) where
        F: 'static + Send + FnOnce(WorldArg)
    {
        let (signal, pulse) = Signal::new();
        let world = self.world.clone();
        self.threads.execute(|| {
            let warg = WorldArg(world, RefCell::new(Some(pulse)));
            functor(warg);
        });
        signal.wait().unwrap();
    }
    pub fn add_entity<'a>(&'a mut self) -> EntityBuilder<'a> {
        let mut appendix = self.appendix.write().unwrap();
        let ent = appendix.next;
        assert!(ent.get_gen() > 0);
        if ent.get_gen() == 1 {
            let mut gens = self.world.generations.write().unwrap();
            assert!(gens.len() == ent.get_id());
            gens.push(ent.get_gen());
        }
        appendix.next = self.world.find_next(ent.get_id() + 1);
        EntityBuilder(ent, &self.world)
    }
    pub fn del_entity(&mut self, entity: Entity) {
        for boxed in self.world.components.values() {
            boxed.del_slice(&[entity]);
        }
        let mut gens = self.world.generations.write().unwrap();
        let mut gen = &mut gens[entity.get_id() as usize];
        assert!(*gen > 0);
        let mut appendix = self.appendix.write().unwrap();
        if entity.get_id() < appendix.next.get_id() {
            appendix.next = Entity(entity.0, *gen+1);
        }
        *gen *= -1;
    }
    pub fn wait(&self) {
        while self.threads.active_count() > 0 {} //TODO
    }
}

macro_rules! impl_run {
    ($name:ident [$( $write:ident ),*] [$( $read:ident ),*]) => (impl Scheduler {
        #[allow(non_snake_case, unused_mut)]
        pub fn $name<
            $($write:Component,)* $($read:Component,)*
            F: 'static + Send + FnMut( $(&mut $write,)* $(&$read,)* )
        >(&mut self, functor: F) {
            self.run(|warg| {
                let mut fun = functor;
                let ($(mut $write,)* $($read,)* entities) = warg.fetch(|w|
                    ($(w.write::<$write>(),)*
                     $(w.read::<$read>(),)*
                       w.entities())
                );
                for ent in entities {
                    if let ( $( Some($write), )* $( Some($read), )* ) =
                        ( $( $write.get_mut(ent), )* $( $read.get(ent), )* ) {
                        fun( $($write,)* $($read,)* );
                    }
                }
            });
        }
    })
}

impl_run!( run0w1r [] [R0] );
impl_run!( run0w2r [] [R0, R1] );
impl_run!( run1w0r [W0] [] );
impl_run!( run1w1r [W0] [R0] );
impl_run!( run1w2r [W0] [R0, R1] );
impl_run!( run1w3r [W0] [R0, R1, R2] );
impl_run!( run1w4r [W0] [R0, R1, R2, R3] );
impl_run!( run1w5r [W0] [R0, R1, R2, R3, R4] );
impl_run!( run1w6r [W0] [R0, R1, R2, R3, R4, R5] );
impl_run!( run1w7r [W0] [R0, R1, R2, R3, R5, R6, R7] );
impl_run!( run2w0r [W0, W1] [] );
impl_run!( run2w1r [W0, W1] [R0] );
impl_run!( run2w2r [W0, W1] [R0, R1] );
<commit_msg>Roughly implemented dynamic entity insertion and removal<commit_after>#[macro_use]
extern crate mopa;
extern crate pulse;
extern crate threadpool;
extern crate fnv;

use std::any::TypeId;
use std::cell::RefCell;
use std::collections::HashMap;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
use mopa::Any;
use pulse::{Pulse, Signal};
use threadpool::ThreadPool;

pub use storage::{Storage, StorageBase, VecStorage, HashMapStorage};

mod storage;

/// Index generation. When a new entity is placed at the old index,
/// it bumps the generation by 1. This allows to avoid using components
/// from the entities that were deleted.
/// G<=0 - the entity of generation G is dead
/// G >0 - the entity of generation G is alive
pub type Generation = i32;
/// Index type is arbitrary. It doesn't show up in any interfaces.
/// Keeping it 32bit allows for a single 64bit word per entity.
pub type Index = u32;
/// Entity type, as seen by the user.
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct Entity(Index, Generation);

impl Entity {
    #[cfg(test)]
    /// Create a new entity (externally from ECS)
    pub fn new(index: u32, gen: i32) -> Entity {
        Entity(index, gen)
    }

    /// Get the index of the entity.
    pub fn get_id(&self) -> usize { self.0 as usize }
    /// Get the generation of the entity.
    pub fn get_gen(&self) -> Generation { self.1 }
}

/// A custom entity iterator. Needed because the world doesn't really store
/// entities directly, but rather has just a vector of Index -> Generation.
pub struct EntityIter<'a> {
    guard: RwLockReadGuard<'a, Vec<Generation>>,
    index: usize,
}

impl<'a> Iterator for EntityIter<'a> {
    type Item = Entity;
    fn next(&mut self) -> Option<Entity> {
        loop {
            match self.guard.get(self.index) {
                Some(&gen) if gen > 0 => {
                    let ent = Entity(self.index as Index, gen);
                    self.index += 1;
                    return Some(ent)
                },
                Some(_) => self.index += 1, // continue
                None => return None,
            }
        }
    }
}

/// Abstract component type. Doesn't have to be Copy or even Clone.
pub trait Component: Any + Sized {
    type Storage: Storage<Self> + Any + Send + Sync;
}

trait StorageLock: Any + Send + Sync {
    fn del_slice(&self, &[Entity]);
}

mopafy!(StorageLock);

impl<S: StorageBase + Any + Send + Sync> StorageLock for RwLock<S> {
    fn del_slice(&self, entities: &[Entity]) {
        let mut guard = self.write().unwrap();
        for &e in entities.iter() {
            guard.del(e);
        }
    }
}

/// The world struct contains all the data, which is entities and their components.
/// The methods are supposed to be valid for any context they are available in.
pub struct World {
    generations: RwLock<Vec<Generation>>,
    components: HashMap<TypeId, Box<StorageLock>>,
}

impl World {
    /// Create a new empty world.
    pub fn new() -> World {
        World {
            generations: RwLock::new(Vec::new()),
            components: HashMap::new(),
        }
    }
    /// Register a new component type.
    pub fn register<T: Component>(&mut self) {
        let any = RwLock::new(T::Storage::new());
        self.components.insert(TypeId::of::<T>(), Box::new(any));
    }
    /// Unregister a component type.
    pub fn unregister<T: Component>(&mut self) -> Option<T::Storage> {
        self.components.remove(&TypeId::of::<T>()).map(|boxed|
            match boxed.downcast::<RwLock<T::Storage>>() {
                Ok(b) => (*b).into_inner().unwrap(),
                Err(_) => panic!("Unable to downcast the storage type"),
            }
        )
    }
    fn lock<T: Component>(&self) -> &RwLock<T::Storage> {
        let boxed = self.components.get(&TypeId::of::<T>()).unwrap();
        boxed.downcast_ref().unwrap()
    }
    /// Lock a component for reading.
    pub fn read<'a, T: Component>(&'a self) -> RwLockReadGuard<'a, T::Storage> {
        self.lock::<T>().read().unwrap()
    }
    /// Lock a component for writing.
    pub fn write<'a, T: Component>(&'a self) -> RwLockWriteGuard<'a, T::Storage> {
        self.lock::<T>().write().unwrap()
    }
    /// Return the entity iterator.
    pub fn entities<'a>(&'a self) -> EntityIter<'a> {
        EntityIter {
            guard: self.generations.read().unwrap(),
            index: 0,
        }
    }
    fn find_next(&self, base: usize) -> Entity {
        let gens = self.generations.read().unwrap();
        match gens.iter().enumerate().skip(base).find(|&(_, g)| *g <= 0) {
            Some((id, gen)) => Entity(id as Index, 1 - gen),
            None => Entity(gens.len() as Index, 1),
        }
    }
}

struct Appendix {
    next: Entity,
    add_queue: Vec<Entity>,
    sub_queue: Vec<Entity>
}

/// A custom entity iterator for dynamically added entities.
pub struct ExtraEntityIter<'a> {
    guard: RwLockReadGuard<'a, Appendix>,
    index: usize,
}

impl<'a> Iterator for ExtraEntityIter<'a> {
    type Item = Entity;
    fn next(&mut self) -> Option<Entity> {
        let ent = self.guard.add_queue.get(self.index);
        self.index += 1;
        ent.map(|e| *e)
    }
}

/// World argument for a system closure.
pub struct WorldArg {
    world: Arc<World>,
    pulse: RefCell<Option<Pulse>>,
    app: Arc<RwLock<Appendix>>,
}

impl WorldArg {
    /// Borrows the world, allowing the system lock some components and get the entity
    /// iterator. Has to be called only once. Fires a pulse at the end.
    pub fn fetch<'a, U, F>(&'a self, f: F) -> U
        where F: FnOnce(&'a World) -> U
    {
        let pulse = self.pulse.borrow_mut().take()
                        .expect("fetch may only be called once.");
        let u = f(&self.world);
        pulse.pulse();
        u
    }
    /// Insert a new entity dynamically.
    pub fn insert(&self) -> Entity {
        let mut app = self.app.write().unwrap();
        let ent = app.next;
        app.add_queue.push(ent);
        app.next = self.world.find_next(ent.get_id() + 1);
        ent
    }
    /// Remove an entity dynamically.
    pub fn remove(&self, entity: Entity) {
        let mut app = self.app.write().unwrap();
        app.sub_queue.push(entity);
    }
    /// Iterate dynamically added entities.
    pub fn extra_entities<'a>(&'a self) -> ExtraEntityIter<'a> {
        ExtraEntityIter {
            guard: self.app.read().unwrap(),
            index: 0,
        }
    }
}

/// Helper builder for entities.
pub struct EntityBuilder<'a>(Entity, &'a World);

impl<'a> EntityBuilder<'a> {
    /// Add a component value to the new entity.
    pub fn with<T: Component>(self, value: T) -> EntityBuilder<'a> {
        self.1.write::<T>().insert(self.0, value);
        self
    }
    /// Finish entity construction.
    pub fn build(self) -> Entity {
        self.0
    }
}

pub struct Scheduler {
    world: Arc<World>,
    threads: ThreadPool,
    appendix: Arc<RwLock<Appendix>>,
}

impl Scheduler {
    pub fn new(world: World, num_threads: usize) -> Scheduler {
        let next = Appendix {
            next: world.find_next(0),
            add_queue: Vec::new(),
            sub_queue: Vec::new(),
        };
        Scheduler {
            world: Arc::new(world),
            threads: ThreadPool::new(num_threads),
            appendix: Arc::new(RwLock::new(next)),
        }
    }
    pub fn get_world(&self) -> &World {
        //println!("{:?}", &*self.world.generations.read().unwrap());
        &self.world
    }
    pub fn run<F>(&mut self, functor: F) where
        F: 'static + Send + FnOnce(WorldArg)
    {
        let (signal, pulse) = Signal::new();
        let world = self.world.clone();
        let app = self.appendix.clone();
        self.threads.execute(|| {
            functor(WorldArg {
                world: world,
                pulse: RefCell::new(Some(pulse)),
                app: app,
            });
        });
        signal.wait().unwrap();
    }
    pub fn add_entity<'a>(&'a mut self) -> EntityBuilder<'a> {
        let mut appendix = self.appendix.write().unwrap();
        let ent = appendix.next;
        assert!(ent.get_gen() > 0);
        if ent.get_gen() == 1 {
            let mut gens = self.world.generations.write().unwrap();
            assert!(gens.len() == ent.get_id());
            gens.push(ent.get_gen());
        }
        appendix.next = self.world.find_next(ent.get_id() + 1);
        EntityBuilder(ent, &self.world)
    }
    pub fn del_entity(&mut self, entity: Entity) {
        for boxed in self.world.components.values() {
            boxed.del_slice(&[entity]);
        }
        let mut gens = self.world.generations.write().unwrap();
        let mut gen = &mut gens[entity.get_id() as usize];
        assert!(*gen > 0);
        let mut appendix = self.appendix.write().unwrap();
        if entity.get_id() < appendix.next.get_id() {
            appendix.next = Entity(entity.0, *gen+1);
        }
        *gen *= -1;
    }
    pub fn wait(&self) {
        while self.threads.active_count() > 0 {} //TODO
    }
}

macro_rules! impl_run {
    ($name:ident [$( $write:ident ),*] [$( $read:ident ),*]) => (impl Scheduler {
        #[allow(non_snake_case, unused_mut)]
        pub fn $name<
            $($write:Component,)* $($read:Component,)*
            F: 'static + Send + FnMut( $(&mut $write,)* $(&$read,)* )
        >(&mut self, functor: F) {
            self.run(|warg| {
                let mut fun = functor;
                let ($(mut $write,)* $($read,)* entities) = warg.fetch(|w|
                    ($(w.write::<$write>(),)*
                     $(w.read::<$read>(),)*
                       w.entities())
                );
                for ent in entities {
                    if let ( $( Some($write), )* $( Some($read), )* ) =
                        ( $( $write.get_mut(ent), )* $( $read.get(ent), )* ) {
                        fun( $($write,)* $($read,)* );
                    }
                }
            });
        }
    })
}

impl_run!( run0w1r [] [R0] );
impl_run!( run0w2r [] [R0, R1] );
impl_run!( run1w0r [W0] [] );
impl_run!( run1w1r [W0] [R0] );
impl_run!( run1w2r [W0] [R0, R1] );
impl_run!( run1w3r [W0] [R0, R1, R2] );
impl_run!( run1w4r [W0] [R0, R1, R2, R3] );
impl_run!( run1w5r [W0] [R0, R1, R2, R3, R4] );
impl_run!( run1w6r [W0] [R0, R1, R2, R3, R4, R5] );
impl_run!( run1w7r [W0] [R0, R1, R2, R3, R5, R6, R7] );
impl_run!( run2w0r [W0, W1] [] );
impl_run!( run2w1r [W0, W1] [R0] );
impl_run!( run2w2r [W0, W1] [R0, R1] );
<|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 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() {}
}
<commit_msg>Link to LLDB and LLVM via HTTPS.<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]: https://lldb.llvm.org/
//! [LLVM project]: https://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>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! # Cap'n Proto Schema Compiler Plugin Library
//!
//! This library allows you to do [Cap'n Proto code generation]
//! (https://capnproto.org/otherlang.html#how-to-write-compiler-plugins)
//! within a Cargo build.
//!
//! In your Cargo.toml:
//!
//! ```ignore
//!   [package]
//!   build = "build.rs"
//!
//!   [build-dependencies]
//!   capnpc = "*"
//! ```
//!
//! In your build.rs:
//!
//! ```ignore
//! extern crate capnpc;
//!
//! fn main() {
//!     ::capnpc::compile("schema", &["schema/foo.capnp", "schema/bar.capnp"]).unwrap();
//! }
//! ```
//!
//! This will be equivalent to executing the shell command
//!
//! ```ignore
//!   capnp compile -orust:$OUT_DIR --src-prefix=schema schema/foo.capnp schema/bar.capnp
//! ```
//!

extern crate capnp;

/// Code generated from [schema.capnp]
/// (https://github.com/sandstorm-io/capnproto/blob/master/c%2B%2B/src/capnp/schema.capnp).
pub mod schema_capnp;

pub mod codegen;
pub mod codegen_types;
pub mod schema;

use std::path::Path;

fn run_command(mut command: ::std::process::Command) -> ::capnp::Result<()> {
    let mut p = try!(command.spawn());
    try!(::codegen::main(p.stdout.take().unwrap(),
                         ::std::path::Path::new(&::std::env::var("OUT_DIR").unwrap())));
    let exit_status = try!(p.wait());
    if !exit_status.success() {
        Err(::capnp::Error::failed(format!("Non-success exit status: {}", exit_status)))
    } else {
        Ok(())
    }
}

pub fn compile<P1, P2>(src_prefix: P1, files: &[P2]) -> ::capnp::Result<()>
    where P1: AsRef<Path>, P2: AsRef<Path>
{
    compile_with_src_prefixes(&[src_prefix], files)
}

// TODO(version bump): We should have only one `compile` function and it should allow
// multiple --src-prefix flags to be set.
pub fn compile_with_src_prefixes<P1, P2>(src_prefixes: &[P1], files: &[P2]) -> ::capnp::Result<()>
    where P1: AsRef<Path>, P2: AsRef<Path>
{
    let mut command = ::std::process::Command::new("capnp");
    command.arg("compile").arg("-o").arg("-");
    for src_prefix in src_prefixes {
        command.arg(&format!("--src-prefix={}", src_prefix.as_ref().display()));
    }

    for file in files {
        command.arg(&format!("{}", file.as_ref().display()));
    }

    command.stdout(::std::process::Stdio::piped());
    command.stderr(::std::process::Stdio::inherit());

    run_command(command).map_err(|error| {
        ::capnp::Error::failed(format!("Error while trying to execute `capnp compile`: {}.  \
                                        Please verify that version 0.5.2 or higher of the capnp executable \
                                        is installed on your system. See https://capnproto.org/install.html",
                                       error))})
}
<commit_msg>comment about builder pattern<commit_after>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! # Cap'n Proto Schema Compiler Plugin Library
//!
//! This library allows you to do [Cap'n Proto code generation]
//! (https://capnproto.org/otherlang.html#how-to-write-compiler-plugins)
//! within a Cargo build.
//!
//! In your Cargo.toml:
//!
//! ```ignore
//!   [package]
//!   build = "build.rs"
//!
//!   [build-dependencies]
//!   capnpc = "*"
//! ```
//!
//! In your build.rs:
//!
//! ```ignore
//! extern crate capnpc;
//!
//! fn main() {
//!     ::capnpc::compile("schema", &["schema/foo.capnp", "schema/bar.capnp"]).unwrap();
//! }
//! ```
//!
//! This will be equivalent to executing the shell command
//!
//! ```ignore
//!   capnp compile -orust:$OUT_DIR --src-prefix=schema schema/foo.capnp schema/bar.capnp
//! ```
//!

extern crate capnp;

/// Code generated from [schema.capnp]
/// (https://github.com/sandstorm-io/capnproto/blob/master/c%2B%2B/src/capnp/schema.capnp).
pub mod schema_capnp;

pub mod codegen;
pub mod codegen_types;
pub mod schema;

use std::path::Path;

fn run_command(mut command: ::std::process::Command) -> ::capnp::Result<()> {
    let mut p = try!(command.spawn());
    try!(::codegen::main(p.stdout.take().unwrap(),
                         ::std::path::Path::new(&::std::env::var("OUT_DIR").unwrap())));
    let exit_status = try!(p.wait());
    if !exit_status.success() {
        Err(::capnp::Error::failed(format!("Non-success exit status: {}", exit_status)))
    } else {
        Ok(())
    }
}

pub fn compile<P1, P2>(src_prefix: P1, files: &[P2]) -> ::capnp::Result<()>
    where P1: AsRef<Path>, P2: AsRef<Path>
{
    compile_with_src_prefixes(&[src_prefix], files)
}

// TODO(version bump): We should have only one `compile` function and it should allow
// multiple --src-prefix flags to be set. Possibly we should use the "builder pattern".
pub fn compile_with_src_prefixes<P1, P2>(src_prefixes: &[P1], files: &[P2]) -> ::capnp::Result<()>
    where P1: AsRef<Path>, P2: AsRef<Path>
{
    let mut command = ::std::process::Command::new("capnp");
    command.arg("compile").arg("-o").arg("-");
    for src_prefix in src_prefixes {
        command.arg(&format!("--src-prefix={}", src_prefix.as_ref().display()));
    }

    for file in files {
        command.arg(&format!("{}", file.as_ref().display()));
    }

    command.stdout(::std::process::Stdio::piped());
    command.stderr(::std::process::Stdio::inherit());

    run_command(command).map_err(|error| {
        ::capnp::Error::failed(format!("Error while trying to execute `capnp compile`: {}.  \
                                        Please verify that version 0.5.2 or higher of the capnp executable \
                                        is installed on your system. See https://capnproto.org/install.html",
                                       error))})
}
<|endoftext|>


<commit_before>//! This crate implements the backend server for https://crates.io/
//!
//! All implemented routes are defined in the [middleware](fn.middleware.html) function and
//! implemented in the [category](category/index.html), [keyword](keyword/index.html),
//! [krate](krate/index.html), [user](user/index.html) and [version](version/index.html) modules.

#![deny(warnings)]
#![deny(missing_debug_implementations, missing_copy_implementations)]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![recursion_limit="128"]

#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate ammonia;
extern crate chrono;
extern crate comrak;
extern crate curl;
extern crate diesel_full_text_search;
extern crate dotenv;
extern crate flate2;
extern crate git2;
extern crate hex;
extern crate license_exprs;
extern crate oauth2;
extern crate openssl;
extern crate r2d2;
extern crate r2d2_diesel;
extern crate rand;
extern crate s3;
extern crate semver;
extern crate serde;
extern crate tar;
extern crate time;
extern crate toml;
extern crate url;

extern crate conduit;
extern crate conduit_conditional_get;
extern crate conduit_cookie;
extern crate cookie;
extern crate conduit_git_http_backend;
extern crate conduit_log_requests;
extern crate conduit_middleware;
extern crate conduit_router;
extern crate conduit_static;

pub use app::App;
pub use self::badge::Badge;
pub use self::category::Category;
pub use config::Config;
pub use self::dependency::Dependency;
pub use self::download::VersionDownload;
pub use self::keyword::Keyword;
pub use self::krate::Crate;
pub use self::user::User;
pub use self::version::Version;
pub use self::uploaders::{Uploader, Bomb};

use std::sync::Arc;
use std::error::Error;

use conduit_router::RouteBuilder;
use conduit_middleware::MiddlewareBuilder;

use util::{C, R, R404};

pub mod app;
pub mod badge;
pub mod categories;
pub mod category;
pub mod config;
pub mod crate_owner_invitation;
pub mod db;
pub mod dependency;
pub mod dist;
pub mod download;
pub mod git;
pub mod http;
pub mod keyword;
pub mod krate;
pub mod owner;
pub mod render;
pub mod schema;
pub mod token;
pub mod upload;
pub mod uploaders;
pub mod user;
pub mod util;
pub mod version;

mod local_upload;
mod pagination;

/// Used for setting different values depending on whether the app is being run in production,
/// in development, or for testing.
///
/// The app's `config.env` value is set in *src/bin/server.rs* to `Production` if the environment
/// variable `HEROKU` is set and `Development` otherwise. `config.env` is set to `Test`
/// unconditionally in *src/test/all.rs*.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Env {
    Development,
    Test,
    Production,
}

/// Used for setting different values depending on the type of registry this instance is.
///
/// `Primary` indicates this instance is a primary registry that is the source of truth for these
/// crates' information. `ReadOnlyMirror` indicates this instanceis a read-only mirror of crate
/// information that exists on another instance.
///
/// The app's `config.mirror` value is set in *src/bin/server.rs* to `ReadOnlyMirror` if the
/// `MIRROR` environment variable is set and to `Primary` otherwise.
///
/// There may be more ways to run crates.io servers in the future, such as a
/// mirror that also has private crates that crates.io does not have.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Replica {
    Primary,
    ReadOnlyMirror,
}

/// Configures routes, sessions, logging, and other middleware.
///
/// Called from *src/bin/server.rs*.
pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
    let mut api_router = RouteBuilder::new();

    api_router.get("/crates", C(krate::index));
    api_router.get("/crates/:crate_id", C(krate::show));
    api_router.put("/crates/new", C(krate::new));
    api_router.get("/crates/:crate_id/:version", C(version::show));
    api_router.get("/crates/:crate_id/:version/download", C(krate::download));
    api_router.get("/crates/:crate_id/:version/readme", C(krate::readme));
    api_router.get(
        "/crates/:crate_id/:version/dependencies",
        C(version::dependencies),
    );
    api_router.get(
        "/crates/:crate_id/:version/downloads",
        C(version::downloads),
    );
    api_router.get("/crates/:crate_id/:version/authors", C(version::authors));
    // Used to generate download graphs
    api_router.get("/crates/:crate_id/downloads", C(krate::downloads));
    api_router.get("/crates/:crate_id/versions", C(krate::versions));
    api_router.put("/crates/:crate_id/follow", C(krate::follow));
    api_router.delete("/crates/:crate_id/follow", C(krate::unfollow));
    api_router.get("/crates/:crate_id/following", C(krate::following));
    // This endpoint may now be redundant, check frontend to see if it is
    // being used
    api_router.get("/crates/:crate_id/owners", C(krate::owners));
    api_router.get("/crates/:crate_id/owner_team", C(krate::owner_team));
    api_router.get("/crates/:crate_id/owner_user", C(krate::owner_user));
    api_router.put("/crates/:crate_id/owners", C(krate::add_owners));
    api_router.delete("/crates/:crate_id/owners", C(krate::remove_owners));
    api_router.delete("/crates/:crate_id/:version/yank", C(version::yank));
    api_router.put("/crates/:crate_id/:version/unyank", C(version::unyank));
    api_router.get(
        "/crates/:crate_id/reverse_dependencies",
        C(krate::reverse_dependencies),
    );
    api_router.get("/versions", C(version::index));
    api_router.get("/versions/:version_id", C(version::show));
    api_router.get("/keywords", C(keyword::index));
    api_router.get("/keywords/:keyword_id", C(keyword::show));
    api_router.get("/categories", C(category::index));
    api_router.get("/categories/:category_id", C(category::show));
    api_router.get("/category_slugs", C(category::slugs));
    api_router.get("/users/:user_id", C(user::show));
    api_router.put("/users/:user_id", C(user::update_user));
    api_router.get("/users/:user_id/stats", C(user::stats));
    api_router.get("/teams/:team_id", C(user::show_team));
    api_router.get("/me", C(user::me));
    api_router.get("/me/updates", C(user::updates));
    api_router.get("/me/tokens", C(token::list));
    api_router.post("/me/tokens", C(token::new));
    api_router.delete("/me/tokens/:id", C(token::revoke));
    api_router.get(
        "/me/crate_owner_invitations",
        C(crate_owner_invitation::list),
    );
    api_router.get("/summary", C(krate::summary));
    let api_router = Arc::new(R404(api_router));

    let mut router = RouteBuilder::new();

    // Mount the router under the /api/v1 path so we're at least somewhat at the
    // liberty to change things in the future!
    router.get("/api/v1/*path", R(api_router.clone()));
    router.put("/api/v1/*path", R(api_router.clone()));
    router.post("/api/v1/*path", R(api_router.clone()));
    router.head("/api/v1/*path", R(api_router.clone()));
    router.delete("/api/v1/*path", R(api_router));

    router.get("/authorize_url", C(user::github_authorize));
    router.get("/authorize", C(user::github_access_token));
    router.delete("/logout", C(user::logout));

    // Only serve the local checkout of the git index in development mode.
    // In production, for crates.io, cargo gets the index from
    // https://github.com/rust-lang/crates.io-index directly.
    let env = app.config.env;
    if env == Env::Development {
        let s = conduit_git_http_backend::Serve(app.git_repo_checkout.clone());
        let s = Arc::new(s);
        router.get("/git/index/*path", R(s.clone()));
        router.post("/git/index/*path", R(s));
    }

    let mut m = MiddlewareBuilder::new(R404(router));

    if env == Env::Development {
        // DebugMiddleware is defined below to print logs for each request.
        m.add(DebugMiddleware);
        m.around(local_upload::Middleware::default());
    }

    if env != Env::Test {
        m.add(conduit_log_requests::LogRequests(log::LogLevel::Info));
    }

    m.around(util::Head::default());
    m.add(conduit_conditional_get::ConditionalGet);
    m.add(conduit_cookie::Middleware::new());
    m.add(conduit_cookie::SessionMiddleware::new(
        "cargo_session",
        cookie::Key::from_master(app.session_key.as_bytes()),
        env == Env::Production,
    ));
    if env == Env::Production {
        m.add(http::SecurityHeadersMiddleware::new(&app.config.uploader));
    }
    m.add(app::AppMiddleware::new(app));

    // Sets the current user on each request.
    m.add(user::Middleware);

    // Serve the static files in the *dist* directory, which are the frontend assets.
    // Not needed for the backend tests.
    if env != Env::Test {
        m.around(dist::Middleware::default());
    }

    return m;

    struct DebugMiddleware;

    impl conduit_middleware::Middleware for DebugMiddleware {
        fn before(&self, req: &mut conduit::Request) -> Result<(), Box<Error + Send>> {
            println!("  version: {}", req.http_version());
            println!("  method: {:?}", req.method());
            println!("  scheme: {:?}", req.scheme());
            println!("  host: {:?}", req.host());
            println!("  path: {}", req.path());
            println!("  query_string: {:?}", req.query_string());
            println!("  remote_addr: {:?}", req.remote_addr());
            for &(k, ref v) in &req.headers().all() {
                println!("  hdr: {}={:?}", k, v);
            }
            Ok(())
        }
        fn after(
            &self,
            _req: &mut conduit::Request,
            res: Result<conduit::Response, Box<Error + Send>>,
        ) -> Result<conduit::Response, Box<Error + Send>> {
            res.map(|res| {
                println!("  <- {:?}", res.status);
                for (k, v) in &res.headers {
                    println!("  <- {} {:?}", k, v);
                }
                res
            })
        }
    }
}

/// Convenience function for getting the current server time in UTC.
pub fn now() -> time::Timespec {
    time::now_utc().to_timespec()
}

/// Convenience function for getting a time in RFC 3339 format.
///
/// Example: `2012-02-22T14:53:18Z`. Used for returning time values in JSON API responses.
pub fn encode_time(ts: time::Timespec) -> String {
    time::at_utc(ts).rfc3339().to_string()
}

/// Convenience function requiring that an environment variable is set.
///
/// Ensures that we've initialized the dotenv crate in order to read environment variables
/// from a *.env* file if present. Don't use this for optionally set environment variables.
///
/// # Panics
///
/// Panics if the environment variable with the name passed in as an argument is not defined
/// in the current environment.
pub fn env(s: &str) -> String {
    dotenv::dotenv().ok();
    ::std::env::var(s).unwrap_or_else(|_| panic!("must have `{}` defined", s))
}

sql_function!(lower, lower_t, (x: ::diesel::types::Text) -> ::diesel::types::Text);
<commit_msg>Add routing info and lettre crate for confirming emails<commit_after>//! This crate implements the backend server for https://crates.io/
//!
//! All implemented routes are defined in the [middleware](fn.middleware.html) function and
//! implemented in the [category](category/index.html), [keyword](keyword/index.html),
//! [krate](krate/index.html), [user](user/index.html) and [version](version/index.html) modules.

#![deny(warnings)]
#![deny(missing_debug_implementations, missing_copy_implementations)]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![recursion_limit="128"]

#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate ammonia;
extern crate chrono;
extern crate comrak;
extern crate curl;
extern crate diesel_full_text_search;
extern crate dotenv;
extern crate flate2;
extern crate git2;
extern crate hex;
extern crate license_exprs;
extern crate oauth2;
extern crate openssl;
extern crate r2d2;
extern crate r2d2_diesel;
extern crate rand;
extern crate s3;
extern crate semver;
extern crate serde;
extern crate tar;
extern crate time;
extern crate toml;
extern crate url;
extern crate lettre;

extern crate conduit;
extern crate conduit_conditional_get;
extern crate conduit_cookie;
extern crate cookie;
extern crate conduit_git_http_backend;
extern crate conduit_log_requests;
extern crate conduit_middleware;
extern crate conduit_router;
extern crate conduit_static;

pub use app::App;
pub use self::badge::Badge;
pub use self::category::Category;
pub use config::Config;
pub use self::dependency::Dependency;
pub use self::download::VersionDownload;
pub use self::keyword::Keyword;
pub use self::krate::Crate;
pub use self::user::User;
pub use self::version::Version;
pub use self::uploaders::{Uploader, Bomb};

use std::sync::Arc;
use std::error::Error;

use conduit_router::RouteBuilder;
use conduit_middleware::MiddlewareBuilder;

use util::{C, R, R404};

pub mod app;
pub mod badge;
pub mod categories;
pub mod category;
pub mod config;
pub mod crate_owner_invitation;
pub mod db;
pub mod dependency;
pub mod dist;
pub mod download;
pub mod git;
pub mod http;
pub mod keyword;
pub mod krate;
pub mod owner;
pub mod render;
pub mod schema;
pub mod token;
pub mod upload;
pub mod uploaders;
pub mod user;
pub mod util;
pub mod version;

mod local_upload;
mod pagination;

/// Used for setting different values depending on whether the app is being run in production,
/// in development, or for testing.
///
/// The app's `config.env` value is set in *src/bin/server.rs* to `Production` if the environment
/// variable `HEROKU` is set and `Development` otherwise. `config.env` is set to `Test`
/// unconditionally in *src/test/all.rs*.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Env {
    Development,
    Test,
    Production,
}

/// Used for setting different values depending on the type of registry this instance is.
///
/// `Primary` indicates this instance is a primary registry that is the source of truth for these
/// crates' information. `ReadOnlyMirror` indicates this instanceis a read-only mirror of crate
/// information that exists on another instance.
///
/// The app's `config.mirror` value is set in *src/bin/server.rs* to `ReadOnlyMirror` if the
/// `MIRROR` environment variable is set and to `Primary` otherwise.
///
/// There may be more ways to run crates.io servers in the future, such as a
/// mirror that also has private crates that crates.io does not have.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Replica {
    Primary,
    ReadOnlyMirror,
}

/// Configures routes, sessions, logging, and other middleware.
///
/// Called from *src/bin/server.rs*.
pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
    let mut api_router = RouteBuilder::new();

    api_router.get("/crates", C(krate::index));
    api_router.get("/crates/:crate_id", C(krate::show));
    api_router.put("/crates/new", C(krate::new));
    api_router.get("/crates/:crate_id/:version", C(version::show));
    api_router.get("/crates/:crate_id/:version/download", C(krate::download));
    api_router.get("/crates/:crate_id/:version/readme", C(krate::readme));
    api_router.get(
        "/crates/:crate_id/:version/dependencies",
        C(version::dependencies),
    );
    api_router.get(
        "/crates/:crate_id/:version/downloads",
        C(version::downloads),
    );
    api_router.get("/crates/:crate_id/:version/authors", C(version::authors));
    // Used to generate download graphs
    api_router.get("/crates/:crate_id/downloads", C(krate::downloads));
    api_router.get("/crates/:crate_id/versions", C(krate::versions));
    api_router.put("/crates/:crate_id/follow", C(krate::follow));
    api_router.delete("/crates/:crate_id/follow", C(krate::unfollow));
    api_router.get("/crates/:crate_id/following", C(krate::following));
    // This endpoint may now be redundant, check frontend to see if it is
    // being used
    api_router.get("/crates/:crate_id/owners", C(krate::owners));
    api_router.get("/crates/:crate_id/owner_team", C(krate::owner_team));
    api_router.get("/crates/:crate_id/owner_user", C(krate::owner_user));
    api_router.put("/crates/:crate_id/owners", C(krate::add_owners));
    api_router.delete("/crates/:crate_id/owners", C(krate::remove_owners));
    api_router.delete("/crates/:crate_id/:version/yank", C(version::yank));
    api_router.put("/crates/:crate_id/:version/unyank", C(version::unyank));
    api_router.get(
        "/crates/:crate_id/reverse_dependencies",
        C(krate::reverse_dependencies),
    );
    api_router.get("/versions", C(version::index));
    api_router.get("/versions/:version_id", C(version::show));
    api_router.get("/keywords", C(keyword::index));
    api_router.get("/keywords/:keyword_id", C(keyword::show));
    api_router.get("/categories", C(category::index));
    api_router.get("/categories/:category_id", C(category::show));
    api_router.get("/category_slugs", C(category::slugs));
    api_router.get("/users/:user_id", C(user::show));
    api_router.put("/users/:user_id", C(user::update_user));
    api_router.get("/users/:user_id/stats", C(user::stats));
    api_router.get("/teams/:team_id", C(user::show_team));
    api_router.get("/me", C(user::me));
    api_router.get("/me/updates", C(user::updates));
    api_router.get("/me/tokens", C(token::list));
    api_router.post("/me/tokens", C(token::new));
    api_router.delete("/me/tokens/:id", C(token::revoke));
    api_router.get(
        "/me/crate_owner_invitations",
        C(crate_owner_invitation::list),
    );
    api_router.get("/summary", C(krate::summary));
    api_router.put("/confirm/:email_token", C(user::confirm_user_email));
    let api_router = Arc::new(R404(api_router));

    let mut router = RouteBuilder::new();

    // Mount the router under the /api/v1 path so we're at least somewhat at the
    // liberty to change things in the future!
    router.get("/api/v1/*path", R(api_router.clone()));
    router.put("/api/v1/*path", R(api_router.clone()));
    router.post("/api/v1/*path", R(api_router.clone()));
    router.head("/api/v1/*path", R(api_router.clone()));
    router.delete("/api/v1/*path", R(api_router));

    router.get("/authorize_url", C(user::github_authorize));
    router.get("/authorize", C(user::github_access_token));
    router.delete("/logout", C(user::logout));

    // Only serve the local checkout of the git index in development mode.
    // In production, for crates.io, cargo gets the index from
    // https://github.com/rust-lang/crates.io-index directly.
    let env = app.config.env;
    if env == Env::Development {
        let s = conduit_git_http_backend::Serve(app.git_repo_checkout.clone());
        let s = Arc::new(s);
        router.get("/git/index/*path", R(s.clone()));
        router.post("/git/index/*path", R(s));
    }

    let mut m = MiddlewareBuilder::new(R404(router));

    if env == Env::Development {
        // DebugMiddleware is defined below to print logs for each request.
        m.add(DebugMiddleware);
        m.around(local_upload::Middleware::default());
    }

    if env != Env::Test {
        m.add(conduit_log_requests::LogRequests(log::LogLevel::Info));
    }

    m.around(util::Head::default());
    m.add(conduit_conditional_get::ConditionalGet);
    m.add(conduit_cookie::Middleware::new());
    m.add(conduit_cookie::SessionMiddleware::new(
        "cargo_session",
        cookie::Key::from_master(app.session_key.as_bytes()),
        env == Env::Production,
    ));
    if env == Env::Production {
        m.add(http::SecurityHeadersMiddleware::new(&app.config.uploader));
    }
    m.add(app::AppMiddleware::new(app));

    // Sets the current user on each request.
    m.add(user::Middleware);

    // Serve the static files in the *dist* directory, which are the frontend assets.
    // Not needed for the backend tests.
    if env != Env::Test {
        m.around(dist::Middleware::default());
    }

    return m;

    struct DebugMiddleware;

    impl conduit_middleware::Middleware for DebugMiddleware {
        fn before(&self, req: &mut conduit::Request) -> Result<(), Box<Error + Send>> {
            println!("  version: {}", req.http_version());
            println!("  method: {:?}", req.method());
            println!("  scheme: {:?}", req.scheme());
            println!("  host: {:?}", req.host());
            println!("  path: {}", req.path());
            println!("  query_string: {:?}", req.query_string());
            println!("  remote_addr: {:?}", req.remote_addr());
            for &(k, ref v) in &req.headers().all() {
                println!("  hdr: {}={:?}", k, v);
            }
            Ok(())
        }
        fn after(
            &self,
            _req: &mut conduit::Request,
            res: Result<conduit::Response, Box<Error + Send>>,
        ) -> Result<conduit::Response, Box<Error + Send>> {
            res.map(|res| {
                println!("  <- {:?}", res.status);
                for (k, v) in &res.headers {
                    println!("  <- {} {:?}", k, v);
                }
                res
            })
        }
    }
}

/// Convenience function for getting the current server time in UTC.
pub fn now() -> time::Timespec {
    time::now_utc().to_timespec()
}

/// Convenience function for getting a time in RFC 3339 format.
///
/// Example: `2012-02-22T14:53:18Z`. Used for returning time values in JSON API responses.
pub fn encode_time(ts: time::Timespec) -> String {
    time::at_utc(ts).rfc3339().to_string()
}

/// Convenience function requiring that an environment variable is set.
///
/// Ensures that we've initialized the dotenv crate in order to read environment variables
/// from a *.env* file if present. Don't use this for optionally set environment variables.
///
/// # Panics
///
/// Panics if the environment variable with the name passed in as an argument is not defined
/// in the current environment.
pub fn env(s: &str) -> String {
    dotenv::dotenv().ok();
    ::std::env::var(s).unwrap_or_else(|_| panic!("must have `{}` defined", s))
}

sql_function!(lower, lower_t, (x: ::diesel::types::Text) -> ::diesel::types::Text);
<|endoftext|>


<commit_before>//! Compile-time assertions to ensure that invariants are met.
//!
//! # Usage
//!
//! This crate is available [on crates.io][crate] and can be used by adding the
//! following to your project's `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! static_assertions = "0.1"
//! ```
//!
//! and this to your crate root:
//!
//! ```
//! #[macro_use]
//! extern crate static_assertions;
//! # fn main() {}
//! ```
//!
//! # Assert Equal Size
//!
//! When performing operations such as pointer casts or dealing with [`usize`]
//! versus [`u64`] versus [`u32`], the size of your types matter. This is where
//! [`assert_eq_size`] comes into play. Types provided as arguments to
//! [`assert_eq_size`] are ensured to be the same size at compile-time. If the
//! types differ in size, the code will fail to compile.
//!
//! ```
//! # #[macro_use]
//! # extern crate static_assertions;
//! # fn main() {
//! assert_eq_size!([u8; 4], (u16, u16), u32);
//!
//! // Produces a compilation failure:
//! // assert_eq_size!(u32, u8);
//! # }
//! ```
//!
//! Similar to [`assert_eq_size`], there is [`assert_eq_size_val`]. Instead of
//! specifying types to compare, values' sizes can be directly compared against
//! each other.
//!
//! ```
//! # #[macro_use]
//! # extern crate static_assertions;
//! # fn main() {
//! let x = 42u8;
//! let y = true;
//!
//! assert_eq_size_val!(x, y);
//! # }
//! ```
//! [`assert_eq_size_val`] doesn't consume its arguments and thus works for
//! non-[`Clone`]able values.
//!
//! ```
//! # #[macro_use]
//! # extern crate static_assertions;
//! # fn main() {
//! struct Buffer([u8; 256]);
//!
//! let buf = Buffer([0; 256]);
//! let val = [0u64; 32];
//!
//! assert_eq_size_val!(buf, val);
//!
//! // `buf` and `val` can be used here
//! # }
//! ```
//!
//! # Assert Constant Expression
//!
//! Constant expressions can be ensured to have certain properties via
//! [`const_assert`]. If the expression evaluates to `false`, the file will fail
//! to compile. This is synonymous to [`static_assert` in C++][static_assert].
//!
//! ```
//! # #[macro_use]
//! # extern crate static_assertions;
//! # fn main() {
//! const NUM: usize = 32;
//!
//! const_assert!(NUM * NUM == 1024);
//! # }
//! ```
//!
//! As a shorthand for `const_assert!(a == b)`, there's [`const_assert_eq`].
//!
//! ```
//! # #[macro_use]
//! # extern crate static_assertions;
//! # fn main() {
//! const NUM: usize = 32;
//! const_assert_eq!(NUM + NUM, 64);
//!
//! const TWO: usize = 2;
//! const_assert_eq!(TWO * TWO, TWO + TWO, 4);
//! # }
//! ```
//!
//! **Limitation:** Due to implementation details, [`assert_eq_size`],
//! [`const_assert`], and [`const_assert_eq`] can only be used from within the
//! context of a function.
//!
//! [crate]: https://crates.io/crates/static_assertions
//! [static_assert]: http://en.cppreference.com/w/cpp/language/static_assert
//! [`Clone`]: https://doc.rust-lang.org/std/clone/trait.Clone.html
//! [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html
//! [`u64`]: https://doc.rust-lang.org/std/primitive.u64.html
//! [`u32`]: https://doc.rust-lang.org/std/primitive.u32.html
//! [`assert_eq_size_val`]: macro.assert_eq_size_val.html
//! [`assert_eq_size`]: macro.assert_eq_size.html
//! [`const_assert`]: macro.const_assert.html
//! [`const_assert_eq`]: macro.const_assert_eq.html

#![no_std]

#[doc(hidden)]
pub extern crate core as _core;

/// Asserts at compile-time that the types have equal sizes.
///
/// This especially is useful for when coercing pointers between different types
/// and ensuring the underlying values are the same size.
///
/// # Example
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// struct Byte(u8);
///
/// # fn main() {
/// assert_eq_size!(Byte, u8);
///
/// // Supports unlimited arguments:
/// assert_eq_size!([Byte; 4], [u16; 2], u32);
///
/// // Fails to compile:
/// // assert_eq_size!(Byte, u16);
/// # }
/// ```
#[macro_export]
macro_rules! assert_eq_size {
    ($x:ty, $($xs:ty),+) => {
        #[allow(unused_unsafe)]
        unsafe {
            use $crate::_core::mem::{forget, transmute, uninitialized};
            $(forget::<$xs>(transmute(uninitialized::<$x>()));)+
        }
    }
}

/// Asserts at compile-time that the values have equal sizes.
///
/// # Example
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// # fn main() {
/// struct Byte(u8);
///
/// let x = 10u8;
/// let y = Byte(42); // Works for non-cloneable types
///
/// assert_eq_size_val!(x, y);
/// assert_eq_size_val!(x, y, 0u8);
///
/// // Fails to compile:
/// // assert_eq_size_val!(x, 0u32);
/// # }
/// ```
#[macro_export]
macro_rules! assert_eq_size_val {
    ($x:expr, $($xs:expr),+) => {
        #[allow(unused_unsafe)]
        unsafe {
            use $crate::_core::{mem, ptr};
            let mut copy = ptr::read(&$x);
            $(ptr::write(&mut copy, mem::transmute(ptr::read(&$xs)));)+
            mem::forget(copy);
        }
    }
}

/// Asserts at compile-time that the constant expression evaluates to `true`.
///
/// # Example
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// # fn main() {
/// const_assert!(2 + 2 == 4);
///
/// const FIVE: usize = 5;
/// const_assert!(FIVE - FIVE == 0);
///
/// // Fails to compile:
/// // const_assert!(1 >= 2);
/// # }
/// ```
#[macro_export]
macro_rules! const_assert {
    ($cond:expr) => {
        // Causes overflow if condition is false
        let _ = [(); 0 - (!($cond) as usize)];
    };
    ($($xs:expr),+) => {
        const_assert!($($xs)&&+);
    };
    ($($xs:expr);+ $(;)*) => {
        const_assert!($($xs),+);
    };
}

/// Asserts at compile-time that the constants are equal in value.
#[macro_export]
macro_rules! const_assert_eq {
    ($x:expr, $($xs:expr),+) => {
        const_assert!($($x == $xs),+);
    }
}
<commit_msg>Use colon prior to const_assert_eq example<commit_after>//! Compile-time assertions to ensure that invariants are met.
//!
//! # Usage
//!
//! This crate is available [on crates.io][crate] and can be used by adding the
//! following to your project's `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! static_assertions = "0.1"
//! ```
//!
//! and this to your crate root:
//!
//! ```
//! #[macro_use]
//! extern crate static_assertions;
//! # fn main() {}
//! ```
//!
//! # Assert Equal Size
//!
//! When performing operations such as pointer casts or dealing with [`usize`]
//! versus [`u64`] versus [`u32`], the size of your types matter. This is where
//! [`assert_eq_size`] comes into play. Types provided as arguments to
//! [`assert_eq_size`] are ensured to be the same size at compile-time. If the
//! types differ in size, the code will fail to compile.
//!
//! ```
//! # #[macro_use]
//! # extern crate static_assertions;
//! # fn main() {
//! assert_eq_size!([u8; 4], (u16, u16), u32);
//!
//! // Produces a compilation failure:
//! // assert_eq_size!(u32, u8);
//! # }
//! ```
//!
//! Similar to [`assert_eq_size`], there is [`assert_eq_size_val`]. Instead of
//! specifying types to compare, values' sizes can be directly compared against
//! each other.
//!
//! ```
//! # #[macro_use]
//! # extern crate static_assertions;
//! # fn main() {
//! let x = 42u8;
//! let y = true;
//!
//! assert_eq_size_val!(x, y);
//! # }
//! ```
//! [`assert_eq_size_val`] doesn't consume its arguments and thus works for
//! non-[`Clone`]able values.
//!
//! ```
//! # #[macro_use]
//! # extern crate static_assertions;
//! # fn main() {
//! struct Buffer([u8; 256]);
//!
//! let buf = Buffer([0; 256]);
//! let val = [0u64; 32];
//!
//! assert_eq_size_val!(buf, val);
//!
//! // `buf` and `val` can be used here
//! # }
//! ```
//!
//! # Assert Constant Expression
//!
//! Constant expressions can be ensured to have certain properties via
//! [`const_assert`]. If the expression evaluates to `false`, the file will fail
//! to compile. This is synonymous to [`static_assert` in C++][static_assert].
//!
//! ```
//! # #[macro_use]
//! # extern crate static_assertions;
//! # fn main() {
//! const NUM: usize = 32;
//!
//! const_assert!(NUM * NUM == 1024);
//! # }
//! ```
//!
//! As a shorthand for `const_assert!(a == b)`, there's [`const_assert_eq`]:
//!
//! ```
//! # #[macro_use]
//! # extern crate static_assertions;
//! # fn main() {
//! const NUM: usize = 32;
//! const_assert_eq!(NUM + NUM, 64);
//!
//! const TWO: usize = 2;
//! const_assert_eq!(TWO * TWO, TWO + TWO, 4);
//! # }
//! ```
//!
//! **Limitation:** Due to implementation details, [`assert_eq_size`],
//! [`const_assert`], and [`const_assert_eq`] can only be used from within the
//! context of a function.
//!
//! [crate]: https://crates.io/crates/static_assertions
//! [static_assert]: http://en.cppreference.com/w/cpp/language/static_assert
//! [`Clone`]: https://doc.rust-lang.org/std/clone/trait.Clone.html
//! [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html
//! [`u64`]: https://doc.rust-lang.org/std/primitive.u64.html
//! [`u32`]: https://doc.rust-lang.org/std/primitive.u32.html
//! [`assert_eq_size_val`]: macro.assert_eq_size_val.html
//! [`assert_eq_size`]: macro.assert_eq_size.html
//! [`const_assert`]: macro.const_assert.html
//! [`const_assert_eq`]: macro.const_assert_eq.html

#![no_std]

#[doc(hidden)]
pub extern crate core as _core;

/// Asserts at compile-time that the types have equal sizes.
///
/// This especially is useful for when coercing pointers between different types
/// and ensuring the underlying values are the same size.
///
/// # Example
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// struct Byte(u8);
///
/// # fn main() {
/// assert_eq_size!(Byte, u8);
///
/// // Supports unlimited arguments:
/// assert_eq_size!([Byte; 4], [u16; 2], u32);
///
/// // Fails to compile:
/// // assert_eq_size!(Byte, u16);
/// # }
/// ```
#[macro_export]
macro_rules! assert_eq_size {
    ($x:ty, $($xs:ty),+) => {
        #[allow(unused_unsafe)]
        unsafe {
            use $crate::_core::mem::{forget, transmute, uninitialized};
            $(forget::<$xs>(transmute(uninitialized::<$x>()));)+
        }
    }
}

/// Asserts at compile-time that the values have equal sizes.
///
/// # Example
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// # fn main() {
/// struct Byte(u8);
///
/// let x = 10u8;
/// let y = Byte(42); // Works for non-cloneable types
///
/// assert_eq_size_val!(x, y);
/// assert_eq_size_val!(x, y, 0u8);
///
/// // Fails to compile:
/// // assert_eq_size_val!(x, 0u32);
/// # }
/// ```
#[macro_export]
macro_rules! assert_eq_size_val {
    ($x:expr, $($xs:expr),+) => {
        #[allow(unused_unsafe)]
        unsafe {
            use $crate::_core::{mem, ptr};
            let mut copy = ptr::read(&$x);
            $(ptr::write(&mut copy, mem::transmute(ptr::read(&$xs)));)+
            mem::forget(copy);
        }
    }
}

/// Asserts at compile-time that the constant expression evaluates to `true`.
///
/// # Example
///
/// ```
/// # #[macro_use]
/// # extern crate static_assertions;
/// # fn main() {
/// const_assert!(2 + 2 == 4);
///
/// const FIVE: usize = 5;
/// const_assert!(FIVE - FIVE == 0);
///
/// // Fails to compile:
/// // const_assert!(1 >= 2);
/// # }
/// ```
#[macro_export]
macro_rules! const_assert {
    ($cond:expr) => {
        // Causes overflow if condition is false
        let _ = [(); 0 - (!($cond) as usize)];
    };
    ($($xs:expr),+) => {
        const_assert!($($xs)&&+);
    };
    ($($xs:expr);+ $(;)*) => {
        const_assert!($($xs),+);
    };
}

/// Asserts at compile-time that the constants are equal in value.
#[macro_export]
macro_rules! const_assert_eq {
    ($x:expr, $($xs:expr),+) => {
        const_assert!($($x == $xs),+);
    }
}
<|endoftext|>


<commit_before>
//! **petgraph** is a graph data structure library.
//!
//! The most prominent type is [`Graph`](./graph/struct.Graph.html) which is
//! a directed or undirected graph with arbitrary mutable node and edge weights.
//! It is based on rustc's graph implementation.
//!
//! Petgraph also provides [`GraphMap`](./graphmap/struct.GraphMap.html) which
//! is an undirected hashmap-backed graph which only allows simple node identifiers
//! (such as integers or references).

extern crate fixedbitset;

use std::cmp::Ordering;
use std::hash::{self, Hash};
use std::fmt;
use std::ops::{Deref};

pub use scored::MinScored;
pub use graphmap::GraphMap;
pub use graph::Graph;

pub use self::EdgeDirection::{Outgoing, Incoming};
pub use visit::{
    Bfs,
    BfsIter,
    Dfs,
    DfsIter,
};

mod scored;
pub mod algo;
#[doc(hidden)] // Not for public consumption -- only for testing
pub mod generate;
pub mod graphmap;
pub mod graph;
pub mod visit;
pub mod unionfind;
mod dijkstra;
mod isomorphism;
mod traits_graph;
#[cfg(feature = "quickcheck")]
pub mod quickcheck;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum EdgeDirection {
    /// An `Outgoing` edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An `Incoming` edge is an inbound edge *to* the current node.
    Incoming = 1
}

impl EdgeDirection {
    #[inline]
    fn opposite(&self) -> EdgeDirection {
        match *self {
            Outgoing => Incoming,
            Incoming => Outgoing,
        }
    }
}

/// Marker type for a directed graph.
#[derive(Copy, Clone, Debug)]
pub struct Directed;

/// Marker type for an undirected graph.
#[derive(Copy, Clone, Debug)]
pub struct Undirected;

/// A graph's edge type determines whether is has directed edges or not.
pub trait EdgeType {
    fn is_directed() -> bool;
}

impl EdgeType for Directed {
    #[inline]
    fn is_directed() -> bool { true }
}

impl EdgeType for Undirected {
    #[inline]
    fn is_directed() -> bool { false }
}

/// A reference that is hashed and compared by its pointer value.
pub struct Ptr<'b, T: 'b>(pub &'b T);

impl<'b, T> Copy for Ptr<'b, T> {}
impl<'b, T> Clone for Ptr<'b, T>
{
    fn clone(&self) -> Self { *self }
}

fn ptr_eq<T>(a: *const T, b: *const T) -> bool {
    a == b
}

impl<'b, T> PartialEq for Ptr<'b, T>
{
    /// Ptr compares by pointer equality, i.e if they point to the same value
    fn eq(&self, other: &Ptr<'b, T>) -> bool {
        ptr_eq(self.0, other.0)
    }
}

impl<'b, T> PartialOrd for Ptr<'b, T>
{
    fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'b, T> Ord for Ptr<'b, T>
{
    /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
    fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
        let a = self.0 as *const _;
        let b = other.0 as *const _;
        a.cmp(&b)
    }
}

impl<'b, T> Deref for Ptr<'b, T> {
    type Target = T;
    fn deref<'a>(&'a self) -> &'a T {
        self.0
    }
}

impl<'b, T> Eq for Ptr<'b, T> {}

impl<'b, T> Hash for Ptr<'b, T>
{
    fn hash<H: hash::Hasher>(&self, st: &mut H)
    {
        let ptr = (self.0) as *const T;
        ptr.hash(st)
    }
}

impl<'b, T: fmt::Debug> fmt::Debug for Ptr<'b, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// Convert an element like `(i, j)` or `(i, j, w)` into
/// a triple of source, target, edge weight.
///
/// For `Graph::from_edges` and `GraphMap::from_edges`.
pub trait IntoWeightedEdge<Ix, E> {
    fn into_edge(self) -> (Ix, Ix, E);
}

impl<'a, Ix, E> IntoWeightedEdge<Ix, E> for &'a (Ix, Ix)
    where Ix: Copy, E: Default
{
    fn into_edge(self) -> (Ix, Ix, E) {
        let (s, t) = *self;
        (s, t, E::default())
    }
}

impl<'a, Ix, E> IntoWeightedEdge<Ix, E> for &'a (Ix, Ix, E)
    where Ix: Copy, E: Clone
{
    fn into_edge(self) -> (Ix, Ix, E) {
        self.clone()
    }
}

impl<'a, Ix, E> IntoWeightedEdge<Ix, E> for (Ix, Ix, &'a E)
    where Ix: Copy, E: Clone
{
    fn into_edge(self) -> (Ix, Ix, E) {
        let (a, b, c) = self;
        (a, b, c.clone())
    }
}

impl<Ix, E> IntoWeightedEdge<Ix, E> for (Ix, Ix)
    where E: Default
{
    fn into_edge(self) -> (Ix, Ix, E) {
        let (s, t) = self;
        (s, t, E::default())
    }
}

impl<Ix, E> IntoWeightedEdge<Ix, E> for (Ix, Ix, E)
{
    fn into_edge(self) -> (Ix, Ix, E) {
        self
    }
}
<commit_msg>lib.rs: Reorder `pub use` for docs<commit_after>
//! **petgraph** is a graph data structure library.
//!
//! The most prominent type is [`Graph`](./graph/struct.Graph.html) which is
//! a directed or undirected graph with arbitrary mutable node and edge weights.
//! It is based on rustc's graph implementation.
//!
//! Petgraph also provides [`GraphMap`](./graphmap/struct.GraphMap.html) which
//! is an undirected hashmap-backed graph which only allows simple node identifiers
//! (such as integers or references).

extern crate fixedbitset;

use std::cmp::Ordering;
use std::hash::{self, Hash};
use std::fmt;
use std::ops::{Deref};

pub use scored::MinScored;
pub use graph::Graph;
pub use graphmap::GraphMap;

pub use visit::{
    Bfs,
    BfsIter,
    Dfs,
    DfsIter,
};
pub use EdgeDirection::{Outgoing, Incoming};

mod scored;
pub mod algo;
#[doc(hidden)] // Not for public consumption -- only for testing
pub mod generate;
pub mod graphmap;
pub mod graph;
pub mod visit;
pub mod unionfind;
mod dijkstra;
mod isomorphism;
mod traits_graph;
#[cfg(feature = "quickcheck")]
pub mod quickcheck;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum EdgeDirection {
    /// An `Outgoing` edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An `Incoming` edge is an inbound edge *to* the current node.
    Incoming = 1
}

impl EdgeDirection {
    #[inline]
    fn opposite(&self) -> EdgeDirection {
        match *self {
            Outgoing => Incoming,
            Incoming => Outgoing,
        }
    }
}

/// Marker type for a directed graph.
#[derive(Copy, Clone, Debug)]
pub struct Directed;

/// Marker type for an undirected graph.
#[derive(Copy, Clone, Debug)]
pub struct Undirected;

/// A graph's edge type determines whether is has directed edges or not.
pub trait EdgeType {
    fn is_directed() -> bool;
}

impl EdgeType for Directed {
    #[inline]
    fn is_directed() -> bool { true }
}

impl EdgeType for Undirected {
    #[inline]
    fn is_directed() -> bool { false }
}

/// A reference that is hashed and compared by its pointer value.
pub struct Ptr<'b, T: 'b>(pub &'b T);

impl<'b, T> Copy for Ptr<'b, T> {}
impl<'b, T> Clone for Ptr<'b, T>
{
    fn clone(&self) -> Self { *self }
}

fn ptr_eq<T>(a: *const T, b: *const T) -> bool {
    a == b
}

impl<'b, T> PartialEq for Ptr<'b, T>
{
    /// Ptr compares by pointer equality, i.e if they point to the same value
    fn eq(&self, other: &Ptr<'b, T>) -> bool {
        ptr_eq(self.0, other.0)
    }
}

impl<'b, T> PartialOrd for Ptr<'b, T>
{
    fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'b, T> Ord for Ptr<'b, T>
{
    /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
    fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
        let a = self.0 as *const _;
        let b = other.0 as *const _;
        a.cmp(&b)
    }
}

impl<'b, T> Deref for Ptr<'b, T> {
    type Target = T;
    fn deref<'a>(&'a self) -> &'a T {
        self.0
    }
}

impl<'b, T> Eq for Ptr<'b, T> {}

impl<'b, T> Hash for Ptr<'b, T>
{
    fn hash<H: hash::Hasher>(&self, st: &mut H)
    {
        let ptr = (self.0) as *const T;
        ptr.hash(st)
    }
}

impl<'b, T: fmt::Debug> fmt::Debug for Ptr<'b, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// Convert an element like `(i, j)` or `(i, j, w)` into
/// a triple of source, target, edge weight.
///
/// For `Graph::from_edges` and `GraphMap::from_edges`.
pub trait IntoWeightedEdge<Ix, E> {
    fn into_edge(self) -> (Ix, Ix, E);
}

impl<'a, Ix, E> IntoWeightedEdge<Ix, E> for &'a (Ix, Ix)
    where Ix: Copy, E: Default
{
    fn into_edge(self) -> (Ix, Ix, E) {
        let (s, t) = *self;
        (s, t, E::default())
    }
}

impl<'a, Ix, E> IntoWeightedEdge<Ix, E> for &'a (Ix, Ix, E)
    where Ix: Copy, E: Clone
{
    fn into_edge(self) -> (Ix, Ix, E) {
        self.clone()
    }
}

impl<'a, Ix, E> IntoWeightedEdge<Ix, E> for (Ix, Ix, &'a E)
    where Ix: Copy, E: Clone
{
    fn into_edge(self) -> (Ix, Ix, E) {
        let (a, b, c) = self;
        (a, b, c.clone())
    }
}

impl<Ix, E> IntoWeightedEdge<Ix, E> for (Ix, Ix)
    where E: Default
{
    fn into_edge(self) -> (Ix, Ix, E) {
        let (s, t) = self;
        (s, t, E::default())
    }
}

impl<Ix, E> IntoWeightedEdge<Ix, E> for (Ix, Ix, E)
{
    fn into_edge(self) -> (Ix, Ix, E) {
        self
    }
}
<|endoftext|>


<commit_before>#![doc(html_root_url = "https://docs.rs/rayon/1.0")]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]

//! Data-parallelism library that makes it easy to convert sequential
//! computations into parallel
//!
//! Rayon is lightweight and convenient for introducing parallelism into existing
//! code. It guarantees data-race free executions and takes advantage of
//! parallelism when sensible, based on work-load at runtime.
//!
//! # How to use Rayon
//!
//! There are two ways to use Rayon:
//!
//! - **High-level parallel constructs** are the simplest way to use Rayon and also
//!   typically the most efficient.
//!   - [Parallel iterators][iter module] make it easy to convert a sequential iterator to
//!     execute in parallel.
//!   - The [`par_sort`] method sorts `&mut [T]` slices (or vectors) in parallel.
//!   - [`par_extend`] can be used to efficiently grow collections with items produced
//!     by a parallel iterator.
//! - **Custom tasks** let you divide your work into parallel tasks yourself.
//!   - [`join`] is used to subdivide a task into two pieces.
//!   - [`scope`] creates a scope within which you can create any number of parallel tasks.
//!   - [`ThreadPoolBuilder`] can be used to create your own thread pools or customize
//!     the global one.
//!
//! [iter module]: iter/index.html
//! [`join`]: fn.join.html
//! [`scope`]: fn.scope.html
//! [`par_sort`]: slice/trait.ParallelSliceMut.html#method.par_sort
//! [`par_extend`]: iter/trait.ParallelExtend.html#tymethod.par_extend
//! [`ThreadPoolBuilder`]: struct.ThreadPoolBuilder.html
//!
//! # Basic usage and the Rayon prelude
//!
//! First, you will need to add `rayon` to your `Cargo.toml` and put
//! `extern crate rayon` in your main file (`lib.rs`, `main.rs`).
//!
//! Next, to use parallel iterators or the other high-level methods,
//! you need to import several traits. Those traits are bundled into
//! the module [`rayon::prelude`]. It is recommended that you import
//! all of these traits at once by adding `use rayon::prelude::*` at
//! the top of each module that uses Rayon methods.
//!
//! These traits give you access to the `par_iter` method which provides
//! parallel implementations of many iterative functions such as [`map`],
//! [`for_each`], [`filter`], [`fold`], and [more].
//!
//! [`rayon::prelude`]: prelude/index.html
//! [`map`]: iter/trait.ParallelIterator.html#method.map
//! [`for_each`]: iter/trait.ParallelIterator.html#method.for_each
//! [`filter`]: iter/trait.ParallelIterator.html#method.filter
//! [`fold`]: iter/trait.ParallelIterator.html#method.fold
//! [more]: iter/trait.ParallelIterator.html#provided-methods
//!
//! # Crate Layout
//!
//! Rayon extends many of the types found in the standard library with
//! parallel iterator implementations. The modules in the `rayon`
//! crate mirror [`std`] itself: so, e.g., the `option` module in
//! Rayon contains parallel iterators for the `Option` type, which is
//! found in [the `option` module of `std`]. Similarly, the
//! `collections` module in Rayon offers parallel iterator types for
//! [the `collections` from `std`]. You will rarely need to access
//! these submodules unless you need to name iterator types
//! explicitly.
//!
//! [the `option` module of `std`]: https://doc.rust-lang.org/std/option/index.html
//! [the `collections` from `std`]: https://doc.rust-lang.org/std/collections/index.html
//! [`std`]: https://doc.rust-lang.org/std/
//!
//! # Other questions?
//!
//! See [the Rayon FAQ][faq].
//!
//! [faq]: https://github.com/rayon-rs/rayon/blob/master/FAQ.md

extern crate crossbeam_deque;
extern crate either;
extern crate rayon_core;

#[cfg(test)]
extern crate rand;

#[macro_use]
mod delegate;

#[macro_use]
mod private;

mod split_producer;

pub mod collections;
pub mod iter;
pub mod option;
pub mod prelude;
pub mod range;
pub mod result;
pub mod slice;
pub mod str;
pub mod vec;

mod math;
mod par_either;

mod compile_fail;

pub use rayon_core::current_num_threads;
pub use rayon_core::spawn;
pub use rayon_core::FnContext;
pub use rayon_core::ThreadPool;
pub use rayon_core::ThreadPoolBuildError;
pub use rayon_core::ThreadPoolBuilder;
pub use rayon_core::{join, join_context};
pub use rayon_core::{scope, Scope};
<commit_msg>Re-export FIFO items in rayon<commit_after>#![doc(html_root_url = "https://docs.rs/rayon/1.0")]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]

//! Data-parallelism library that makes it easy to convert sequential
//! computations into parallel
//!
//! Rayon is lightweight and convenient for introducing parallelism into existing
//! code. It guarantees data-race free executions and takes advantage of
//! parallelism when sensible, based on work-load at runtime.
//!
//! # How to use Rayon
//!
//! There are two ways to use Rayon:
//!
//! - **High-level parallel constructs** are the simplest way to use Rayon and also
//!   typically the most efficient.
//!   - [Parallel iterators][iter module] make it easy to convert a sequential iterator to
//!     execute in parallel.
//!   - The [`par_sort`] method sorts `&mut [T]` slices (or vectors) in parallel.
//!   - [`par_extend`] can be used to efficiently grow collections with items produced
//!     by a parallel iterator.
//! - **Custom tasks** let you divide your work into parallel tasks yourself.
//!   - [`join`] is used to subdivide a task into two pieces.
//!   - [`scope`] creates a scope within which you can create any number of parallel tasks.
//!   - [`ThreadPoolBuilder`] can be used to create your own thread pools or customize
//!     the global one.
//!
//! [iter module]: iter/index.html
//! [`join`]: fn.join.html
//! [`scope`]: fn.scope.html
//! [`par_sort`]: slice/trait.ParallelSliceMut.html#method.par_sort
//! [`par_extend`]: iter/trait.ParallelExtend.html#tymethod.par_extend
//! [`ThreadPoolBuilder`]: struct.ThreadPoolBuilder.html
//!
//! # Basic usage and the Rayon prelude
//!
//! First, you will need to add `rayon` to your `Cargo.toml` and put
//! `extern crate rayon` in your main file (`lib.rs`, `main.rs`).
//!
//! Next, to use parallel iterators or the other high-level methods,
//! you need to import several traits. Those traits are bundled into
//! the module [`rayon::prelude`]. It is recommended that you import
//! all of these traits at once by adding `use rayon::prelude::*` at
//! the top of each module that uses Rayon methods.
//!
//! These traits give you access to the `par_iter` method which provides
//! parallel implementations of many iterative functions such as [`map`],
//! [`for_each`], [`filter`], [`fold`], and [more].
//!
//! [`rayon::prelude`]: prelude/index.html
//! [`map`]: iter/trait.ParallelIterator.html#method.map
//! [`for_each`]: iter/trait.ParallelIterator.html#method.for_each
//! [`filter`]: iter/trait.ParallelIterator.html#method.filter
//! [`fold`]: iter/trait.ParallelIterator.html#method.fold
//! [more]: iter/trait.ParallelIterator.html#provided-methods
//!
//! # Crate Layout
//!
//! Rayon extends many of the types found in the standard library with
//! parallel iterator implementations. The modules in the `rayon`
//! crate mirror [`std`] itself: so, e.g., the `option` module in
//! Rayon contains parallel iterators for the `Option` type, which is
//! found in [the `option` module of `std`]. Similarly, the
//! `collections` module in Rayon offers parallel iterator types for
//! [the `collections` from `std`]. You will rarely need to access
//! these submodules unless you need to name iterator types
//! explicitly.
//!
//! [the `option` module of `std`]: https://doc.rust-lang.org/std/option/index.html
//! [the `collections` from `std`]: https://doc.rust-lang.org/std/collections/index.html
//! [`std`]: https://doc.rust-lang.org/std/
//!
//! # Other questions?
//!
//! See [the Rayon FAQ][faq].
//!
//! [faq]: https://github.com/rayon-rs/rayon/blob/master/FAQ.md

extern crate crossbeam_deque;
extern crate either;
extern crate rayon_core;

#[cfg(test)]
extern crate rand;

#[macro_use]
mod delegate;

#[macro_use]
mod private;

mod split_producer;

pub mod collections;
pub mod iter;
pub mod option;
pub mod prelude;
pub mod range;
pub mod result;
pub mod slice;
pub mod str;
pub mod vec;

mod math;
mod par_either;

mod compile_fail;

pub use rayon_core::current_num_threads;
pub use rayon_core::FnContext;
pub use rayon_core::ThreadPool;
pub use rayon_core::ThreadPoolBuildError;
pub use rayon_core::ThreadPoolBuilder;
pub use rayon_core::{join, join_context};
pub use rayon_core::{scope, Scope};
pub use rayon_core::{scope_fifo, ScopeFifo};
pub use rayon_core::{spawn, spawn_fifo};
<|endoftext|>