<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>>,
    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 {
            map: HashMap::new(),
            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(), 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);
        }
    }

    /// 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 keys = self.map.keys().collect::<Vec<&(&str, &str)>>();
        let state = if keys.is_empty() {
            ("", "")
        } else {
            **choose(&mut self.rng, &keys).unwrap()
        };
        Words {
            map: &self.map,
            rng: &mut self.rng,
            keys: 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 {
        let keys = self.map.keys().collect::<Vec<&(&str, &str)>>();
        Words {
            map: &self.map,
            rng: &mut self.rng,
            keys: keys,
            state: from,
        }
    }
}

pub struct Words<'a> {
    map: &'a HashMap<Bigram<'a>, Vec<&'a str>>,
    rng: &'a mut rand::Rng,
    keys: Vec<&'a 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();
        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"]);
    }
}
<commit_msg>MarkovChain: ensure deterministic output<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 {
            map: HashMap::new(),
            keys: Vec::new(),
            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();
        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");
    }
}
<|endoftext|>


<commit_before>extern crate libc;

use std::*;
use libc::*;

#[allow(dead_code, non_camel_case_types)]
mod bladerf;
use bladerf::*;

//impl fmt::Display for Struct_bladerf_devinfo {
//    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
//        write!(f, "serial: UNIMPLEMENTED, bus: {}, address: {})", self.usb_bus, self.usb_addr)
//    }
//}

//#[link(name = "bladerf")]
//extern {
//	fn bladerf_get_device_list(devices: &*mut [Struct_bladerf_devinfo]) -> libc::c_int;
//	fn bladerf_free_device_list(devices: *mut [Struct_bladerf_devinfo]);
//    fn bladerf_set_usb_reset_on_open (enabled: bool);
//}

pub fn get_device_list() -> Result<Vec<Struct_bladerf_devinfo>, isize> {

	unsafe{
		let devices: *mut [Struct_bladerf_devinfo] = mem::uninitialized();

		let n = bladerf_get_device_list(&devices) as isize;

		let mut safe_device_list: Vec<Struct_bladerf_devinfo> = Vec::new();

		if n >= 0 {

			for i in 0..n {
				println!("iterator: {}", i);
				let local_device = (*devices)[i as usize];
				//Safe if this is a copy, unsafe if it is not?
				safe_device_list.push(local_device);
			}
			bladerf_free_device_list(devices);

			Ok(safe_device_list)
		} else {
			Err(n)
		}
	}
}

pub fn set_usb_reset_on_open(enabled: bool) {
    unsafe{
    	bladerf_set_usb_reset_on_open(enabled as uint8_t);
    }
}

pub fn open_with_devinfo(devinfo: &Struct_bladerf_devinfo) -> Result<*mut Struct_bladerf, isize> {
	unsafe {
		let device_ptr: *mut Struct_bladerf = mem::uninitialized();
		let device_ptr_ptr: *mut *mut Struct_bladerf = device_ptr as *mut *mut Struct_bladerf;
		let unsafe_devinfo: *const Struct_bladerf_devinfo = devinfo as *const Struct_bladerf_devinfo;

		let res = bladerf_open_with_devinfo(device_ptr_ptr, unsafe_devinfo) as isize;

		if res >= 0 {
			Ok(device_ptr)
		} else {
			Err(res)
		}
	}
}

pub fn fw_version(dev: *mut Struct_bladerf) -> Result<Struct_bladerf_version, isize> {
	unsafe {
		let mut version: Struct_bladerf_version = mem::uninitialized();

		let res = bladerf_fw_version(dev, &mut version as *mut Struct_bladerf_version) as isize;

		if res >= 0 {
			Ok(version)
		} else {
			Err(res)
		}
	}
}

pub fn fpga_version(dev: *mut Struct_bladerf) -> Result<Struct_bladerf_version, isize> {
	unsafe {
		let mut version: Struct_bladerf_version = mem::uninitialized();

		let res = bladerf_fpga_version(dev, &mut version as *mut Struct_bladerf_version) as isize;

		if res >= 0 {
			Ok(version)
		} else {
			Err(res)
		}
	}
}

pub fn close_device(device: *mut Struct_bladerf) {
	unsafe {
		bladerf_close(device)
	}
}

#[test]
fn discovery() {
	match get_device_list() {
		Ok(devices) => {
			println!("Discovered {:?} devices", devices.len());
		},
		Err(code) => {
			println!("Error {:?} listing devices", code);
			assert!(false);
		}
	}
}

#[test]
fn connection() {
	match get_device_list() {
		Ok(devices) => {
			assert!(devices.len() == 1);
			match(open_with_devinfo(&devices[0])) {
				Ok(dev) => {
					println!("Device opened");
				},
				Err(code) => {
					println!("Error {:?} opening device", code);
			assert!(false);
				}
			}
		},
		Err(code) => {
			println!("Error {:?} listing devices", code);
			assert!(false);
		}
	}

}

<commit_msg>So close causes a segfault, pretty well expected really<commit_after>extern crate libc;

use std::*;
use libc::*;

#[allow(dead_code, non_camel_case_types)]
mod bladerf;
use bladerf::*;

//impl fmt::Display for Struct_bladerf_devinfo {
//    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
//        write!(f, "serial: UNIMPLEMENTED, bus: {}, address: {})", self.usb_bus, self.usb_addr)
//    }
//}

//#[link(name = "bladerf")]
//extern {
//	fn bladerf_get_device_list(devices: &*mut [Struct_bladerf_devinfo]) -> libc::c_int;
//	fn bladerf_free_device_list(devices: *mut [Struct_bladerf_devinfo]);
//    fn bladerf_set_usb_reset_on_open (enabled: bool);
//}

pub fn get_device_list() -> Result<Vec<Struct_bladerf_devinfo>, isize> {

	unsafe{
		let devices: *mut [Struct_bladerf_devinfo] = mem::uninitialized();

		let n = bladerf_get_device_list(&devices) as isize;

		let mut safe_device_list: Vec<Struct_bladerf_devinfo> = Vec::new();

		if n >= 0 {

			for i in 0..n {
				println!("iterator: {}", i);
				let local_device = (*devices)[i as usize];
				//Safe if this is a copy, unsafe if it is not?
				safe_device_list.push(local_device);
			}
			bladerf_free_device_list(devices);

			Ok(safe_device_list)
		} else {
			Err(n)
		}
	}
}

pub fn set_usb_reset_on_open(enabled: bool) {
    unsafe{
    	bladerf_set_usb_reset_on_open(enabled as uint8_t);
    }
}

pub fn open_with_devinfo(devinfo: &Struct_bladerf_devinfo) -> Result<*mut Struct_bladerf, isize> {
	unsafe {
		let device_ptr: *mut Struct_bladerf = mem::uninitialized();
		let device_ptr_ptr: *mut *mut Struct_bladerf = device_ptr as *mut *mut Struct_bladerf;
		let unsafe_devinfo: *const Struct_bladerf_devinfo = devinfo as *const Struct_bladerf_devinfo;

		let res = bladerf_open_with_devinfo(device_ptr_ptr, unsafe_devinfo) as isize;

		if res >= 0 {
			Ok(device_ptr)
		} else {
			Err(res)
		}
	}
}

pub fn fw_version(dev: *mut Struct_bladerf) -> Result<Struct_bladerf_version, isize> {
	unsafe {
		let mut version: Struct_bladerf_version = mem::uninitialized();

		let res = bladerf_fw_version(dev, &mut version as *mut Struct_bladerf_version) as isize;

		if res >= 0 {
			Ok(version)
		} else {
			Err(res)
		}
	}
}

pub fn fpga_version(dev: *mut Struct_bladerf) -> Result<Struct_bladerf_version, isize> {
	unsafe {
		let mut version: Struct_bladerf_version = mem::uninitialized();

		let res = bladerf_fpga_version(dev, &mut version as *mut Struct_bladerf_version) as isize;

		if res >= 0 {
			Ok(version)
		} else {
			Err(res)
		}
	}
}

pub fn close_device(device: *mut Struct_bladerf) {
	unsafe {
		bladerf_close(device)
	}
}

#[test]
fn discovery() {
	match get_device_list() {
		Ok(devices) => {
			println!("Discovered {:?} devices", devices.len());
		},
		Err(code) => {
			println!("Error {:?} listing devices", code);
			assert!(false);
		}
	}
}

