<commit_before><commit_msg>Add redis pool example<commit_after>extern crate spaceapi_server;
extern crate env_logger;
extern crate redis;
extern crate r2d2;
extern crate r2d2_redis;

use spaceapi_server::SpaceapiServerBuilder;
use spaceapi_server::api;
use spaceapi_server::modifiers::StatusModifier;

use r2d2::Pool;
use r2d2_redis::RedisConnectionManager;
use redis::{Commands, RedisResult};

type RedisPool = Pool<RedisConnectionManager>;

struct OpenStatusFromRedisModifier {
    pool: RedisPool
}

impl OpenStatusFromRedisModifier {
    fn new(pool: RedisPool) -> OpenStatusFromRedisModifier {
        OpenStatusFromRedisModifier{pool}
    }
}

impl StatusModifier for OpenStatusFromRedisModifier {
    fn modify(&self, status: &mut api::Status) {
        let conn = self.pool.get().unwrap();
        let state : RedisResult<String> = conn.get("state_open");
        status.state.open = match state {
            Ok(v) => Some(v == "open"),
            Err(_) => None
        };
        status.state.lastchange = conn.get("state_lastchange").ok();
        status.state.trigger_person = conn.get("state_triggerperson").ok();
    }
}

fn main() {
    env_logger::init().unwrap();

    let status = api::StatusBuilder::new("Mittelab")
        .logo("https://www.mittelab.org/images/logo.svg")
        .url("https://www.mittelab.org")
        .location(api::Location {
            address: Some("Piazza Libertà 5/B, 34132 Trieste (TS), Italy".into()),
            lat: 45.656_652_6,
            lon: 13.773_387_2,
        })
        .contact(api::Contact {
            email: Some("info@mittelab.org".into()),
            irc: Some("irc://irc.freenode.net/#mittelab".into()),
            twitter: Some("@mittelab".into()),
            facebook: Some("https://facebook.com/mittelab".into()),
            phone: Some("+390409776431".into()),
            issue_mail: Some("sysadmin@mittelab.org".into()),
            ..Default::default()
        })
        .add_issue_report_channel("email")
        .add_project("https://git.mittelab.org")
        .add_project("https://github.com/mittelab")
        .add_project("https://wiki.mittelab.org/progetti/")
        .build()
        .expect("Creating status failed");

    let config = Default::default();
    let manager = r2d2_redis::RedisConnectionManager::new("redis://localhost").unwrap();
    let pool = r2d2::Pool::new(config, manager).unwrap();

    // Set up server
    let server = SpaceapiServerBuilder::new(status)
        // .add_redis_pool(pool) waiting for
        .redis_pool(pool.clone())
        .add_status_modifier(OpenStatusFromRedisModifier::new(pool))
        .build()
        .expect("Could not initialize server");

    // Serve!
    server.serve("127.0.0.1:8000").expect("Could not start the server");
}
<|endoftext|>


<commit_before><commit_msg>Add an example<commit_after>extern crate crowbook_text_processing;

use crowbook_text_processing::escape::*;
use crowbook_text_processing::clean::*;
use crowbook_text_processing::french::FrenchFormatter;

fn main() {

    let s = " Some  string with  too much   whitespaces & around 1% characters that might cause trouble to HTML or LaTeX.";
    let new_s = remove_whitespaces(s);
    println!("for HTML: {}", escape_html(new_s.clone()));
    println!("for LaTeX: {}", escape_tex(new_s));

    let s = " Une chaîne en français ! On voudrait un résultat « typographiquement correct ».";
    let new_s = FrenchFormatter::new().format(s);
    println!("for HTML: {}", escape_nb_spaces(escape_html(new_s.clone())));
    println!("for LaTeX: {}", escape_nb_spaces_tex(escape_tex(new_s)));
}
<|endoftext|>


<commit_before><commit_msg>Added a square example.<commit_after>extern crate orbclient;
extern crate tetrahedrane;

fn rotate(x: f32, y: f32, around_x: f32, around_y: f32, angle: f32) -> (f32, f32) {
    use std::f32;

    let s = f32::sin(angle);
    let c = f32::cos(angle);

    let x = x - around_x;
    let y = y - around_y;

    let x = x * c - y * s;
    let y = x * s + y * c;

    (x + around_x, y + around_y)
}

fn main() {
    use tetrahedrane::geometry::{Triangle, Point};
    let mut window = orbclient::window::Window::new_flags(-1, -1, 640, 480, &"dziki wunsz", true).unwrap();

    let mut framecounter = 0;
    let mut timecounter = std::time::Duration::new(0,0);

    let mut triangle1 = Triangle::new(Point::new(-0.5, -0.5, 1.0),
                                      Point::new( 0.5, -0.5, 1.0),
                                      Point::new( 0.5,  0.5, 1.0));

    let mut triangle2 = Triangle::new(Point::new( 0.5,  0.5, 1.0),
                                      Point::new(-0.5,  0.5, 1.0),
                                      Point::new(-0.5, -0.5, 1.0));

    'gameloop: loop {
        use tetrahedrane::util::Rotation;

        let begin = std::time::Instant::now();

        for event in window.events() {
            use orbclient::event::EventOption;
            let ev_opt = event.to_option();

            match ev_opt {
                EventOption::Quit(..) => break 'gameloop,
                _ => {}
            }
        }

        window.clear();

        tetrahedrane::renderers::filled::triangle_s(&triangle1,
                                                    orbclient::Color::rgb(255,0,255),
                                                    &mut window);

        tetrahedrane::renderers::filled::triangle_s(&triangle2,
                                                    orbclient::Color::rgb(255,0,255),
                                                    &mut window);

        /*let (n_x, n_y) = rotate(triangle1.p1.x, triangle1.p1.y, 0.0, 0.0, 0.01);

        println!("{} {}", n_x, n_y);

        triangle1.p1.x = n_x;
        triangle1.p1.y = n_y;*/
        triangle1.rotate_x_y(0.0, 0.0, 0.01);
        triangle2.rotate_x_y(0.0, 0.0, 0.01);
        triangle1.rotate_x_z(0.0, 1.0, 0.01);
        triangle2.rotate_x_z(0.0, 1.0, 0.01);
        triangle1.rotate_y_z(0.0, 1.0, 0.02);
        triangle2.rotate_y_z(0.0, 1.0, 0.02);

        window.sync();

        let end = std::time::Instant::now();

        framecounter += 1;
        timecounter += end.duration_since(begin);

        if timecounter > std::time::Duration::new(1, 0) {
            timecounter = std::time::Duration::new(0, 0);
            println!("FPS: {}", framecounter);
            framecounter = 0;
        }
    }
}<|endoftext|>


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

use prelude::v1::*;

use cmp;
use fmt;
use intrinsics;
use libc::{self, uintptr_t};
use os;
use slice;
use str;
use sync::atomic::{self, Ordering};

/// Dynamically inquire about whether we're running under V.
/// You should usually not use this unless your test definitely
/// can't run correctly un-altered. Valgrind is there to help
/// you notice weirdness in normal, un-doctored code paths!
pub fn running_on_valgrind() -> bool {
    extern {
        fn rust_running_on_valgrind() -> uintptr_t;
    }
    unsafe { rust_running_on_valgrind() != 0 }
}

/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors
/// wired into it; this is a hard limit and requires rebuilding valgrind if you
/// want to go beyond it. Normally this is not a problem, but in some tests, we
/// produce a lot of threads casually.  Making lots of threads alone might not
/// be a problem _either_, except on OSX, the segments produced for new threads
/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv
/// schedulers fork off a separate thread for polling fsevents on OSX, we get a
/// perfect storm of creating "too many mappings" for valgrind to handle when
/// running certain stress tests in the runtime.
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
    (cfg!(target_os="macos")) && running_on_valgrind()
}

pub fn min_stack() -> uint {
    static MIN: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
    match MIN.load(Ordering::SeqCst) {
        0 => {}
        n => return n - 1,
    }
    let amt = os::getenv("RUST_MIN_STACK").and_then(|s| s.parse());
    let amt = amt.unwrap_or(2 * 1024 * 1024);
    // 0 is our sentinel value, so ensure that we'll never see 0 after
    // initialization has run
    MIN.store(amt + 1, Ordering::SeqCst);
    return amt;
}

/// Get's the number of scheduler threads requested by the environment
/// either `RUST_THREADS` or `num_cpus`.
pub fn default_sched_threads() -> uint {
    match os::getenv("RUST_THREADS") {
        Some(nstr) => {
            let opt_n: Option<uint> = nstr.parse();
            match opt_n {
                Some(n) if n > 0 => n,
                _ => panic!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
            }
        }
        None => {
            if limit_thread_creation_due_to_osx_and_valgrind() {
                1
            } else {
                os::num_cpus()
            }
        }
    }
}

// Indicates whether we should perform expensive sanity checks, including rtassert!
//
// FIXME: Once the runtime matures remove the `true` below to turn off rtassert,
//        etc.
pub const ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) ||
                                  cfg!(rtassert);

#[allow(missing_copy_implementations)]
pub struct Stdio(libc::c_int);

#[allow(non_upper_case_globals)]
pub const Stdout: Stdio = Stdio(libc::STDOUT_FILENO);
#[allow(non_upper_case_globals)]
pub const Stderr: Stdio = Stdio(libc::STDERR_FILENO);

impl Stdio {
    pub fn write_bytes(&mut self, data: &[u8]) {
        #[cfg(unix)]
        type WriteLen = libc::size_t;
        #[cfg(windows)]
        type WriteLen = libc::c_uint;
        unsafe {
            let Stdio(fd) = *self;
            libc::write(fd,
                        data.as_ptr() as *const libc::c_void,
                        data.len() as WriteLen);
        }
    }
}

impl fmt::Writer for Stdio {
    fn write_str(&mut self, data: &str) -> fmt::Result {
        self.write_bytes(data.as_bytes());
        Ok(()) // yes, we're lying
    }
}

pub fn dumb_print(args: fmt::Arguments) {
    let _ = Stderr.write_fmt(args);
}

