<commit_before>extern crate flat_tree;

#[derive(Clone, Debug)]
pub struct Node {
    index: u64,
    parent: u64,
    hash: Vec<u8>,
    data: Option<Vec<u8>>,
    size: usize,
}

pub struct Generator {
    roots: Vec<Node>,
    blocks: u64,
    leaf: fn(&Node, &Vec<Node>) -> Vec<u8>,
    parent: fn(&Node, &Node) -> Vec<u8>,
}

impl Generator {
    pub fn new(leaf: fn(&Node, &Vec<Node>) -> Vec<u8>,
               parent: fn(&Node, &Node) -> Vec<u8>)
               -> Generator {
        Generator {
            roots: vec![],
            blocks: 0,
            leaf: leaf,
            parent: parent,
        }
    }

    pub fn next(&mut self, data: Vec<u8>) -> Vec<Node> {
        self.blocks += 1;
        let mut nodes = vec![];
        let index = 2 * self.blocks;
        let len = data.len();
        let mut leaf = Node {
            index: index,
            parent: flat_tree::parent(index),
            hash: vec![],
            data: Some(data),
            size: len,
        };
        let hash = (self.leaf)(&leaf, &self.roots);
        leaf.hash = hash;
        self.roots.push(leaf.clone());
        nodes.push(leaf.clone());

        while self.roots.len() > 1 {
            let ref left = self.roots[self.roots.len() - 2].clone();
            let ref right = self.roots[self.roots.len() - 1].clone();

            if left.parent != right.parent {
                break;
            }

            self.roots.pop();
            let leaf = Node {
                index: left.parent,
                parent: flat_tree::parent(left.parent),
                hash: (self.parent)(left, right),
                size: left.size + right.size,
                data: None,
            };
            let len = self.roots.len();
            self.roots[len - 1] = leaf.clone();
            nodes.push(leaf.clone());
        }

        nodes
    }
}

extern crate ring;

#[cfg(test)]
mod tests {
    use ring::digest;
    use super::{Generator, Node};

    #[test]
    fn it_works() {
        let mut gen = Generator::new(leaf, parent);
        let nodes = gen.next(b"Hello World".to_vec());
        println!("{:?}", nodes);
    }

    fn parent(a: &Node, b: &Node) -> Vec<u8> {
        let mut data = a.data.clone().unwrap();
        data.append(&mut b.data.clone().unwrap());

        digest::digest(&digest::SHA256, data.as_slice())
            .as_ref()
            .to_vec()
    }

    fn leaf(leaf: &Node, roots: &Vec<Node>) -> Vec<u8> {
        let data = leaf.data.clone().unwrap();
        digest::digest(&digest::SHA256, data.as_slice()).as_ref().to_vec()
    }
}
<commit_msg>fix test<commit_after>extern crate flat_tree;

#[derive(Clone, Debug)]
pub struct Node {
    index: u64,
    parent: u64,
    hash: Vec<u8>,
    data: Option<Vec<u8>>,
    size: usize,
}

pub struct Generator {
    roots: Vec<Node>,
    blocks: u64,
    leaf: fn(&Node, &Vec<Node>) -> Vec<u8>,
    parent: fn(&Node, &Node) -> Vec<u8>,
}

impl Generator {
    pub fn new(leaf: fn(&Node, &Vec<Node>) -> Vec<u8>,
               parent: fn(&Node, &Node) -> Vec<u8>)
               -> Generator {
        Generator {
            roots: vec![],
            blocks: 0,
            leaf: leaf,
            parent: parent,
        }
    }

    pub fn next(&mut self, data: Vec<u8>) -> Vec<Node> {
        let mut nodes = vec![];
        let index = 2 * self.blocks;
        self.blocks += 1;
        let len = data.len();
        let mut leaf = Node {
            index: index,
            parent: flat_tree::parent(index),
            hash: vec![],
            data: Some(data),
            size: len,
        };
        let hash = (self.leaf)(&leaf, &self.roots);
        leaf.hash = hash;
        self.roots.push(leaf.clone());
        nodes.push(leaf.clone());

        while self.roots.len() > 1 {
            let ref left = self.roots[self.roots.len() - 2].clone();
            let ref right = self.roots[self.roots.len() - 1].clone();

            if left.parent != right.parent {
                break;
            }

            self.roots.pop();
            let leaf = Node {
                index: left.parent,
                parent: flat_tree::parent(left.parent),
                hash: (self.parent)(left, right),
                size: left.size + right.size,
                data: None,
            };
            let len = self.roots.len();
            self.roots[len - 1] = leaf.clone();
            nodes.push(leaf.clone());
        }

        nodes
    }
}

extern crate ring;

#[cfg(test)]
mod tests {
    use ring::digest;
    use super::{Generator, Node};

    #[test]
    fn it_works() {
        let mut gen = Generator::new(leaf, parent);
        let nodes = gen.next(b"Hello World".to_vec());
        assert!(nodes[0].index == 0);
        assert!(nodes[0].parent == 1);
        let data = nodes[0].data.clone().unwrap();
        assert!(data == b"Hello World");
        let hash = digest::digest(&digest::SHA256, b"Hello World").as_ref().to_vec();
        assert!(nodes[0].hash == hash);
    }

    fn parent(a: &Node, b: &Node) -> Vec<u8> {
        let mut data = a.data.clone().unwrap();
        data.append(&mut b.data.clone().unwrap());

        digest::digest(&digest::SHA256, data.as_slice())
            .as_ref()
            .to_vec()
    }

    fn leaf(leaf: &Node, roots: &Vec<Node>) -> Vec<u8> {
        let data = leaf.data.clone().unwrap();
        digest::digest(&digest::SHA256, data.as_slice()).as_ref().to_vec()
    }
}
<|endoftext|>


<commit_before>extern crate rustcmb;

use rustcmb::spectra::{gasdev, gasdev_exp_k0, gasdev_max_k, gasdev_exp_and_sin, return_spectra};
use rustcmb::io::{write_2d, write_1d};
use rustcmb::fourier::fft_2d;

const SIZE: usize = 512;
const DATA_OUT: &str = "data/examples/out/spectra/";
const MAX_ARG: f64 = SIZE as f64 / 8.;
//const MAX_ARG: f64 = 15.;

fn main() {

    println!("MAX_ARG: {}\n", MAX_ARG);

    let mut field: Vec<Vec<f64>> = vec![vec![0.; SIZE + 1]; SIZE + 1];
    let mut a_mods: Vec<Vec<f64>> = vec![vec![0.; SIZE]; SIZE / 2 + 1];
    let mut b_mods: Vec<Vec<f64>> = vec![vec![0.; SIZE]; SIZE / 2 + 1];

    gasdev(&field, &mut a_mods, &mut b_mods, 0., 1.);
    //    write_2d(&a_mods, &DATA_OUT, &"a_mods.dat");
    //    write_2d(&b_mods, &DATA_OUT, &"b_mods.dat");
    fft_2d::torus::first_realization(&mut field, &a_mods, &b_mods);
    write_2d(&field, &DATA_OUT, &"gasdev_field.dat");

    gasdev_exp_k0(&field, &mut a_mods, &mut b_mods, 0., 1., MAX_ARG);
    //    write_2d(&a_mods, &DATA_OUT, &"exp_a_mods.dat");
    //    write_2d(&b_mods, &DATA_OUT, &"exp_b_mods.dat");
    fft_2d::torus::first_realization(&mut field, &a_mods, &b_mods);
    write_2d(&field, &DATA_OUT, &"gasdev_exp_k0_field.dat");

    gasdev_max_k(&field, &mut a_mods, &mut b_mods, 0., 1., MAX_ARG);
    //    write_2d(&a_mods, &DATA_OUT, &"max_k_a_mods.dat");
    //    write_2d(&b_mods, &DATA_OUT, &"max_k_b_mods.dat");
    fft_2d::torus::first_realization(&mut field, &a_mods, &b_mods);
    write_2d(&field, &DATA_OUT, &"gasdev_max_k_field.dat");

    gasdev_exp_and_sin(
        &field,
        &mut a_mods,
        &mut b_mods,
        0.,
        20.,
        0.,
        0.,
        1.,
        2.,
        6.,
    );
    //    write_2d(&a_mods, &DATA_OUT, &"exp_and_sin_a_mods.dat");
    //    write_2d(&b_mods, &DATA_OUT, &"exp_and_sin_b_mods.dat");
    fft_2d::torus::first_realization(&mut field, &a_mods, &b_mods);
    write_2d(&field, &DATA_OUT, &"gasdev_exp_and_sin_field.dat");

    let returned_spectra = return_spectra(&field, &a_mods, &b_mods, 100);
    write_1d(&returned_spectra, &DATA_OUT, &"returned_exp_k0_spectra.dat");
}
<commit_msg>Small fix<commit_after>extern crate rustcmb;

use rustcmb::spectra::{gasdev, gasdev_exp_k0, gasdev_max_k, gasdev_exp_and_sin, return_spectra};
use rustcmb::io::{write_2d, write_1d};
use rustcmb::fourier::fft_2d;

const SIZE: usize = 512;
const DATA_OUT: &str = "data/examples/out/spectra/";
const MAX_ARG: f64 = SIZE as f64 / 8.;
//const MAX_ARG: f64 = 15.;

fn main() {

    println!("MAX_ARG: {}\n", MAX_ARG);

    let mut field: Vec<Vec<f64>> = vec![vec![0.; SIZE + 1]; SIZE + 1];
    let mut a_mods: Vec<Vec<f64>> = vec![vec![0.; SIZE]; SIZE / 2 + 1];
    let mut b_mods: Vec<Vec<f64>> = vec![vec![0.; SIZE]; SIZE / 2 + 1];

    gasdev(&field, &mut a_mods, &mut b_mods, 0., 1.);
    //    write_2d(&a_mods, &DATA_OUT, &"a_mods.dat");
    //    write_2d(&b_mods, &DATA_OUT, &"b_mods.dat");
    fft_2d::torus::first_realization(&mut field, &a_mods, &b_mods);
    write_2d(&field, &DATA_OUT, &"gasdev_field.dat");

    gasdev_exp_k0(&field, &mut a_mods, &mut b_mods, 0., 1., MAX_ARG);
    //    write_2d(&a_mods, &DATA_OUT, &"exp_a_mods.dat");
    //    write_2d(&b_mods, &DATA_OUT, &"exp_b_mods.dat");
    fft_2d::torus::first_realization(&mut field, &a_mods, &b_mods);
    write_2d(&field, &DATA_OUT, &"gasdev_exp_k0_field.dat");

    gasdev_max_k(&field, &mut a_mods, &mut b_mods, 0., 1., MAX_ARG);
    //    write_2d(&a_mods, &DATA_OUT, &"max_k_a_mods.dat");
    //    write_2d(&b_mods, &DATA_OUT, &"max_k_b_mods.dat");
    fft_2d::torus::first_realization(&mut field, &a_mods, &b_mods);
    write_2d(&field, &DATA_OUT, &"gasdev_max_k_field.dat");

    gasdev_exp_and_sin(
        &field,
        &mut a_mods,
        &mut b_mods,
        0.,
        20.,
        0.,
        0.,
        1.,
        2.,
        6.,
    );
    //    write_2d(&a_mods, &DATA_OUT, &"exp_and_sin_a_mods.dat");
    //    write_2d(&b_mods, &DATA_OUT, &"exp_and_sin_b_mods.dat");
    fft_2d::torus::first_realization(&mut field, &a_mods, &b_mods);
    write_2d(&field, &DATA_OUT, &"gasdev_exp_and_sin_field.dat");

    let returned_spectra = return_spectra(&field, &a_mods, &b_mods, 100);
    write_1d(&returned_spectra[0], &DATA_OUT, &"returned_exp_k0_spectra.dat");
}
<|endoftext|>


<commit_before>pub mod grid;
pub mod engine;
pub mod repr;

mod examples;

pub mod traits {

    use std::collections::HashMap;
    use std::fmt::Debug;

    use repr::GridRepr;