#[test]
fn connection() {
	match get_device_list() {
		Ok(devices) => {
			assert!(devices.len() == 1);
			match open_with_devinfo(&devices[0]) {
				Ok(dev) => {
					println!("Device opened");
					close_device(dev);
					println!("Device closed");
				},
				Err(code) => {
					println!("Error {:?} opening device", code);
			assert!(false);
				}
			}
		},
		Err(code) => {
			println!("Error {:?} listing devices", code);
			assert!(false);
		}
	}

}

<|endoftext|>


<commit_before>// Copyright 2016 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was not
// distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.

//! simple_slab provides a fast, minimal, slab allocator.
//! ## Usage
//!
//! ```no_run
//! extern crate simple_slab;
//!
//! use simple_slab::Slab;
//!
//! fn main() {
//!     const MAX_ELEMS: usize = 100000;
//!
//!     let mut slab = Slab::<u32>::with_capacity(MAX_ELEMS);
//!
//!     // Insertion
//!     for num in 0..MAX_ELEMS {
//!         slab.insert(num as u32);
//!     }
//!
//!     // Traversal
//!     for offset in 0..slab.len() {
//!         slab[offset] = 33;
//!     }
//!
//!     // Iteration
//!     for num in slab.iter() {
//!         // Stuff...
//!     }
//!
//!     // Removal
//!     for offset in 0..slab.len() {
//!         let num = slab.remove(offset);
//!     }
//! }
//! ```

extern crate libc;

use std::{mem, ptr};
use std::ops::{Drop, Index};
use std::iter::{Iterator, IntoIterator};

pub struct Slab<T> {
    capacity: usize,
    num_elems: usize,
    mem_ptr: *mut T
}

pub struct SlabIter<'a, T: 'a> {
    slab: &'a Slab<T>,
    current_offset: usize
}

pub struct SlabMutIter<'a, T: 'a> {
    iter: SlabIter<'a, T>
}

impl<T> Slab<T> {
    /// Creates a new, empty Slab
    pub fn new() -> Slab<T> {
        Slab {
            capacity: 0,
            num_elems: 0,
            mem_ptr: ptr::null_mut()
        }
    }

    /// Creates a new, empty Slab with room for `capacity` elems
    ///
    /// # Panics
    ///
    /// Panics if the host system is out of memory
    pub fn with_capacity(capacity: usize) -> Slab<T> {
        unsafe {
            let maybe_ptr = libc::malloc((mem::size_of::<T>() * capacity)) as *mut T;

            // malloc will return NULL if called with zero
            if maybe_ptr.is_null() && capacity != 0 {
                panic!("Unable to allocate requested capacity")
            }

            return Slab {
                capacity: capacity,
                num_elems: 0,
                mem_ptr: maybe_ptr
            }
        }
    }

    /// Inserts a new element into the slab, re-allocating if neccessary.
    ///
    /// # Panics
    /// * If the host system is out of memory.
    #[inline]
    pub fn insert(&mut self, elem: T) {
        if self.num_elems == self.capacity {
            self.reallocate();
        }

        let next_elem_offset = self.num_elems as isize;
        unsafe {
            ptr::write(self.mem_ptr.offset(next_elem_offset), elem);
        }
        self.num_elems += 1;
    }

    /// Removes the element at `offset`.
    ///
    /// # Panics
    ///
    /// * If `offset` is out of bounds.
    #[inline]
    pub fn remove(&mut self, offset: usize) -> T {
        if offset >= self.num_elems {
            panic!("Offset {} out of bounds for slab.len: {}", offset, self.num_elems)
        }

        let last_elem_offset = (self.num_elems - 1) as isize;
        let elem = unsafe {
            let elem_ptr = self.mem_ptr.offset(offset as isize);
            let last_elem_ptr = self.mem_ptr.offset(last_elem_offset);
            mem::replace(&mut (*elem_ptr), ptr::read(last_elem_ptr))
        };

        return elem;
    }

    /// Returns the number of elements in the slab
    #[inline]
    pub fn len(&self) -> usize {
        self.num_elems
    }

    /// Returns an iterator over the slab
    #[inline]
    pub fn iter(&self) -> SlabIter<T> {
        SlabIter {
            slab: self,
            current_offset: 0
        }
    }

    /// Returns a mutable iterator over the slab
    #[inline]
    pub fn iter_mut(&mut self) -> SlabMutIter<T> {
        SlabMutIter {
            iter: self.iter()
        }
    }

    /// Reserves capacity * 2 extra space in this slab
    ///
    /// # Panics
    ///
    /// Panics if the host system is out of memory
    #[inline]
    fn reallocate(&mut self) {
        let new_capacity = if self.capacity != 0 {
            self.capacity * 2
        } else {
            1
        };

        unsafe {
            let maybe_ptr = libc::realloc(self.mem_ptr as *mut libc::c_void,
                                          (mem::size_of::<T>() * new_capacity)) as *mut T;

            if maybe_ptr.is_null() {
                panic!("Unable to allocate new capacity")
            }

            self.capacity = new_capacity;
            self.mem_ptr = maybe_ptr;
        }
    }
}

impl<T> Drop for Slab<T> {
    fn drop(&mut self) {
        unsafe {
            for x in 0..self.len() {
                let elem_ptr = self.mem_ptr.offset(x as isize);
                ptr::drop_in_place(elem_ptr);
            }

            libc::free(self.mem_ptr as *mut _ as *mut libc::c_void);
        }
    }
}

impl<T> Index<usize> for Slab<T> {
    type Output = T;
    fn index(&self, index: usize) -> &Self::Output {
        unsafe {
            &(*(self.mem_ptr.offset(index as isize)))
        }
    }
}

impl<'a, T> Iterator for SlabIter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        while self.current_offset < self.slab.len() {
            let offset = self.current_offset;
            self.current_offset += 1;
            unsafe {
                return Some(&(*self.slab.mem_ptr.offset(offset as isize)));
            }
        }

        return  None;
    }
}

impl<'a, T> Iterator for SlabMutIter<'a, T> {
    type Item = &'a mut T;
    fn next(&mut self) -> Option<&'a mut T> {
        unsafe { mem::transmute(self.iter.next()) }
    }
}

impl<'a, T> IntoIterator for &'a Slab<T> {
    type Item = &'a T;
    type IntoIter = SlabIter<'a, T>;
    fn into_iter(self) -> SlabIter<'a, T> {
        self.iter()
    }
}

impl<'a, T> IntoIterator for &'a mut Slab<T> {
    type Item = &'a mut T;
    type IntoIter = SlabMutIter<'a, T>;
    fn into_iter(self) -> SlabMutIter<'a, T> {
        self.iter_mut()
    }
}

unsafe impl<T: Send> Send for Slab<T> {}
unsafe impl<T: Sync> Sync for Slab<T> {}
<commit_msg>Element count updated after remove. Closes #1.<commit_after>// Copyright 2016 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was not
// distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.

//! simple_slab provides a fast, minimal, slab allocator.
//! ## Usage
//!
//! ```no_run
//! extern crate simple_slab;
//!
//! use simple_slab::Slab;
//!
//! fn main() {
//!     const MAX_ELEMS: usize = 100000;
//!
//!     let mut slab = Slab::<u32>::with_capacity(MAX_ELEMS);
//!
//!     // Insertion
//!     for num in 0..MAX_ELEMS {
//!         slab.insert(num as u32);
//!     }
//!
//!     // Traversal
//!     for offset in 0..slab.len() {
//!         slab[offset] = 33;
//!     }
//!
//!     // Iteration
//!     for num in slab.iter() {
//!         // Stuff...
//!     }
//!
//!     // Removal
//!     for offset in 0..slab.len() {
//!         let num = slab.remove(offset);
//!     }
//! }
//! ```

extern crate libc;

use std::{mem, ptr};
use std::ops::{Drop, Index};
use std::iter::{Iterator, IntoIterator};

pub struct Slab<T> {
    capacity: usize,
    num_elems: usize,
    mem_ptr: *mut T
}

pub struct SlabIter<'a, T: 'a> {
    slab: &'a Slab<T>,
    current_offset: usize
}

pub struct SlabMutIter<'a, T: 'a> {
    iter: SlabIter<'a, T>
}

impl<T> Slab<T> {
    /// Creates a new, empty Slab
    pub fn new() -> Slab<T> {
        Slab {
            capacity: 0,
            num_elems: 0,
            mem_ptr: ptr::null_mut()
        }
    }