pub fn abort(args: fmt::Arguments) -> ! {
    use fmt::Writer;

    struct BufWriter<'a> {
        buf: &'a mut [u8],
        pos: uint,
    }
    impl<'a> fmt::Writer for BufWriter<'a> {
        fn write_str(&mut self, bytes: &str) -> fmt::Result {
            let left = self.buf.slice_from_mut(self.pos);
            let to_write = &bytes.as_bytes()[0..cmp::min(bytes.len(), left.len())];
            slice::bytes::copy_memory(left, to_write);
            self.pos += to_write.len();
            Ok(())
        }
    }

    // Convert the arguments into a stack-allocated string
    let mut msg = [0u8; 512];
    let mut w = BufWriter { buf: &mut msg, pos: 0 };
    let _ = write!(&mut w, "{}", args);
    let msg = str::from_utf8(&w.buf[0..w.pos]).unwrap_or("aborted");
    let msg = if msg.is_empty() {"aborted"} else {msg};

    // Give some context to the message
    let hash = msg.bytes().fold(0, |accum, val| accum + (val as uint) );
    let quote = match hash % 10 {
        0 => "
It was from the artists and poets that the pertinent answers came, and I
know that panic would have broken loose had they been able to compare notes.
As it was, lacking their original letters, I half suspected the compiler of
having asked leading questions, or of having edited the correspondence in
corroboration of what he had latently resolved to see.",
        1 => "
There are not many persons who know what wonders are opened to them in the
stories and visions of their youth; for when as children we listen and dream,
we think but half-formed thoughts, and when as men we try to remember, we are
dulled and prosaic with the poison of life. But some of us awake in the night
with strange phantasms of enchanted hills and gardens, of fountains that sing
in the sun, of golden cliffs overhanging murmuring seas, of plains that stretch
down to sleeping cities of bronze and stone, and of shadowy companies of heroes
that ride caparisoned white horses along the edges of thick forests; and then
we know that we have looked back through the ivory gates into that world of
wonder which was ours before we were wise and unhappy.",
        2 => "
Instead of the poems I had hoped for, there came only a shuddering blackness
and ineffable loneliness; and I saw at last a fearful truth which no one had
ever dared to breathe before — the unwhisperable secret of secrets — The fact
that this city of stone and stridor is not a sentient perpetuation of Old New
York as London is of Old London and Paris of Old Paris, but that it is in fact
quite dead, its sprawling body imperfectly embalmed and infested with queer
animate things which have nothing to do with it as it was in life.",
        3 => "
The ocean ate the last of the land and poured into the smoking gulf, thereby
giving up all it had ever conquered. From the new-flooded lands it flowed
again, uncovering death and decay; and from its ancient and immemorial bed it
trickled loathsomely, uncovering nighted secrets of the years when Time was
young and the gods unborn. Above the waves rose weedy remembered spires. The
moon laid pale lilies of light on dead London, and Paris stood up from its damp
grave to be sanctified with star-dust. Then rose spires and monoliths that were
weedy but not remembered; terrible spires and monoliths of lands that men never
knew were lands...",
        4 => "
There was a night when winds from unknown spaces whirled us irresistibly into
limitless vacuum beyond all thought and entity. Perceptions of the most
maddeningly untransmissible sort thronged upon us; perceptions of infinity
which at the time convulsed us with joy, yet which are now partly lost to my
memory and partly incapable of presentation to others.",
        _ => "You've met with a terrible fate, haven't you?"
    };
    rterrln!("{}", "");
    rterrln!("{}", quote);
    rterrln!("{}", "");
    rterrln!("fatal runtime error: {}", msg);
    unsafe { intrinsics::abort(); }
}

pub unsafe fn report_overflow() {
    use thread::Thread;

    // See the message below for why this is not emitted to the
    // ^ Where did the message below go?
    // task's logger. This has the additional conundrum of the
    // logger may not be initialized just yet, meaning that an FFI
    // call would happen to initialized it (calling out to libuv),
    // and the FFI call needs 2MB of stack when we just ran out.

    rterrln!("\nthread '{}' has overflowed its stack",
             Thread::current().name().unwrap_or("<unknown>"));
}
<commit_msg>auto merge of #20944 : brson/rust/weve-met-with-a-terrible-fate-havent-we, r=brson<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// ignore-lexer-test FIXME #15677

use prelude::v1::*;

use cmp;
use fmt;
use intrinsics;
use libc::{self, uintptr_t};
use os;
use slice;
use str;
use sync::atomic::{self, Ordering};

/// Dynamically inquire about whether we're running under V.
/// You should usually not use this unless your test definitely
/// can't run correctly un-altered. Valgrind is there to help
/// you notice weirdness in normal, un-doctored code paths!
pub fn running_on_valgrind() -> bool {
    extern {
        fn rust_running_on_valgrind() -> uintptr_t;
    }
    unsafe { rust_running_on_valgrind() != 0 }
}

/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors
/// wired into it; this is a hard limit and requires rebuilding valgrind if you
/// want to go beyond it. Normally this is not a problem, but in some tests, we
/// produce a lot of threads casually.  Making lots of threads alone might not
/// be a problem _either_, except on OSX, the segments produced for new threads
/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv
/// schedulers fork off a separate thread for polling fsevents on OSX, we get a
/// perfect storm of creating "too many mappings" for valgrind to handle when
/// running certain stress tests in the runtime.
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
    (cfg!(target_os="macos")) && running_on_valgrind()
}

pub fn min_stack() -> uint {
    static MIN: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
    match MIN.load(Ordering::SeqCst) {
        0 => {}
        n => return n - 1,
    }
    let amt = os::getenv("RUST_MIN_STACK").and_then(|s| s.parse());
    let amt = amt.unwrap_or(2 * 1024 * 1024);
    // 0 is our sentinel value, so ensure that we'll never see 0 after
    // initialization has run
    MIN.store(amt + 1, Ordering::SeqCst);
    return amt;
}

/// Get's the number of scheduler threads requested by the environment
/// either `RUST_THREADS` or `num_cpus`.
pub fn default_sched_threads() -> uint {
    match os::getenv("RUST_THREADS") {
        Some(nstr) => {
            let opt_n: Option<uint> = nstr.parse();
            match opt_n {
                Some(n) if n > 0 => n,
                _ => panic!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
            }
        }
        None => {
            if limit_thread_creation_due_to_osx_and_valgrind() {
                1
            } else {
                os::num_cpus()
            }
        }
    }
}

// Indicates whether we should perform expensive sanity checks, including rtassert!
//
// FIXME: Once the runtime matures remove the `true` below to turn off rtassert,
//        etc.
pub const ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) ||
                                  cfg!(rtassert);

#[allow(missing_copy_implementations)]
pub struct Stdio(libc::c_int);

#[allow(non_upper_case_globals)]
pub const Stdout: Stdio = Stdio(libc::STDOUT_FILENO);
#[allow(non_upper_case_globals)]
pub const Stderr: Stdio = Stdio(libc::STDERR_FILENO);

impl Stdio {
    pub fn write_bytes(&mut self, data: &[u8]) {
        #[cfg(unix)]
        type WriteLen = libc::size_t;
        #[cfg(windows)]
        type WriteLen = libc::c_uint;
        unsafe {
            let Stdio(fd) = *self;
            libc::write(fd,
                        data.as_ptr() as *const libc::c_void,
                        data.len() as WriteLen);
        }
    }
}

impl fmt::Writer for Stdio {
    fn write_str(&mut self, data: &str) -> fmt::Result {
        self.write_bytes(data.as_bytes());
        Ok(()) // yes, we're lying
    }
}

pub fn dumb_print(args: fmt::Arguments) {
    let _ = Stderr.write_fmt(args);
}

pub fn abort(args: fmt::Arguments) -> ! {
    use fmt::Writer;

    struct BufWriter<'a> {
        buf: &'a mut [u8],
        pos: uint,
    }
    impl<'a> fmt::Writer for BufWriter<'a> {
        fn write_str(&mut self, bytes: &str) -> fmt::Result {
            let left = self.buf.slice_from_mut(self.pos);
            let to_write = &bytes.as_bytes()[0..cmp::min(bytes.len(), left.len())];
            slice::bytes::copy_memory(left, to_write);
            self.pos += to_write.len();
            Ok(())
        }
    }

    // Convert the arguments into a stack-allocated string
    let mut msg = [0u8; 512];
    let mut w = BufWriter { buf: &mut msg, pos: 0 };
    let _ = write!(&mut w, "{}", args);
    let msg = str::from_utf8(&w.buf[0..w.pos]).unwrap_or("aborted");
    let msg = if msg.is_empty() {"aborted"} else {msg};
    rterrln!("fatal runtime error: {}", msg);
    unsafe { intrinsics::abort(); }
}

pub unsafe fn report_overflow() {
    use thread::Thread;

    // See the message below for why this is not emitted to the
    // ^ Where did the message below go?
    // task's logger. This has the additional conundrum of the
    // logger may not be initialized just yet, meaning that an FFI
    // call would happen to initialized it (calling out to libuv),
    // and the FFI call needs 2MB of stack when we just ran out.

    rterrln!("\nthread '{}' has overflowed its stack",
             Thread::current().name().unwrap_or("<unknown>"));
}
<|endoftext|>


<commit_before><commit_msg>Add current state of stems.rs<commit_after>extern crate stemmer;

use self::stemmer::Stemmer;

//#[derive(Debug)]
pub struct Stems<'a> {
    text: &'a str,
    // The current cursor position
    current: usize,
    stemmer: Stemmer,
}

#[derive(Debug, PartialEq)]
pub struct StemmedWord {
    // Where the stemmed word starts
    pub stemmed_offset: usize,
    // Where the suffix starts
    pub suffix_offset: usize,
    // The length of the suffix
    suffix_len: usize,
    pub stemmed: String,
    pub suffix: String,
}

impl<'a> Stems<'a> {
    pub fn new(text: &str) -> Stems {
        Stems{
            text: text,
            current: 0,
            stemmer: Stemmer::new("english").unwrap(),
        }
    }

    /// Return the *byte* length of the common prefix between two strings
    fn common_prefix_len(aa: &str, bb: &str) -> usize {
        let mut count = 0;
        for (charsa, charsb) in aa.chars().zip(bb.chars()) {
            if charsa != charsb {
                break;
            }
            count += charsa.len_utf8();
          }
        count
    }
}