    pub trait Cell: Default + Clone {
        fn step<'a, I>(&'a self, neighbors: I) -> Self
            where I: Iterator<Item=Option<&'a Self>>;
        fn repr(&self, meta: &mut HashMap<&str, &str>);
        fn from_repr(&mut self, meta: &HashMap<&str, &str>);
    }

    pub trait Nhood {
        type Coord: Coord;

        fn neighbors(&self, coord: &Self::Coord) -> Vec<Self::Coord>;
        fn neighbors_count(&self) -> usize;
    }

    pub trait Coord: Debug {
        fn from_2d(x: i32, y: i32) -> Self;

        fn x(&self) -> i32;
        fn y(&self) -> i32;
        fn z(&self) -> i32 { 0 }
    }

    pub trait Grid {
        type Coord: Coord;

        fn step(&mut self);
        fn repr(&self) -> &GridRepr<Self::Coord>;
        fn from_repr<'a: 'b, 'b, C: Coord>(&'a mut self, &GridRepr<'b, C>);
    }

    pub trait ReprConsumer {
        fn consume<C: Coord>(&mut self, repr: &GridRepr<C>);
    }

    pub trait Engine {
        fn run_times(&mut self, times: i64);
    }
}

<commit_msg>Removed useless trait bound and import.<commit_after>pub mod grid;
pub mod engine;
pub mod repr;

mod examples;

pub mod traits {

    use std::collections::HashMap;

    use repr::GridRepr;

    pub trait Cell: Default + Clone {
        fn step<'a, I>(&'a self, neighbors: I) -> Self
            where I: Iterator<Item=Option<&'a Self>>;
        fn repr(&self, meta: &mut HashMap<&str, &str>);
        fn from_repr(&mut self, meta: &HashMap<&str, &str>);
    }

    pub trait Nhood {
        type Coord: Coord;

        fn neighbors(&self, coord: &Self::Coord) -> Vec<Self::Coord>;
        fn neighbors_count(&self) -> usize;
    }

    pub trait Coord {
        fn from_2d(x: i32, y: i32) -> Self;

        fn x(&self) -> i32;
        fn y(&self) -> i32;
        fn z(&self) -> i32 { 0 }
    }

    pub trait Grid {
        type Coord: Coord;

        fn step(&mut self);
        fn repr(&self) -> &GridRepr<Self::Coord>;
        fn from_repr<'a: 'b, 'b, C: Coord>(&'a mut self, &GridRepr<'b, C>);
    }

    pub trait ReprConsumer {
        fn consume<C: Coord>(&mut self, repr: &GridRepr<C>);
    }

    pub trait Engine {
        fn run_times(&mut self, times: i64);
    }
}

<|endoftext|>


<commit_before>//! Lorem ipsum generator.
//!
//! This crate contains functions for generating pseudo-Latin lorem
//! ipsum placeholder text. The traditional lorem ipsum text start
//! like this:
//!
//! > Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
//! > eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
//! > enim ad minim veniam, quis nostrud exercitation ullamco laboris
//! > nisi ut aliquip ex ea commodo consequat. [...]
//!
//! This text is in the [`LOREM_IPSUM`] constant. Random text looking
//! like the above can be generated using the [`lipsum`] function.
//! This function allows you to generate as much text as desired and
//! each invocation will generate different text. This is done using a
//! [Markov chain] based on both the [`LOREM_IPSUM`] and
//! [`LIBER_PRIMUS`] texts. The latter constant holds the full text of
//! the first book of a work by Cicero, of which the lorem ipsum text
//! is a scrambled subset.
//!
//! The random looking text is generatd using a Markov chain of order
//! two, which simply means that the next word is based on the
//! previous two words in the input texts. The Markov chain can be
//! used with other input texts by creating an instance of
//! [`MarkovChain`] and calling its [`learn`] method.
//!
//! [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
//! [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
//! [`lipsum`]: fn.lipsum.html
//! [`MarkovChain`]: struct.MarkovChain.html
//! [`learn`]: struct.MarkovChain.html#method.learn
//! [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain

extern crate rand;

use std::cell::RefCell;
use std::collections::HashMap;
use rand::Rng;

/// A bigram is simply two consecutive words.
pub type Bigram<'a> = (&'a str, &'a str);

/// Simple order two Markov chain implementation.
///
/// The [Markov chain] is a chain of order two, which means that it
/// will use the previous two words (a bigram) when predicting the
/// next word. This is normally enough to generate random text that
/// looks somewhat plausible. The implementation is based on
/// [Generating arbitrary text with Markov chains in Rust][blog post].
///
/// [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain
/// [blog post]: https://blakewilliams.me/posts/generating-arbitrary-text-with-markov-chains-in-rust
pub struct MarkovChain<'a, R: Rng> {
    map: HashMap<Bigram<'a>, Vec<&'a str>>,
    keys: Vec<Bigram<'a>>,
    rng: R,
}

impl<'a> MarkovChain<'a, rand::ThreadRng> {
    /// Create a new Markov chain. It will use a default thread-local
    /// random number generator.
    pub fn new() -> MarkovChain<'a, rand::ThreadRng> {
        MarkovChain::new_with_rng(rand::thread_rng())
    }
}

impl<'a, R: Rng> MarkovChain<'a, R> {
    /// Create a new Markov chain that uses the given random number
    /// generator.
    pub fn new_with_rng(rng: R) -> MarkovChain<'a, R> {
        MarkovChain {
            map: HashMap::new(),
            keys: Vec::new(),
            rng: rng,
        }
    }

    /// Add new text to the Markov chain. This can be called several
    /// times to build up the chain.
    ///
    /// # Examples
    ///
    /// ```
    /// use lipsum::MarkovChain;
    ///
    /// let mut chain = MarkovChain::new();
    /// chain.learn("red green blue");
    /// assert_eq!(chain.words(("red", "green")), Some(&vec!["blue"]));
    ///
    /// chain.learn("red green yellow");
    /// assert_eq!(chain.words(("red", "green")), Some(&vec!["blue", "yellow"]));
    /// ```
    pub fn learn(&mut self, sentence: &'a str) {
        let words = sentence.split_whitespace().collect::<Vec<&str>>();
        for window in words.windows(3) {
            let (a, b, c) = (window[0], window[1], window[2]);
            self.map.entry((a, b)).or_insert_with(Vec::new).push(c);
        }
        // Sync the keys with the current map.
        self.keys = self.map.keys().cloned().collect();
        self.keys.sort();
    }

    /// Get the possible words following the given bigram, or `None`
    /// if the state is invalid.
    ///
    /// # Examples
    ///
    /// ```
    /// use lipsum::MarkovChain;
    ///
    /// let mut chain = MarkovChain::new();
    /// chain.learn("red green blue");
    /// assert_eq!(chain.words(("red", "green")), Some(&vec!["blue"]));
    /// assert_eq!(chain.words(("foo", "bar")), None);
    /// ```
    pub fn words(&self, state: Bigram<'a>) -> Option<&Vec<&str>> {
        self.map.get(&state)
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from a random point in the Markov chain.
    ///
    /// See [`generate_from`] if you want to control the starting
    /// point for the generated text.
    ///
    /// # Examples
    ///
    /// Generating the sounds of a grandfather clock:
    ///
    /// ```
    /// use lipsum::MarkovChain;
    ///
    /// let mut chain = MarkovChain::new();
    /// chain.learn("Tick, Tock, Tick, Tock, Ding! Tick, Tock, Ding! Ding!");
    /// println!("{}", chain.generate(15));
    /// ```
    ///
    /// The output looks like this:
    ///
    /// > Ding! Tick, Tock, Tick, Tock, Ding! Ding! Tock, Ding! Tick,
    /// > Tock, Tick, Tock, Tick, Tock
    ///
    /// [`generate_from`]: struct.MarkovChain.html#method.generate_from
    pub fn generate(&mut self, n: usize) -> String {
        join_words(self.iter().take(n))
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from the given bigram.
    ///
    /// Use [`generate`] if the starting point is not important.
    ///
    /// [`generate`]: struct.MarkovChain.html#method.generate
    pub fn generate_from(&mut self, n: usize, from: Bigram<'a>) -> String {
        join_words(self.iter_from(from).take(n))
    }

    /// Make a never-ending iterator over the words in the Markov
    /// chain. The iterator starts at a random point in the chain.
    pub fn iter(&mut self) -> Words {
        let state = if self.keys.is_empty() {
            ("", "")
        } else {
            *choose(&mut self.rng, &self.keys).unwrap()
        };
        Words {
            map: &self.map,
            rng: &mut self.rng,
            keys: &self.keys,
            state: state,
        }
    }

    /// Make a never-ending iterator over the words in the Markov
    /// chain. The iterator starts at the given bigram.
    pub fn iter_from(&mut self, from: Bigram<'a>) -> Words {
        Words {
            map: &self.map,
            rng: &mut self.rng,
            keys: &self.keys,
            state: from,
        }
    }
}

pub struct Words<'a> {
    map: &'a HashMap<Bigram<'a>, Vec<&'a str>>,
    rng: &'a mut rand::Rng,
    keys: &'a Vec<Bigram<'a>>,
    state: Bigram<'a>,
}

impl<'a> Iterator for Words<'a> {
    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        if self.map.is_empty() {
            return None;
        }

        let result = Some(self.state.0);

        while !self.map.contains_key(&self.state) {
            self.state = *choose(self.rng, self.keys).unwrap();
        }
        let next_words = &self.map[&self.state];
        let next = choose(self.rng, next_words).unwrap();
        self.state = (self.state.1, next);
        result
    }
}

/// Choose a random element from a slice.
///
/// Unlike `Rng::choose`, this function does not require the RNG to be
/// Sized and thus works on any random number generator.
fn choose<'a, T>(rng: &mut Rng, values: &'a [T]) -> Option<&'a T> {
    if values.is_empty() {
        None
    } else {
        let idx = (values.len() as f32 * rng.next_f32()) as usize;
        Some(&values[idx])
    }
}

fn join_words<'a, I: Iterator<Item = &'a str>>(mut words: I) -> String {
    match words.next() {
        None => String::new(),
        Some(word) => {
            let mut sentence = String::from(word);
            for word in words {
                sentence.push(' ');
                sentence.push_str(word);
            }
            sentence
        }
    }
}

/// The traditional lorem ipsum text as given in [Wikipedia]. Using
/// this text alone for a Markov chain of order two doesn't work very
/// well since each bigram (two consequtive words) is followed by just
/// one other word. In other words, the Markov chain will always
/// produce the same output and recreate the lorem ipsum text
/// precisely. However, combining it with the full text in
/// [`LIBER_PRIMUS`] works well.
///
/// [Wikipedia]: https://en.wikipedia.org/wiki/Lorem_ipsum
/// [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
pub const LOREM_IPSUM: &'static str = include_str!("lorem-ipsum.txt");

/// The first book in Cicero's work De finibus bonorum et malorum ("On
/// the ends of good and evil"). The lorem ipsum text in
/// [`LOREM_IPSUM`] is derived from part of this text.
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
pub const LIBER_PRIMUS: &'static str = include_str!("liber-primus.txt");

thread_local! {
    // Markov chain generating lorem ipsum text.
    static LOREM_IPSUM_CHAIN: RefCell<MarkovChain<'static, rand::ThreadRng>> = {
        let mut chain = MarkovChain::new();
        // The cost of learning increases as more and more text is
        // added, so we start with the smallest text.
        chain.learn(LOREM_IPSUM);
        chain.learn(LIBER_PRIMUS);
        RefCell::new(chain)
    }
}