    /// Creates a new, empty Slab with room for `capacity` elems
    ///
    /// # Panics
    ///
    /// Panics if the host system is out of memory
    pub fn with_capacity(capacity: usize) -> Slab<T> {
        unsafe {
            let maybe_ptr = libc::malloc((mem::size_of::<T>() * capacity)) as *mut T;

            // malloc will return NULL if called with zero
            if maybe_ptr.is_null() && capacity != 0 {
                panic!("Unable to allocate requested capacity")
            }

            return Slab {
                capacity: capacity,
                num_elems: 0,
                mem_ptr: maybe_ptr
            }
        }
    }

    /// Inserts a new element into the slab, re-allocating if neccessary.
    ///
    /// # Panics
    /// * If the host system is out of memory.
    #[inline]
    pub fn insert(&mut self, elem: T) {
        if self.num_elems == self.capacity {
            self.reallocate();
        }

        let next_elem_offset = self.num_elems as isize;
        unsafe {
            ptr::write(self.mem_ptr.offset(next_elem_offset), elem);
        }
        self.num_elems += 1;
    }

    /// Removes the element at `offset`.
    ///
    /// # Panics
    ///
    /// * If `offset` is out of bounds.
    #[inline]
    pub fn remove(&mut self, offset: usize) -> T {
        if offset >= self.num_elems {
            panic!("Offset {} out of bounds for slab.len: {}", offset, self.num_elems)
        }

        let last_elem_offset = (self.num_elems - 1) as isize;
        let elem = unsafe {
            let elem_ptr = self.mem_ptr.offset(offset as isize);
            let last_elem_ptr = self.mem_ptr.offset(last_elem_offset);
            mem::replace(&mut (*elem_ptr), ptr::read(last_elem_ptr))
        };
        self.num_elems -= 1;

        return elem;
    }

    /// Returns the number of elements in the slab
    #[inline]
    pub fn len(&self) -> usize {
        self.num_elems
    }

    /// Returns an iterator over the slab
    #[inline]
    pub fn iter(&self) -> SlabIter<T> {
        SlabIter {
            slab: self,
            current_offset: 0
        }
    }

    /// Returns a mutable iterator over the slab
    #[inline]
    pub fn iter_mut(&mut self) -> SlabMutIter<T> {
        SlabMutIter {
            iter: self.iter()
        }
    }

    /// Reserves capacity * 2 extra space in this slab
    ///
    /// # Panics
    ///
    /// Panics if the host system is out of memory
    #[inline]
    fn reallocate(&mut self) {
        let new_capacity = if self.capacity != 0 {
            self.capacity * 2
        } else {
            1
        };

        unsafe {
            let maybe_ptr = libc::realloc(self.mem_ptr as *mut libc::c_void,
                                          (mem::size_of::<T>() * new_capacity)) as *mut T;

            if maybe_ptr.is_null() {
                panic!("Unable to allocate new capacity")
            }

            self.capacity = new_capacity;
            self.mem_ptr = maybe_ptr;
        }
    }
}

impl<T> Drop for Slab<T> {
    fn drop(&mut self) {
        unsafe {
            for x in 0..self.len() {
                let elem_ptr = self.mem_ptr.offset(x as isize);
                ptr::drop_in_place(elem_ptr);
            }

            libc::free(self.mem_ptr as *mut _ as *mut libc::c_void);
        }
    }
}

impl<T> Index<usize> for Slab<T> {
    type Output = T;
    fn index(&self, index: usize) -> &Self::Output {
        unsafe {
            &(*(self.mem_ptr.offset(index as isize)))
        }
    }
}

impl<'a, T> Iterator for SlabIter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        while self.current_offset < self.slab.len() {
            let offset = self.current_offset;
            self.current_offset += 1;
            unsafe {
                return Some(&(*self.slab.mem_ptr.offset(offset as isize)));
            }
        }

        return  None;
    }
}

impl<'a, T> Iterator for SlabMutIter<'a, T> {
    type Item = &'a mut T;
    fn next(&mut self) -> Option<&'a mut T> {
        unsafe { mem::transmute(self.iter.next()) }
    }
}

impl<'a, T> IntoIterator for &'a Slab<T> {
    type Item = &'a T;
    type IntoIter = SlabIter<'a, T>;
    fn into_iter(self) -> SlabIter<'a, T> {
        self.iter()
    }
}

impl<'a, T> IntoIterator for &'a mut Slab<T> {
    type Item = &'a mut T;
    type IntoIter = SlabMutIter<'a, T>;
    fn into_iter(self) -> SlabMutIter<'a, T> {
        self.iter_mut()
    }
}

unsafe impl<T: Send> Send for Slab<T> {}
unsafe impl<T: Sync> Sync for Slab<T> {}
<|endoftext|>


<commit_before>#![feature(macro_rules, phase)]

extern crate serialize;
extern crate time;
#[phase(plugin, link)] extern crate log;

extern crate "postgres" as pg;
extern crate curl;
extern crate flate2;
extern crate git2;
extern crate html;
extern crate oauth2;
extern crate openssl;
extern crate r2d2;
extern crate r2d2_postgres;
extern crate s3;
extern crate semver;
extern crate url;

extern crate "conduit-router" as conduit_router;
extern crate conduit;
extern crate "conduit-cookie" as conduit_cookie;
extern crate "conduit-middleware" as conduit_middleware;
extern crate "conduit-conditional-get" as conduit_conditional_get;
extern crate "conduit-log-requests" as conduit_log_requests;
extern crate "conduit-static" as conduit_static;
extern crate "conduit-json-parser" as conduit_json_parser;

pub use app::App;
pub use config::Config;
pub use self::dependency::Dependency;
pub use self::download::{CrateDownload, VersionDownload};
pub use self::keyword::Keyword;
pub use self::krate::Crate;
pub use self::model::Model;
pub use self::user::User;
pub use self::version::Version;

use std::sync::Arc;

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

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

mod macros;

pub mod app;
pub mod config;
pub mod db;
pub mod dependency;
pub mod dist;
pub mod download;
pub mod git;
pub mod keyword;
pub mod krate;
pub mod model;
pub mod upload;
pub mod user;
pub mod util;
pub mod version;
mod licenses;

#[deriving(PartialEq, Eq, Clone)]
pub enum Env {
    Development,
    Test,
    Production,
}

pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
    let mut api_router = RouteBuilder::new();

    api_router.get("/crates", C(krate::index));
    api_router.get("/crates/:crate_id", C(krate::show));
    api_router.put("/crates/new", C(krate::new));
    api_router.get("/crates/:crate_id/:version", C(version::show));
    api_router.get("/crates/:crate_id/:version/download", C(krate::download));
    api_router.get("/crates/:crate_id/:version/dependencies", C(version::dependencies));
    api_router.get("/crates/:crate_id/:version/downloads", C(version::downloads));
    api_router.get("/crates/:crate_id/:version/authors", C(version::authors));
    api_router.get("/crates/:crate_id/downloads", C(krate::downloads));
    api_router.get("/crates/:crate_id/versions", C(krate::versions));
    api_router.put("/crates/:crate_id/follow", C(krate::follow));
    api_router.delete("/crates/:crate_id/follow", C(krate::unfollow));
    api_router.get("/crates/:crate_id/following", C(krate::following));
    api_router.get("/crates/:crate_id/owners", C(krate::owners));
    api_router.put("/crates/:crate_id/owners", C(krate::add_owners));
    api_router.delete("/crates/:crate_id/owners", C(krate::remove_owners));
    api_router.delete("/crates/:crate_id/:version/yank", C(version::yank));
    api_router.put("/crates/:crate_id/:version/unyank", C(version::unyank));
    api_router.get("/versions", C(version::index));
    api_router.get("/versions/:version_id", C(version::show));
    api_router.get("/keywords", C(keyword::index));
    api_router.get("/keywords/:keyword_id", C(keyword::show));
    let api_router = Arc::new(R404(api_router));

    let mut router = RouteBuilder::new();

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

    router.get("/authorize_url", C(user::github_authorize));
    router.get("/authorize", C(user::github_access_token));
    router.get("/logout", C(user::logout));
    router.get("/me", C(user::me));
    router.put("/me/reset_token", C(user::reset_token));
    router.get("/me/updates", C(user::updates));
    router.get("/summary", C(krate::summary));

    let env = app.config.env;
    if env == Env::Development {
        router.get("/git/index/*path", C(git::serve_index));
        router.post("/git/index/*path", C(git::serve_index));
    }

    let mut m = MiddlewareBuilder::new(R404(router));
    m.add(DebugMiddleware);
    if env != Env::Test {
        m.add(conduit_log_requests::LogRequests(0));
    }
    m.around(util::Head::new());
    m.add(conduit_conditional_get::ConditionalGet);
    m.add(conduit_cookie::Middleware::new(app.session_key.as_bytes()));
    m.add(conduit_cookie::SessionMiddleware::new("cargo_session",
                                                 env == Env::Production));
    m.add(app::AppMiddleware::new(app));
    m.add(db::TransactionMiddleware);
    m.add(user::Middleware);
    if env != Env::Test {
        m.around(dist::Middleware::new());
    }

    return m;

    struct DebugMiddleware;

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