impl<'a> Iterator for Stems<'a> {
    type Item = StemmedWord;

    fn next(&mut self) -> Option<StemmedWord> {
        let text = &self.text[self.current..];
        let mut word_start = 0;
        let mut word_len = 0;
        for cc in text.chars() {
            // A character that is part of a word we want to stem
            if cc.is_alphabetic() {
                word_len += cc.len_utf8();
            }
            else {
                // There might be characters we don't care about for stemming
                // (whitespace and numbers) before the word
                if word_len == 0 {
                    word_start += cc.len_utf8();
                }
                // We've reached the end of the word
                else  {
                    break;
                }
            }
        }
        // No word found
        if word_len == 0 {
            None
        } else {
            // Do the actual stemming
            let input = text[word_start..word_start + word_len].to_lowercase();
            // The lowercase version might contain more bytes than the uppercase one:
            // e.g. İ => i̇
            let lowercase_len = input.len();
            let stemmed = self.stemmer.stem(&input);
            let prefix_len = Stems::common_prefix_len(&stemmed, &input);
            println!("{} {} {}", input, stemmed, prefix_len);

            let ret = StemmedWord {
                stemmed_offset: self.current + word_start,
                suffix_offset: self.current + word_start + prefix_len,
                suffix_len: lowercase_len - prefix_len,
                stemmed: stemmed,
                suffix: (&input[prefix_len..lowercase_len]).to_string(),
            };
            self.current += word_start + word_len;
            Some(ret)
        }
    }

}

#[cfg(test)]
mod tests {
    use super::{StemmedWord, Stems};

    #[test]
    fn test_stems_lowercase() {
        let input = "These words deeply test smoothly that stemming";
        let stems = Stems::new(input);
        let result = Stems::new(input).collect::<Vec<StemmedWord>>();
        let expected = vec![
            StemmedWord { stemmed_offset: 0, suffix_offset: 5, suffix_len: 0,
                          stemmed: String::from("these"), suffix: String::from("") },
            StemmedWord { stemmed_offset: 6, suffix_offset: 10, suffix_len: 1,
                          stemmed: String::from("word"), suffix: String::from("s") },
            // "deeply" stems to "deepli"
            StemmedWord { stemmed_offset: 12, suffix_offset: 17, suffix_len: 1,
                          stemmed: String::from("deepli"), suffix: String::from("y") },
            StemmedWord { stemmed_offset: 19, suffix_offset: 23, suffix_len: 0,
                          stemmed: String::from("test"), suffix: String::from("") },
            StemmedWord { stemmed_offset: 24, suffix_offset: 30, suffix_len: 2,
                          stemmed: String::from("smooth"), suffix: String::from("ly") },
            StemmedWord { stemmed_offset: 33, suffix_offset: 37, suffix_len: 0,
                          stemmed: String::from("that"), suffix: String::from("") },
            StemmedWord { stemmed_offset: 38, suffix_offset: 42, suffix_len: 4,
                          stemmed: String::from("stem"), suffix: String::from("ming") },
            ];
        assert_eq!(result.len(), expected.len());
        for (stem, expected_stem) in result.iter().zip(expected.iter()) {
            assert_eq!(stem, expected_stem);
        }
    }

    #[test]
    fn test_stems_mixedcase() {
        let input = "THEse Words deeplY test smOOthly that stemmING";
        let stems = Stems::new(input);
        let result = Stems::new(input).collect::<Vec<StemmedWord>>();
        let expected = vec![
            StemmedWord { stemmed_offset: 0, suffix_offset: 5, suffix_len: 0,
                          stemmed: String::from("these"), suffix: String::from("") },
            StemmedWord { stemmed_offset: 6, suffix_offset: 10, suffix_len: 1,
                          stemmed: String::from("word"), suffix: String::from("s") },
            // "deeply" stems to "deepli"
            StemmedWord { stemmed_offset: 12, suffix_offset: 17, suffix_len: 1,
                          stemmed: String::from("deepli"), suffix: String::from("y") },
            StemmedWord { stemmed_offset: 19, suffix_offset: 23, suffix_len: 0,
                          stemmed: String::from("test"), suffix: String::from("") },
            StemmedWord { stemmed_offset: 24, suffix_offset: 30, suffix_len: 2,
                          stemmed: String::from("smooth"), suffix: String::from("ly") },
            StemmedWord { stemmed_offset: 33, suffix_offset: 37, suffix_len: 0,
                          stemmed: String::from("that"), suffix: String::from("") },
            StemmedWord { stemmed_offset: 38, suffix_offset: 42, suffix_len: 4,
                          stemmed: String::from("stem"), suffix: String::from("ming") },
            ];
        assert_eq!(result.len(), expected.len());
        for (stem, expected_stem) in result.iter().zip(expected.iter()) {
            assert_eq!(stem, expected_stem);
        }
    }

    #[test]
    fn test_stems_nonchars() {
        let input = "  1234 \t89";
        let stems = Stems::new(input);
        let result = Stems::new(input).collect::<Vec<StemmedWord>>();
        assert_eq!(result.len(), 0);
    }

    #[test]
    fn test_stems_some_nonchars() {
        let input = "534   Let's seeing89";
        let result = Stems::new(input).collect::<Vec<StemmedWord>>();
        let expected = vec![
            StemmedWord { stemmed_offset: 6, suffix_offset: 9, suffix_len: 0,
                          stemmed: String::from("let"), suffix: String::from("") },
            StemmedWord { stemmed_offset: 10, suffix_offset: 11, suffix_len: 0,
                          stemmed: String::from("s"), suffix: String::from("") },
            StemmedWord { stemmed_offset: 12, suffix_offset: 15, suffix_len: 3,
                          stemmed: String::from("see"), suffix: String::from("ing") },
            ];
        assert_eq!(result.len(), expected.len());
        for (stem, expected_stem) in result.iter().zip(expected.iter()) {
            assert_eq!(stem, expected_stem);
        }
    }

    #[test]
    fn test_stems_unicode() {
        let input = "Ünicöde stemming";
        let result = Stems::new(input).collect::<Vec<StemmedWord>>();
        let expected = vec![
            StemmedWord { stemmed_offset: 0, suffix_offset: 8, suffix_len: 1,
                          stemmed: String::from("ünicöd"), suffix: String::from("e") },
            StemmedWord { stemmed_offset: 10, suffix_offset: 14, suffix_len: 4,
                          stemmed: String::from("stem"), suffix: String::from("ming") },
            ];
        assert_eq!(result.len(), expected.len());
        for (stem, expected_stem) in result.iter().zip(expected.iter()) {
            assert_eq!(stem, expected_stem);
        }
    }

    #[test]
    fn test_stems_unicode_lowercase_has_more_bytes() {
        let input = "İ";
        println!("{} {} {} {}", input, input.to_lowercase(), input.len(), input.to_lowercase().len());
        let stems = Stems::new(input);
        for stemmed in stems {
            println!("stemmed: {:?}", stemmed);
        }
        let result = Stems::new(input).collect::<Vec<StemmedWord>>();
        let expected = vec![
            StemmedWord { stemmed_offset: 0, suffix_offset: 3, suffix_len: 0,
                          stemmed: String::from("i̇"), suffix: String::from("") },
            ];
        assert_eq!(result.len(), expected.len());
        for (stem, expected_stem) in result.iter().zip(expected.iter()) {
            assert_eq!(stem, expected_stem);
        }
    }

    // NOTE vmx 2016-10-21: Those cases exist in theory, but (language independent) it doesn't
    // seem to be the case (after reading
    // ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt ). Some characters don't have
    // a corresponding uppercase chararacter with the same byte size, but when those uppercase
    // letters are transformed, to lowercase, they are transformed to the same number of bytes
    // combining several characters (although there is a single character for it).
    // Here's an example in Python:
    //
    //     >>> u"Ρ̓".lower() == u"ῤ"
    //     False
    //     >>> u"Ρ̓".lower() == u"ῤ".upper().lower()
    //     True
    // Or Rust:
    //
    //    let upper = "Ρ̓";
    //    let lower = "ῤ";
    //    println!("lower({}) == {}: {}", upper, lower, upper.to_lowercase() == lower);
    //    println!("lower({}) == lower(upper({})): {}", upper, lower, upper.to_lowercase() == lower.to_uppercase().to_lowercase());
    //    lower(Ρ̓) == ῤ: false
    //    lower(Ρ̓) == lower(upper(ῤ)): true
    //#[test]
    //fn test_stems_unicode_lowercase_has_less_bytes() {
    //}