/// Generate `n` words of lorem ipsum text. The output starts with
/// "Lorem ipsum" and continues with the standard lorem ipsum text
/// from [`LOREM_IPSUM`]. The text will become random if sufficiently
/// long output is requested.
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
pub fn lipsum(n: usize) -> String {
    LOREM_IPSUM_CHAIN.with(|cell| {
                               let mut chain = cell.borrow_mut();
                               chain.generate_from(n, ("Lorem", "ipsum"))
                           })
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn starts_with_lorem_ipsum() {
        assert_eq!(&lipsum(10)[..11], "Lorem ipsum");
    }

    #[test]
    fn generate_zero_words() {
        assert_eq!(lipsum(0).split_whitespace().count(), 0);
    }

    #[test]
    fn generate_one_word() {
        assert_eq!(lipsum(1).split_whitespace().count(), 1);
    }

    #[test]
    fn generate_two_words() {
        assert_eq!(lipsum(2).split_whitespace().count(), 2);
    }

    #[test]
    fn empty_chain() {
        let mut chain = MarkovChain::new();
        assert_eq!(chain.generate(10), "");
    }

    #[test]
    fn generate_from() {
        let mut chain = MarkovChain::new();
        chain.learn("red orange yellow green blue indigo violet");
        assert_eq!(chain.generate_from(5, ("orange", "yellow")),
                   "orange yellow green blue indigo");
    }

    #[test]
    fn generate_last_bigram() {
        // The bigram "yyy zzz" will not be present in the Markov
        // chain's map, and so we will not generate "xxx yyy zzz" as
        // one would expect. The chain moves from state "xxx yyy" to
        // "yyy zzz", but sees that as invalid state and resets itsel
        // back to "xxx yyy".
        let mut chain = MarkovChain::new();
        chain.learn("xxx yyy zzz");
        // We use assert! instead of assert_ne! to support early
        // versions of Rust.
        assert!(chain.generate_from(3, ("xxx", "yyy")) != "xxx yyy zzz");
    }

    #[test]
    fn generate_from_no_panic() {
        // No panic when asked to generate a chain from a starting
        // point that doesn't exist in the chain.
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz");
        chain.generate_from(3, ("xxx", "yyy"));
    }

    #[test]
    fn chain_map() {
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz quuz");
        let map = &chain.map;

        assert_eq!(map.len(), 2);
        assert_eq!(map[&("foo", "bar")], vec!["baz"]);
        assert_eq!(map[&("bar", "baz")], vec!["quuz"]);
    }

    #[test]
    fn new_with_rng() {
        extern crate rand;
        use rand::SeedableRng;

        let rng = rand::XorShiftRng::from_seed([1, 2, 3, 4]);
        let mut chain = MarkovChain::new_with_rng(rng);
        chain.learn("foo bar x y z");
        chain.learn("foo bar a b c");

        assert_eq!(chain.generate(15), "a b b x y b x y x y x y bar x y");
    }
}
<commit_msg>lipsum: add example<commit_after>//! Lorem ipsum generator.
//!
//! This crate contains functions for generating pseudo-Latin lorem
//! ipsum placeholder text. The traditional lorem ipsum text start
//! like this:
//!
//! > Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
//! > eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
//! > enim ad minim veniam, quis nostrud exercitation ullamco laboris
//! > nisi ut aliquip ex ea commodo consequat. [...]
//!
//! This text is in the [`LOREM_IPSUM`] constant. Random text looking
//! like the above can be generated using the [`lipsum`] function.
//! This function allows you to generate as much text as desired and
//! each invocation will generate different text. This is done using a
//! [Markov chain] based on both the [`LOREM_IPSUM`] and
//! [`LIBER_PRIMUS`] texts. The latter constant holds the full text of
//! the first book of a work by Cicero, of which the lorem ipsum text
//! is a scrambled subset.
//!
//! The random looking text is generatd using a Markov chain of order
//! two, which simply means that the next word is based on the
//! previous two words in the input texts. The Markov chain can be
//! used with other input texts by creating an instance of
//! [`MarkovChain`] and calling its [`learn`] method.
//!
//! [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
//! [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
//! [`lipsum`]: fn.lipsum.html
//! [`MarkovChain`]: struct.MarkovChain.html
//! [`learn`]: struct.MarkovChain.html#method.learn
//! [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain

extern crate rand;

use std::cell::RefCell;
use std::collections::HashMap;
use rand::Rng;

/// A bigram is simply two consecutive words.
pub type Bigram<'a> = (&'a str, &'a str);

/// Simple order two Markov chain implementation.
///
/// The [Markov chain] is a chain of order two, which means that it
/// will use the previous two words (a bigram) when predicting the
/// next word. This is normally enough to generate random text that
/// looks somewhat plausible. The implementation is based on
/// [Generating arbitrary text with Markov chains in Rust][blog post].
///
/// [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain
/// [blog post]: https://blakewilliams.me/posts/generating-arbitrary-text-with-markov-chains-in-rust
pub struct MarkovChain<'a, R: Rng> {
    map: HashMap<Bigram<'a>, Vec<&'a str>>,
    keys: Vec<Bigram<'a>>,
    rng: R,
}

impl<'a> MarkovChain<'a, rand::ThreadRng> {
    /// Create a new Markov chain. It will use a default thread-local
    /// random number generator.
    pub fn new() -> MarkovChain<'a, rand::ThreadRng> {
        MarkovChain::new_with_rng(rand::thread_rng())
    }
}

impl<'a, R: Rng> MarkovChain<'a, R> {
    /// Create a new Markov chain that uses the given random number
    /// generator.
    pub fn new_with_rng(rng: R) -> MarkovChain<'a, R> {
        MarkovChain {
            map: HashMap::new(),
            keys: Vec::new(),
            rng: rng,
        }
    }

    /// Add new text to the Markov chain. This can be called several
    /// times to build up the chain.
    ///
    /// # Examples
    ///
    /// ```
    /// use lipsum::MarkovChain;
    ///
    /// let mut chain = MarkovChain::new();
    /// chain.learn("red green blue");
    /// assert_eq!(chain.words(("red", "green")), Some(&vec!["blue"]));
    ///
    /// chain.learn("red green yellow");
    /// assert_eq!(chain.words(("red", "green")), Some(&vec!["blue", "yellow"]));
    /// ```
    pub fn learn(&mut self, sentence: &'a str) {
        let words = sentence.split_whitespace().collect::<Vec<&str>>();
        for window in words.windows(3) {
            let (a, b, c) = (window[0], window[1], window[2]);
            self.map.entry((a, b)).or_insert_with(Vec::new).push(c);
        }
        // Sync the keys with the current map.
        self.keys = self.map.keys().cloned().collect();
        self.keys.sort();
    }

    /// Get the possible words following the given bigram, or `None`
    /// if the state is invalid.
    ///
    /// # Examples
    ///
    /// ```
    /// use lipsum::MarkovChain;
    ///
    /// let mut chain = MarkovChain::new();
    /// chain.learn("red green blue");
    /// assert_eq!(chain.words(("red", "green")), Some(&vec!["blue"]));
    /// assert_eq!(chain.words(("foo", "bar")), None);
    /// ```
    pub fn words(&self, state: Bigram<'a>) -> Option<&Vec<&str>> {
        self.map.get(&state)
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from a random point in the Markov chain.
    ///
    /// See [`generate_from`] if you want to control the starting
    /// point for the generated text.
    ///
    /// # Examples
    ///
    /// Generating the sounds of a grandfather clock:
    ///
    /// ```
    /// use lipsum::MarkovChain;
    ///
    /// let mut chain = MarkovChain::new();
    /// chain.learn("Tick, Tock, Tick, Tock, Ding! Tick, Tock, Ding! Ding!");
    /// println!("{}", chain.generate(15));
    /// ```
    ///
    /// The output looks like this:
    ///
    /// > Ding! Tick, Tock, Tick, Tock, Ding! Ding! Tock, Ding! Tick,
    /// > Tock, Tick, Tock, Tick, Tock
    ///
    /// [`generate_from`]: struct.MarkovChain.html#method.generate_from
    pub fn generate(&mut self, n: usize) -> String {
        join_words(self.iter().take(n))
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from the given bigram.
    ///
    /// Use [`generate`] if the starting point is not important.
    ///
    /// [`generate`]: struct.MarkovChain.html#method.generate
    pub fn generate_from(&mut self, n: usize, from: Bigram<'a>) -> String {
        join_words(self.iter_from(from).take(n))
    }

    /// Make a never-ending iterator over the words in the Markov
    /// chain. The iterator starts at a random point in the chain.
    pub fn iter(&mut self) -> Words {
        let state = if self.keys.is_empty() {
            ("", "")
        } else {
            *choose(&mut self.rng, &self.keys).unwrap()
        };
        Words {
            map: &self.map,
            rng: &mut self.rng,
            keys: &self.keys,
            state: state,
        }
    }

    /// Make a never-ending iterator over the words in the Markov
    /// chain. The iterator starts at the given bigram.
    pub fn iter_from(&mut self, from: Bigram<'a>) -> Words {
        Words {
            map: &self.map,
            rng: &mut self.rng,
            keys: &self.keys,
            state: from,
        }
    }
}

pub struct Words<'a> {
    map: &'a HashMap<Bigram<'a>, Vec<&'a str>>,
    rng: &'a mut rand::Rng,
    keys: &'a Vec<Bigram<'a>>,
    state: Bigram<'a>,
}

impl<'a> Iterator for Words<'a> {
    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        if self.map.is_empty() {
            return None;
        }

        let result = Some(self.state.0);

        while !self.map.contains_key(&self.state) {
            self.state = *choose(self.rng, self.keys).unwrap();
        }
        let next_words = &self.map[&self.state];
        let next = choose(self.rng, next_words).unwrap();
        self.state = (self.state.1, next);
        result
    }
}

/// Choose a random element from a slice.
///
/// Unlike `Rng::choose`, this function does not require the RNG to be
/// Sized and thus works on any random number generator.
fn choose<'a, T>(rng: &mut Rng, values: &'a [T]) -> Option<&'a T> {
    if values.is_empty() {
        None
    } else {
        let idx = (values.len() as f32 * rng.next_f32()) as usize;
        Some(&values[idx])
    }
}

fn join_words<'a, I: Iterator<Item = &'a str>>(mut words: I) -> String {
    match words.next() {
        None => String::new(),
        Some(word) => {
            let mut sentence = String::from(word);
            for word in words {
                sentence.push(' ');
                sentence.push_str(word);
            }
            sentence
        }
    }
}

/// The traditional lorem ipsum text as given in [Wikipedia]. Using
/// this text alone for a Markov chain of order two doesn't work very
/// well since each bigram (two consequtive words) is followed by just
/// one other word. In other words, the Markov chain will always
/// produce the same output and recreate the lorem ipsum text
/// precisely. However, combining it with the full text in
/// [`LIBER_PRIMUS`] works well.
///
/// [Wikipedia]: https://en.wikipedia.org/wiki/Lorem_ipsum
/// [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
pub const LOREM_IPSUM: &'static str = include_str!("lorem-ipsum.txt");

/// The first book in Cicero's work De finibus bonorum et malorum ("On
/// the ends of good and evil"). The lorem ipsum text in
/// [`LOREM_IPSUM`] is derived from part of this text.
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
pub const LIBER_PRIMUS: &'static str = include_str!("liber-primus.txt");

thread_local! {
    // Markov chain generating lorem ipsum text.
    static LOREM_IPSUM_CHAIN: RefCell<MarkovChain<'static, rand::ThreadRng>> = {
        let mut chain = MarkovChain::new();
        // The cost of learning increases as more and more text is
        // added, so we start with the smallest text.
        chain.learn(LOREM_IPSUM);
        chain.learn(LIBER_PRIMUS);
        RefCell::new(chain)
    }
}