pub fn now() -> time::Timespec {
    time::now_utc().to_timespec()
}

pub fn encode_time(ts: time::Timespec) -> String {
    time::at_utc(ts).rfc3339().to_string()
}
<commit_msg>Only debug in development<commit_after>#![feature(macro_rules, phase)]

extern crate serialize;
extern crate time;
#[phase(plugin, link)] extern crate log;

extern crate "postgres" as pg;
extern crate curl;
extern crate flate2;
extern crate git2;
extern crate html;
extern crate oauth2;
extern crate openssl;
extern crate r2d2;
extern crate r2d2_postgres;
extern crate s3;
extern crate semver;
extern crate url;

extern crate "conduit-router" as conduit_router;
extern crate conduit;
extern crate "conduit-cookie" as conduit_cookie;
extern crate "conduit-middleware" as conduit_middleware;
extern crate "conduit-conditional-get" as conduit_conditional_get;
extern crate "conduit-log-requests" as conduit_log_requests;
extern crate "conduit-static" as conduit_static;
extern crate "conduit-json-parser" as conduit_json_parser;

pub use app::App;
pub use config::Config;
pub use self::dependency::Dependency;
pub use self::download::{CrateDownload, VersionDownload};
pub use self::keyword::Keyword;
pub use self::krate::Crate;
pub use self::model::Model;
pub use self::user::User;
pub use self::version::Version;

use std::sync::Arc;

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

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

mod macros;

pub mod app;
pub mod config;
pub mod db;
pub mod dependency;
pub mod dist;
pub mod download;
pub mod git;
pub mod keyword;
pub mod krate;
pub mod model;
pub mod upload;
pub mod user;
pub mod util;
pub mod version;
mod licenses;

#[deriving(PartialEq, Eq, Clone)]
pub enum Env {
    Development,
    Test,
    Production,
}

pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
    let mut api_router = RouteBuilder::new();

    api_router.get("/crates", C(krate::index));
    api_router.get("/crates/:crate_id", C(krate::show));
    api_router.put("/crates/new", C(krate::new));
    api_router.get("/crates/:crate_id/:version", C(version::show));
    api_router.get("/crates/:crate_id/:version/download", C(krate::download));
    api_router.get("/crates/:crate_id/:version/dependencies", C(version::dependencies));
    api_router.get("/crates/:crate_id/:version/downloads", C(version::downloads));
    api_router.get("/crates/:crate_id/:version/authors", C(version::authors));
    api_router.get("/crates/:crate_id/downloads", C(krate::downloads));
    api_router.get("/crates/:crate_id/versions", C(krate::versions));
    api_router.put("/crates/:crate_id/follow", C(krate::follow));
    api_router.delete("/crates/:crate_id/follow", C(krate::unfollow));
    api_router.get("/crates/:crate_id/following", C(krate::following));
    api_router.get("/crates/:crate_id/owners", C(krate::owners));
    api_router.put("/crates/:crate_id/owners", C(krate::add_owners));
    api_router.delete("/crates/:crate_id/owners", C(krate::remove_owners));
    api_router.delete("/crates/:crate_id/:version/yank", C(version::yank));
    api_router.put("/crates/:crate_id/:version/unyank", C(version::unyank));
    api_router.get("/versions", C(version::index));
    api_router.get("/versions/:version_id", C(version::show));
    api_router.get("/keywords", C(keyword::index));
    api_router.get("/keywords/:keyword_id", C(keyword::show));
    let api_router = Arc::new(R404(api_router));

    let mut router = RouteBuilder::new();

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

    router.get("/authorize_url", C(user::github_authorize));
    router.get("/authorize", C(user::github_access_token));
    router.get("/logout", C(user::logout));
    router.get("/me", C(user::me));
    router.put("/me/reset_token", C(user::reset_token));
    router.get("/me/updates", C(user::updates));
    router.get("/summary", C(krate::summary));

    let env = app.config.env;
    if env == Env::Development {
        router.get("/git/index/*path", C(git::serve_index));
        router.post("/git/index/*path", C(git::serve_index));
    }

    let mut m = MiddlewareBuilder::new(R404(router));
    if env == Env::Development {
        m.add(DebugMiddleware);
    }
    if env != Env::Test {
        m.add(conduit_log_requests::LogRequests(0));
    }
    m.around(util::Head::new());
    m.add(conduit_conditional_get::ConditionalGet);
    m.add(conduit_cookie::Middleware::new(app.session_key.as_bytes()));
    m.add(conduit_cookie::SessionMiddleware::new("cargo_session",
                                                 env == Env::Production));
    m.add(app::AppMiddleware::new(app));
    m.add(db::TransactionMiddleware);
    m.add(user::Middleware);
    if env != Env::Test {
        m.around(dist::Middleware::new());
    }

    return m;

    struct DebugMiddleware;

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

pub fn now() -> time::Timespec {
    time::now_utc().to_timespec()
}

pub fn encode_time(ts: time::Timespec) -> String {
    time::at_utc(ts).rfc3339().to_string()
}
<|endoftext|>


<commit_before>//! # `rad-rs` - A high-level wrapper library for talking to Ceph RADOS clusters.
//!
//! Only certain features are currently available, mainly writing and reading to
//! RADOS objects, as well as a limited set of other operations (object stats,
//! for example.) However, the operations that are provided are supplied in
//! an idiomatic, Rusty fashion, using the futures library for asynchronous
//! operations.
//!
//! Missing functionality includes MON/OSD/PGS commands.
//!
//! Current features:
//! - Read, write, full-write, append
//! - Automatic `rados_shutdown` on drop of the reference-counted `RadosCluster` type
//! - Asynchronous read/write/etc. using futures
//!
//! ## Examples
//!
//! ### Connecting to a cluster
//!
//! ```rust,no_run
//! # extern crate rad;
//! use std::path::Path;
//!
//! use rad::RadosConnectionBuilder;
//! # fn dummy() -> ::rad::errors::Result<()> {
//!
//! let cluster = RadosConnectionBuilder::with_user("admin")?
//!     .read_conf_file(Path::new("/etc/ceph.conf"))?
//!     .conf_set("keyring", "/etc/ceph.client.admin.keyring")?
//!     .connect()?;
//! # Ok(()) } fn main() {}
//! ```
//!
//! ### Synchronous cluster operations
//!
//! ```rust,no_run
//! # extern crate rad;
//! # fn dummy() -> ::rad::errors::Result<()> {
//! use std::fs::File;
//! use std::io::Read;
//! use std::path::Path;
//!
//! use rad::RadosConnectionBuilder;
//!
//! let mut cluster = RadosConnectionBuilder::with_user("admin")?
//!     .read_conf_file(Path::new("/etc/ceph.conf"))?
//!     .conf_set("keyring", "/etc/ceph.client.admin.keyring")?
//!     .connect()?;
//!
//! // Read in bytes from some file to send to the cluster.
//! let mut file = File::open("/path/to/file")?;
//! let mut bytes = Vec::new();
//! file.read_to_end(&mut bytes)?;
//!
//! let mut pool = cluster.get_pool_context("rbd")?;
//!
//! pool.write_full("object-name", &bytes)?;
//!
//! // Our file is now in the cluster! We can check for its existence:
//! assert!(pool.exists("object-name")?);
//!
//! // And we can also check that it contains the bytes we wrote to it.
//! let mut bytes_from_cluster = vec![0u8; bytes.len()];
//! let bytes_read = pool.read("object-name", &mut bytes_from_cluster, 0)?;
//! assert_eq!(bytes_read, bytes_from_cluster.len());
//! assert!(bytes_from_cluster == bytes);
//! # Ok(()) } fn main() {}
//! ```
//!
//! ### Asynchronous cluster I/O
//!
//! ```rust,no_run
//! # extern crate futures;
//! # extern crate rad;
//! # extern crate rand;
//! # fn dummy() -> ::rad::errors::Result<()> {
//! use std::path::Path;
//! use std::io::Read;
//!
//! use futures::prelude::*;
//! use futures::stream;
//! use rand::{Rng, SeedableRng, XorShiftRng};
//!
//! use rad::RadosConnectionBuilder;
//!
//! const NUM_OBJECTS: usize = 8;
//!
//! let mut cluster = RadosConnectionBuilder::with_user("admin")?
//!     .read_conf_file(Path::new("/etc/ceph.conf"))?
//!     .conf_set("keyring", "/etc/ceph.client.admin.keyring")?
//!     .connect()?;
//!
//! let mut pool = cluster.get_pool_context("rbd")?;
//!
//! stream::iter_ok((0..NUM_OBJECTS)
//!     .map(|i| {
//!         let bytes = XorShiftRng::from_seed([i as u32 + 1, 2, 3, 4])
//!             .gen_iter::<u8>()
//!             .take(1 << 16)
//!             .collect::<Vec<u8>>();
//!
//!         let name = format!("object-{}", i);
//!
//!         pool.write_full_async(&name, &bytes)
//!     }))
//!     .buffer_unordered(NUM_OBJECTS)
//!     .collect()
//!     .wait()?;
//! # Ok(()) } fn main() {}
//! ```