    #[test]
    fn test_common_prefix_len() {
        let tests = vec![
            ("a", "a", 1),
            ("ab", "a", 1),
            ("a", "ab", 1),
            ("ab", "ab", 2),
            ("a", "b", 0),
            ("b", "a", 0),
            ("ab", "cd", 0),
            ("ab", "bc", 0),
            ("abc", "abd", 2),
            ("ac", "abcd", 1),
            (" a", "a", 0),
            ("a", "a ", 1),
            ("xyzabc", "xyz", 3),
            ("xyz", "xyzabc", 3),
            ("öxyz", "öx", 3),
            ];
        for (aa, bb, expected) in tests {
            let prefix_len = Stems::common_prefix_len(aa, bb);
            assert_eq!(prefix_len, expected);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Fixed issue with secret<commit_after><|endoftext|>


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

#![feature(generators)]

fn foo(_b: &bool, _a: ()) {}

fn main() {
	|| {
		let b = true;
		foo(&b, yield); // ERROR `b` does not live long enough
	};
}
<|endoftext|>


<commit_before><commit_msg>tut-02 uses a view transform<commit_after><|endoftext|>


<commit_before><commit_msg>test borrowing untagged enum<commit_after>// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use]
extern crate serde_derive;

#[derive(Deserialize)]
#[serde(untagged)]
enum RelData<'a> {
    Single(#[serde(borrow)] RelObject<'a>),
    Many(#[serde(borrow)] Vec<RelObject<'a>>),
}

#[derive(Deserialize)]
struct RelObject<'a> {
    ty: &'a str,
    id: String,
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Impl. get_left_child<commit_after><|endoftext|>


<commit_before><commit_msg>[Rust] "".to_string() is the same with String::new()<commit_after>fn main() {
    let a = String::new();
    let b = "".to_string();
    assert_eq!(a, b);
    assert_eq!(a.as_str(), b.as_str());
}
<|endoftext|>


<commit_before><commit_msg>practice<commit_after>fn add_one(x: i32) -> i32 {
    x + 1
}

fn main() {
    println!("{}", add_one(1));
}
<|endoftext|>


<commit_before>// Code that generates a test runner to run all the tests in a crate

import std::option;
import std::ivec;
import syntax::ast;
import syntax::fold;

export modify_for_testing;

type node_id_gen = @fn() -> ast::node_id;

type test_ctxt = rec(node_id_gen next_node_id,
                     mutable ast::ident[] path);

// Traverse the crate, collecting all the test functions, eliding any
// existing main functions, and synthesizing a main test harness
fn modify_for_testing(@ast::crate crate) -> @ast::crate {

    // FIXME: This hackasaurus assumes that 200000 is a safe number to start
    // generating node_ids at (which is totally not the case). pauls is going
    // to land a patch that puts parse_sess into session, which will give us
    // access to the real next node_id.
    auto next_node_id = @mutable 200000;
    auto next_node_id_fn = @bind fn(@mutable ast::node_id next_node_id)
        -> ast::node_id {
        auto this_node_id = *next_node_id;
        *next_node_id = next_node_id + 1;
        ret this_node_id;
    } (next_node_id);

    auto cx = rec(next_node_id = next_node_id_fn,
                  mutable path = ~[]);

    auto precursor = rec(fold_crate = bind fold_crate(cx, _, _),
                         fold_item = bind fold_item(cx, _, _)
                         with *fold::default_ast_fold());

    auto fold = fold::make_fold(precursor);
    auto res = @fold.fold_crate(*crate);
    // FIXME: This is necessary to break a circular reference
    fold::dummy_out(fold);
    ret res;
}

fn fold_crate(&test_ctxt cx, &ast::crate_ c,
              fold::ast_fold fld) -> ast::crate_ {
    auto folded = fold::noop_fold_crate(c, fld);

    // Add a special __test module to the crate that will contain code
    // generated for the test harness
    ret rec(module = add_test_module(cx, folded.module)
            with folded);
}

fn add_test_module(&test_ctxt cx, &ast::_mod m) -> ast::_mod {
    auto testmod = mk_test_module(cx);
    ret rec(items=m.items + ~[testmod] with m);
}

fn mk_test_module(&test_ctxt cx) -> @ast::item {
    auto mainfn = mk_main(cx);
    let ast::_mod testmod = rec(view_items=~[], items=~[mainfn]);
    auto item_ = ast::item_mod(testmod);
    let ast::item item = rec(ident = "__test",
                             attrs = ~[],
                             id = cx.next_node_id(),
                             node = item_,
                             span = rec(lo=0u, hi=0u));
    ret @item;
}

fn mk_main(&test_ctxt cx) -> @ast::item {
    auto ret_ty = @rec(node=ast::ty_nil,
                       span=rec(lo=0u, hi=0u));

    let ast::fn_decl decl = rec(inputs = ~[],
                                output = ret_ty,
                                purity = ast::impure_fn,
                                cf = ast::return,
                                constraints = ~[]);
    auto proto = ast::proto_fn;

    let ast::block_ body_ = rec(stmts = ~[],
                                 expr = option::none,
                                 id = cx.next_node_id());
    auto body = rec(node = body_, span = rec(lo=0u, hi=0u));

    auto fn_ = rec(decl = decl,
                   proto = proto,
                   body = body);

    auto item_ = ast::item_fn(fn_, ~[]);
    let ast::item item = rec(ident = "main",
                             attrs = ~[],
                             id = cx.next_node_id(),
                             node = item_,
                             span = rec(lo=0u, hi=0u));
    ret @item;
}

fn fold_item(&test_ctxt cx, &@ast::item i,
             fold::ast_fold fld) -> @ast::item {

    cx.path += ~[i.ident];
    log #fmt("current path: %s", ast::path_name_i(cx.path));
    auto res = fold::noop_fold_item(i, fld);
    ivec::pop(cx.path);
    ret res;
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>Collect functions that look like unit tests. Issue #428<commit_after>// Code that generates a test runner to run all the tests in a crate

import std::option;
import std::ivec;
import syntax::ast;
import syntax::fold;
import front::attr;

export modify_for_testing;

type node_id_gen = @fn() -> ast::node_id;

type test_ctxt = rec(node_id_gen next_node_id,
                     mutable ast::ident[] path,
                     mutable ast::ident[][] testfns);

// Traverse the crate, collecting all the test functions, eliding any
// existing main functions, and synthesizing a main test harness
fn modify_for_testing(@ast::crate crate) -> @ast::crate {

    // FIXME: This hackasaurus assumes that 200000 is a safe number to start
    // generating node_ids at (which is totally not the case). pauls is going
    // to land a patch that puts parse_sess into session, which will give us
    // access to the real next node_id.
    auto next_node_id = @mutable 200000;
    auto next_node_id_fn = @bind fn(@mutable ast::node_id next_node_id)
        -> ast::node_id {
        auto this_node_id = *next_node_id;
        *next_node_id = next_node_id + 1;
        ret this_node_id;
    } (next_node_id);

    let test_ctxt cx = rec(next_node_id = next_node_id_fn,
                  mutable path = ~[],
                  mutable testfns = ~[]);

    auto precursor = rec(fold_crate = bind fold_crate(cx, _, _),
                         fold_item = bind fold_item(cx, _, _)
                         with *fold::default_ast_fold());

    auto fold = fold::make_fold(precursor);
    auto res = @fold.fold_crate(*crate);
    // FIXME: This is necessary to break a circular reference
    fold::dummy_out(fold);
    ret res;
}

fn fold_crate(&test_ctxt cx, &ast::crate_ c,
              fold::ast_fold fld) -> ast::crate_ {
    auto folded = fold::noop_fold_crate(c, fld);

    // Add a special __test module to the crate that will contain code
    // generated for the test harness
    ret rec(module = add_test_module(cx, folded.module)
            with folded);
}

fn add_test_module(&test_ctxt cx, &ast::_mod m) -> ast::_mod {
    auto testmod = mk_test_module(cx);
    ret rec(items=m.items + ~[testmod] with m);
}

fn mk_test_module(&test_ctxt cx) -> @ast::item {
    auto mainfn = mk_main(cx);
    let ast::_mod testmod = rec(view_items=~[], items=~[mainfn]);
    auto item_ = ast::item_mod(testmod);
    let ast::item item = rec(ident = "__test",
                             attrs = ~[],
                             id = cx.next_node_id(),
                             node = item_,
                             span = rec(lo=0u, hi=0u));
    ret @item;
}

fn mk_main(&test_ctxt cx) -> @ast::item {
    auto ret_ty = @rec(node=ast::ty_nil,
                       span=rec(lo=0u, hi=0u));

    let ast::fn_decl decl = rec(inputs = ~[],
                                output = ret_ty,
                                purity = ast::impure_fn,
                                cf = ast::return,
                                constraints = ~[]);
    auto proto = ast::proto_fn;

    let ast::block_ body_ = rec(stmts = ~[],
                                 expr = option::none,
                                 id = cx.next_node_id());
    auto body = rec(node = body_, span = rec(lo=0u, hi=0u));

    auto fn_ = rec(decl = decl,
                   proto = proto,
                   body = body);

    auto item_ = ast::item_fn(fn_, ~[]);
    let ast::item item = rec(ident = "main",
                             attrs = ~[],
                             id = cx.next_node_id(),
                             node = item_,
                             span = rec(lo=0u, hi=0u));
    ret @item;
}

fn fold_item(&test_ctxt cx, &@ast::item i,
             fold::ast_fold fld) -> @ast::item {

    cx.path += ~[i.ident];
    log #fmt("current path: %s", ast::path_name_i(cx.path));

    if (is_test_fn(i)) {
        log "this is a test function";
        cx.testfns += ~[cx.path];
    }

    auto res = fold::noop_fold_item(i, fld);
    ivec::pop(cx.path);
    ret res;
}

fn is_test_fn(&@ast::item i) -> bool {
    auto has_test_attr =
        ivec::len(attr::find_attrs_by_name(i.attrs, "test")) > 0u;

    fn has_test_signature(&@ast::item i) -> bool {
        alt (i.node) {
            case (ast::item_fn(?f, ?tps)) {
                auto input_cnt = ivec::len(f.decl.inputs);
                auto no_output = f.decl.output.node == ast::ty_nil;
                auto tparm_cnt = ivec::len(tps);
                input_cnt == 0u && no_output && tparm_cnt == 0u
            }
            case (_) { false }
        }
    }

    ret has_test_attr && has_test_signature(i);
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before><commit_msg>ShardMap: remove the redundant `shards` field<commit_after><|endoftext|>


<commit_before><commit_msg>Add a Ctrl+C example<commit_after>//! Prints the elapsed time every 1 second and quits on Ctrl+C.

#[macro_use]
extern crate crossbeam_channel;
extern crate signal_hook;

use std::io;
use std::time::{Duration, Instant};
use std::thread;
use crossbeam_channel::{bounded, tick, Receiver};

fn sigint_notifier() -> io::Result<Receiver<()>> {
    let (s, r) = bounded(100);
    let signals = signal_hook::iterator::Signals::new(&[signal_hook::SIGINT])?;

    thread::spawn(move || {
        for _ in signals.forever() {
            if s.send(()).is_err() {
                break;
            }
        }
    });

    Ok(r)
}

fn main() {
    let ctrl_c = sigint_notifier().unwrap();
    let update = tick(Duration::from_secs(1));
    let now = Instant::now();

    loop {
        select! {
            recv(update) -> _ => {
                println!("Elapsed time: {:?}", now.elapsed());
            }
            recv(ctrl_c) -> _ => {
                println!("Goodbye!");
                break;
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add example on Euclids algorithm<commit_after>extern crate ramp;

use std::cmp::Ordering;
use ramp::Int;

#[derive(Debug,Copy,Clone,PartialEq,Eq)]
struct GcdResult<T> {
    /// Greatest common divisor.
    gcd: T,
    /// Coefficients such that: gcd(a, b) = c1*a + c2*b
    c1: T, c2: T,
}

/// Calculate greatest common divisor and the corresponding coefficients.
fn extended_gcd(a: Int, b: Int) -> GcdResult<Int> {
    // Euclid's extended algorithm
    let (mut s, mut old_s) = (Int::zero(), Int::one());
    let (mut t, mut old_t) = (Int::one(), Int::zero());
    let (mut r, mut old_r) = (b, a);

    let mut tmp = Int::zero();
    while r != 0 {
        let quotient = &old_r / &r;
        tmp.clone_from(&r); r = &old_r - &quotient * r; old_r.clone_from(&tmp);
        tmp.clone_from(&s); s = &old_s - &quotient * s; old_s.clone_from(&tmp);
        tmp.clone_from(&t); t = &old_t - &quotient * t; old_t.clone_from(&tmp);
    }

    let _quotients = (t, s); // == (a, b) / gcd

    GcdResult { gcd: old_r, c1: old_s, c2: old_t }
}

/// Find the standard representation of a (mod n).
fn normalize(a: Int, n: &Int) -> Int {
    let a = a % n;
    match a.cmp(&Int::zero()) {
        Ordering::Less => a + n,
        _ => a,
    }
}

/// Calculate the inverse of a (mod n).
fn inverse(a: Int, n: &Int) -> Option<Int> {
    let GcdResult { gcd, c1: c, c2: _ } = extended_gcd(a, n.clone());
    if gcd == 1 {
        Some(normalize(c, n))
    } else {
        None
    }
}

/// Calculate base^exp (mod modulus).
fn mpow(mut base: Int, mut exp: u32, modulus: &Int) -> Int {
    let mut result = Int::one();
    base = base % modulus;
    while exp > 0 {
        if exp % 2 == 1 {
            result = (result * &base) % modulus;
        }
        exp = exp >> 1;
        base = (base.dsquare()) % modulus;
    }
    result
}

fn main() {
    let (a, b) = (Int::from(6), Int::from(3));
    let GcdResult { gcd, c1, c2 } = extended_gcd(a.clone(), b.clone());
    println!("gcd({}, {}) = {}*{} + {}*{} = {}", &a, &b, &c1, &a, &c2, &b, &gcd);
    println!("7**-1 (mod 10) = {}", inverse(Int::from(7), &Int::from(10)).unwrap());
    println!("7**1000 (mod 13) = {}", mpow(Int::from(7), 1000, &Int::from(13)));
}
<|endoftext|>


<commit_before>use std::old_io::{fs, IoResult};
use file::{File, GREY};

#[cfg(feature="git")] use ansi_term::{ANSIString, ANSIStrings};
#[cfg(feature="git")] use ansi_term::Colour::*;
#[cfg(feature="git")] use git2;

/// A **Dir** provides a cached list of the file paths in a directory that's
/// being listed.
///
/// This object gets passed to the Files themselves, in order for them to
/// check the existence of surrounding files, then highlight themselves
/// accordingly. (See `File#get_source_files`)
pub struct Dir {
    contents: Vec<Path>,
    path: Path,
    git: Option<Git>,
}

impl Dir {
    /// Create a new Dir object filled with all the files in the directory
    /// pointed to by the given path. Fails if the directory can't be read, or
    /// isn't actually a directory.
    pub fn readdir(path: &Path) -> IoResult<Dir> {
        fs::readdir(path).map(|paths| Dir {
            contents: paths,
            path: path.clone(),
            git: Git::scan(path).ok(),
        })
    }

    /// Produce a vector of File objects from an initialised directory,
    /// printing out an error if any of the Files fail to be created.
    ///
    /// Passing in `recurse` means that any directories will be scanned for
    /// their contents, as well.
    pub fn files(&self, recurse: bool) -> Vec<File> {
        let mut files = vec![];

        for path in self.contents.iter() {
            match File::from_path(path, Some(self), recurse) {
                Ok(file) => files.push(file),
                Err(e)   => println!("{}: {}", path.display(), e),
            }
        }

        files
    }

    /// Whether this directory contains a file with the given path.
    pub fn contains(&self, path: &Path) -> bool {
        self.contents.contains(path)
    }

    /// Append a path onto the path specified by this directory.
    pub fn join(&self, child: Path) -> Path {
        self.path.join(child)
    }

    /// Return whether there's a Git repository on or above this directory.
    pub fn has_git_repo(&self) -> bool {
        self.git.is_some()
    }

    /// Get a string describing the Git status of the given file.
    pub fn git_status(&self, path: &Path, prefix_lookup: bool) -> String {
        match (&self.git, prefix_lookup) {
            (&Some(ref git), false) => git.status(path),
            (&Some(ref git), true)  => git.dir_status(path),
            (&None, _)              => GREY.paint("--").to_string(),
        }
    }
}

/// Container of Git statuses for all the files in this folder's Git repository.
#[cfg(feature="git")]
struct Git {
    statuses: Vec<(Path, git2::Status)>,
}

#[cfg(feature="git")]
impl Git {

    /// Discover a Git repository on or above this directory, scanning it for
    /// the files' statuses if one is found.
    fn scan(path: &Path) -> Result<Git, git2::Error> {
        let repo = try!(git2::Repository::discover(path));
        let workdir = repo.workdir().unwrap_or(Path::new("."));
        let statuses = try!(repo.statuses(None)).iter()
                                                .map(|e| (workdir.join(e.path_bytes()), e.status()))
                                                .collect();
        Ok(Git { statuses: statuses })
    }

    /// Get the status for the file at the given path, if present.
    fn status(&self, path: &Path) -> String {
        let status = self.statuses.iter()
                                  .find(|p| &p.0 == path);
        match status {
            Some(&(_, s)) => ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s) ]).to_string(),
            None => GREY.paint("--").to_string(),
        }
    }

    /// Get the combined status for all the files whose paths begin with the
    /// path that gets passed in. This is used for getting the status of
    /// directories, which don't really have an 'official' status.
    fn dir_status(&self, dir: &Path) -> String {
        let s = self.statuses.iter()
                             .filter(|p| dir.is_ancestor_of(&p.0))
                             .fold(git2::Status::empty(), |a, b| a | b.1);

        ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s)] ).to_string()
    }

    /// The character to display if the file has been modified, but not staged.
    fn working_tree_status(status: git2::Status) -> ANSIString<'static> {
        match status {
            s if s.contains(git2::STATUS_WT_NEW) => Green.paint("A"),
            s if s.contains(git2::STATUS_WT_MODIFIED) => Blue.paint("M"),
            s if s.contains(git2::STATUS_WT_DELETED) => Red.paint("D"),
            s if s.contains(git2::STATUS_WT_RENAMED) => Yellow.paint("R"),
            s if s.contains(git2::STATUS_WT_TYPECHANGE) => Purple.paint("T"),
            _ => GREY.paint("-"),
        }
    }

    /// The character to display if the file has been modified, and the change
    /// has been staged.
    fn index_status(status: git2::Status) -> ANSIString<'static> {
        match status {
            s if s.contains(git2::STATUS_INDEX_NEW) => Green.paint("A"),
            s if s.contains(git2::STATUS_INDEX_MODIFIED) => Blue.paint("M"),
            s if s.contains(git2::STATUS_INDEX_DELETED) => Red.paint("D"),
            s if s.contains(git2::STATUS_INDEX_RENAMED) => Yellow.paint("R"),
            s if s.contains(git2::STATUS_INDEX_TYPECHANGE) => Purple.paint("T"),
            _ => GREY.paint("-"),
        }
    }
}

#[cfg(not(feature="git"))]
struct Git;

#[cfg(not(feature="git"))]
impl Git {
    fn scan(_: &Path) -> Result<Git, ()> {
        // Don't do anything without Git support
        Err(())
    }

    fn status(&self, _: &Path) -> String {
        // The Err above means that this should never happen
        panic!("Tried to access a Git repo without Git support!");
    }

    fn dir_status(&self, path: &Path) -> String {
        self.status(path)
    }
}
<commit_msg>Temporary workaround for Path in libgit2-rs<commit_after>use std::old_io::{fs, IoResult};
use file::{File, GREY};

#[cfg(feature="git")] use ansi_term::{ANSIString, ANSIStrings};
#[cfg(feature="git")] use ansi_term::Colour::*;
#[cfg(feature="git")] use git2;

/// A **Dir** provides a cached list of the file paths in a directory that's
/// being listed.
///
/// This object gets passed to the Files themselves, in order for them to
/// check the existence of surrounding files, then highlight themselves
/// accordingly. (See `File#get_source_files`)
pub struct Dir {
    contents: Vec<Path>,
    path: Path,
    git: Option<Git>,
}

impl Dir {
    /// Create a new Dir object filled with all the files in the directory
    /// pointed to by the given path. Fails if the directory can't be read, or
    /// isn't actually a directory.
    pub fn readdir(path: &Path) -> IoResult<Dir> {
        fs::readdir(path).map(|paths| Dir {
            contents: paths,
            path: path.clone(),
            git: Git::scan(path).ok(),
        })
    }

    /// Produce a vector of File objects from an initialised directory,
    /// printing out an error if any of the Files fail to be created.
    ///
    /// Passing in `recurse` means that any directories will be scanned for
    /// their contents, as well.
    pub fn files(&self, recurse: bool) -> Vec<File> {
        let mut files = vec![];

        for path in self.contents.iter() {
            match File::from_path(path, Some(self), recurse) {
                Ok(file) => files.push(file),
                Err(e)   => println!("{}: {}", path.display(), e),
            }
        }

        files
    }

    /// Whether this directory contains a file with the given path.
    pub fn contains(&self, path: &Path) -> bool {
        self.contents.contains(path)
    }

    /// Append a path onto the path specified by this directory.
    pub fn join(&self, child: Path) -> Path {
        self.path.join(child)
    }

    /// Return whether there's a Git repository on or above this directory.
    pub fn has_git_repo(&self) -> bool {
        self.git.is_some()
    }

    /// Get a string describing the Git status of the given file.
    pub fn git_status(&self, path: &Path, prefix_lookup: bool) -> String {
        match (&self.git, prefix_lookup) {
            (&Some(ref git), false) => git.status(path),
            (&Some(ref git), true)  => git.dir_status(path),
            (&None, _)              => GREY.paint("--").to_string(),
        }
    }
}

/// Container of Git statuses for all the files in this folder's Git repository.
#[cfg(feature="git")]
struct Git {
    statuses: Vec<(Path, git2::Status)>,
}

#[cfg(feature="git")]
impl Git {

    /// Discover a Git repository on or above this directory, scanning it for
    /// the files' statuses if one is found.
    fn scan(path: &Path) -> Result<Git, git2::Error> {
        use std::os::unix::OsStrExt;
        use std::ffi::AsOsStr;

        // TODO: libgit2-rs uses the new Path module, but exa still uses the
        // old_path one, and will have to continue to do so until the new IO
        // module gets a bit more developed. So we have to turn Paths into
        // old_path::Paths. Yes, this is hacky, but hopefully temporary.
        let repo = try!(git2::Repository::discover(path));
        let workdir = match repo.workdir() {
            Some(w) => Path::new(w.as_os_str().as_bytes()),
            None => return Ok(Git { statuses: vec![] }),  // bare repo
        };

        let statuses = try!(repo.statuses(None)).iter()
                                                .map(|e| (workdir.join(e.path_bytes()), e.status()))
                                                .collect();
        Ok(Git { statuses: statuses })
    }

    /// Get the status for the file at the given path, if present.
    fn status(&self, path: &Path) -> String {
        let status = self.statuses.iter()
                                  .find(|p| &p.0 == path);
        match status {
            Some(&(_, s)) => ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s) ]).to_string(),
            None => GREY.paint("--").to_string(),
        }
    }

    /// Get the combined status for all the files whose paths begin with the
    /// path that gets passed in. This is used for getting the status of
    /// directories, which don't really have an 'official' status.
    fn dir_status(&self, dir: &Path) -> String {
        let s = self.statuses.iter()
                             .filter(|p| dir.is_ancestor_of(&p.0))
                             .fold(git2::Status::empty(), |a, b| a | b.1);

        ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s)] ).to_string()
    }

    /// The character to display if the file has been modified, but not staged.
    fn working_tree_status(status: git2::Status) -> ANSIString<'static> {
        match status {
            s if s.contains(git2::STATUS_WT_NEW) => Green.paint("A"),
            s if s.contains(git2::STATUS_WT_MODIFIED) => Blue.paint("M"),
            s if s.contains(git2::STATUS_WT_DELETED) => Red.paint("D"),
            s if s.contains(git2::STATUS_WT_RENAMED) => Yellow.paint("R"),
            s if s.contains(git2::STATUS_WT_TYPECHANGE) => Purple.paint("T"),
            _ => GREY.paint("-"),
        }
    }

    /// The character to display if the file has been modified, and the change
    /// has been staged.
    fn index_status(status: git2::Status) -> ANSIString<'static> {
        match status {
            s if s.contains(git2::STATUS_INDEX_NEW) => Green.paint("A"),
            s if s.contains(git2::STATUS_INDEX_MODIFIED) => Blue.paint("M"),
            s if s.contains(git2::STATUS_INDEX_DELETED) => Red.paint("D"),
            s if s.contains(git2::STATUS_INDEX_RENAMED) => Yellow.paint("R"),
            s if s.contains(git2::STATUS_INDEX_TYPECHANGE) => Purple.paint("T"),
            _ => GREY.paint("-"),
        }
    }
}