/// Generate `n` words of lorem ipsum text. The output starts with
/// "Lorem ipsum" and continues with the standard lorem ipsum text
/// from [`LOREM_IPSUM`]. The text will become random if sufficiently
/// long output is requested.
///
/// # Examples
///
/// ```
/// use lipsum::lipsum;
///
/// assert_eq!(lipsum(7), "Lorem ipsum dolor sit amet, consectetur adipiscing");
/// ```
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
pub fn lipsum(n: usize) -> String {
    LOREM_IPSUM_CHAIN.with(|cell| {
                               let mut chain = cell.borrow_mut();
                               chain.generate_from(n, ("Lorem", "ipsum"))
                           })
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn starts_with_lorem_ipsum() {
        assert_eq!(&lipsum(10)[..11], "Lorem ipsum");
    }

    #[test]
    fn generate_zero_words() {
        assert_eq!(lipsum(0).split_whitespace().count(), 0);
    }

    #[test]
    fn generate_one_word() {
        assert_eq!(lipsum(1).split_whitespace().count(), 1);
    }

    #[test]
    fn generate_two_words() {
        assert_eq!(lipsum(2).split_whitespace().count(), 2);
    }

    #[test]
    fn empty_chain() {
        let mut chain = MarkovChain::new();
        assert_eq!(chain.generate(10), "");
    }

    #[test]
    fn generate_from() {
        let mut chain = MarkovChain::new();
        chain.learn("red orange yellow green blue indigo violet");
        assert_eq!(chain.generate_from(5, ("orange", "yellow")),
                   "orange yellow green blue indigo");
    }

    #[test]
    fn generate_last_bigram() {
        // The bigram "yyy zzz" will not be present in the Markov
        // chain's map, and so we will not generate "xxx yyy zzz" as
        // one would expect. The chain moves from state "xxx yyy" to
        // "yyy zzz", but sees that as invalid state and resets itsel
        // back to "xxx yyy".
        let mut chain = MarkovChain::new();
        chain.learn("xxx yyy zzz");
        // We use assert! instead of assert_ne! to support early
        // versions of Rust.
        assert!(chain.generate_from(3, ("xxx", "yyy")) != "xxx yyy zzz");
    }

    #[test]
    fn generate_from_no_panic() {
        // No panic when asked to generate a chain from a starting
        // point that doesn't exist in the chain.
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz");
        chain.generate_from(3, ("xxx", "yyy"));
    }

    #[test]
    fn chain_map() {
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz quuz");
        let map = &chain.map;

        assert_eq!(map.len(), 2);
        assert_eq!(map[&("foo", "bar")], vec!["baz"]);
        assert_eq!(map[&("bar", "baz")], vec!["quuz"]);
    }

    #[test]
    fn new_with_rng() {
        extern crate rand;
        use rand::SeedableRng;

        let rng = rand::XorShiftRng::from_seed([1, 2, 3, 4]);
        let mut chain = MarkovChain::new_with_rng(rng);
        chain.learn("foo bar x y z");
        chain.learn("foo bar a b c");

        assert_eq!(chain.generate(15), "a b b x y b x y x y x y bar x y");
    }
}
<|endoftext|>


<commit_before>extern crate euclid;
extern crate image;
extern crate num;
extern crate rand;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate tempdir;
extern crate time;
extern crate vec_map;

mod alg_misc;
mod colors;
pub mod ease;
mod fov;
mod hex;
mod hex_fov;
mod legend_builder;
mod parser;
mod prefab;
mod rng;
mod search;
mod space;
mod system;
mod text;
mod timing;

pub use alg_misc::{clamp, lerp, noise, retry_gen, sorted_pair, Deciban, WeightedChoice,
                   compact_bits_by_2, spread_bits_by_2};
pub use colors::{color, scolor, to_linear, to_srgb, Rgba, SRgba, NAMED_COLORS};
pub use fov::{Fov, FovValue, PolarPoint};
pub use hex::{hex_disc, hex_neighbors, Dir12, Dir6, HexDisc, HexGeom, HexNeighbor};
pub use hex_fov::{AddFakeIsometricCorners, HexFov, HexFovIter, HexPolarPoint};
pub use legend_builder::LegendBuilder;
pub use prefab::{IntoPrefab, Prefab};
pub use rng::{EncodeRng, RandomPermutation, RngExt};
pub use search::{astar_path_with, Dijkstra, GridNode};
pub use space::{CellSpace, CellVector, Space, Transformation};
pub use system::{app_data_path, save_screenshot, TimeLogItem};
pub use text::{split_line, templatize};
pub use timing::{cycle_anim, single_anim, spike, AverageDuration, Ticker, TimePerFrame};
<commit_msg>More prefab publics<commit_after>extern crate euclid;
extern crate image;
extern crate num;
extern crate rand;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate tempdir;
extern crate time;
extern crate vec_map;

mod alg_misc;
mod colors;
pub mod ease;
mod fov;
mod hex;
mod hex_fov;
mod legend_builder;
mod parser;
mod prefab;
mod rng;
mod search;
mod space;
mod system;
mod text;
mod timing;

pub use alg_misc::{clamp, lerp, noise, retry_gen, sorted_pair, Deciban, WeightedChoice,
                   compact_bits_by_2, spread_bits_by_2};
pub use colors::{color, scolor, to_linear, to_srgb, Rgba, SRgba, NAMED_COLORS};
pub use fov::{Fov, FovValue, PolarPoint};
pub use hex::{hex_disc, hex_neighbors, Dir12, Dir6, HexDisc, HexGeom, HexNeighbor};
pub use hex_fov::{AddFakeIsometricCorners, HexFov, HexFovIter, HexPolarPoint};
pub use legend_builder::LegendBuilder;
pub use prefab::{IntoPrefab, Prefab, PrefabError, TextSpace, MinimapSpace};
pub use rng::{EncodeRng, RandomPermutation, RngExt};
pub use search::{astar_path_with, Dijkstra, GridNode};
pub use space::{CellSpace, CellVector, Space, Transformation};
pub use system::{app_data_path, save_screenshot, TimeLogItem};
pub use text::{split_line, templatize};
pub use timing::{cycle_anim, single_anim, spike, AverageDuration, Ticker, TimePerFrame};
<|endoftext|>


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

//! Shim which is passed to Cargo as "rustc" when running the bootstrap.
//!
//! This shim will take care of some various tasks that our build process
//! requires that Cargo can't quite do through normal configuration:
//!
//! 1. When compiling build scripts and build dependencies, we need a guaranteed
//!    full standard library available. The only compiler which actually has
//!    this is the snapshot, so we detect this situation and always compile with
//!    the snapshot compiler.
//! 2. We pass a bunch of `--cfg` and other flags based on what we're compiling
//!    (and this slightly differs based on a whether we're using a snapshot or
//!    not), so we do that all here.
//!
//! This may one day be replaced by RUSTFLAGS, but the dynamic nature of
//! switching compilers for the bootstrap and for build scripts will probably
//! never get replaced.

#![deny(warnings)]

extern crate bootstrap;

use std::env;
use std::ffi::OsString;
use std::io;
use std::io::prelude::*;
use std::str::FromStr;
use std::path::PathBuf;
use std::process::{Command, ExitStatus};

fn main() {
    let mut args = env::args_os().skip(1).collect::<Vec<_>>();

    // Append metadata suffix for internal crates. See the corresponding entry
    // in bootstrap/lib.rs for details.
    if let Ok(s) = env::var("RUSTC_METADATA_SUFFIX") {
        for i in 1..args.len() {
            // Dirty code for borrowing issues
            let mut new = None;
            if let Some(current_as_str) = args[i].to_str() {
                if (&*args[i - 1] == "-C" && current_as_str.starts_with("metadata")) ||
                   current_as_str.starts_with("-Cmetadata") {
                    new = Some(format!("{}-{}", current_as_str, s));
                }
            }
            if let Some(new) = new { args[i] = new.into(); }
        }
    }

    // Drop `--error-format json` because despite our desire for json messages
    // from Cargo we don't want any from rustc itself.
    if let Some(n) = args.iter().position(|n| n == "--error-format") {
        args.remove(n);
        args.remove(n);
    }

    // Detect whether or not we're a build script depending on whether --target
    // is passed (a bit janky...)
    let target = args.windows(2)
        .find(|w| &*w[0] == "--target")
        .and_then(|w| w[1].to_str());
    let version = args.iter().find(|w| &**w == "-vV");

    let verbose = match env::var("RUSTC_VERBOSE") {
        Ok(s) => usize::from_str(&s).expect("RUSTC_VERBOSE should be an integer"),
        Err(_) => 0,
    };

    // Build scripts always use the snapshot compiler which is guaranteed to be
    // able to produce an executable, whereas intermediate compilers may not
    // have the standard library built yet and may not be able to produce an
    // executable. Otherwise we just use the standard compiler we're
    // bootstrapping with.
    //
    // Also note that cargo will detect the version of the compiler to trigger
    // a rebuild when the compiler changes. If this happens, we want to make
    // sure to use the actual compiler instead of the snapshot compiler becase
    // that's the one that's actually changing.
    let (rustc, libdir) = if target.is_none() && version.is_none() {
        ("RUSTC_SNAPSHOT", "RUSTC_SNAPSHOT_LIBDIR")
    } else {
        ("RUSTC_REAL", "RUSTC_LIBDIR")
    };
    let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set");
    let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
    let mut on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of));

    let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc));
    let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir));
    let mut dylib_path = bootstrap::util::dylib_path();
    dylib_path.insert(0, PathBuf::from(libdir));

    let mut cmd = Command::new(rustc);
    cmd.args(&args)
        .arg("--cfg")
        .arg(format!("stage{}", stage))
        .env(bootstrap::util::dylib_path_var(),
             env::join_paths(&dylib_path).unwrap());

    if let Some(target) = target {
        // The stage0 compiler has a special sysroot distinct from what we
        // actually downloaded, so we just always pass the `--sysroot` option.
        cmd.arg("--sysroot").arg(sysroot);

        // When we build Rust dylibs they're all intended for intermediate
        // usage, so make sure we pass the -Cprefer-dynamic flag instead of
        // linking all deps statically into the dylib.
        if env::var_os("RUSTC_NO_PREFER_DYNAMIC").is_none() {
            cmd.arg("-Cprefer-dynamic");
        }

        // Pass the `rustbuild` feature flag to crates which rustbuild is
        // building. See the comment in bootstrap/lib.rs where this env var is
        // set for more details.
        if env::var_os("RUSTBUILD_UNSTABLE").is_some() {
            cmd.arg("--cfg").arg("rustbuild");
        }

        // Help the libc crate compile by assisting it in finding the MUSL
        // native libraries.
        if let Some(s) = env::var_os("MUSL_ROOT") {
            let mut root = OsString::from("native=");
            root.push(&s);
            root.push("/lib");
            cmd.arg("-L").arg(&root);
        }

        // Pass down extra flags, commonly used to configure `-Clinker` when
        // cross compiling.
        if let Ok(s) = env::var("RUSTC_FLAGS") {
            cmd.args(&s.split(" ").filter(|s| !s.is_empty()).collect::<Vec<_>>());
        }

        // Pass down incremental directory, if any.
        if let Ok(dir) = env::var("RUSTC_INCREMENTAL") {
            cmd.arg(format!("-Zincremental={}", dir));

            if verbose > 0 {
                cmd.arg("-Zincremental-info");
            }
        }

        // If we're compiling specifically the `panic_abort` crate then we pass
        // the `-C panic=abort` option. Note that we do not do this for any
        // other crate intentionally as this is the only crate for now that we
        // ship with panic=abort.
        //
        // This... is a bit of a hack how we detect this. Ideally this
        // information should be encoded in the crate I guess? Would likely
        // require an RFC amendment to RFC 1513, however.
        let is_panic_abort = args.windows(2)
            .any(|a| &*a[0] == "--crate-name" && &*a[1] == "panic_abort");
        if is_panic_abort {
            cmd.arg("-C").arg("panic=abort");
        }

        // Set various options from config.toml to configure how we're building
        // code.
        if env::var("RUSTC_DEBUGINFO") == Ok("true".to_string()) {
            cmd.arg("-g");
        } else if env::var("RUSTC_DEBUGINFO_LINES") == Ok("true".to_string()) {
            cmd.arg("-Cdebuginfo=1");
        }
        let debug_assertions = match env::var("RUSTC_DEBUG_ASSERTIONS") {
            Ok(s) => if s == "true" { "y" } else { "n" },
            Err(..) => "n",
        };
        cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions));
        if let Ok(s) = env::var("RUSTC_CODEGEN_UNITS") {
            cmd.arg("-C").arg(format!("codegen-units={}", s));
        }

        // Emit save-analysis info.
        if env::var("RUSTC_SAVE_ANALYSIS") == Ok("api".to_string()) {
            cmd.arg("-Zsave-analysis-api");
        }

        // Dealing with rpath here is a little special, so let's go into some
        // detail. First off, `-rpath` is a linker option on Unix platforms
        // which adds to the runtime dynamic loader path when looking for
        // dynamic libraries. We use this by default on Unix platforms to ensure
        // that our nightlies behave the same on Windows, that is they work out
        // of the box. This can be disabled, of course, but basically that's why
        // we're gated on RUSTC_RPATH here.
        //
        // Ok, so the astute might be wondering "why isn't `-C rpath` used
        // here?" and that is indeed a good question to task. This codegen
        // option is the compiler's current interface to generating an rpath.
        // Unfortunately it doesn't quite suffice for us. The flag currently
        // takes no value as an argument, so the compiler calculates what it
        // should pass to the linker as `-rpath`. This unfortunately is based on
        // the **compile time** directory structure which when building with
        // Cargo will be very different than the runtime directory structure.
        //
        // All that's a really long winded way of saying that if we use
        // `-Crpath` then the executables generated have the wrong rpath of
        // something like `$ORIGIN/deps` when in fact the way we distribute
        // rustc requires the rpath to be `$ORIGIN/../lib`.
        //
        // So, all in all, to set up the correct rpath we pass the linker
        // argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
        // fun to pass a flag to a tool to pass a flag to pass a flag to a tool
        // to change a flag in a binary?
        if env::var("RUSTC_RPATH") == Ok("true".to_string()) {
            let rpath = if target.contains("apple") {

                // Note that we need to take one extra step on macOS to also pass
                // `-Wl,-instal_name,@rpath/...` to get things to work right. To
                // do that we pass a weird flag to the compiler to get it to do
                // so. Note that this is definitely a hack, and we should likely
                // flesh out rpath support more fully in the future.
                //
                // FIXME: remove condition after next stage0
                if stage != "0" {
                    cmd.arg("-Z").arg("osx-rpath-install-name");
                }
                Some("-Wl,-rpath,@loader_path/../lib")
            } else if !target.contains("windows") {
                Some("-Wl,-rpath,$ORIGIN/../lib")
            } else {
                None
            };
            if let Some(rpath) = rpath {
                cmd.arg("-C").arg(format!("link-args={}", rpath));
            }

            if let Ok(s) = env::var("RUSTFLAGS") {
                for flag in s.split_whitespace() {
                    cmd.arg(flag);
                }
            }
        }

        if target.contains("pc-windows-msvc") {
            cmd.arg("-Z").arg("unstable-options");
            cmd.arg("-C").arg("target-feature=+crt-static");
        }

        // Force all crates compiled by this compiler to (a) be unstable and (b)
        // allow the `rustc_private` feature to link to other unstable crates
        // also in the sysroot.
        //
        // FIXME: remove condition after next stage0
        if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
            if stage != "0" {
                cmd.arg("-Z").arg("force-unstable-if-unmarked");
            }
        }
    }

    if verbose > 1 {
        writeln!(&mut io::stderr(), "rustc command: {:?}", cmd).unwrap();
    }

    // Actually run the compiler!
    std::process::exit(if let Some(ref mut on_fail) = on_fail {
        match cmd.status() {
            Ok(s) if s.success() => 0,
            _ => {
                println!("\nDid not run successfully:\n{:?}\n-------------", cmd);
                exec_cmd(on_fail).expect("could not run the backup command");
                1
            }
        }
    } else {
        std::process::exit(match exec_cmd(&mut cmd) {
            Ok(s) => s.code().unwrap_or(0xfe),
            Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e),
        })
    })
}