#![recursion_limit = "1024"]
#![feature(conservative_impl_trait)]

extern crate ceph_rust;
extern crate chrono;
#[macro_use]
extern crate error_chain;
extern crate ffi_pool;
extern crate futures;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate stable_deref_trait;

pub use stable_deref_trait::StableDeref;

#[macro_export]
macro_rules! c {
    ($s:expr) => {
        CString::new($s)
            .expect(concat!("Could not convert `", $s, "` to an FFI-compatible CString!"))
    };
}

mod async;
pub mod errors;
pub mod rados;

pub use errors::*;
pub use rados::{RadosConnectionBuilder, RadosConnection, RadosContext, RadosStat};
<commit_msg>Remove unnecessary nightly feature flag.<commit_after>//! # `rad-rs` - A high-level wrapper library for talking to Ceph RADOS clusters.
//!
//! Only certain features are currently available, mainly writing and reading to
//! RADOS objects, as well as a limited set of other operations (object stats,
//! for example.) However, the operations that are provided are supplied in
//! an idiomatic, Rusty fashion, using the futures library for asynchronous
//! operations.
//!
//! Missing functionality includes MON/OSD/PGS commands.
//!
//! Current features:
//! - Read, write, full-write, append
//! - Automatic `rados_shutdown` on drop of the reference-counted `RadosCluster` type
//! - Asynchronous read/write/etc. using futures
//!
//! ## Examples
//!
//! ### Connecting to a cluster
//!
//! ```rust,no_run
//! # extern crate rad;
//! use std::path::Path;
//!
//! use rad::RadosConnectionBuilder;
//! # fn dummy() -> ::rad::errors::Result<()> {
//!
//! let cluster = RadosConnectionBuilder::with_user("admin")?
//!     .read_conf_file(Path::new("/etc/ceph.conf"))?
//!     .conf_set("keyring", "/etc/ceph.client.admin.keyring")?
//!     .connect()?;
//! # Ok(()) } fn main() {}
//! ```
//!
//! ### Synchronous cluster operations
//!
//! ```rust,no_run
//! # extern crate rad;
//! # fn dummy() -> ::rad::errors::Result<()> {
//! use std::fs::File;
//! use std::io::Read;
//! use std::path::Path;
//!
//! use rad::RadosConnectionBuilder;
//!
//! let mut cluster = RadosConnectionBuilder::with_user("admin")?
//!     .read_conf_file(Path::new("/etc/ceph.conf"))?
//!     .conf_set("keyring", "/etc/ceph.client.admin.keyring")?
//!     .connect()?;
//!
//! // Read in bytes from some file to send to the cluster.
//! let mut file = File::open("/path/to/file")?;
//! let mut bytes = Vec::new();
//! file.read_to_end(&mut bytes)?;
//!
//! let mut pool = cluster.get_pool_context("rbd")?;
//!
//! pool.write_full("object-name", &bytes)?;
//!
//! // Our file is now in the cluster! We can check for its existence:
//! assert!(pool.exists("object-name")?);
//!
//! // And we can also check that it contains the bytes we wrote to it.
//! let mut bytes_from_cluster = vec![0u8; bytes.len()];
//! let bytes_read = pool.read("object-name", &mut bytes_from_cluster, 0)?;
//! assert_eq!(bytes_read, bytes_from_cluster.len());
//! assert!(bytes_from_cluster == bytes);
//! # Ok(()) } fn main() {}
//! ```
//!
//! ### Asynchronous cluster I/O
//!
//! ```rust,no_run
//! # extern crate futures;
//! # extern crate rad;
//! # extern crate rand;
//! # fn dummy() -> ::rad::errors::Result<()> {
//! use std::path::Path;
//! use std::io::Read;
//!
//! use futures::prelude::*;
//! use futures::stream;
//! use rand::{Rng, SeedableRng, XorShiftRng};
//!
//! use rad::RadosConnectionBuilder;
//!
//! const NUM_OBJECTS: usize = 8;
//!
//! let mut cluster = RadosConnectionBuilder::with_user("admin")?
//!     .read_conf_file(Path::new("/etc/ceph.conf"))?
//!     .conf_set("keyring", "/etc/ceph.client.admin.keyring")?
//!     .connect()?;
//!
//! let mut pool = cluster.get_pool_context("rbd")?;
//!
//! stream::iter_ok((0..NUM_OBJECTS)
//!     .map(|i| {
//!         let bytes = XorShiftRng::from_seed([i as u32 + 1, 2, 3, 4])
//!             .gen_iter::<u8>()
//!             .take(1 << 16)
//!             .collect::<Vec<u8>>();
//!
//!         let name = format!("object-{}", i);
//!
//!         pool.write_full_async(&name, &bytes)
//!     }))
//!     .buffer_unordered(NUM_OBJECTS)
//!     .collect()
//!     .wait()?;
//! # Ok(()) } fn main() {}
//! ```

#![recursion_limit = "1024"]

extern crate ceph_rust;
extern crate chrono;
#[macro_use]
extern crate error_chain;
extern crate ffi_pool;
extern crate futures;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate stable_deref_trait;

pub use stable_deref_trait::StableDeref;

#[macro_export]
macro_rules! c {
    ($s:expr) => {
        CString::new($s)
            .expect(concat!("Could not convert `", $s, "` to an FFI-compatible CString!"))
    };
}

mod async;
pub mod errors;
pub mod rados;

pub use errors::*;
pub use rados::{RadosConnectionBuilder, RadosConnection, RadosContext, RadosStat};
<|endoftext|>


<commit_before>// This is a part of rust-chrono.
// Copyright (c) 2014, Kang Seonghoon.
// See README.md and LICENSE.txt for details.

/*!
Experimental date and time handling for Rust.
*/

#![comment = "Date and time library for Rust"]
#![license = "MIT"]

#![feature(macro_rules)]
#![deny(missing_doc)]

extern crate num;
extern crate stdtime = "time";

pub use duration::Duration;
pub use offset::{Offset, LocalResult};
pub use offset::{UTC, FixedOffset, Local};
pub use naive::date::NaiveDate;
pub use naive::time::NaiveTime;
pub use naive::datetime::NaiveDateTime;
pub use date::Date;
pub use time::Time;
pub use datetime::DateTime;

pub mod duration {
    //! ISO 8601 duration.
    //!
    //! This used to be a part of rust-chrono,
    //! but has been subsequently merged into Rust's standard library.
    pub use std::time::duration::{MIN, MAX, Duration};
}
pub mod offset;
pub mod naive {
    //! Date and time types which do not concern about the timezones.
    //!
    //! They are primarily building blocks for other types (e.g. `Offset`),
    //! but can be also used for the simpler date and time handling.
    pub mod date;
    pub mod time;
    pub mod datetime;
}
pub mod date;
pub mod time;
pub mod datetime;
pub mod format;

/// The day of week (DOW).
///
/// The order of the days of week depends on the context.
/// One should prefer `*_from_monday` or `*_from_sunday` methods to get the correct result.
#[deriving(PartialEq, Eq, Clone, FromPrimitive, Show)]
pub enum Weekday {
    /// Monday.
    Mon = 0,
    /// Tuesday.
    Tue = 1,
    /// Wednesday.
    Wed = 2,
    /// Thursday.
    Thu = 3,
    /// Friday.
    Fri = 4,
    /// Saturday.
    Sat = 5,
    /// Sunday.
    Sun = 6,
}