#[cfg(not(feature="git"))]
struct Git;

#[cfg(not(feature="git"))]
impl Git {
    fn scan(_: &Path) -> Result<Git, ()> {
        // Don't do anything without Git support
        Err(())
    }

    fn status(&self, _: &Path) -> String {
        // The Err above means that this should never happen
        panic!("Tried to access a Git repo without Git support!");
    }

    fn dir_status(&self, path: &Path) -> String {
        self.status(path)
    }
}
<|endoftext|>


<commit_before><commit_msg>Use Value in place of just plain old i64s<commit_after><|endoftext|>


<commit_before><commit_msg>Revert "Reduced code redundancy"<commit_after><|endoftext|>


<commit_before><commit_msg>DenseVector: Indexing an unset value returns 0 harmlessly<commit_after><|endoftext|>


<commit_before><commit_msg>Create lib.rs<commit_after><|endoftext|>


<commit_before>#![deny(missing_docs)]

//! The official Piston window back-end for the Piston game engine

extern crate glutin_window;
extern crate piston;
extern crate gfx;
extern crate gfx_device_gl;
extern crate gfx_graphics;
extern crate graphics;

use std::cell::RefCell;
use std::rc::Rc;
use std::any::Any;

use glutin_window::GlutinWindow;
use piston::{ event, window };
use gfx::traits::*;
use gfx_graphics::{ Gfx2d, GfxGraphics };
use graphics::Context;