#[cfg(unix)]
fn exec_cmd(cmd: &mut Command) -> ::std::io::Result<ExitStatus> {
    use std::os::unix::process::CommandExt;
    Err(cmd.exec())
}

#[cfg(not(unix))]
fn exec_cmd(cmd: &mut Command) -> ::std::io::Result<ExitStatus> {
    cmd.status()
}
<commit_msg>Rollup merge of #42382 - alexcrichton:remove-rustflags, r=Mark-Simulacrum<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Shim which is passed to Cargo as "rustc" when running the bootstrap.
//!
//! This shim will take care of some various tasks that our build process
//! requires that Cargo can't quite do through normal configuration:
//!
//! 1. When compiling build scripts and build dependencies, we need a guaranteed
//!    full standard library available. The only compiler which actually has
//!    this is the snapshot, so we detect this situation and always compile with
//!    the snapshot compiler.
//! 2. We pass a bunch of `--cfg` and other flags based on what we're compiling
//!    (and this slightly differs based on a whether we're using a snapshot or
//!    not), so we do that all here.
//!
//! This may one day be replaced by RUSTFLAGS, but the dynamic nature of
//! switching compilers for the bootstrap and for build scripts will probably
//! never get replaced.

#![deny(warnings)]

extern crate bootstrap;

use std::env;
use std::ffi::OsString;
use std::io;
use std::io::prelude::*;
use std::str::FromStr;
use std::path::PathBuf;
use std::process::{Command, ExitStatus};

fn main() {
    let mut args = env::args_os().skip(1).collect::<Vec<_>>();

    // Append metadata suffix for internal crates. See the corresponding entry
    // in bootstrap/lib.rs for details.
    if let Ok(s) = env::var("RUSTC_METADATA_SUFFIX") {
        for i in 1..args.len() {
            // Dirty code for borrowing issues
            let mut new = None;
            if let Some(current_as_str) = args[i].to_str() {
                if (&*args[i - 1] == "-C" && current_as_str.starts_with("metadata")) ||
                   current_as_str.starts_with("-Cmetadata") {
                    new = Some(format!("{}-{}", current_as_str, s));
                }
            }
            if let Some(new) = new { args[i] = new.into(); }
        }
    }

    // Drop `--error-format json` because despite our desire for json messages
    // from Cargo we don't want any from rustc itself.
    if let Some(n) = args.iter().position(|n| n == "--error-format") {
        args.remove(n);
        args.remove(n);
    }

    // Detect whether or not we're a build script depending on whether --target
    // is passed (a bit janky...)
    let target = args.windows(2)
        .find(|w| &*w[0] == "--target")
        .and_then(|w| w[1].to_str());
    let version = args.iter().find(|w| &**w == "-vV");

    let verbose = match env::var("RUSTC_VERBOSE") {
        Ok(s) => usize::from_str(&s).expect("RUSTC_VERBOSE should be an integer"),
        Err(_) => 0,
    };

    // Build scripts always use the snapshot compiler which is guaranteed to be
    // able to produce an executable, whereas intermediate compilers may not
    // have the standard library built yet and may not be able to produce an
    // executable. Otherwise we just use the standard compiler we're
    // bootstrapping with.
    //
    // Also note that cargo will detect the version of the compiler to trigger
    // a rebuild when the compiler changes. If this happens, we want to make
    // sure to use the actual compiler instead of the snapshot compiler becase
    // that's the one that's actually changing.
    let (rustc, libdir) = if target.is_none() && version.is_none() {
        ("RUSTC_SNAPSHOT", "RUSTC_SNAPSHOT_LIBDIR")
    } else {
        ("RUSTC_REAL", "RUSTC_LIBDIR")
    };
    let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set");
    let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
    let mut on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of));

    let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc));
    let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir));
    let mut dylib_path = bootstrap::util::dylib_path();
    dylib_path.insert(0, PathBuf::from(libdir));

    let mut cmd = Command::new(rustc);
    cmd.args(&args)
        .arg("--cfg")
        .arg(format!("stage{}", stage))
        .env(bootstrap::util::dylib_path_var(),
             env::join_paths(&dylib_path).unwrap());

    if let Some(target) = target {
        // The stage0 compiler has a special sysroot distinct from what we
        // actually downloaded, so we just always pass the `--sysroot` option.
        cmd.arg("--sysroot").arg(sysroot);

        // When we build Rust dylibs they're all intended for intermediate
        // usage, so make sure we pass the -Cprefer-dynamic flag instead of
        // linking all deps statically into the dylib.
        if env::var_os("RUSTC_NO_PREFER_DYNAMIC").is_none() {
            cmd.arg("-Cprefer-dynamic");
        }

        // Pass the `rustbuild` feature flag to crates which rustbuild is
        // building. See the comment in bootstrap/lib.rs where this env var is
        // set for more details.
        if env::var_os("RUSTBUILD_UNSTABLE").is_some() {
            cmd.arg("--cfg").arg("rustbuild");
        }

        // Help the libc crate compile by assisting it in finding the MUSL
        // native libraries.
        if let Some(s) = env::var_os("MUSL_ROOT") {
            let mut root = OsString::from("native=");
            root.push(&s);
            root.push("/lib");
            cmd.arg("-L").arg(&root);
        }

        // Pass down extra flags, commonly used to configure `-Clinker` when
        // cross compiling.
        if let Ok(s) = env::var("RUSTC_FLAGS") {
            cmd.args(&s.split(" ").filter(|s| !s.is_empty()).collect::<Vec<_>>());
        }

        // Pass down incremental directory, if any.
        if let Ok(dir) = env::var("RUSTC_INCREMENTAL") {
            cmd.arg(format!("-Zincremental={}", dir));

            if verbose > 0 {
                cmd.arg("-Zincremental-info");
            }
        }

        // If we're compiling specifically the `panic_abort` crate then we pass
        // the `-C panic=abort` option. Note that we do not do this for any
        // other crate intentionally as this is the only crate for now that we
        // ship with panic=abort.
        //
        // This... is a bit of a hack how we detect this. Ideally this
        // information should be encoded in the crate I guess? Would likely
        // require an RFC amendment to RFC 1513, however.
        let is_panic_abort = args.windows(2)
            .any(|a| &*a[0] == "--crate-name" && &*a[1] == "panic_abort");
        if is_panic_abort {
            cmd.arg("-C").arg("panic=abort");
        }

        // Set various options from config.toml to configure how we're building
        // code.
        if env::var("RUSTC_DEBUGINFO") == Ok("true".to_string()) {
            cmd.arg("-g");
        } else if env::var("RUSTC_DEBUGINFO_LINES") == Ok("true".to_string()) {
            cmd.arg("-Cdebuginfo=1");
        }
        let debug_assertions = match env::var("RUSTC_DEBUG_ASSERTIONS") {
            Ok(s) => if s == "true" { "y" } else { "n" },
            Err(..) => "n",
        };
        cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions));
        if let Ok(s) = env::var("RUSTC_CODEGEN_UNITS") {
            cmd.arg("-C").arg(format!("codegen-units={}", s));
        }

        // Emit save-analysis info.
        if env::var("RUSTC_SAVE_ANALYSIS") == Ok("api".to_string()) {
            cmd.arg("-Zsave-analysis-api");
        }

        // Dealing with rpath here is a little special, so let's go into some
        // detail. First off, `-rpath` is a linker option on Unix platforms
        // which adds to the runtime dynamic loader path when looking for
        // dynamic libraries. We use this by default on Unix platforms to ensure
        // that our nightlies behave the same on Windows, that is they work out
        // of the box. This can be disabled, of course, but basically that's why
        // we're gated on RUSTC_RPATH here.
        //
        // Ok, so the astute might be wondering "why isn't `-C rpath` used
        // here?" and that is indeed a good question to task. This codegen
        // option is the compiler's current interface to generating an rpath.
        // Unfortunately it doesn't quite suffice for us. The flag currently
        // takes no value as an argument, so the compiler calculates what it
        // should pass to the linker as `-rpath`. This unfortunately is based on
        // the **compile time** directory structure which when building with
        // Cargo will be very different than the runtime directory structure.
        //
        // All that's a really long winded way of saying that if we use
        // `-Crpath` then the executables generated have the wrong rpath of
        // something like `$ORIGIN/deps` when in fact the way we distribute
        // rustc requires the rpath to be `$ORIGIN/../lib`.
        //
        // So, all in all, to set up the correct rpath we pass the linker
        // argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
        // fun to pass a flag to a tool to pass a flag to pass a flag to a tool
        // to change a flag in a binary?
        if env::var("RUSTC_RPATH") == Ok("true".to_string()) {
            let rpath = if target.contains("apple") {

                // Note that we need to take one extra step on macOS to also pass
                // `-Wl,-instal_name,@rpath/...` to get things to work right. To
                // do that we pass a weird flag to the compiler to get it to do
                // so. Note that this is definitely a hack, and we should likely
                // flesh out rpath support more fully in the future.
                //
                // FIXME: remove condition after next stage0
                if stage != "0" {
                    cmd.arg("-Z").arg("osx-rpath-install-name");
                }
                Some("-Wl,-rpath,@loader_path/../lib")
            } else if !target.contains("windows") {
                Some("-Wl,-rpath,$ORIGIN/../lib")
            } else {
                None
            };
            if let Some(rpath) = rpath {
                cmd.arg("-C").arg(format!("link-args={}", rpath));
            }
        }

        if target.contains("pc-windows-msvc") {
            cmd.arg("-Z").arg("unstable-options");
            cmd.arg("-C").arg("target-feature=+crt-static");
        }

        // Force all crates compiled by this compiler to (a) be unstable and (b)
        // allow the `rustc_private` feature to link to other unstable crates
        // also in the sysroot.
        //
        // FIXME: remove condition after next stage0
        if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
            if stage != "0" {
                cmd.arg("-Z").arg("force-unstable-if-unmarked");
            }
        }
    }

    if verbose > 1 {
        writeln!(&mut io::stderr(), "rustc command: {:?}", cmd).unwrap();
    }

    // Actually run the compiler!
    std::process::exit(if let Some(ref mut on_fail) = on_fail {
        match cmd.status() {
            Ok(s) if s.success() => 0,
            _ => {
                println!("\nDid not run successfully:\n{:?}\n-------------", cmd);
                exec_cmd(on_fail).expect("could not run the backup command");
                1
            }
        }
    } else {
        std::process::exit(match exec_cmd(&mut cmd) {
            Ok(s) => s.code().unwrap_or(0xfe),
            Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e),
        })
    })
}