impl Weekday {
    /// The next day in the week.
    #[inline]
    pub fn succ(&self) -> Weekday {
        match *self {
            Mon => Tue,
            Tue => Wed,
            Wed => Thu,
            Thu => Fri,
            Fri => Sat,
            Sat => Sun,
            Sun => Mon,
        }
    }

    /// The previous day in the week.
    #[inline]
    pub fn pred(&self) -> Weekday {
        match *self {
            Mon => Sun,
            Tue => Mon,
            Wed => Tue,
            Thu => Wed,
            Fri => Thu,
            Sat => Fri,
            Sun => Sat,
        }
    }

    /// Returns a DOW number starting from Monday = 1. (ISO 8601 weekday number)
    #[inline]
    pub fn number_from_monday(&self) -> u32 {
        match *self {
            Mon => 1,
            Tue => 2,
            Wed => 3,
            Thu => 4,
            Fri => 5,
            Sat => 6,
            Sun => 7,
        }
    }

    /// Returns a DOW number starting from Sunday = 1.
    #[inline]
    pub fn number_from_sunday(&self) -> u32 {
        match *self {
            Mon => 2,
            Tue => 3,
            Wed => 4,
            Thu => 5,
            Fri => 6,
            Sat => 7,
            Sun => 1,
        }
    }

    /// Returns a DOW number starting from Monday = 0.
    #[inline]
    pub fn num_days_from_monday(&self) -> u32 {
        match *self {
            Mon => 0,
            Tue => 1,
            Wed => 2,
            Thu => 3,
            Fri => 4,
            Sat => 5,
            Sun => 6,
        }
    }

    /// Returns a DOW number starting from Sunday = 0.
    #[inline]
    pub fn num_days_from_sunday(&self) -> u32 {
        match *self {
            Mon => 1,
            Tue => 2,
            Wed => 3,
            Thu => 4,
            Fri => 5,
            Sat => 6,
            Sun => 0,
        }
    }
}

/// The common set of methods for date component.
pub trait Datelike {
    /// Returns the year number.
    fn year(&self) -> i32;

    /// Returns the absolute year number starting from 1 with a boolean flag,
    /// which is false when the year predates the epoch (BCE/BC) and true otherwise (CE/AD).
    #[inline]
    fn year_ce(&self) -> (bool, u32) {
        let year = self.year();
        if year < 1 {
            (false, (1 - year) as u32)
        } else {
            (true, year as u32)
        }
    }

    /// Returns the month number starting from 1.
    fn month(&self) -> u32;

    /// Returns the month number starting from 0.
    fn month0(&self) -> u32;

    /// Returns the day of month starting from 1.
    fn day(&self) -> u32;

    /// Returns the day of month starting from 0.
    fn day0(&self) -> u32;

    /// Returns the day of year starting from 1.
    fn ordinal(&self) -> u32;

    /// Returns the day of year starting from 0.
    fn ordinal0(&self) -> u32;

    /// Returns the day of week.
    fn weekday(&self) -> Weekday;

    /// Returns the ISO week date: an adjusted year, week number and day of week.
    /// The adjusted year may differ from that of the calendar date.
    fn isoweekdate(&self) -> (i32, u32, Weekday);

    /// Makes a new value with the year number changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_year(&self, year: i32) -> Option<Self>;

    /// Makes a new value with the month number (starting from 1) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_month(&self, month: u32) -> Option<Self>;

    /// Makes a new value with the month number (starting from 0) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_month0(&self, month0: u32) -> Option<Self>;

    /// Makes a new value with the day of month (starting from 1) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_day(&self, day: u32) -> Option<Self>;

    /// Makes a new value with the day of month (starting from 0) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_day0(&self, day0: u32) -> Option<Self>;

    /// Makes a new value with the day of year (starting from 1) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_ordinal(&self, ordinal: u32) -> Option<Self>;

    /// Makes a new value with the day of year (starting from 0) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_ordinal0(&self, ordinal0: u32) -> Option<Self>;

    /// Returns the number of days since January 1, 1 (Day 1) in the proleptic Gregorian calendar.
    fn num_days_from_ce(&self) -> i32 {
        // we know this wouldn't overflow since year is limited to 1/2^13 of i32's full range.
        let mut year = self.year() - 1;
        let mut ndays = 0;
        if year < 0 {
            let excess = 1 + (-year) / 400;
            year += excess * 400;
            ndays -= excess * 146097;
        }
        let div_100 = year / 100;
        ndays += ((year * 1461) >> 2) - div_100 + (div_100 >> 2);
        ndays + self.ordinal() as i32
    }
}

/// The common set of methods for time component.
pub trait Timelike {
    /// Returns the hour number from 0 to 23.
    fn hour(&self) -> u32;

    /// Returns the hour number from 1 to 12 with a boolean flag,
    /// which is false for AM and true for PM.
    #[inline]
    fn hour12(&self) -> (bool, u32) {
        let hour = self.hour();
        let mut hour12 = hour % 12;
        if hour12 == 0 { hour12 = 12; }
        (hour >= 12, hour12)
    }

    /// Returns the minute number from 0 to 59.
    fn minute(&self) -> u32;

    /// Returns the second number from 0 to 59.
    fn second(&self) -> u32;

    /// Returns the number of nanoseconds since the whole non-leap second.
    /// The range from 1,000,000,000 to 1,999,999,999 represents the leap second.
    fn nanosecond(&self) -> u32;

    /// Makes a new value with the hour number changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_hour(&self, hour: u32) -> Option<Self>;

    /// Makes a new value with the minute number changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_minute(&self, min: u32) -> Option<Self>;

    /// Makes a new value with the second number changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_second(&self, sec: u32) -> Option<Self>;

    /// Makes a new value with nanoseconds since the whole non-leap second changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_nanosecond(&self, nano: u32) -> Option<Self>;

    /// Returns the number of non-leap seconds past the last midnight.
    #[inline]
    fn num_seconds_from_midnight(&self) -> u32 {
        self.hour() * 3600 + self.minute() * 60 + self.second()
    }
}

#[test]
fn test_readme_doomsday() {
    use std::iter::range_inclusive;

    for y in range_inclusive(naive::date::MIN.year(), naive::date::MAX.year()) {
        // even months
        let d4   = NaiveDate::from_ymd(y,  4,  4);
        let d6   = NaiveDate::from_ymd(y,  6,  6);
        let d8   = NaiveDate::from_ymd(y,  8,  8);
        let d10  = NaiveDate::from_ymd(y, 10, 10);
        let d12  = NaiveDate::from_ymd(y, 12, 12);

        // nine to five, seven-eleven
        let d59  = NaiveDate::from_ymd(y,  5,  9);
        let d95  = NaiveDate::from_ymd(y,  9,  5);
        let d711 = NaiveDate::from_ymd(y,  7, 11);
        let d117 = NaiveDate::from_ymd(y, 11,  7);

        // "March 0"
        let d30  = NaiveDate::from_ymd(y,  3,  1).pred();

        let weekday = d30.weekday();
        let other_dates = [d4, d6, d8, d10, d12, d59, d95, d711, d117];
        assert!(other_dates.iter().all(|d| d.weekday() == weekday));
    }
}

<commit_msg>language changes: `extern crate A = "B";` -> `extern crate "B" as A;`.<commit_after>// This is a part of rust-chrono.
// Copyright (c) 2014, Kang Seonghoon.
// See README.md and LICENSE.txt for details.

/*!
Experimental date and time handling for Rust.
*/

#![comment = "Date and time library for Rust"]
#![license = "MIT"]

#![feature(macro_rules)]
#![deny(missing_doc)]

extern crate num;
extern crate "time" as stdtime;

pub use duration::Duration;
pub use offset::{Offset, LocalResult};
pub use offset::{UTC, FixedOffset, Local};
pub use naive::date::NaiveDate;
pub use naive::time::NaiveTime;
pub use naive::datetime::NaiveDateTime;
pub use date::Date;
pub use time::Time;
pub use datetime::DateTime;

pub mod duration {
    //! ISO 8601 duration.
    //!
    //! This used to be a part of rust-chrono,
    //! but has been subsequently merged into Rust's standard library.
    pub use std::time::duration::{MIN, MAX, Duration};
}
pub mod offset;
pub mod naive {
    //! Date and time types which do not concern about the timezones.
    //!
    //! They are primarily building blocks for other types (e.g. `Offset`),
    //! but can be also used for the simpler date and time handling.
    pub mod date;
    pub mod time;
    pub mod datetime;
}
pub mod date;
pub mod time;
pub mod datetime;
pub mod format;