/// The type of event emitted from event loop.
pub type PistonEvent = event::Event<<GlutinWindow as window::Window>::Event>;

/// Contains everything required for controlling window, graphics, event loop.
#[derive(Clone)]
pub struct PistonWindow<T = ()> {
    /// The window.
    pub window: Rc<RefCell<GlutinWindow>>,
    /// The gfx data.
    pub gfx: Rc<RefCell<Gfx>>,
    /// The event loop.
    pub events: Rc<RefCell<event::events::Events<GlutinWindow, PistonEvent>>>,
    /// The event.
    pub event: Option<PistonEvent>,
    /// Application structure.
    pub app: Rc<RefCell<T>>,
}

/// Contains Gfx data.
pub struct Gfx {
    /// The device.
    pub device: gfx_device_gl::Device,
    /// The output.
    pub output: gfx_device_gl::Output,
    /// The factory.
    pub factory: gfx_device_gl::Factory,
    /// Renderer.
    pub renderer: gfx::render::Renderer<gfx_device_gl::Resources,
        gfx_device_gl::CommandBuffer>,
    /// Gfx2d.
    pub g2d: Gfx2d<gfx_device_gl::Resources>,
}

impl<T> PistonWindow<T> {
    /// Creates a new piston object.
    pub fn new(window: Rc<RefCell<GlutinWindow>>, app: Rc<RefCell<T>>) -> Self {
        use piston::event::Events;
        use piston::window::{ OpenGLWindow, Window };

        let (mut device, mut factory) = gfx_device_gl::create(|s| window.borrow_mut().get_proc_address(s));
        let size = window.borrow().size();
        let output = factory.make_fake_output(size.width as u16, size.height as u16);
        let renderer = factory.create_renderer();
        let g2d = Gfx2d::new(&mut device, &mut factory);

        PistonWindow {
            window: window.clone(),
            gfx: Rc::new(RefCell::new(Gfx {
                device: device,
                output: output,
                factory: factory,
                renderer: renderer,
                g2d: g2d,
            })),
            events: Rc::new(RefCell::new(window.events())),
            event: None,
            app: app,
        }
    }

    /// Changes application structure.
    pub fn app<U>(self, app: Rc<RefCell<U>>) -> PistonWindow<U> {
        PistonWindow {
            window: self.window,
            gfx: self.gfx,
            events: self.events,
            event: self.event,
            app: app,
        }
    }

    /// Renders 2D graphics.
    pub fn draw_2d<F>(&self, f: F)
        where F: FnMut(Context, &mut GfxGraphics<
            gfx_device_gl::Resources, gfx_device_gl::CommandBuffer,
            gfx_device_gl::Output>)
    {
        use piston::event::RenderEvent;

        if let Some(ref e) = self.event {
            if let Some(args) = e.render_args() {
                let &mut Gfx { ref mut device, ref mut renderer, ref mut output,
                    ref mut g2d, .. } = &mut *self.gfx.borrow_mut();
                g2d.draw(renderer, output, args.viewport(), f);
                device.submit(renderer.as_buffer());
                renderer.reset();
            }
        }
    }
}

impl Iterator for PistonWindow {
    type Item = PistonWindow;

    fn next(&mut self) -> Option<PistonWindow> {
        use piston::event::AfterRenderEvent;

        if let Some(e) = self.events.borrow_mut().next() {
            if let Some(_) = e.after_render_args() {
                // After swapping buffers.
                let &mut Gfx {
                    ref mut device,
                    ref mut factory,
                    ..
                } = &mut *self.gfx.borrow_mut();
                device.after_frame();
                factory.cleanup();
            }

            Some(PistonWindow {
                window: self.window.clone(),
                gfx: self.gfx.clone(),
                events: self.events.clone(),
                event: Some(e),
                app: self.app.clone(),
            })
        } else { None }
    }
}

impl event::GenericEvent for PistonWindow {
    fn event_id(&self) -> event::EventId {
        match self.event {
            Some(ref e) => e.event_id(),
            None => event::EventId("")
        }
    }

    fn with_args<'a, F, U>(&'a self, f: F) -> U
       where F: FnMut(&Any) -> U
    {
        self.event.as_ref().unwrap().with_args(f)
    }

    fn from_args(event_id: event::EventId, any: &Any, old_event: &Self) -> Option<Self> {
        if let Some(ref e) = old_event.event {
            match event::GenericEvent::from_args(event_id, any, e) {
                Some(e) => {
                    Some(PistonWindow {
                        window: old_event.window.clone(),
                        gfx: old_event.gfx.clone(),
                        events: old_event.events.clone(),
                        event: Some(e),
                        app: old_event.app.clone(),
                    })
                }
                None => None
            }
        } else { None }
    }
}

impl window::Window for PistonWindow {
    type Event = <GlutinWindow as window::Window>::Event;

    fn should_close(&self) -> bool { self.window.borrow().should_close() }
    fn size(&self) -> window::Size { self.window.borrow().size() }
    fn draw_size(&self) -> window::Size { self.window.borrow().draw_size() }
    fn swap_buffers(&mut self) { self.window.borrow_mut().swap_buffers() }
    fn poll_event(&mut self) -> Option<Self::Event> {
        window::Window::poll_event(&mut *self.window.borrow_mut())
    }
}