#[cfg(unix)]
fn exec_cmd(cmd: &mut Command) -> ::std::io::Result<ExitStatus> {
    use std::os::unix::process::CommandExt;
    Err(cmd.exec())
}

#[cfg(not(unix))]
fn exec_cmd(cmd: &mut Command) -> ::std::io::Result<ExitStatus> {
    cmd.status()
}
<|endoftext|>


<commit_before>#![cfg(any(target_arch="x86", target_arch="x86_64"))]

#![no_std]
#![crate_name="cpu"]
#![crate_type="rlib"]
#![feature(no_std)]
#![feature(asm)]
#![feature(associated_consts)]
#![feature(core)]

#[macro_use]
extern crate core;
#[macro_use]
extern crate bitflags;

pub use cpu::*;

#[cfg(target_arch="x86")]
#[path = "x86.rs"]
mod cpu;
#[cfg(target_arch="x86_64")]
#[path = "x86_64.rs"]
mod cpu;

pub mod std { pub use core::*; }
<commit_msg>Rust update<commit_after>#![cfg(any(target_arch="x86", target_arch="x86_64"))]

#![no_std]
#![crate_name="cpu"]
#![crate_type="rlib"]
#![feature(no_std)]
#![feature(asm)]
#![feature(associated_consts)]
#![feature(core, core_prelude, core_slice_ext)]

#[macro_use]
extern crate core;
#[macro_use]
extern crate bitflags;

pub use cpu::*;

#[cfg(target_arch="x86")]
#[path = "x86.rs"]
mod cpu;
#[cfg(target_arch="x86_64")]
#[path = "x86_64.rs"]
mod cpu;

pub mod std { pub use core::*; }
<|endoftext|>


<commit_before>//! # FFI bindings to **libpmem**
//!
//! Rust bindings for the NVM Library [http://pmem.io](http://pmem.io)
//!
//! The **pmem** library provides low level persistent memory support.
//! The libraries above are implemented using **pmem**.
//! Developers wishing to roll their own persistent memory algorithms will find this library useful,
//! but most developers will likely use **pmem-obj** and let that library call **pmem** for them.
//!
//! > This is **not** an official port of the NVM Library.
//! >
//! > The official **libpmem** documentation can be found at: [http://pmem.io/nvml/libpmem/](http://pmem.io/nvml/libpmem/)

#[macro_use]
extern crate bitflags;
extern crate pmem_sys;
extern crate libc;

// Modules

pub mod persistentmap;
pub mod ptr;
pub mod nodrain;

// lib module

use ::std::mem;
use ::std::io;
use ::std::ffi::CStr;

use ::libc::c_void;
use ::libc::size_t;
use ::pmem_sys as ffi;

/// Description of the last error
///
/// The error message is thread-local; errors encountered in one thread do not affect its value in other threads.
/// Its content is significant only when the return value of the immediately preceding
/// call to a function indicated an error.
pub fn errormsg() -> Option<String> {
    unsafe {
        let reason_p = ffi::pmem_errormsg();
        if !reason_p.is_null() {
            CStr::from_ptr(reason_p).to_owned().into_string().ok()
        } else {
            None
        }
    }
}

/// Checks if an entire object consists of persistent memory
/// If `true` then it is safe to use `persist(1)` and other related functions to make changes durable for that memory range.
///
/// The implementation of `is_pmem(1)` requires a non-trivial amount of work to determine if the given range is
/// entirely persistent memory. For this reason, it is better to call `is_pmem(1)` once when a range of memory is first encountered,
/// save the result, and use the saved result to determine whether `persist()` or `msync(1)` is appropriate for flushing changes to persistence.
/// Calling `is_pmem(1)` each time changes are flushed to persistence will not perform well.
///
/// > **Warning:** Using `persist(1)` on a range where `is_pmem(1)` returns `false` may not do anything useful -- use `msync(1)` instead.
pub fn is_pmem<T>(x: &T) -> bool {
    let len = mem::size_of_val(x);
    let r = unsafe { ffi::pmem_is_pmem(x as *const _ as *const c_void, len as size_t) };
    r > 0
}

/// Force an object to be stored durably in persistent memory.
///
/// This is equivalent to calling `msync(1)` but may be more optimal
/// and will avoid calling into the kernel if possible.
/// There are no alignment restrictions on the range the object is in,
/// but `persist(1)` may expand the range as necessary to meet platform alignment requirements.
///
/// > **Warning:** Like `msync()`, there is nothing atomic or transactional about this call.
/// > Any unwritten stores in the given range will be written, but some stores may have already been written
/// > by virtue of normal cache eviction/replacement policies. Correctly written code must not depend on stores
/// > waiting until `persist(1)` is called to become persistent -- they can become persistent at
/// > any time before `persist(1)` is called.
///
/// To create your own variations of `persist(1)`, see `flush(1)` and `drain()`. One can think of `persist(1)` as:
///
/// ```
/// def persist<T>(x: &T) {
///     // flush the processor caches
///     pmem::flush(x);
///
///     // wait for any pmem stores to drain from HW buffers
///     pmem::drain();
/// }
/// ```
pub fn persist<T>(x: &T) {
    let len = mem::size_of_val(x);
    unsafe { ffi::pmem_persist(x as *const _ as *const c_void, len as size_t) };
}

/// Forces any changes in an object to be stored durably.
///
/// This function works on either persistent memory or a memory mapped file on traditional storage.
/// `msync()` takes steps to ensure the alignment of addresses and lengths passed down meet the requirements of that system call.
/// It calls msync() with the MS_SYNC flag as described in msync(2).
/// Typically the application only checks for the existence of persistent memory once,
/// and then uses that result throughout the program, for example:
///
/// # Example
///
/// ```
/// // do this call once, after the pmem is memory mapped
/// let is_pmem = pmem::is_pmem(&x);
///
/// // ...make some changes to x
///
/// // make the changes durable
/// if is_pmem {
///     pmem::persist(&x);
/// } else{
///     pmem::msync(&x).unwrap();
/// }
/// ```
pub fn msync<T>(x: &T) -> Result<(), io::Error> {
    let len = mem::size_of_val(x);
    let r = unsafe { ffi::pmem_msync(x as *const _ as *const c_void, len as size_t) };
    if r == -1 {
        Err(io::Error::last_os_error())
    } else {
        Ok(())
    }
}

/// Flushes the processor caches
///
/// This is the first of two steps in flushing to persistence,
/// the second stpe is `drain()`.
///
/// These steps are performed together when `persist()` is called.
///
/// > Note that either of these steps may be unnecessary on a given platform, and
/// > the library knows how to check for that and do the right thing.
/// > For example, on Intel platforms, pmem_drain() is an empty function.
pub fn flush<T>(x: &T) {
    let len = mem::size_of_val(x);
    unsafe { ffi::pmem_flush(x as *const _ as *const c_void, len as size_t) };
}

/// Waits for any pmem stores to drain from HW buffers
///
/// This is the second of two steps in flushing to persistence,
/// the first step is `flush(1)`.
///
/// These steps are performed together when `persist(1)` is called.
///
/// > Note that either of these steps may be unnecessary on a given platform, and
/// > the library knows how to check for that and do the right thing.
/// > For example, on Intel platforms, pmem_drain() is an empty function.
pub fn drain() { unsafe { ffi::pmem_drain() }; }

/// Wether or not the machine supports an explicit hardware drain instruction for persistent memory.
///
/// On Intel processors with persistent memory, stores to persistent memory are considered persistent
/// once they are flushed from the CPU caches, so this function always returns false.
///
/// Despite that, programs using `flush(1)` to flush ranges of memory should still follow up by calling `drain()`
// once to ensure the flushes are complete. As mentioned above, `persist(1)` handles calling both `flush(1)` and `drain()`.
pub fn has_hw_drain() -> bool {
    let r = unsafe { ffi::pmem_has_hw_drain() };
    r > 0
}
<commit_msg>misc: fix documentation tests<commit_after>//! # FFI bindings to **libpmem**
//!
//! Rust bindings for the NVM Library [http://pmem.io](http://pmem.io)
//!
//! The **pmem** library provides low level persistent memory support.
//! The libraries above are implemented using **pmem**.
//! Developers wishing to roll their own persistent memory algorithms will find this library useful,
//! but most developers will likely use **pmem-obj** and let that library call **pmem** for them.
//!
//! > This is **not** an official port of the NVM Library.
//! >
//! > The official **libpmem** documentation can be found at: [http://pmem.io/nvml/libpmem/](http://pmem.io/nvml/libpmem/)

#[macro_use]
extern crate bitflags;
extern crate pmem_sys;
extern crate libc;

// Modules

pub mod persistentmap;
pub mod ptr;
pub mod nodrain;

// lib module

use ::std::mem;
use ::std::io;
use ::std::ffi::CStr;

use ::libc::c_void;
use ::libc::size_t;
use ::pmem_sys as ffi;

/// Description of the last error
///
/// The error message is thread-local; errors encountered in one thread do not affect its value in other threads.
/// Its content is significant only when the return value of the immediately preceding
/// call to a function indicated an error.
pub fn errormsg() -> Option<String> {
    unsafe {
        let reason_p = ffi::pmem_errormsg();
        if !reason_p.is_null() {
            CStr::from_ptr(reason_p).to_owned().into_string().ok()
        } else {
            None
        }
    }
}

/// Checks if an entire object consists of persistent memory
/// If `true` then it is safe to use `persist(1)` and other related functions to make changes durable for that memory range.
///
/// The implementation of `is_pmem(1)` requires a non-trivial amount of work to determine if the given range is
/// entirely persistent memory. For this reason, it is better to call `is_pmem(1)` once when a range of memory is first encountered,
/// save the result, and use the saved result to determine whether `persist()` or `msync(1)` is appropriate for flushing changes to persistence.
/// Calling `is_pmem(1)` each time changes are flushed to persistence will not perform well.
///
/// > **Warning:** Using `persist(1)` on a range where `is_pmem(1)` returns `false` may not do anything useful -- use `msync(1)` instead.
pub fn is_pmem<T>(x: &T) -> bool {
    let len = mem::size_of_val(x);
    let r = unsafe { ffi::pmem_is_pmem(x as *const _ as *const c_void, len as size_t) };
    r > 0
}