/// The day of week (DOW).
///
/// The order of the days of week depends on the context.
/// One should prefer `*_from_monday` or `*_from_sunday` methods to get the correct result.
#[deriving(PartialEq, Eq, Clone, FromPrimitive, Show)]
pub enum Weekday {
    /// Monday.
    Mon = 0,
    /// Tuesday.
    Tue = 1,
    /// Wednesday.
    Wed = 2,
    /// Thursday.
    Thu = 3,
    /// Friday.
    Fri = 4,
    /// Saturday.
    Sat = 5,
    /// Sunday.
    Sun = 6,
}

impl Weekday {
    /// The next day in the week.
    #[inline]
    pub fn succ(&self) -> Weekday {
        match *self {
            Mon => Tue,
            Tue => Wed,
            Wed => Thu,
            Thu => Fri,
            Fri => Sat,
            Sat => Sun,
            Sun => Mon,
        }
    }

    /// The previous day in the week.
    #[inline]
    pub fn pred(&self) -> Weekday {
        match *self {
            Mon => Sun,
            Tue => Mon,
            Wed => Tue,
            Thu => Wed,
            Fri => Thu,
            Sat => Fri,
            Sun => Sat,
        }
    }

    /// Returns a DOW number starting from Monday = 1. (ISO 8601 weekday number)
    #[inline]
    pub fn number_from_monday(&self) -> u32 {
        match *self {
            Mon => 1,
            Tue => 2,
            Wed => 3,
            Thu => 4,
            Fri => 5,
            Sat => 6,
            Sun => 7,
        }
    }

    /// Returns a DOW number starting from Sunday = 1.
    #[inline]
    pub fn number_from_sunday(&self) -> u32 {
        match *self {
            Mon => 2,
            Tue => 3,
            Wed => 4,
            Thu => 5,
            Fri => 6,
            Sat => 7,
            Sun => 1,
        }
    }

    /// Returns a DOW number starting from Monday = 0.
    #[inline]
    pub fn num_days_from_monday(&self) -> u32 {
        match *self {
            Mon => 0,
            Tue => 1,
            Wed => 2,
            Thu => 3,
            Fri => 4,
            Sat => 5,
            Sun => 6,
        }
    }

    /// Returns a DOW number starting from Sunday = 0.
    #[inline]
    pub fn num_days_from_sunday(&self) -> u32 {
        match *self {
            Mon => 1,
            Tue => 2,
            Wed => 3,
            Thu => 4,
            Fri => 5,
            Sat => 6,
            Sun => 0,
        }
    }
}

/// The common set of methods for date component.
pub trait Datelike {
    /// Returns the year number.
    fn year(&self) -> i32;

    /// Returns the absolute year number starting from 1 with a boolean flag,
    /// which is false when the year predates the epoch (BCE/BC) and true otherwise (CE/AD).
    #[inline]
    fn year_ce(&self) -> (bool, u32) {
        let year = self.year();
        if year < 1 {
            (false, (1 - year) as u32)
        } else {
            (true, year as u32)
        }
    }

    /// Returns the month number starting from 1.
    fn month(&self) -> u32;

    /// Returns the month number starting from 0.
    fn month0(&self) -> u32;

    /// Returns the day of month starting from 1.
    fn day(&self) -> u32;

    /// Returns the day of month starting from 0.
    fn day0(&self) -> u32;

    /// Returns the day of year starting from 1.
    fn ordinal(&self) -> u32;

    /// Returns the day of year starting from 0.
    fn ordinal0(&self) -> u32;

    /// Returns the day of week.
    fn weekday(&self) -> Weekday;

    /// Returns the ISO week date: an adjusted year, week number and day of week.
    /// The adjusted year may differ from that of the calendar date.
    fn isoweekdate(&self) -> (i32, u32, Weekday);

    /// Makes a new value with the year number changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_year(&self, year: i32) -> Option<Self>;

    /// Makes a new value with the month number (starting from 1) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_month(&self, month: u32) -> Option<Self>;

    /// Makes a new value with the month number (starting from 0) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_month0(&self, month0: u32) -> Option<Self>;

    /// Makes a new value with the day of month (starting from 1) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_day(&self, day: u32) -> Option<Self>;

    /// Makes a new value with the day of month (starting from 0) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_day0(&self, day0: u32) -> Option<Self>;

    /// Makes a new value with the day of year (starting from 1) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_ordinal(&self, ordinal: u32) -> Option<Self>;

    /// Makes a new value with the day of year (starting from 0) changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_ordinal0(&self, ordinal0: u32) -> Option<Self>;

    /// Returns the number of days since January 1, 1 (Day 1) in the proleptic Gregorian calendar.
    fn num_days_from_ce(&self) -> i32 {
        // we know this wouldn't overflow since year is limited to 1/2^13 of i32's full range.
        let mut year = self.year() - 1;
        let mut ndays = 0;
        if year < 0 {
            let excess = 1 + (-year) / 400;
            year += excess * 400;
            ndays -= excess * 146097;
        }
        let div_100 = year / 100;
        ndays += ((year * 1461) >> 2) - div_100 + (div_100 >> 2);
        ndays + self.ordinal() as i32
    }
}

/// The common set of methods for time component.
pub trait Timelike {
    /// Returns the hour number from 0 to 23.
    fn hour(&self) -> u32;

    /// Returns the hour number from 1 to 12 with a boolean flag,
    /// which is false for AM and true for PM.
    #[inline]
    fn hour12(&self) -> (bool, u32) {
        let hour = self.hour();
        let mut hour12 = hour % 12;
        if hour12 == 0 { hour12 = 12; }
        (hour >= 12, hour12)
    }

    /// Returns the minute number from 0 to 59.
    fn minute(&self) -> u32;

    /// Returns the second number from 0 to 59.
    fn second(&self) -> u32;

    /// Returns the number of nanoseconds since the whole non-leap second.
    /// The range from 1,000,000,000 to 1,999,999,999 represents the leap second.
    fn nanosecond(&self) -> u32;

    /// Makes a new value with the hour number changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_hour(&self, hour: u32) -> Option<Self>;

    /// Makes a new value with the minute number changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_minute(&self, min: u32) -> Option<Self>;

    /// Makes a new value with the second number changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_second(&self, sec: u32) -> Option<Self>;

    /// Makes a new value with nanoseconds since the whole non-leap second changed.
    ///
    /// Returns `None` when the resulting value would be invalid.
    fn with_nanosecond(&self, nano: u32) -> Option<Self>;

    /// Returns the number of non-leap seconds past the last midnight.
    #[inline]
    fn num_seconds_from_midnight(&self) -> u32 {
        self.hour() * 3600 + self.minute() * 60 + self.second()
    }
}

#[test]
fn test_readme_doomsday() {
    use std::iter::range_inclusive;

    for y in range_inclusive(naive::date::MIN.year(), naive::date::MAX.year()) {
        // even months
        let d4   = NaiveDate::from_ymd(y,  4,  4);
        let d6   = NaiveDate::from_ymd(y,  6,  6);
        let d8   = NaiveDate::from_ymd(y,  8,  8);
        let d10  = NaiveDate::from_ymd(y, 10, 10);
        let d12  = NaiveDate::from_ymd(y, 12, 12);

        // nine to five, seven-eleven
        let d59  = NaiveDate::from_ymd(y,  5,  9);
        let d95  = NaiveDate::from_ymd(y,  9,  5);
        let d711 = NaiveDate::from_ymd(y,  7, 11);
        let d117 = NaiveDate::from_ymd(y, 11,  7);

        // "March 0"
        let d30  = NaiveDate::from_ymd(y,  3,  1).pred();

        let weekday = d30.weekday();
        let other_dates = [d4, d6, d8, d10, d12, d59, d95, d711, d117];
        assert!(other_dates.iter().all(|d| d.weekday() == weekday));
    }
}

<|endoftext|>


<commit_before>#![cfg_attr(test, deny(missing_docs, warnings))]
#![forbid(unused_variables)]

use std::{fmt, mem};
use std::borrow::{Borrow, ToOwned};
use std::default::Default;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::ops::{Deref, Index, Range, RangeFrom, RangeFull, RangeTo};

/// An owned sequence of Unicode scalar values, equivalent to `String`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UString(Vec<char>);

/// A Unicode string slice, equivalent to `str`.
pub struct UStr([char]);

impl UString {
    pub fn remove(&mut self, idx: usize) -> char {
        self.0.remove(idx)
    }
}