impl window::AdvancedWindow for PistonWindow {
    fn get_title(&self) -> String { self.window.borrow().get_title() }
    fn set_title(&mut self, title: String) {
        self.window.borrow_mut().set_title(title)
    }
    fn get_exit_on_esc(&self) -> bool { self.window.borrow().get_exit_on_esc() }
    fn set_exit_on_esc(&mut self, value: bool) {
        self.window.borrow_mut().set_exit_on_esc(value)
    }
    fn set_capture_cursor(&mut self, value: bool) {
        self.window.borrow_mut().set_capture_cursor(value)
    }
}

/// Creates a new empty application.
pub fn empty_app() -> Rc<RefCell<()>> { Rc::new(RefCell::new(())) }
<commit_msg>Added `draw_3d`<commit_after>#![deny(missing_docs)]

//! The official Piston window back-end for the Piston game engine

extern crate glutin_window;
extern crate piston;
extern crate gfx;
extern crate gfx_device_gl;
extern crate gfx_graphics;
extern crate graphics;

use std::cell::RefCell;
use std::rc::Rc;
use std::any::Any;

use glutin_window::GlutinWindow;
use piston::{ event, window };
use gfx::traits::*;
use gfx_graphics::{ Gfx2d, GfxGraphics };
use graphics::Context;

/// The type of event emitted from event loop.
pub type PistonEvent = event::Event<<GlutinWindow as window::Window>::Event>;

/// Contains everything required for controlling window, graphics, event loop.
#[derive(Clone)]
pub struct PistonWindow<T = ()> {
    /// The window.
    pub window: Rc<RefCell<GlutinWindow>>,
    /// The gfx data.
    pub gfx: Rc<RefCell<Gfx>>,
    /// The event loop.
    pub events: Rc<RefCell<event::events::Events<GlutinWindow, PistonEvent>>>,
    /// The event.
    pub event: Option<PistonEvent>,
    /// Application structure.
    pub app: Rc<RefCell<T>>,
}

/// Contains Gfx data.
pub struct Gfx {
    /// The device.
    pub device: gfx_device_gl::Device,
    /// The output.
    pub output: gfx_device_gl::Output,
    /// The factory.
    pub factory: gfx_device_gl::Factory,
    /// Renderer.
    pub renderer: gfx::render::Renderer<gfx_device_gl::Resources,
        gfx_device_gl::CommandBuffer>,
    /// Gfx2d.
    pub g2d: Gfx2d<gfx_device_gl::Resources>,
}

impl<T> PistonWindow<T> {
    /// Creates a new piston object.
    pub fn new(window: Rc<RefCell<GlutinWindow>>, app: Rc<RefCell<T>>) -> Self {
        use piston::event::Events;
        use piston::window::{ OpenGLWindow, Window };

        let (mut device, mut factory) = gfx_device_gl::create(|s| window.borrow_mut().get_proc_address(s));
        let size = window.borrow().size();
        let output = factory.make_fake_output(size.width as u16, size.height as u16);
        let renderer = factory.create_renderer();
        let g2d = Gfx2d::new(&mut device, &mut factory);

        PistonWindow {
            window: window.clone(),
            gfx: Rc::new(RefCell::new(Gfx {
                device: device,
                output: output,
                factory: factory,
                renderer: renderer,
                g2d: g2d,
            })),
            events: Rc::new(RefCell::new(window.events())),
            event: None,
            app: app,
        }
    }

    /// Changes application structure.
    pub fn app<U>(self, app: Rc<RefCell<U>>) -> PistonWindow<U> {
        PistonWindow {
            window: self.window,
            gfx: self.gfx,
            events: self.events,
            event: self.event,
            app: app,
        }
    }

    /// Renders 2D graphics.
    pub fn draw_2d<F>(&self, f: F)
        where F: FnMut(Context, &mut GfxGraphics<
            gfx_device_gl::Resources, gfx_device_gl::CommandBuffer,
            gfx_device_gl::Output>)
    {
        use piston::event::RenderEvent;

        if let Some(ref e) = self.event {
            if let Some(args) = e.render_args() {
                let &mut Gfx { ref mut device, ref mut renderer, ref mut output,
                    ref mut g2d, .. } = &mut *self.gfx.borrow_mut();
                g2d.draw(renderer, output, args.viewport(), f);
                device.submit(renderer.as_buffer());
                renderer.reset();
            }
        }
    }

    /// Renders 3D graphics.
    pub fn draw_3d<F>(&self, mut f: F)
        where F: FnMut(&mut Gfx)
    {
        use piston::event::RenderEvent;

        if let Some(ref e) = self.event {
            if let Some(_) = e.render_args() {
                f(&mut *self.gfx.borrow_mut())
            }
        }
    }
}

impl Iterator for PistonWindow {
    type Item = PistonWindow;

    fn next(&mut self) -> Option<PistonWindow> {
        use piston::event::AfterRenderEvent;

        if let Some(e) = self.events.borrow_mut().next() {
            if let Some(_) = e.after_render_args() {
                // After swapping buffers.
                let &mut Gfx {
                    ref mut device,
                    ref mut factory,
                    ..
                } = &mut *self.gfx.borrow_mut();
                device.after_frame();
                factory.cleanup();
            }

            Some(PistonWindow {
                window: self.window.clone(),
                gfx: self.gfx.clone(),
                events: self.events.clone(),
                event: Some(e),
                app: self.app.clone(),
            })
        } else { None }
    }
}

impl event::GenericEvent for PistonWindow {
    fn event_id(&self) -> event::EventId {
        match self.event {
            Some(ref e) => e.event_id(),
            None => event::EventId("")
        }
    }

    fn with_args<'a, F, U>(&'a self, f: F) -> U
       where F: FnMut(&Any) -> U
    {
        self.event.as_ref().unwrap().with_args(f)
    }

    fn from_args(event_id: event::EventId, any: &Any, old_event: &Self) -> Option<Self> {
        if let Some(ref e) = old_event.event {
            match event::GenericEvent::from_args(event_id, any, e) {
                Some(e) => {
                    Some(PistonWindow {
                        window: old_event.window.clone(),
                        gfx: old_event.gfx.clone(),
                        events: old_event.events.clone(),
                        event: Some(e),
                        app: old_event.app.clone(),
                    })
                }
                None => None
            }
        } else { None }
    }
}

impl window::Window for PistonWindow {
    type Event = <GlutinWindow as window::Window>::Event;

    fn should_close(&self) -> bool { self.window.borrow().should_close() }
    fn size(&self) -> window::Size { self.window.borrow().size() }
    fn draw_size(&self) -> window::Size { self.window.borrow().draw_size() }
    fn swap_buffers(&mut self) { self.window.borrow_mut().swap_buffers() }
    fn poll_event(&mut self) -> Option<Self::Event> {
        window::Window::poll_event(&mut *self.window.borrow_mut())
    }
}

impl window::AdvancedWindow for PistonWindow {
    fn get_title(&self) -> String { self.window.borrow().get_title() }
    fn set_title(&mut self, title: String) {
        self.window.borrow_mut().set_title(title)
    }
    fn get_exit_on_esc(&self) -> bool { self.window.borrow().get_exit_on_esc() }
    fn set_exit_on_esc(&mut self, value: bool) {
        self.window.borrow_mut().set_exit_on_esc(value)
    }
    fn set_capture_cursor(&mut self, value: bool) {
        self.window.borrow_mut().set_capture_cursor(value)
    }
}

/// Creates a new empty application.
pub fn empty_app() -> Rc<RefCell<()>> { Rc::new(RefCell::new(())) }
<|endoftext|>


<commit_before>//! # Daemon abstraction
//! This is documentation for the `daemon` module.
//!
//! Lorem Ipsum
//! functionality for building portable Rust software.

use base::{Operation};
use std::thread::{spawn, sleep};
use std::fmt::{Display, Formatter};
use std::fmt::Result as FmtResult;
use std::time::Duration;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Sender};

#[derive(Debug, PartialEq, Clone)]
pub enum State {
    Running,
    NotRunning,
}

pub type Status = Result<State, State>;

#[derive(Debug)]
pub struct Daemon<T: ? Sized> {
    state: State,
    should_stop: Arc<AtomicBool>,
    finished: Arc<AtomicBool>,
    name: T //unsized must be last
}

impl<T> Display for Daemon<T> where T: Display {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        write!(f, "{}", self.name)
    }
}

impl<T> Daemon<T> where T: Display {
    /// Constructs a new `Daemon<T>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use base::Daemon;
    /// let mut d = Daemon::new("some_name")
    /// ```
    pub fn new(id: T) -> Daemon<T> {
        let ss = Arc::new(AtomicBool::new(false));
        let fin = Arc::new(AtomicBool::new(false));
        Daemon { name: id, should_stop: ss, finished: fin, state: State::NotRunning }
    }

    pub fn start(&mut self, op: Box<Operation>, finish_chan_tx: Sender<Status>) -> Status {
        match self.state {
            State::NotRunning => {
                self.state = State::Running;
                println!("[-] daemon name {}", self.name);
                println!("[-] spawning worker thread");
                let stop = self.should_stop.clone();
                let finished = self.finished.clone();
                spawn(move || {
                    loop {
                        if stop.load(Ordering::Relaxed) {
                            break;
                        }
                        op.exec();
                        sleep(Duration::from_secs(1));
                    }
                    finished.store(true, Ordering::Relaxed);
                    let notification_status = finish_chan_tx.send(Ok(State::NotRunning));
                    println!("[-] finish msg send status {:?}", notification_status);
                    println!("[-] worker thread finished");

                });
                println!("[-] worker thread ready");
                Ok(State::Running)
            },
            State::Running => {
                println!("[-] {} already running", self.name);
                Err(State::Running)
            }
        }
    }

    pub fn stop(&mut self) -> Status {
        match self.state {
            State::Running => {
                self.state = State::NotRunning;
                println!("[-] {} will stop", self.name);
                let stop = self.should_stop.clone();
                let finished = self.finished.clone();
                stop.store(true, Ordering::Relaxed);
                while !finished.load(Ordering::Relaxed) {
                    println!("[-] worker thread closing");
                    sleep(Duration::from_millis(300));
                }
                Ok(State::NotRunning)
            },
            State::NotRunning => {
                Err(State::NotRunning)
            }
        }
    }