/// Force an object to be stored durably in persistent memory.
///
/// This is equivalent to calling `msync(1)` but may be more optimal
/// and will avoid calling into the kernel if possible.
/// There are no alignment restrictions on the range the object is in,
/// but `persist(1)` may expand the range as necessary to meet platform alignment requirements.
///
/// > **Warning:** Like `msync()`, there is nothing atomic or transactional about this call.
/// > Any unwritten stores in the given range will be written, but some stores may have already been written
/// > by virtue of normal cache eviction/replacement policies. Correctly written code must not depend on stores
/// > waiting until `persist(1)` is called to become persistent -- they can become persistent at
/// > any time before `persist(1)` is called.
///
/// To create your own variations of `persist(1)`, see `flush(1)` and `drain()`. One can think of `persist(1)` as:
///
/// ```no_run
/// fn persist<T>(x: &T) {
///     // flush the processor caches
///     pmem::flush(x);
///
///     // wait for any pmem stores to drain from HW buffers
///     pmem::drain();
/// }
/// ```
pub fn persist<T>(x: &T) {
    let len = mem::size_of_val(x);
    unsafe { ffi::pmem_persist(x as *const _ as *const c_void, len as size_t) };
}

/// Forces any changes in an object to be stored durably.
///
/// This function works on either persistent memory or a memory mapped file on traditional storage.
/// `msync()` takes steps to ensure the alignment of addresses and lengths passed down meet the requirements of that system call.
/// It calls msync() with the MS_SYNC flag as described in msync(2).
/// Typically the application only checks for the existence of persistent memory once,
/// and then uses that result throughout the program, for example:
///
/// # Example
///
/// ```no_run
/// fn some_method<T>(x: &T) {
///     // do this call once, after the pmem is memory mapped
///     let is_pmem = pmem::is_pmem(x);
///
///     // ...make some changes to x
///
///     // make the changes durable
///     if is_pmem {
///         pmem::persist(&x);
///     } else{
///         pmem::msync(&x).unwrap();
///     }
/// }
/// ```
pub fn msync<T>(x: &T) -> Result<(), io::Error> {
    let len = mem::size_of_val(x);
    let r = unsafe { ffi::pmem_msync(x as *const _ as *const c_void, len as size_t) };
    if r == -1 {
        Err(io::Error::last_os_error())
    } else {
        Ok(())
    }
}

/// Flushes the processor caches
///
/// This is the first of two steps in flushing to persistence,
/// the second stpe is `drain()`.
///
/// These steps are performed together when `persist()` is called.
///
/// > Note that either of these steps may be unnecessary on a given platform, and
/// > the library knows how to check for that and do the right thing.
/// > For example, on Intel platforms, pmem_drain() is an empty function.
pub fn flush<T>(x: &T) {
    let len = mem::size_of_val(x);
    unsafe { ffi::pmem_flush(x as *const _ as *const c_void, len as size_t) };
}

/// Waits for any pmem stores to drain from HW buffers
///
/// This is the second of two steps in flushing to persistence,
/// the first step is `flush(1)`.
///
/// These steps are performed together when `persist(1)` is called.
///
/// > Note that either of these steps may be unnecessary on a given platform, and
/// > the library knows how to check for that and do the right thing.
/// > For example, on Intel platforms, pmem_drain() is an empty function.
pub fn drain() { unsafe { ffi::pmem_drain() }; }

/// Wether or not the machine supports an explicit hardware drain instruction for persistent memory.
///
/// On Intel processors with persistent memory, stores to persistent memory are considered persistent
/// once they are flushed from the CPU caches, so this function always returns false.
///
/// Despite that, programs using `flush(1)` to flush ranges of memory should still follow up by calling `drain()`
// once to ensure the flushes are complete. As mentioned above, `persist(1)` handles calling both `flush(1)` and `drain()`.
pub fn has_hw_drain() -> bool {
    let r = unsafe { ffi::pmem_has_hw_drain() };
    r > 0
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![feature(old_io)]
#![plugin(regex_macros)]

extern crate hyper;
extern crate regex;

pub mod upnp;
<commit_msg>Add feature core.<commit_after>#![feature(plugin)]
#![feature(old_io)]
#![feature(core)]
#![plugin(regex_macros)]

extern crate hyper;
extern crate regex;

pub mod upnp;
<|endoftext|>


<commit_before>#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![cfg_attr(test, deny(warnings))]
#![doc(html_root_url = "https://docs.rs/reqwest/0.10.0-alpha.1")]

//! # reqwest
//!
//! The `reqwest` crate provides a convenient, higher-level HTTP
//! [`Client`][client].
//!
//! It handles many of the things that most people just expect an HTTP client
//! to do for them.
//!
//! - Async and [blocking](blocking) Clients
//! - Plain bodies, [JSON](#json), [urlencoded](#forms), [multipart](multipart)
//! - Customizable [redirect policy](#redirect-policy)
//! - HTTP [Proxies](#proxies)
//! - Uses system-native [TLS](#tls)
//! - Cookies
//!
//! The [`reqwest::Client`][client] is asynchronous. For applications wishing
//! to only make a few HTTP requests, the [`reqwest::blocking`](blocking) API
//! may be more convenient.
//!
//! Additional learning resources include:
//!
//! - [The Rust Cookbook](https://rust-lang-nursery.github.io/rust-cookbook/web/clients.html)
//! - [Reqwest Repository Examples](https://github.com/seanmonstar/reqwest/tree/master/examples)
//!
//! ## Making a GET request
//!
//! For a single request, you can use the [`get`][get] shortcut method.
//!
//! ```rust
//! # async fn run() -> Result<(), reqwest::Error> {
//! let body = reqwest::get("https://www.rust-lang.org")
//!     .await?
//!     .text()
//!     .await?;
//!
//! println!("body = {:?}", body);
//! # Ok(())
//! # }
//! ```
//!
//! **NOTE**: If you plan to perform multiple requests, it is best to create a
//! [`Client`][client] and reuse it, taking advantage of keep-alive connection
//! pooling.
//!
//! ## Making POST requests (or setting request bodies)
//!
//! There are several ways you can set the body of a request. The basic one is
//! by using the `body()` method of a [`RequestBuilder`][builder]. This lets you set the
//! exact raw bytes of what the body should be. It accepts various types,
//! including `String`, `Vec<u8>`, and `File`. If you wish to pass a custom
//! type, you can use the `reqwest::Body` constructors.
//!
//! ```rust
//! # use reqwest::Error;
//! #
//! # async fn run() -> Result<(), Error> {
//! let client = reqwest::Client::new();
//! let res = client.post("http://httpbin.org/post")
//!     .body("the exact body that is sent")
//!     .send()
//!     .await?;
//! # Ok(())
//! # }
//! ```
//!
//! ### Forms
//!
//! It's very common to want to send form data in a request body. This can be
//! done with any type that can be serialized into form data.
//!
//! This can be an array of tuples, or a `HashMap`, or a custom type that
//! implements [`Serialize`][serde].
//!
//! ```rust
//! # use reqwest::Error;
//! #
//! # async fn run() -> Result<(), Error> {
//! // This will POST a body of `foo=bar&baz=quux`
//! let params = [("foo", "bar"), ("baz", "quux")];
//! let client = reqwest::Client::new();
//! let res = client.post("http://httpbin.org/post")
//!     .form(&params)
//!     .send()
//!     .await?;
//! # Ok(())
//! # }
//! ```
//!
//! ### JSON
//!
//! There is also a `json` method helper on the [`RequestBuilder`][builder] that works in
//! a similar fashion the `form` method. It can take any value that can be
//! serialized into JSON. The feature `json` is required.
//!
//! ```rust
//! # use reqwest::Error;
//! # use std::collections::HashMap;
//! #
//! # #[cfg(feature = "json")]
//! # async fn run() -> Result<(), Error> {
//! // This will POST a body of `{"lang":"rust","body":"json"}`
//! let mut map = HashMap::new();
//! map.insert("lang", "rust");
//! map.insert("body", "json");
//!
//! let client = reqwest::Client::new();
//! let res = client.post("http://httpbin.org/post")
//!     .json(&map)
//!     .send()
//!     .await?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Redirect Policies
//!
//! By default, a `Client` will automatically handle HTTP redirects, detecting
//! loops, and having a maximum redirect chain of 10 hops. To customize this
//! behavior, a [`RedirectPolicy`][redirect] can used with a `ClientBuilder`.
//!
//! ## Cookies
//!
//! The automatic storing and sending of session cookies can be enabled with
//! the [`cookie_store`][ClientBuilder::cookie_store] method on `ClientBuilder`.
//!
//! ## Proxies
//!
//! A `Client` can be configured to make use of HTTP proxies by adding
//! [`Proxy`](Proxy)s to a `ClientBuilder`.
//!
//! ** NOTE** System proxies will be used in the next breaking change.
//!
//! ## TLS
//!
//! By default, a `Client` will make use of system-native transport layer
//! security to connect to HTTPS destinations. This means schannel on Windows,
//! Security-Framework on macOS, and OpenSSL on Linux.
//!
//! - Additional X509 certificates can be configured on a `ClientBuilder` with the
//!   [`Certificate`](Certificate) type.
//! - Client certificates can be add to a `ClientBuilder` with the
//!   [`Identity`][Identity] type.
//! - Various parts of TLS can also be configured or even disabled on the
//!   `ClientBuilder`.
//!
//! ## Optional Features
//!
//! The following are a list of [Cargo features][cargo-features] that can be
//! enabled or disabled:
//!
//! - **default-tls** *(enabled by default)*: Provides TLS support via the
//!   `native-tls` library to connect over HTTPS.
//! - **default-tls-vendored**: Enables the `vendored` feature of `native-tls`.
//! - **blocking**: Provides the [blocking][] client API.
//! - **cookies**: Provides cookie session support.
//! - **gzip**: Provides response body gzip decompression.
//! - **json**: Provides serialization and deserialization for JSON bodies.
//! - **unstable-stream** *(unstable)*: Adds support for `futures::Stream`.
//!
//!
//! [hyper]: http://hyper.rs
//! [client]: ./struct.Client.html
//! [response]: ./struct.Response.html
//! [get]: ./fn.get.html
//! [builder]: ./struct.RequestBuilder.html
//! [serde]: http://serde.rs
//! [redirect]: ./struct.RedirectPolicy.html
//! [Proxy]: ./struct.Proxy.html
//! [cargo-features]: https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section

////! - **rustls-tls**: Provides TLS support via the `rustls` library.
////! - **socks**: Provides SOCKS5 proxy support.
////! - **trust-dns**: Enables a trust-dns async resolver instead of default
////!   threadpool using `getaddrinfo`.

macro_rules! if_wasm {
    ($($item:item)*) => {$(
        #[cfg(target_arch = "wasm32")]
        $item
    )*}
}

macro_rules! if_hyper {
    ($($item:item)*) => {$(
        #[cfg(not(target_arch = "wasm32"))]
        $item
    )*}
}

pub use http::header;
pub use http::Method;
pub use http::{StatusCode, Version};
pub use url::Url;

// universal mods
#[macro_use]
mod error;
mod into_url;

pub use self::error::{Error, Result};
pub use self::into_url::IntoUrl;

/// Shortcut method to quickly make a `GET` request.
///
/// See also the methods on the [`reqwest::Response`](./struct.Response.html)
/// type.
///
/// **NOTE**: This function creates a new internal `Client` on each call,
/// and so should not be used if making many requests. Create a
/// [`Client`](./struct.Client.html) instead.
///
/// # Examples
///
/// ```rust
/// # async fn run() -> Result<(), reqwest::Error> {
/// let body = reqwest::get("https://www.rust-lang.org").await?
///     .text().await?;
/// # Ok(())
/// # }
/// ```
///
/// # Errors
///
/// This function fails if:
///
/// - native TLS backend cannot be initialized
/// - supplied `Url` cannot be parsed
/// - there was an error while sending request
/// - redirect loop was detected
/// - redirect limit was exhausted
pub async fn get<T: IntoUrl>(url: T) -> crate::Result<Response> {
    Client::builder().build()?.get(url).send().await
}

fn _assert_impls() {
    fn assert_send<T: Send>() {}
    fn assert_sync<T: Sync>() {}
    fn assert_clone<T: Clone>() {}

    assert_send::<Client>();
    assert_sync::<Client>();
    assert_clone::<Client>();

    assert_send::<Request>();
    assert_send::<RequestBuilder>();

    #[cfg(not(target_arch = "wasm32"))]
    {
        assert_send::<Response>();
    }

    assert_send::<Error>();
    assert_sync::<Error>();
}

if_hyper! {
    #[cfg(test)]
    #[macro_use]
    extern crate doc_comment;

    #[macro_use]
    extern crate lazy_static;

    #[cfg(test)]
    doctest!("../README.md");

    pub use self::async_impl::{
        multipart, Body, Client, ClientBuilder, Request, RequestBuilder, Response,
    };
    pub use self::proxy::Proxy;
    pub use self::redirect::{RedirectAction, RedirectAttempt, RedirectPolicy};
    #[cfg(feature = "tls")]
    pub use self::tls::{Certificate, Identity};

    mod async_impl;
    #[cfg(feature = "blocking")]
    pub mod blocking;
    mod connect;
    #[cfg(feature = "cookies")]
    pub mod cookie;
    //#[cfg(feature = "trust-dns")]
    //mod dns;
    mod proxy;
    mod redirect;
    #[cfg(feature = "tls")]
    mod tls;

    #[doc(hidden)]
    #[deprecated(note = "types moved to top of crate")]
    pub mod r#async {
        pub use crate::async_impl::{
            multipart, Body, Client, ClientBuilder, Request, RequestBuilder, Response,
        };
    }
}