impl UStr {
    /// Returns the number of Unicode scalar values in this string.
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Retrieves the first character from a `&UStr` and returns it.
    ///
    /// This does not allocate a new string; instead, it returns a slice that points one character beyond the character that was shifted.
    ///
    /// If the slice does not contain any characters, None is returned instead.
    pub fn slice_shift_char(&self) -> Option<(char, &UStr)> {
        if self.len() == 0 {
            None
        } else {
            let ch = self[0];
            let next_s = &self[1..];
            Some((ch, next_s))
        }
    }
}

impl Borrow<UStr> for UString {
    fn borrow(&self) -> &UStr {
        &self
    }
}

impl Default for UString {
    fn default() -> UString {
        UString(Vec::new())
    }
}

impl Deref for UString {
    type Target = UStr;

    fn deref(&self) -> &UStr {
        unsafe {
            mem::transmute(&*self.0)
            // just so you can be clear what it is:
            //mem::transmute::<&[char], &UStr>(&*self.0)
        }
    }
}

impl From<String> for UString {
    fn from(string: String) -> UString {
        UString(string.chars().collect())
    }
}

impl From<Vec<char>> for UString {
    fn from(chars: Vec<char>) -> UString {
        UString(chars)
    }
}

impl<'a> From<&'a str> for UString {
    fn from(string: &'a str) -> UString {
        UString(string.chars().collect())
    }
}

impl<'a> From<&'a [char]> for UString {
    fn from(slice: &[char]) -> UString {
        UString(slice.to_vec())
    }
}

impl From<UString> for String {
    fn from(string: UString) -> String {
        String::from_iter(string)
    }
}

impl<'a> From<&'a UString> for String {
    fn from(string: &UString) -> String {
        String::from_iter(string.into_iter().cloned())
    }
}

impl<'a> From<&'a UStr> for String {
    fn from(slice: &UStr) -> String {
        String::from_iter(slice.into_iter().cloned())
    }
}

impl<C: Into<char>> FromIterator<C> for UString {
    fn from_iter<T>(iterator: T) -> UString where T: IntoIterator<Item=C> {
        UString(iterator.into_iter().map(C::into).collect())
    }
}

impl Hash for UString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state);
    }
}

impl Index<usize> for UStr {
    type Output = char;

    fn index(&self, idx: usize) -> &char {
        &self.0[idx]
    }
}

impl Index<Range<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: Range<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFrom<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeFrom<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFull> for UStr {
    type Output = UStr;

    fn index(&self, _: RangeFull) -> &UStr {
        self
    }
}

impl Index<RangeTo<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeTo<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl ToOwned for UStr {
    type Owned = UString;

    fn to_owned(&self) -> UString {
        UString::from(self.0.to_owned())
    }
}

impl fmt::Display for UStr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for c in &self.0 {
            try!(write!(f, "{}", c));
        }
        Ok(())
    }
}

pub struct Iter<'a>(&'a [char]);

pub struct IntoIter(Vec<char>);

impl<'a> Iterator for Iter<'a> {
    type Item = &'a char;

    fn next(&mut self) -> Option<&'a char> {
        if self.0.len() > 0 {
            let result = &self.0[0];
            self.0 = &self.0[1..];
            Some(result)
        } else {
            None
        }
    }
}

impl Iterator for IntoIter {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        if self.0.len() > 0 {
            Some(self.0.remove(0))
        } else {
            None
        }
    }
}

impl IntoIterator for UString {
    type Item = char;
    type IntoIter = IntoIter;

    fn into_iter(self) -> IntoIter {
        IntoIter(self.0)
    }
}

impl<'a> IntoIterator for &'a UString {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}

impl<'a> IntoIterator for &'a UStr {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}
<commit_msg>Derive Debug for the iterator types<commit_after>#![cfg_attr(test, deny(missing_docs, warnings))]
#![forbid(unused_variables)]

use std::{fmt, mem};
use std::borrow::{Borrow, ToOwned};
use std::default::Default;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::ops::{Deref, Index, Range, RangeFrom, RangeFull, RangeTo};

/// An owned sequence of Unicode scalar values, equivalent to `String`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UString(Vec<char>);

/// A Unicode string slice, equivalent to `str`.
pub struct UStr([char]);

impl UString {
    pub fn remove(&mut self, idx: usize) -> char {
        self.0.remove(idx)
    }
}

impl UStr {
    /// Returns the number of Unicode scalar values in this string.
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Retrieves the first character from a `&UStr` and returns it.
    ///
    /// This does not allocate a new string; instead, it returns a slice that points one character beyond the character that was shifted.
    ///
    /// If the slice does not contain any characters, None is returned instead.
    pub fn slice_shift_char(&self) -> Option<(char, &UStr)> {
        if self.len() == 0 {
            None
        } else {
            let ch = self[0];
            let next_s = &self[1..];
            Some((ch, next_s))
        }
    }
}

impl Borrow<UStr> for UString {
    fn borrow(&self) -> &UStr {
        &self
    }
}

impl Default for UString {
    fn default() -> UString {
        UString(Vec::new())
    }
}

impl Deref for UString {
    type Target = UStr;

    fn deref(&self) -> &UStr {
        unsafe {
            mem::transmute(&*self.0)
            // just so you can be clear what it is:
            //mem::transmute::<&[char], &UStr>(&*self.0)
        }
    }
}

impl From<String> for UString {
    fn from(string: String) -> UString {
        UString(string.chars().collect())
    }
}

impl From<Vec<char>> for UString {
    fn from(chars: Vec<char>) -> UString {
        UString(chars)
    }
}

impl<'a> From<&'a str> for UString {
    fn from(string: &'a str) -> UString {
        UString(string.chars().collect())
    }
}

impl<'a> From<&'a [char]> for UString {
    fn from(slice: &[char]) -> UString {
        UString(slice.to_vec())
    }
}

impl From<UString> for String {
    fn from(string: UString) -> String {
        String::from_iter(string)
    }
}

impl<'a> From<&'a UString> for String {
    fn from(string: &UString) -> String {
        String::from_iter(string.into_iter().cloned())
    }
}

impl<'a> From<&'a UStr> for String {
    fn from(slice: &UStr) -> String {
        String::from_iter(slice.into_iter().cloned())
    }
}

impl<C: Into<char>> FromIterator<C> for UString {
    fn from_iter<T>(iterator: T) -> UString where T: IntoIterator<Item=C> {
        UString(iterator.into_iter().map(C::into).collect())
    }
}

impl Hash for UString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state);
    }
}

impl Index<usize> for UStr {
    type Output = char;

    fn index(&self, idx: usize) -> &char {
        &self.0[idx]
    }
}

impl Index<Range<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: Range<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFrom<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeFrom<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFull> for UStr {
    type Output = UStr;

    fn index(&self, _: RangeFull) -> &UStr {
        self
    }
}

impl Index<RangeTo<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeTo<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl ToOwned for UStr {
    type Owned = UString;

    fn to_owned(&self) -> UString {
        UString::from(self.0.to_owned())
    }
}

impl fmt::Display for UStr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for c in &self.0 {
            try!(write!(f, "{}", c));
        }
        Ok(())
    }
}

#[derive(Debug)]
pub struct Iter<'a>(&'a [char]);

#[derive(Debug)]
pub struct IntoIter(Vec<char>);

impl<'a> Iterator for Iter<'a> {
    type Item = &'a char;

    fn next(&mut self) -> Option<&'a char> {
        if self.0.len() > 0 {
            let result = &self.0[0];
            self.0 = &self.0[1..];
            Some(result)
        } else {
            None
        }
    }
}

impl Iterator for IntoIter {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        if self.0.len() > 0 {
            Some(self.0.remove(0))
        } else {
            None
        }
    }
}

impl IntoIterator for UString {
    type Item = char;
    type IntoIter = IntoIter;

    fn into_iter(self) -> IntoIter {
        IntoIter(self.0)
    }
}

impl<'a> IntoIterator for &'a UString {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}

impl<'a> IntoIterator for &'a UStr {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

mod groups;
mod hundreds;
mod tens;

mod words;
mod formatting;

#[cfg(test)]
mod test;<commit_msg>added main convert method<commit_after>#![allow(dead_code)]

mod groups;
mod hundreds;
mod tens;

mod words;
mod formatting;

#[cfg(test)]
mod test;

pub use formatting::Formatting;

pub fn convert(val: i64, fmt: Formatting) -> String
{
    groups::Groups::new(val)
        .build()
        .build(fmt)
}<|endoftext|>