    pub fn reload(&mut self) -> Status {
        match self.state {
            State::Running => {
                println!("[-] {} reloading", self.name);
                Ok(State::Running)
            },
            State::NotRunning => {
                Err(State::NotRunning)
            }
        }
    }
}

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

    #[test]
    fn can_start_when_not_running() {
        let mut daemon = Daemon::new("some_name");
        let expected = Ok(State::Running);
        let op = Box::new(DebugPrint);
        let actual = daemon.start(op);
        assert_eq!(expected, actual);
    }

    #[test]
    fn cant_reload_when_not_running() {
        let mut daemon = Daemon::new("some_name");
        let expected = Err(State::NotRunning);
        let actual = daemon.reload();
        assert_eq!(expected, actual);
    }

    #[test]
    fn cant_stop_when_not_running() {
        let mut daemon = Daemon::new("some_name");
        let expected = Err(State::NotRunning);
        let actual = daemon.stop();
        assert_eq!(expected, actual);
    }

    #[test]
    fn can_stop_when_already_running() {
        let mut daemon = Daemon::new("some_name");
        match daemon.start() {
            Err(_) => {
                panic!("Error, can't run daemon for unknown reason");
            },
            _ => ()
        }
        let expected = Ok(State::NotRunning);
        let actual = daemon.stop();
        assert_eq!(expected, actual);
    }

    #[test]
    fn can_reload_when_already_running() {
        let mut daemon = Daemon::new("some_name");
        match daemon.start() {
            Err(_) => {
                panic!("Error, can't run daemon for unknown reason");
            },
            _ => ()
        }
        let expected = Ok(State::Running);
        let actual = daemon.reload();
        assert_eq!(expected, actual);
    }

    #[test]
    fn can_reload_when_already_reloaded() {
        let mut daemon = Daemon::new("some_name");
        match daemon.start() {
            Err(_) => {
                panic!("Error, can't run daemon for unknown reason");
            },
            _ => ()
        }
        let expected = Ok(State::Running);
        let actual = daemon.reload();
        assert_eq!(expected, actual);

        let expected = Ok(State::Running);
        let actual = daemon.reload();
        assert_eq!(expected, actual);
    }

    #[test]
    fn cant_start_when_already_running() {
        let mut daemon = Daemon::new("some_name");
        match daemon.start() {
            Err(_) => {
                panic!("Error, can't run daemon for unknown reason");
            },
            _ => ()
        }
        let expected = Err(State::Running);
        let actual = daemon.start();
        assert_eq!(expected, actual);
    }

    #[test]
    fn cant_start_when_already_reloaded() {
        let mut daemon = Daemon::new("some_name");
        match daemon.start() {
            Err(_) => {
                panic!("Error, can't run daemon for unknown reason");
            },
            _ => ()
        }
        let expected = Ok(State::Running);
        let actual = daemon.reload();
        assert_eq!(expected, actual);

        let expected = Err(State::Running);
        let actual = daemon.start();
        assert_eq!(expected, actual);
    }
}<commit_msg>daemon tests adjusted<commit_after>//! # Daemon abstraction
//! This is documentation for the `daemon` module.
//!
//! Lorem Ipsum
//! functionality for building portable Rust software.

use base::{Operation};
use std::thread::{spawn, sleep};
use std::fmt::{Display, Formatter};
use std::fmt::Result as FmtResult;
use std::time::Duration;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Sender};

#[derive(Debug, PartialEq, Clone)]
pub enum State {
    Running,
    NotRunning,
}

pub type Status = Result<State, State>;

#[derive(Debug)]
pub struct Daemon<T: ? Sized> {
    state: State,
    should_stop: Arc<AtomicBool>,
    finished: Arc<AtomicBool>,
    name: T //unsized must be last
}

impl<T> Display for Daemon<T> where T: Display {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        write!(f, "{}", self.name)
    }
}

impl<T> Daemon<T> where T: Display {
    /// Constructs a new `Daemon<T>`.
    ///
    /// # Examples
    ///
    /// ```
    /// use base::Daemon;
    /// let mut d = Daemon::new("some_name")
    /// ```
    pub fn new(id: T) -> Daemon<T> {
        let ss = Arc::new(AtomicBool::new(false));
        let fin = Arc::new(AtomicBool::new(false));
        Daemon { name: id, should_stop: ss, finished: fin, state: State::NotRunning }
    }

    pub fn start(&mut self, op: Box<Operation>, finish_chan_tx: Sender<Status>) -> Status {
        match self.state {
            State::NotRunning => {
                self.state = State::Running;
                println!("[-] daemon name {}", self.name);
                println!("[-] spawning worker thread");
                let stop = self.should_stop.clone();
                let finished = self.finished.clone();
                spawn(move || {
                    loop {
                        if stop.load(Ordering::Relaxed) {
                            break;
                        }
                        op.exec();
                        sleep(Duration::from_secs(1));
                    }
                    finished.store(true, Ordering::Relaxed);
                    let notification_status = finish_chan_tx.send(Ok(State::NotRunning));
                    println!("[-] finish msg send status {:?}", notification_status);
                    println!("[-] worker thread finished");
                });
                println!("[-] worker thread ready");
                Ok(State::Running)
            },
            State::Running => {
                println!("[-] {} already running", self.name);
                Err(State::Running)
            }
        }
    }

    pub fn stop(&mut self) -> Status {
        match self.state {
            State::Running => {
                self.state = State::NotRunning;
                println!("[-] {} will stop", self.name);
                let stop = self.should_stop.clone();
                let finished = self.finished.clone();
                stop.store(true, Ordering::Relaxed);
                while !finished.load(Ordering::Relaxed) {
                    println!("[-] worker thread closing");
                    sleep(Duration::from_millis(300));
                }
                Ok(State::NotRunning)
            },
            State::NotRunning => {
                Err(State::NotRunning)
            }
        }
    }

    pub fn reload(&mut self) -> Status {
        match self.state {
            State::Running => {
                println!("[-] {} reloading", self.name);
                Ok(State::Running)
            },
            State::NotRunning => {
                Err(State::NotRunning)
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::mpsc::{self};

    #[derive(Debug)]
    pub struct OperationMock;

    impl Operation for OperationMock {
        fn exec(&self) -> () {}
    }

    #[test]
    fn can_start_when_not_running() {
        let mut daemon = Daemon::new("some_name");
        let expected = Ok(State::Running);
        let op = Box::new(OperationMock);
        let (end_signal_tx, _) = mpsc::channel();
        let actual = daemon.start(op, end_signal_tx);
        assert_eq!(expected, actual);
    }

    #[test]
    fn cant_reload_when_not_running() {
        let mut daemon = Daemon::new("some_name");
        let expected = Err(State::NotRunning);
        let actual = daemon.reload();
        assert_eq!(expected, actual);
    }

    #[test]
    fn cant_stop_when_not_running() {
        let mut daemon = Daemon::new("some_name");
        let expected = Err(State::NotRunning);
        let actual = daemon.stop();
        assert_eq!(expected, actual);
    }

    #[test]
    fn can_stop_when_already_running() {
        let mut daemon = Daemon::new("some_name");
        let op = Box::new(OperationMock);
        let (end_signal_tx, _) = mpsc::channel();
        match daemon.start(op, end_signal_tx) {
            Err(_) => {
                panic!("Error, can't run daemon for unknown reason");
            },
            _ => ()
        }
        let expected = Ok(State::NotRunning);
        let actual = daemon.stop();
        assert_eq!(expected, actual);
    }

    #[test]
    fn can_reload_when_already_running() {
        let mut daemon = Daemon::new("some_name");
        let op = Box::new(OperationMock);
        let (end_signal_tx, _) = mpsc::channel();
        match daemon.start(op, end_signal_tx) {
            Err(_) => {
                panic!("Error, can't run daemon for unknown reason");
            },
            _ => ()
        }
        let expected = Ok(State::Running);
        let actual = daemon.reload();
        assert_eq!(expected, actual);
    }

    #[test]
    fn can_reload_when_already_reloaded() {
        let mut daemon = Daemon::new("some_name");
        let op = Box::new(OperationMock);
        let (end_signal_tx, _) = mpsc::channel();
        match daemon.start(op, end_signal_tx) {
            Err(_) => {
                panic!("Error, can't run daemon for unknown reason");
            },
            _ => ()
        }
        let expected = Ok(State::Running);
        let actual = daemon.reload();
        assert_eq!(expected, actual);

        let expected = Ok(State::Running);
        let actual = daemon.reload();
        assert_eq!(expected, actual);
    }

    #[test]
    fn cant_start_when_already_running() {
        let mut daemon = Daemon::new("some_name");
        let op = Box::new(OperationMock);
        let (end_signal_tx, _) = mpsc::channel();
        match daemon.start(op, end_signal_tx) {
            Err(_) => {
                panic!("Error, can't run daemon for unknown reason");
            },
            _ => ()
        }
        let expected = Err(State::Running);
        let op = Box::new(OperationMock);
        let (end_signal_tx, _) = mpsc::channel();
        let actual = daemon.start(op, end_signal_tx);
        assert_eq!(expected, actual);
    }

    #[test]
    fn cant_start_when_already_reloaded() {
        let mut daemon = Daemon::new("some_name");
        let op = Box::new(OperationMock);
        let (end_signal_tx, _) = mpsc::channel();
        match daemon.start(op, end_signal_tx) {
            Err(_) => {
                panic!("Error, can't run daemon for unknown reason");
            },
            _ => ()
        }
        let expected = Ok(State::Running);
        let actual = daemon.reload();
        assert_eq!(expected, actual);

        let expected = Err(State::Running);
        let op = Box::new(OperationMock);
        let (end_signal_tx, _) = mpsc::channel();
        let actual = daemon.start(op, end_signal_tx);
        assert_eq!(expected, actual);
    }
}<|endoftext|>


<commit_before><commit_msg>Fix #203, remove the "Fork me on github" banner.<commit_after><|endoftext|>