if_wasm! {
    mod wasm;

    pub use self::wasm::{Body, Client, ClientBuilder, Request, RequestBuilder, Response};
}
<commit_msg>Update documentation to show usage of system proxies (#702)<commit_after>#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![cfg_attr(test, deny(warnings))]
#![doc(html_root_url = "https://docs.rs/reqwest/0.10.0-alpha.1")]

//! # reqwest
//!
//! The `reqwest` crate provides a convenient, higher-level HTTP
//! [`Client`][client].
//!
//! It handles many of the things that most people just expect an HTTP client
//! to do for them.
//!
//! - Async and [blocking](blocking) Clients
//! - Plain bodies, [JSON](#json), [urlencoded](#forms), [multipart](multipart)
//! - Customizable [redirect policy](#redirect-policy)
//! - HTTP [Proxies](#proxies)
//! - Uses system-native [TLS](#tls)
//! - Cookies
//!
//! The [`reqwest::Client`][client] is asynchronous. For applications wishing
//! to only make a few HTTP requests, the [`reqwest::blocking`](blocking) API
//! may be more convenient.
//!
//! Additional learning resources include:
//!
//! - [The Rust Cookbook](https://rust-lang-nursery.github.io/rust-cookbook/web/clients.html)
//! - [Reqwest Repository Examples](https://github.com/seanmonstar/reqwest/tree/master/examples)
//!
//! ## Making a GET request
//!
//! For a single request, you can use the [`get`][get] shortcut method.
//!
//! ```rust
//! # async fn run() -> Result<(), reqwest::Error> {
//! let body = reqwest::get("https://www.rust-lang.org")
//!     .await?
//!     .text()
//!     .await?;
//!
//! println!("body = {:?}", body);
//! # Ok(())
//! # }
//! ```
//!
//! **NOTE**: If you plan to perform multiple requests, it is best to create a
//! [`Client`][client] and reuse it, taking advantage of keep-alive connection
//! pooling.
//!
//! ## Making POST requests (or setting request bodies)
//!
//! There are several ways you can set the body of a request. The basic one is
//! by using the `body()` method of a [`RequestBuilder`][builder]. This lets you set the
//! exact raw bytes of what the body should be. It accepts various types,
//! including `String`, `Vec<u8>`, and `File`. If you wish to pass a custom
//! type, you can use the `reqwest::Body` constructors.
//!
//! ```rust
//! # use reqwest::Error;
//! #
//! # async fn run() -> Result<(), Error> {
//! let client = reqwest::Client::new();
//! let res = client.post("http://httpbin.org/post")
//!     .body("the exact body that is sent")
//!     .send()
//!     .await?;
//! # Ok(())
//! # }
//! ```
//!
//! ### Forms
//!
//! It's very common to want to send form data in a request body. This can be
//! done with any type that can be serialized into form data.
//!
//! This can be an array of tuples, or a `HashMap`, or a custom type that
//! implements [`Serialize`][serde].
//!
//! ```rust
//! # use reqwest::Error;
//! #
//! # async fn run() -> Result<(), Error> {
//! // This will POST a body of `foo=bar&baz=quux`
//! let params = [("foo", "bar"), ("baz", "quux")];
//! let client = reqwest::Client::new();
//! let res = client.post("http://httpbin.org/post")
//!     .form(&params)
//!     .send()
//!     .await?;
//! # Ok(())
//! # }
//! ```
//!
//! ### JSON
//!
//! There is also a `json` method helper on the [`RequestBuilder`][builder] that works in
//! a similar fashion the `form` method. It can take any value that can be
//! serialized into JSON. The feature `json` is required.
//!
//! ```rust
//! # use reqwest::Error;
//! # use std::collections::HashMap;
//! #
//! # #[cfg(feature = "json")]
//! # async fn run() -> Result<(), Error> {
//! // This will POST a body of `{"lang":"rust","body":"json"}`
//! let mut map = HashMap::new();
//! map.insert("lang", "rust");
//! map.insert("body", "json");
//!
//! let client = reqwest::Client::new();
//! let res = client.post("http://httpbin.org/post")
//!     .json(&map)
//!     .send()
//!     .await?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Redirect Policies
//!
//! By default, a `Client` will automatically handle HTTP redirects, detecting
//! loops, and having a maximum redirect chain of 10 hops. To customize this
//! behavior, a [`RedirectPolicy`][redirect] can used with a `ClientBuilder`.
//!
//! ## Cookies
//!
//! The automatic storing and sending of session cookies can be enabled with
//! the [`cookie_store`][ClientBuilder::cookie_store] method on `ClientBuilder`.
//!
//! ## Proxies
//!
//! ** NOTE ** Proxies are enabled by default.
//!
//! System proxies look in environment variables to set HTTP or HTTPS proxies.
//!
//! `HTTP_PROXY` or `http_proxy` provide http proxies for http connections while
//! `HTTPS_PROXY` or `https_proxy` provide HTTPS proxies for HTTPS connections.
//!
//! These can be overwritten by adding a [`Proxy`](Proxy) to `ClientBuilder`
//! i.e. `let proxy = reqwest::Proxy::http("https://secure.example")?;`
//! or disabled by calling `ClientBuilder::no_proxy()`.
//!
//! ## TLS
//!
//! By default, a `Client` will make use of system-native transport layer
//! security to connect to HTTPS destinations. This means schannel on Windows,
//! Security-Framework on macOS, and OpenSSL on Linux.
//!
//! - Additional X509 certificates can be configured on a `ClientBuilder` with the
//!   [`Certificate`](Certificate) type.
//! - Client certificates can be add to a `ClientBuilder` with the
//!   [`Identity`][Identity] type.
//! - Various parts of TLS can also be configured or even disabled on the
//!   `ClientBuilder`.
//!
//! ## Optional Features
//!
//! The following are a list of [Cargo features][cargo-features] that can be
//! enabled or disabled:
//!
//! - **default-tls** *(enabled by default)*: Provides TLS support via the
//!   `native-tls` library to connect over HTTPS.
//! - **default-tls-vendored**: Enables the `vendored` feature of `native-tls`.
//! - **blocking**: Provides the [blocking][] client API.
//! - **cookies**: Provides cookie session support.
//! - **gzip**: Provides response body gzip decompression.
//! - **json**: Provides serialization and deserialization for JSON bodies.
//! - **unstable-stream** *(unstable)*: Adds support for `futures::Stream`.
//!
//!
//! [hyper]: http://hyper.rs
//! [client]: ./struct.Client.html
//! [response]: ./struct.Response.html
//! [get]: ./fn.get.html
//! [builder]: ./struct.RequestBuilder.html
//! [serde]: http://serde.rs
//! [redirect]: ./struct.RedirectPolicy.html
//! [Proxy]: ./struct.Proxy.html
//! [cargo-features]: https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section

////! - **rustls-tls**: Provides TLS support via the `rustls` library.
////! - **socks**: Provides SOCKS5 proxy support.
////! - **trust-dns**: Enables a trust-dns async resolver instead of default
////!   threadpool using `getaddrinfo`.

macro_rules! if_wasm {
    ($($item:item)*) => {$(
        #[cfg(target_arch = "wasm32")]
        $item
    )*}
}

macro_rules! if_hyper {
    ($($item:item)*) => {$(
        #[cfg(not(target_arch = "wasm32"))]
        $item
    )*}
}

pub use http::header;
pub use http::Method;
pub use http::{StatusCode, Version};
pub use url::Url;

// universal mods
#[macro_use]
mod error;
mod into_url;

pub use self::error::{Error, Result};
pub use self::into_url::IntoUrl;

/// Shortcut method to quickly make a `GET` request.
///
/// See also the methods on the [`reqwest::Response`](./struct.Response.html)
/// type.
///
/// **NOTE**: This function creates a new internal `Client` on each call,
/// and so should not be used if making many requests. Create a
/// [`Client`](./struct.Client.html) instead.
///
/// # Examples
///
/// ```rust
/// # async fn run() -> Result<(), reqwest::Error> {
/// let body = reqwest::get("https://www.rust-lang.org").await?
///     .text().await?;
/// # Ok(())
/// # }
/// ```
///
/// # Errors
///
/// This function fails if:
///
/// - native TLS backend cannot be initialized
/// - supplied `Url` cannot be parsed
/// - there was an error while sending request
/// - redirect loop was detected
/// - redirect limit was exhausted
pub async fn get<T: IntoUrl>(url: T) -> crate::Result<Response> {
    Client::builder().build()?.get(url).send().await
}

fn _assert_impls() {
    fn assert_send<T: Send>() {}
    fn assert_sync<T: Sync>() {}
    fn assert_clone<T: Clone>() {}

    assert_send::<Client>();
    assert_sync::<Client>();
    assert_clone::<Client>();

    assert_send::<Request>();
    assert_send::<RequestBuilder>();

    #[cfg(not(target_arch = "wasm32"))]
    {
        assert_send::<Response>();
    }

    assert_send::<Error>();
    assert_sync::<Error>();
}

if_hyper! {
    #[cfg(test)]
    #[macro_use]
    extern crate doc_comment;

    #[macro_use]
    extern crate lazy_static;

    #[cfg(test)]
    doctest!("../README.md");

    pub use self::async_impl::{
        multipart, Body, Client, ClientBuilder, Request, RequestBuilder, Response,
    };
    pub use self::proxy::Proxy;
    pub use self::redirect::{RedirectAction, RedirectAttempt, RedirectPolicy};
    #[cfg(feature = "tls")]
    pub use self::tls::{Certificate, Identity};

    mod async_impl;
    #[cfg(feature = "blocking")]
    pub mod blocking;
    mod connect;
    #[cfg(feature = "cookies")]
    pub mod cookie;
    //#[cfg(feature = "trust-dns")]
    //mod dns;
    mod proxy;
    mod redirect;
    #[cfg(feature = "tls")]
    mod tls;

    #[doc(hidden)]
    #[deprecated(note = "types moved to top of crate")]
    pub mod r#async {
        pub use crate::async_impl::{
            multipart, Body, Client, ClientBuilder, Request, RequestBuilder, Response,
        };
    }
}

if_wasm! {
    mod wasm;

    pub use self::wasm::{Body, Client, ClientBuilder, Request, RequestBuilder, Response};
}
<|endoftext|>