<commit_before>extern crate curl;
extern crate env_logger;
extern crate futures;
extern crate tokio_core;
extern crate tokio_curl;
extern crate threadpool;
#[macro_use]
extern crate clap;
extern crate chrono;

mod args;

use args::{Config, parse_args};

use curl::easy::Easy;
use futures::{Async, Future, lazy, Poll, stream};
use futures::future::{ok, join_all, FutureResult, loop_fn, Loop};
use futures::sync::mpsc::channel;
use futures::{Stream, Sink};
use tokio_core::reactor::{Core, Handle};
use tokio_curl::{Perform, PerformError, Session};
use std::rc::Rc;
use std::cell::RefCell;
use threadpool::ThreadPool;
use std::sync::{Arc, Barrier};
use futures::stream::FuturesUnordered;
use chrono::*;

struct Worker {
    num_requests: u32,
}

impl Worker {
    pub fn new() -> Self {
        Worker { num_requests: 0}
    }

    fn send_request(mut self, url: String, session: &Session) -> futures::BoxFuture<Self, PerformError> {
        let mut a = Easy::new();
        a.get(true).unwrap();
        a.url(&url).unwrap();
        a.write_function(|data| Ok(data.len())).unwrap();
        Box::new(session.perform(a)
            .and_then(move |_| {
                self.num_requests += 1;
                ok(self)
            }))
    }
}

/// Delegates and manages all the work.
struct Boss {
    /// Number of requests successfully completed
    pub requests_completed: usize,
    /// Number of active connections
    pub connections: usize,

    thread_pool: ThreadPool,
    num_threads: usize,
}

impl Boss {
    pub fn new(num_threads: usize) -> Self {
        Boss {
            requests_completed: 0,
            connections: 0,
            thread_pool: ThreadPool::new(num_threads),
            num_threads: num_threads,
        }
    }

    /// Should return a future
    pub fn start_workforce(&self, desired_connections: usize, url: String, duration: Duration) {
        // create a barrier that wait all jobs plus the starter thread
        let barrier = Arc::new(Barrier::new(self.num_threads + 1));
        for _ in 0..self.num_threads {
            let barrier = barrier.clone();
            // let tx = tx.clone();
            let url = url.clone();
            self.thread_pool.execute(move || {

                let mut lp = Core::new().unwrap();
                let start_time = Local::now();
                let wanted_end_time = start_time + duration;
                let session = Session::new(lp.handle());

                let iterator = (0..desired_connections).map(|_| {
                    loop_fn(Worker::new(), |worker| {
                        worker.send_request(url.clone(), &session)
                            .and_then(|count| {
                                let now_time = Local::now();
                                if now_time < wanted_end_time {
                                    Ok(Loop::Continue(count))
                                } else {
                                    Ok(Loop::Break(count))
                                }
                            })
                    })
                });
                let future = stream::futures_unordered(iterator)
                    .fold(0, |acc, res| ok(acc + res.num_requests));
                let res = lp.run(future).unwrap();
                println!("{:?}", res);

                // then wait for the other threads
                barrier.wait();
            });
        }
        // wait for the threads to finish the work
        barrier.wait();
    }
}

fn start(config: Config) {
    let boss = Boss::new(config.num_threads);
    boss.start_workforce(config.num_connections, config.url, config.duration)
}

fn main() {
    env_logger::init().unwrap();
    let config = parse_args();
    start(config);
}
<commit_msg>accept url as string slice<commit_after>extern crate curl;
extern crate env_logger;
extern crate futures;
extern crate tokio_core;
extern crate tokio_curl;
extern crate threadpool;
#[macro_use]
extern crate clap;
extern crate chrono;

mod args;

use args::{Config, parse_args};

use curl::easy::Easy;
use futures::{Async, Future, lazy, Poll, stream};
use futures::future::{ok, join_all, FutureResult, loop_fn, Loop};
use futures::sync::mpsc::channel;
use futures::{Stream, Sink};
use tokio_core::reactor::{Core, Handle};
use tokio_curl::{Perform, PerformError, Session};
use std::rc::Rc;
use std::cell::RefCell;
use threadpool::ThreadPool;
use std::sync::{Arc, Barrier};
use futures::stream::FuturesUnordered;
use chrono::*;

struct Worker {
    num_requests: u32,
}

impl Worker {
    pub fn new() -> Self {
        Worker { num_requests: 0}
    }

    fn send_request(mut self, url: &str, session: &Session) -> futures::BoxFuture<Self, PerformError> {
        let mut a = Easy::new();
        a.get(true).unwrap();
        a.url(url).unwrap();
        a.write_function(|data| Ok(data.len())).unwrap();
        Box::new(session.perform(a)
            .and_then(move |_| {
                self.num_requests += 1;
                ok(self)
            }))
    }
}

/// Delegates and manages all the work.
struct Boss {
    /// Number of requests successfully completed
    pub requests_completed: usize,
    /// Number of active connections
    pub connections: usize,

    thread_pool: ThreadPool,
    num_threads: usize,
}

impl Boss {
    pub fn new(num_threads: usize) -> Self {
        Boss {
            requests_completed: 0,
            connections: 0,
            thread_pool: ThreadPool::new(num_threads),
            num_threads: num_threads,
        }
    }

    /// Should return a future
    pub fn start_workforce(&self, desired_connections: usize, url: String, duration: Duration) {
        // create a barrier that wait all jobs plus the starter thread
        let barrier = Arc::new(Barrier::new(self.num_threads + 1));
        for _ in 0..self.num_threads {
            let barrier = barrier.clone();
            // let tx = tx.clone();
            let url = url.clone();
            self.thread_pool.execute(move || {

                let mut lp = Core::new().unwrap();
                let start_time = Local::now();
                let wanted_end_time = start_time + duration;
                let session = Session::new(lp.handle());

                let iterator = (0..desired_connections).map(|_| {
                    loop_fn(Worker::new(), |worker| {
                        worker.send_request(&url.clone(), &session)
                            .and_then(|count| {
                                let now_time = Local::now();
                                if now_time < wanted_end_time {
                                    Ok(Loop::Continue(count))
                                } else {
                                    Ok(Loop::Break(count))
                                }
                            })
                    })
                });
                let future = stream::futures_unordered(iterator)
                    .fold(0, |acc, res| ok(acc + res.num_requests));
                let res = lp.run(future).unwrap();
                println!("{:?}", res);

                // then wait for the other threads
                barrier.wait();
            });
        }
        // wait for the threads to finish the work
        barrier.wait();
    }
}

fn start(config: Config) {
    let boss = Boss::new(config.num_threads);
    boss.start_workforce(config.num_connections, config.url, config.duration)
}

fn main() {
    env_logger::init().unwrap();
    let config = parse_args();
    start(config);
}
<|endoftext|>


<commit_before>// Copyright 2012 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.

//! Build indexes as appropriate for the markdown pass

use core::prelude::*;

use astsrv;
use config;
use doc::ItemUtils;
use doc;
use fold::Fold;
use fold;
use markdown_pass;
use markdown_writer;
use pass::Pass;

use core::str;

pub fn mk_pass(config: config::Config) -> Pass {
    Pass {
        name: ~"markdown_index",
        f: |srv, doc| run(srv, doc, copy config)
    }
}

pub fn run(
    _srv: astsrv::Srv,
    doc: doc::Doc,
    config: config::Config
) -> doc::Doc {
    let fold = Fold {
        fold_mod: fold_mod,
        fold_nmod: fold_nmod,
        .. fold::default_any_fold(config)
    };
    (fold.fold_doc)(&fold, doc)
}

fn fold_mod(
    fold: &fold::Fold<config::Config>,
    doc: doc::ModDoc
) -> doc::ModDoc {

    let doc = fold::default_any_fold_mod(fold, doc);

    doc::ModDoc {
        index: Some(build_mod_index(copy doc, copy fold.ctxt)),
        .. doc
    }
}

fn fold_nmod(
    fold: &fold::Fold<config::Config>,
    doc: doc::NmodDoc
) -> doc::NmodDoc {

    let doc = fold::default_any_fold_nmod(fold, doc);

    doc::NmodDoc {
        index: Some(build_nmod_index(copy doc, copy fold.ctxt)),
        .. doc
    }
}

fn build_mod_index(
    doc: doc::ModDoc,
    config: config::Config
) -> doc::Index {
    doc::Index {
        entries: doc.items.map(|doc| {
            item_to_entry(copy *doc, copy config)
        })
    }
}

fn build_nmod_index(
    doc: doc::NmodDoc,
    config: config::Config
) -> doc::Index {
    doc::Index {
        entries: doc.fns.map(|doc| {
            item_to_entry(doc::FnTag(copy *doc), copy config)
        })
    }
}

fn item_to_entry(
    doc: doc::ItemTag,
    config: config::Config
) -> doc::IndexEntry {
    let link = match doc {
      doc::ModTag(_) | doc::NmodTag(_)
      if config.output_style == config::DocPerMod => {
        markdown_writer::make_filename(config,
                                       doc::ItemPage(copy doc)).to_str()
      }
      _ => {
        ~"#" + pandoc_header_id(markdown_pass::header_text(copy doc))
      }
    };

    doc::IndexEntry {
        kind: markdown_pass::header_kind(copy doc),
        name: markdown_pass::header_name(copy doc),
        brief: doc.brief(),
        link: link
    }
}

fn pandoc_header_id(header: &str) -> ~str {

    // http://johnmacfarlane.net/pandoc/README.html#headers

    let header = remove_formatting(header);
    let header = remove_punctuation(header);
    let header = replace_with_hyphens(header);
    let header = convert_to_lowercase(header);
    let header = remove_up_to_first_letter(header);
    let header = maybe_use_section_id(header);
    return header;

    fn remove_formatting(s: &str) -> ~str {
        str::replace(s, ~"`", ~"")
    }
    fn remove_punctuation(s: &str) -> ~str {
        let s = str::replace(s, ~"<", ~"");
        let s = str::replace(s, ~">", ~"");
        let s = str::replace(s, ~"[", ~"");
        let s = str::replace(s, ~"]", ~"");
        let s = str::replace(s, ~"(", ~"");
        let s = str::replace(s, ~")", ~"");
        let s = str::replace(s, ~"@~", ~"");
        let s = str::replace(s, ~"~", ~"");
        let s = str::replace(s, ~"/", ~"");
        let s = str::replace(s, ~":", ~"");
        let s = str::replace(s, ~"&", ~"");
        let s = str::replace(s, ~"^", ~"");
        return s;
    }
    fn replace_with_hyphens(s: &str) -> ~str {
        // Collapse sequences of whitespace to a single dash
        // XXX: Hacky implementation here that only covers
        // one or two spaces.
        let s = str::replace(s, ~"  ", ~"-");
        let s = str::replace(s, ~" ", ~"-");
        return s;
    }
    fn convert_to_lowercase(s: &str) -> ~str { str::to_lower(s) }
    fn remove_up_to_first_letter(s: &str) -> ~str { s.to_str() }
    fn maybe_use_section_id(s: &str) -> ~str { s.to_str() }
}

#[test]
fn should_remove_punctuation_from_headers() {
    fail_unless!(pandoc_header_id(~"impl foo of bar<A>") ==
        ~"impl-foo-of-bara");
    fail_unless!(pandoc_header_id(~"impl of num::num for int")
        == ~"impl-of-numnum-for-int");
    fail_unless!(pandoc_header_id(~"impl of num::num for int/&")
        == ~"impl-of-numnum-for-int");
    fail_unless!(pandoc_header_id(~"impl of num::num for ^int")
        == ~"impl-of-numnum-for-int");
    fail_unless!(pandoc_header_id(~"impl for & condvar")
        == ~"impl-for-condvar");
}

#[test]
fn should_index_mod_contents() {
    let doc = test::mk_doc(
        config::DocPerCrate,
        ~"mod a { } fn b() { }"
    );
    fail_unless!((&doc.cratemod().index).get().entries[0] == doc::IndexEntry {
        kind: ~"Module",
        name: ~"a",
        brief: None,
        link: ~"#module-a"
    });
    fail_unless!((&doc.cratemod().index).get().entries[1] == doc::IndexEntry {
        kind: ~"Function",
        name: ~"b",
        brief: None,
        link: ~"#function-b"
    });
}

#[test]
fn should_index_mod_contents_multi_page() {
    let doc = test::mk_doc(
        config::DocPerMod,
        ~"mod a { } fn b() { }"
    );
    fail_unless!((&doc.cratemod().index).get().entries[0] == doc::IndexEntry {
        kind: ~"Module",
        name: ~"a",
        brief: None,
        link: ~"a.html"
    });
    fail_unless!((&doc.cratemod().index).get().entries[1] == doc::IndexEntry {
        kind: ~"Function",
        name: ~"b",
        brief: None,
        link: ~"#function-b"
    });
}

#[test]
fn should_index_foreign_mod_pages() {
    let doc = test::mk_doc(
        config::DocPerMod,
        ~"extern mod a { }"
    );
    fail_unless!((&doc.cratemod().index).get().entries[0] == doc::IndexEntry {
        kind: ~"Foreign module",
        name: ~"a",
        brief: None,
        link: ~"a.html"
    });
}

#[test]
fn should_add_brief_desc_to_index() {
    let doc = test::mk_doc(
        config::DocPerMod,
        ~"#[doc = \"test\"] mod a { }"
    );
    fail_unless!((&doc.cratemod().index).get().entries[0].brief
        == Some(~"test"));
}

#[test]
fn should_index_foreign_mod_contents() {
    let doc = test::mk_doc(
        config::DocPerCrate,
        ~"extern mod a { fn b(); }"
    );
    fail_unless!((&doc.cratemod().nmods()[0].index).get().entries[0]
        == doc::IndexEntry {
        kind: ~"Function",
        name: ~"b",
        brief: None,
        link: ~"#function-b"
    });
}

#[cfg(test)]
mod test {
    use astsrv;
    use attr_pass;
    use config;
    use desc_to_brief_pass;
    use doc;
    use extract;
    use markdown_index_pass::run;
    use path_pass;

    use core::path::Path;

    pub fn mk_doc(output_style: config::OutputStyle, source: ~str)
               -> doc::Doc {
        do astsrv::from_str(source) |srv| {
            let config = config::Config {
                output_style: output_style,
                .. config::default_config(&Path("whatever"))
            };
            let doc = extract::from_srv(srv.clone(), ~"");
            let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
            let doc = (desc_to_brief_pass::mk_pass().f)(srv.clone(), doc);
            let doc = (path_pass::mk_pass().f)(srv.clone(), doc);
            run(srv.clone(), doc, config)
        }
    }
}
<commit_msg>rustdoc: Sanitize links harder<commit_after>// Copyright 2012 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.

//! Build indexes as appropriate for the markdown pass

use core::prelude::*;

use astsrv;
use config;
use doc::ItemUtils;
use doc;
use fold::Fold;
use fold;
use markdown_pass;
use markdown_writer;
use pass::Pass;

use core::str;

pub fn mk_pass(config: config::Config) -> Pass {
    Pass {
        name: ~"markdown_index",
        f: |srv, doc| run(srv, doc, copy config)
    }
}

pub fn run(
    _srv: astsrv::Srv,
    doc: doc::Doc,
    config: config::Config
) -> doc::Doc {
    let fold = Fold {
        fold_mod: fold_mod,
        fold_nmod: fold_nmod,
        .. fold::default_any_fold(config)
    };
    (fold.fold_doc)(&fold, doc)
}

fn fold_mod(
    fold: &fold::Fold<config::Config>,
    doc: doc::ModDoc
) -> doc::ModDoc {

    let doc = fold::default_any_fold_mod(fold, doc);

    doc::ModDoc {
        index: Some(build_mod_index(copy doc, copy fold.ctxt)),
        .. doc
    }
}

fn fold_nmod(
    fold: &fold::Fold<config::Config>,
    doc: doc::NmodDoc
) -> doc::NmodDoc {

    let doc = fold::default_any_fold_nmod(fold, doc);

    doc::NmodDoc {
        index: Some(build_nmod_index(copy doc, copy fold.ctxt)),
        .. doc
    }
}

fn build_mod_index(
    doc: doc::ModDoc,
    config: config::Config
) -> doc::Index {
    doc::Index {
        entries: doc.items.map(|doc| {
            item_to_entry(copy *doc, copy config)
        })
    }
}

fn build_nmod_index(
    doc: doc::NmodDoc,
    config: config::Config
) -> doc::Index {
    doc::Index {
        entries: doc.fns.map(|doc| {
            item_to_entry(doc::FnTag(copy *doc), copy config)
        })
    }
}

fn item_to_entry(
    doc: doc::ItemTag,
    config: config::Config
) -> doc::IndexEntry {
    let link = match doc {
      doc::ModTag(_) | doc::NmodTag(_)
      if config.output_style == config::DocPerMod => {
        markdown_writer::make_filename(config,
                                       doc::ItemPage(copy doc)).to_str()
      }
      _ => {
        ~"#" + pandoc_header_id(markdown_pass::header_text(copy doc))
      }
    };

    doc::IndexEntry {
        kind: markdown_pass::header_kind(copy doc),
        name: markdown_pass::header_name(copy doc),
        brief: doc.brief(),
        link: link
    }
}

fn pandoc_header_id(header: &str) -> ~str {

    // http://johnmacfarlane.net/pandoc/README.html#headers

    let header = remove_formatting(header);
    let header = remove_punctuation(header);
    let header = replace_with_hyphens(header);
    let header = convert_to_lowercase(header);
    let header = remove_up_to_first_letter(header);
    let header = maybe_use_section_id(header);
    return header;

    fn remove_formatting(s: &str) -> ~str {
        str::replace(s, ~"`", ~"")
    }
    fn remove_punctuation(s: &str) -> ~str {
        let s = str::replace(s, ~"<", ~"");
        let s = str::replace(s, ~">", ~"");
        let s = str::replace(s, ~"[", ~"");
        let s = str::replace(s, ~"]", ~"");
        let s = str::replace(s, ~"(", ~"");
        let s = str::replace(s, ~")", ~"");
        let s = str::replace(s, ~"@~", ~"");
        let s = str::replace(s, ~"~", ~"");
        let s = str::replace(s, ~"/", ~"");
        let s = str::replace(s, ~":", ~"");
        let s = str::replace(s, ~"&", ~"");
        let s = str::replace(s, ~"^", ~"");
        let s = str::replace(s, ~",", ~"");
        let s = str::replace(s, ~"'", ~"");
        let s = str::replace(s, ~"+", ~"");
        return s;
    }
    fn replace_with_hyphens(s: &str) -> ~str {
        // Collapse sequences of whitespace to a single dash
        // XXX: Hacky implementation here that only covers
        // one or two spaces.
        let s = str::trim(s);
        let s = str::replace(s, ~"  ", ~"-");
        let s = str::replace(s, ~" ", ~"-");
        return s;
    }
    fn convert_to_lowercase(s: &str) -> ~str { str::to_lower(s) }
    fn remove_up_to_first_letter(s: &str) -> ~str { s.to_str() }
    fn maybe_use_section_id(s: &str) -> ~str { s.to_str() }
}

#[test]
fn should_remove_punctuation_from_headers() {
    fail_unless!(pandoc_header_id(~"impl foo of bar<A>") ==
        ~"impl-foo-of-bara");
    fail_unless!(pandoc_header_id(~"impl of num::num for int")
        == ~"impl-of-numnum-for-int");
    fail_unless!(pandoc_header_id(~"impl of num::num for int/&")
        == ~"impl-of-numnum-for-int");
    fail_unless!(pandoc_header_id(~"impl of num::num for ^int")
        == ~"impl-of-numnum-for-int");
    fail_unless!(pandoc_header_id(~"impl for & condvar")
        == ~"impl-for-condvar");
    fail_unless!(pandoc_header_id(~"impl of Select<T, U> for (Left, Right)")
                 == ~"impl-of-selectt-u-for-left-right");
    fail_unless!(pandoc_header_id(~"impl of Condition<'self, T, U>")
                 == ~"impl-of-conditionself-t-u");
    fail_unless!(pandoc_header_id(~"impl of Condition<T: Copy + Clone>")
                 == ~"impl-of-conditiont-copy-clone");
}

#[test]
fn should_trim_whitespace_after_removing_punctuation() {
    fail_unless!(pandoc_header_id("impl foo for ()") == ~"impl-foo-for");
}

#[test]
fn should_index_mod_contents() {
    let doc = test::mk_doc(
        config::DocPerCrate,
        ~"mod a { } fn b() { }"
    );
    fail_unless!((&doc.cratemod().index).get().entries[0] == doc::IndexEntry {
        kind: ~"Module",
        name: ~"a",
        brief: None,
        link: ~"#module-a"
    });
    fail_unless!((&doc.cratemod().index).get().entries[1] == doc::IndexEntry {
        kind: ~"Function",
        name: ~"b",
        brief: None,
        link: ~"#function-b"
    });
}

#[test]
fn should_index_mod_contents_multi_page() {
    let doc = test::mk_doc(
        config::DocPerMod,
        ~"mod a { } fn b() { }"
    );
    fail_unless!((&doc.cratemod().index).get().entries[0] == doc::IndexEntry {
        kind: ~"Module",
        name: ~"a",
        brief: None,
        link: ~"a.html"
    });
    fail_unless!((&doc.cratemod().index).get().entries[1] == doc::IndexEntry {
        kind: ~"Function",
        name: ~"b",
        brief: None,
        link: ~"#function-b"
    });
}

#[test]
fn should_index_foreign_mod_pages() {
    let doc = test::mk_doc(
        config::DocPerMod,
        ~"extern mod a { }"
    );
    fail_unless!((&doc.cratemod().index).get().entries[0] == doc::IndexEntry {
        kind: ~"Foreign module",
        name: ~"a",
        brief: None,
        link: ~"a.html"
    });
}

#[test]
fn should_add_brief_desc_to_index() {
    let doc = test::mk_doc(
        config::DocPerMod,
        ~"#[doc = \"test\"] mod a { }"
    );
    fail_unless!((&doc.cratemod().index).get().entries[0].brief
        == Some(~"test"));
}

#[test]
fn should_index_foreign_mod_contents() {
    let doc = test::mk_doc(
        config::DocPerCrate,
        ~"extern mod a { fn b(); }"
    );
    fail_unless!((&doc.cratemod().nmods()[0].index).get().entries[0]
        == doc::IndexEntry {
        kind: ~"Function",
        name: ~"b",
        brief: None,
        link: ~"#function-b"
    });
}

#[cfg(test)]
mod test {
    use astsrv;
    use attr_pass;
    use config;
    use desc_to_brief_pass;
    use doc;
    use extract;
    use markdown_index_pass::run;
    use path_pass;

    use core::path::Path;

    pub fn mk_doc(output_style: config::OutputStyle, source: ~str)
               -> doc::Doc {
        do astsrv::from_str(source) |srv| {
            let config = config::Config {
                output_style: output_style,
                .. config::default_config(&Path("whatever"))
            };
            let doc = extract::from_srv(srv.clone(), ~"");
            let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
            let doc = (desc_to_brief_pass::mk_pass().f)(srv.clone(), doc);
            let doc = (path_pass::mk_pass().f)(srv.clone(), doc);
            run(srv.clone(), doc, config)
        }
    }
}
<|endoftext|>


<commit_before>//! Command line utility for querying and working with Iridium SBD messages.

extern crate docopt;
extern crate rustc_serialize;
extern crate sbd;

use docopt::Docopt;

use sbd::filesystem::Storage;

const USAGE: &'static str = "
Iridium Short Burst Data (SBD) message utility.

Usage:
    sbd list <directory>
    sbd (-h | --help)
    sbd --version

Options:
    -h --help   Show this information
    --version   Show version
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_list: bool,
    arg_directory: String,
}

#[cfg_attr(test, allow(dead_code))]
fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| Ok(d.version(Some(env!("CARGO_PKG_VERSION").to_string()))))
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    if args.cmd_list {
        Storage::new(args.arg_directory);
    }
}
<commit_msg>Print out all entries in a storage<commit_after>//! Command line utility for querying and working with Iridium SBD messages.

extern crate docopt;
extern crate rustc_serialize;
extern crate sbd;

use docopt::Docopt;

use sbd::filesystem::Storage;

const USAGE: &'static str = "
Iridium Short Burst Data (SBD) message utility.

Usage:
    sbd list <directory>
    sbd (-h | --help)
    sbd --version

Options:
    -h --help   Show this information
    --version   Show version
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_list: bool,
    arg_directory: String,
}

#[cfg_attr(test, allow(dead_code))]
fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| Ok(d.version(Some(env!("CARGO_PKG_VERSION").to_string()))))
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    if args.cmd_list {
        for entry in &Storage::new(args.arg_directory) {
            println!("{}", entry.path_buf.to_str().unwrap());
        }
    }
}
<|endoftext|>


<commit_before>use std::mem;
use std::str::FromStr;

#[derive(Clone, Copy, Debug, PartialEq)]
enum Stone {
    Flat,
    Standing,
    Capstone,
}

#[derive(Clone, Copy, Debug)]
enum Player {
    One,
    Two,
}

#[derive(Clone, Copy, Debug)]
struct Piece {
    stone: Stone,
    owner: Player,
}

impl Piece {
    // Flatten a standing stone if a capstone moves onto it
    fn move_onto(&self, base: &mut Piece) -> () {
        assert!(base.stone != Stone::Standing || self.stone == Stone::Capstone,
                "Cannot move normal stone onto standing stone");
        if (base.stone == Stone::Standing && self.stone == Stone::Capstone) {
            base.stone = Stone::Flat;
        }
    }
}

impl FromStr for Piece {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.len() < 4 {
            return Err(());
        }
        let mut chars = s.chars();
        let turn = chars.nth(2).unwrap();
        if "FSC".contains(turn) {
            let stone = match turn {
                'F' => Stone::Flat,
                'S' => Stone::Standing,
                'C' => Stone::Capstone,
                _ => return Err(()),
            };
            let player = match chars.next() {
                Some('1') => Player::One,
                Some('2') => Player::Two,
                _ => return Err(()),
            };

            Ok(Piece {
                stone: stone,
                owner: player,
            })
        } else {
            Err(())
        }
    }

}
#[derive(Clone, Debug)]
struct Cell {
    pieces: Vec<Piece>,
}

impl Cell {
    fn new() -> Cell {
        Cell { pieces: vec![] }
    }

    fn len(&self) -> usize {
        self.pieces.len()
    }

    fn add_piece(&mut self, piece: Piece) -> () {
        match self.pieces.last_mut() {
            Some(base) => piece.move_onto(base),
            None => {}
        }
        self.pieces.push(piece);
    }

    fn place_piece(&mut self, piece: Piece) -> () {
        assert!(self.pieces.len() == 0,
                "Cannot place stone on top of existing stone.");
        self.pieces.push(piece);
    }
}

#[derive(Debug)]
enum Direction {
    Right,
    Left,
    Up,
    Down,
}

impl Direction {
    fn adjust(&self, point: &Point, offset: usize) -> Point {
        match self {
            &Direction::Right => Point { x: point.x + offset, y: point.y },
            &Direction::Left => Point { x: point.x - offset, y: point.y },
            &Direction::Up => Point { x: point.x, y: point.y + offset },
            &Direction::Down => Point { x: point.x, y: point.y - offset },
        }
    }
}

#[derive(Debug)]
enum Turn {
    Placement {
        point: Point,
        piece: Piece,
    },
    Slide {
        point: Point,
        direction: Direction,
        offsets: Vec<usize>,
    },
}

impl FromStr for Turn {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.len() < 4 {
            return Err(());
        }
        let point = match s.parse::<Point>() {
            Ok(p) => p,
            Err(_) => return Err(())
        };
        let mut chars = s.chars();
        let turn = chars.nth(2).unwrap();
        if let Ok(piece) = s.parse::<Piece>() {
            Ok(Turn::Placement {
                point: point,
                piece: piece,
            })
        } else {
            let direction = match turn {
                'R' => Direction::Right,
                'L' => Direction::Left,
                'U' => Direction::Up,
                'D' => Direction::Down,
                _ => return Err(()),
            };
            let offsets = chars.map(|c| c.to_digit(10).unwrap() as usize)
                               .collect();

            Ok(Turn::Slide {
                point: point,
                direction: direction,
                offsets: offsets,
            })
        }

    }
}

fn play(turn: &Turn, board: &mut Board) -> () {
    match turn {
        &Turn::Placement { ref point, ref piece } => {
            board.at(point).place_piece(*piece);
        }
        &Turn::Slide { ref point, ref direction, ref offsets } => {
            assert!(offsets.len() == board.at(point).len(),
                    "Trying to move a different number of pieces than exist.");

            let cell = mem::replace(board.at(point), Cell::new());
            let points = offsets.iter().map(|z| direction.adjust(point, *z));
            for (point, piece) in points.zip(cell.pieces.iter()) {
                board.at(&point).add_piece(*piece);
            }
        }
    }
}

#[derive(Debug)]
struct Point {
    x: usize,
    y: usize,
}

impl FromStr for Point {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.len() < 2 {
            return Err(());
        }
        let mut chars = s.chars();
        let letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
        let numbers = ['1', '2', '3', '4', '5', '6', '7', '8'];
        let grid_x = chars.next().unwrap();
        let grid_y = chars.next().unwrap();
        let x = match letters.iter().position(|c| *c == grid_x) {
            Some(num) => num,
            None => return Err(()),
        };
        let y = match numbers.iter().position(|c| *c == grid_y) {
            Some(num) => num,
            None => return Err(()),
        };
        Ok(Point { x: x, y: y })
    }

}

#[derive(Debug)]
struct Board {
    grid: Vec<Vec<Cell>>,
}

impl Board {
    fn new(board_size: usize) -> Board {
        Board { grid: vec![vec![Cell::new(); board_size]; board_size] }
    }

    fn at(&mut self, point: &Point) -> &mut Cell {
        &mut self.grid[point.x][point.y]
    }
}

fn main() {
    let mut game = Board::new(4);
    play(&("a1S1".parse::<Turn>().unwrap()), &mut game);
    play(&("a2F2".parse::<Turn>().unwrap()), &mut game);
    play(&("a1U1".parse::<Turn>().unwrap()), &mut game);
    play(&("a2R12".parse::<Turn>().unwrap()), &mut game);
    println!("{:#?}", game);
    println!("{:#?}", "a1F1".parse::<Turn>());
    println!("{:#?}", "a1D1".parse::<Turn>());
}
<commit_msg>Formatting, and removing unnecessary prints<commit_after>use std::mem;
use std::str::FromStr;

#[derive(Clone, Copy, Debug, PartialEq)]
enum Stone {
    Flat,
    Standing,
    Capstone,
}

#[derive(Clone, Copy, Debug)]
enum Player {
    One,
    Two,
}

#[derive(Clone, Copy, Debug)]
struct Piece {
    stone: Stone,
    owner: Player,
}

impl Piece {
    // Flatten a standing stone if a capstone moves onto it
    fn move_onto(&self, base: &mut Piece) -> () {
        assert!(base.stone != Stone::Standing || self.stone == Stone::Capstone,
                "Cannot move normal stone onto standing stone");
        if base.stone == Stone::Standing && self.stone == Stone::Capstone {
            base.stone = Stone::Flat;
        }
    }
}

impl FromStr for Piece {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.len() < 4 {
            return Err(());
        }
        let mut chars = s.chars();
        let turn = chars.nth(2).unwrap();
        if "FSC".contains(turn) {
            let stone = match turn {
                'F' => Stone::Flat,
                'S' => Stone::Standing,
                'C' => Stone::Capstone,
                _ => return Err(()),
            };
            let player = match chars.next() {
                Some('1') => Player::One,
                Some('2') => Player::Two,
                _ => return Err(()),
            };

            Ok(Piece {
                stone: stone,
                owner: player,
            })
        } else {
            Err(())
        }
    }

}
#[derive(Clone, Debug)]
struct Cell {
    pieces: Vec<Piece>,
}

impl Cell {
    fn new() -> Cell {
        Cell { pieces: vec![] }
    }

    fn len(&self) -> usize {
        self.pieces.len()
    }

    fn add_piece(&mut self, piece: Piece) -> () {
        match self.pieces.last_mut() {
            Some(base) => piece.move_onto(base),
            None => {}
        }
        self.pieces.push(piece);
    }

    fn place_piece(&mut self, piece: Piece) -> () {
        assert!(self.pieces.len() == 0,
                "Cannot place stone on top of existing stone.");
        self.pieces.push(piece);
    }
}

#[derive(Debug)]
enum Direction {
    Right,
    Left,
    Up,
    Down,
}

impl Direction {
    fn adjust(&self, point: &Point, offset: usize) -> Point {
        match self {
            &Direction::Right => Point {
                x: point.x + offset,
                y: point.y,
            },
            &Direction::Left => Point {
                x: point.x - offset,
                y: point.y,
            },
            &Direction::Up => Point {
                x: point.x,
                y: point.y + offset,
            },
            &Direction::Down => Point {
                x: point.x,
                y: point.y - offset,
            },
        }
    }
}

#[derive(Debug)]
enum Turn {
    Placement {
        point: Point,
        piece: Piece,
    },
    Slide {
        point: Point,
        direction: Direction,
        offsets: Vec<usize>,
    },
}

impl FromStr for Turn {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.len() < 4 {
            return Err(());
        }
        let point = match s.parse::<Point>() {
            Ok(p) => p,
            Err(_) => return Err(()),
        };
        let mut chars = s.chars();
        let turn = chars.nth(2).unwrap();
        if let Ok(piece) = s.parse::<Piece>() {
            Ok(Turn::Placement {
                point: point,
                piece: piece,
            })
        } else {
            let direction = match turn {
                'R' => Direction::Right,
                'L' => Direction::Left,
                'U' => Direction::Up,
                'D' => Direction::Down,
                _ => return Err(()),
            };
            let offsets = chars.map(|c| c.to_digit(10).unwrap() as usize)
                               .collect();

            Ok(Turn::Slide {
                point: point,
                direction: direction,
                offsets: offsets,
            })
        }

    }
}

fn play(turn: &Turn, board: &mut Board) -> () {
    match turn {
        &Turn::Placement { ref point, ref piece } => {
            board.at(point).place_piece(*piece);
        }
        &Turn::Slide { ref point, ref direction, ref offsets } => {
            assert!(offsets.len() == board.at(point).len(),
                    "Trying to move a different number of pieces than exist.");

            let cell = mem::replace(board.at(point), Cell::new());
            let points = offsets.iter().map(|z| direction.adjust(point, *z));
            for (point, piece) in points.zip(cell.pieces.iter()) {
                board.at(&point).add_piece(*piece);
            }
        }
    }
}

#[derive(Debug)]
struct Point {
    x: usize,
    y: usize,
}

impl FromStr for Point {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.len() < 2 {
            return Err(());
        }
        let mut chars = s.chars();
        let letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
        let numbers = ['1', '2', '3', '4', '5', '6', '7', '8'];
        let grid_x = chars.next().unwrap();
        let grid_y = chars.next().unwrap();
        let x = match letters.iter().position(|c| *c == grid_x) {
            Some(num) => num,
            None => return Err(()),
        };
        let y = match numbers.iter().position(|c| *c == grid_y) {
            Some(num) => num,
            None => return Err(()),
        };
        Ok(Point { x: x, y: y })
    }

}

#[derive(Debug)]
struct Board {
    grid: Vec<Vec<Cell>>,
}

impl Board {
    fn new(board_size: usize) -> Board {
        Board { grid: vec![vec![Cell::new(); board_size]; board_size] }
    }

    fn at(&mut self, point: &Point) -> &mut Cell {
        &mut self.grid[point.x][point.y]
    }
}

fn main() {
    let mut game = Board::new(4);
    play(&("a1S1".parse::<Turn>().unwrap()), &mut game);
    play(&("a2F2".parse::<Turn>().unwrap()), &mut game);
    play(&("a1U1".parse::<Turn>().unwrap()), &mut game);
    play(&("a2R12".parse::<Turn>().unwrap()), &mut game);
    println!("{:#?}", game);
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate walkdir;

use walkdir::WalkDir;
use rand::{Rng, thread_rng};
use std::env;
use std::fs::File;
use std::fs;
use std::io::prelude::*;
use std::io::Error;
use std::cmp;

fn main() {
    let mut recursive: bool = false;
    let mut file: String = String::from("");

    for argument in env::args().skip(1) {
        if argument.to_lowercase() == "--help" || argument.to_lowercase() == "-help" {
            help();
            return;
        } else if argument.to_lowercase() == "--v" || argument.to_lowercase() == "-v" ||
           argument.to_lowercase() == "-version" ||
           argument.to_lowercase() == "--version" {
            version();
            return;
        } else if argument.to_lowercase() == "-r" {
            recursive = true;
        } else {
            file = argument;
            break;
        }
    }
    if file == "" {
        help();
        return;
    }
    file = get_path(&file);

    if recursive {
        for entry in WalkDir::new(file) {
            let entry = entry.unwrap();
            trumpify(entry.path().display().to_string());
        }
    } else {
        trumpify(file)
    }
}

fn get_path2(file: &str) -> Result<String, Error> {
    let path = try!(fs::canonicalize(file));
    Ok(path.display().to_string())
}

fn get_path(file: &str) -> String {
    get_path2(file).unwrap_or(file.to_owned())
}

fn read_file(file: &str) -> Result<String, Error> {
    let mut file = try!(File::open(file));
    let mut contents = String::new();
    try!(file.read_to_string(&mut contents));
    Ok(contents)
}

fn write_file(file: &str, content: String) -> Result<(), Error> {
    let mut f = try!(File::create(file));
    try!(f.write_all(content.as_bytes()));

    try!(f.sync_data());
    Ok(())
}

fn version() {
    println!("\x1b[32mVersion:");
    println!("\x1b[0m    trump-0.1.0");
    println!("\x1b[32mWebsite:");
    println!("\x1b[0m    https://github.com/x13machine/trump/");
    println!("\x1b[32mCreator:");
    println!("\x1b[0m    <Googolplexking/x13machine> https://googolplex.ninja/");
}
fn help() {
    println!("\x1b[32mHelp:");
    println!("\x1b[0m    trump --help");
    println!("\x1b[32mVersion:");
    println!("\x1b[0m    trump -v");
    println!("\x1b[32mFiles:");
    println!("\x1b[0m    trump <File>");
    println!("\x1b[32mDirectories:");
    println!("\x1b[0m    trump -r <Directory>");
}

fn trumpify(file: String) {
    let dirs: Vec<&str> = file.split('/').collect::<Vec<&str>>();
    let mut name: String = String::from(dirs[dirs.len() - 1]);
    name = format!("{}{}",
                   &name[0..1].to_uppercase(),
                   &name[1..name.len()].to_lowercase());
    // Ansi Color Codes!!!
    println!("\x1b[32mMaking Great Again:\x1b[0m {}", file);

    let text = format!("Make {} Great Again!", name);

    let mut content = match read_file(&file) {
        Ok(content) => content,
        Err(_) => return,
    };
    if content == ""{
        return ;
    }

    let loops = cmp::max(content.len() / text.len() / 2, 1);
    let mut rng = thread_rng();
    for _ in 0..loops {
        let place: usize = rng.gen_range(0, content.len() as u32) as usize;
        let part1: String = String::from(&content[0..place]);
        let part2: String =
            String::from(&content[cmp::min(place + text.len(), content.len())..content.len()]);
        content = format!("{}{}{}", part1, text, part2);
    }
    let _ = write_file(&file, content);
}
<commit_msg>Utilize the power of match expressions<commit_after>extern crate rand;
extern crate walkdir;

use walkdir::WalkDir;
use rand::{Rng, thread_rng};
use std::env;
use std::fs::File;
use std::fs;
use std::io::prelude::*;
use std::io::Error;
use std::cmp;

fn main() {
    let mut recursive: bool = false;
    let mut file: String = String::from("");

    for argument in env::args().skip(1) {
        if argument.to_lowercase() == "--help" || argument.to_lowercase() == "-help" {
            help();
            return;
        } else if argument.to_lowercase() == "--v" || argument.to_lowercase() == "-v" ||
           argument.to_lowercase() == "-version" ||
           argument.to_lowercase() == "--version" {
            version();
            return;
        } else if argument.to_lowercase() == "-r" {
            recursive = true;
        } else {
            file = argument;
            break;
        }
    }
    if file == "" {
        help();
        return;
    }
    file = get_path(&file);

    if recursive {
        for entry in WalkDir::new(file) {
            let entry = entry.unwrap();
            trumpify(entry.path().display().to_string());
        }
    } else {
        trumpify(file)
    }
}

fn get_path2(file: &str) -> Result<String, Error> {
    let path = try!(fs::canonicalize(file));
    Ok(path.display().to_string())
}

fn get_path(file: &str) -> String {
    get_path2(file).unwrap_or(file.to_owned())
}

fn read_file(file: &str) -> Result<String, Error> {
    let mut file = try!(File::open(file));
    let mut contents = String::new();
    try!(file.read_to_string(&mut contents));
    Ok(contents)
}

fn write_file(file: &str, content: String) -> Result<(), Error> {
    let mut f = try!(File::create(file));
    try!(f.write_all(content.as_bytes()));

    try!(f.sync_data());
    Ok(())
}

fn version() {
    println!("\x1b[32mVersion:");
    println!("\x1b[0m    trump-0.1.0");
    println!("\x1b[32mWebsite:");
    println!("\x1b[0m    https://github.com/x13machine/trump/");
    println!("\x1b[32mCreator:");
    println!("\x1b[0m    <Googolplexking/x13machine> https://googolplex.ninja/");
}
fn help() {
    println!("\x1b[32mHelp:");
    println!("\x1b[0m    trump --help");
    println!("\x1b[32mVersion:");
    println!("\x1b[0m    trump -v");
    println!("\x1b[32mFiles:");
    println!("\x1b[0m    trump <File>");
    println!("\x1b[32mDirectories:");
    println!("\x1b[0m    trump -r <Directory>");
}

fn trumpify(file: String) {
    let dirs: Vec<&str> = file.split('/').collect::<Vec<&str>>();
    let mut name: String = String::from(dirs[dirs.len() - 1]);
    name = format!("{}{}",
                   &name[0..1].to_uppercase(),
                   &name[1..name.len()].to_lowercase());
    // Ansi Color Codes!!!
    println!("\x1b[32mMaking Great Again:\x1b[0m {}", file);

    let text = format!("Make {} Great Again!", name);

    let mut content = match read_file(&file) {
        Ok(ref content) if content.is_empty() => return,
        Ok(content) => content,
        Err(_) => return,
    };

    let loops = cmp::max(content.len() / text.len() / 2, 1);
    let mut rng = thread_rng();
    for _ in 0..loops {
        let place: usize = rng.gen_range(0, content.len() as u32) as usize;
        let part1: String = String::from(&content[0..place]);
        let part2: String =
            String::from(&content[cmp::min(place + text.len(), content.len())..content.len()]);
        content = format!("{}{}{}", part1, text, part2);
    }
    let _ = write_file(&file, content);
}
<|endoftext|>


<commit_before>use gl;
use gl::types::GLint;
use noise::{Seed, Brownian1, perlin1};
use std;
use std::mem;
use sdl2;
use sdl2::event;
use sdl2::event::Event;
use sdl2::video;
use stopwatch::TimerSet;
use yaglw::gl_context::GLContext;
use yaglw::shader::Shader;
use yaglw::texture::{BufferTexture, TextureUnit};
use yaglw::vertex_buffer::{ArrayHandle};

pub const WINDOW_WIDTH: u32 = 800;
pub const WINDOW_HEIGHT: u32 = 800;

pub fn main() {
  let timers = TimerSet::new();

  let mut sdl = sdl2::init().everything().unwrap();
  let window = make_window(&sdl);

  let _sdl_gl_context = window.gl_create_context().unwrap();

  // Load the OpenGL function pointers.
  gl::load_with(|s| unsafe {
    mem::transmute(video::gl_get_proc_address(s))
  });

  let mut gl = unsafe {
    GLContext::new()
  };
  let gl = &mut gl;

  match gl.get_error() {
    gl::NO_ERROR => {},
    err => {
      println!("OpenGL error 0x{:x} in setup", err);
      return;
    },
  }

  let mut shader = make_shader(gl);
  shader.use_shader(gl);

  let heightmap = make_heightmap(gl);

  {
    let mut bind = |name, id| {
      let unit: TextureUnit = Default::default();
      unsafe {
        gl::ActiveTexture(unit.gl_id());
        gl::BindTexture(gl::TEXTURE_BUFFER, id);
      }
      let loc = shader.get_uniform_location(name);
      unsafe {
        gl::Uniform1i(loc, unit.glsl_id as GLint);
      }
    };

    bind("heightmap", heightmap.buffer.byte_buffer.handle.gl_id);
  }

  let empty_vao = ArrayHandle::new(gl);

  unsafe {
    gl::BindVertexArray(empty_vao.gl_id);
  }

  let mut event_pump = sdl.event_pump();

  while process_events(&mut event_pump) {
    timers.time("draw", || {
      gl.clear_buffer();
      unsafe {
        gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
      }
      // swap buffers
      window.gl_swap_window();
    });

    std::thread::sleep_ms(10);
  }

  timers.print();
}

fn make_shader<'a, 'b:'a>(
  gl: &'a GLContext,
) -> Shader<'b> {
  let vertex_shader: String = format!("
    #version 330 core

    out vec4 world_pos;

    void main() {{
      if (gl_VertexID == 0) {{
        world_pos = vec4(-1, 1, 0, 1);
      }} else if (gl_VertexID == 1) {{
        world_pos = vec4(-1, -1, 0, 1);
      }} else if (gl_VertexID == 2) {{
        world_pos = vec4(1, 1, 0, 1);
      }} else {{
        world_pos = vec4(1, -1, 0, 1);
      }}
      gl_Position = world_pos;
    }}
  ");

  let fragment_shader: String = format!("
    #version 330 core

    uniform samplerBuffer heightmap;

    in vec4 world_pos;

    layout(location=0) out vec4 frag_color;

    void main() {{
      int x = int(round(gl_FragCoord.x));
      float h = texelFetch(heightmap, x).r;
      if (world_pos.y <= h) {{
        frag_color = vec4(1, 0, 0, 1);
      }} else {{
        frag_color = vec4(0, 0, 0, 1);
      }}
    }}
  ");

  let components = vec!(
    (gl::VERTEX_SHADER, vertex_shader),
    (gl::FRAGMENT_SHADER, fragment_shader),
  );

  Shader::new(gl, components.into_iter())
}

fn make_window(sdl: &sdl2::Sdl) -> video::Window {
  video::gl_attr::set_context_profile(video::GLProfile::Core);
  video::gl_attr::set_context_version(3, 3);

  // Open the window as fullscreen at the current resolution.
  let mut window =
    video::WindowBuilder::new(
      &sdl,
      "Hello, Mandelbrot",
      WINDOW_WIDTH, WINDOW_HEIGHT,
    );

  let window = window.position_centered();
  window.opengl();

  window.build().unwrap()
}

fn make_heightmap<'a, 'b:'a>(
  gl: &'a mut GLContext,
) -> BufferTexture<'b, f32> {
  let mut ram_heightmap = [0.0; WINDOW_WIDTH as usize];

  let noise = Brownian1::new(perlin1, 1).frequency(1.0 / WINDOW_WIDTH as f32);
  let seed = Seed::new(0);

  for i in 0..WINDOW_WIDTH as usize {
    let h = noise.apply(&seed, &[i as f32]);
    ram_heightmap[i] = h;
  }

  let mut vram_heightmap = BufferTexture::new(gl, gl::R32F, WINDOW_WIDTH as usize);
  vram_heightmap.buffer.push(gl, &ram_heightmap);
  vram_heightmap
}

fn process_events<'a>(
  event_pump: &mut event::EventPump,
) -> bool {
  for event in event_pump.poll_iter() {
    match event {
      Event::Quit {..} => {
        return false;
      },
      Event::AppTerminating {..} => {
        return false;
      },
      _ => {},
    }
  }

  true
}
<commit_msg>change window title<commit_after>use gl;
use gl::types::GLint;
use noise::{Seed, Brownian1, perlin1};
use std;
use std::mem;
use sdl2;
use sdl2::event;
use sdl2::event::Event;
use sdl2::video;
use stopwatch::TimerSet;
use yaglw::gl_context::GLContext;
use yaglw::shader::Shader;
use yaglw::texture::{BufferTexture, TextureUnit};
use yaglw::vertex_buffer::{ArrayHandle};

pub const WINDOW_WIDTH: u32 = 800;
pub const WINDOW_HEIGHT: u32 = 800;

pub fn main() {
  let timers = TimerSet::new();

  let mut sdl = sdl2::init().everything().unwrap();
  let window = make_window(&sdl);

  let _sdl_gl_context = window.gl_create_context().unwrap();

  // Load the OpenGL function pointers.
  gl::load_with(|s| unsafe {
    mem::transmute(video::gl_get_proc_address(s))
  });

  let mut gl = unsafe {
    GLContext::new()
  };
  let gl = &mut gl;

  match gl.get_error() {
    gl::NO_ERROR => {},
    err => {
      println!("OpenGL error 0x{:x} in setup", err);
      return;
    },
  }

  let mut shader = make_shader(gl);
  shader.use_shader(gl);

  let heightmap = make_heightmap(gl);

  {
    let mut bind = |name, id| {
      let unit: TextureUnit = Default::default();
      unsafe {
        gl::ActiveTexture(unit.gl_id());
        gl::BindTexture(gl::TEXTURE_BUFFER, id);
      }
      let loc = shader.get_uniform_location(name);
      unsafe {
        gl::Uniform1i(loc, unit.glsl_id as GLint);
      }
    };

    bind("heightmap", heightmap.buffer.byte_buffer.handle.gl_id);
  }

  let empty_vao = ArrayHandle::new(gl);

  unsafe {
    gl::BindVertexArray(empty_vao.gl_id);
  }

  let mut event_pump = sdl.event_pump();

  while process_events(&mut event_pump) {
    timers.time("draw", || {
      gl.clear_buffer();
      unsafe {
        gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
      }
      // swap buffers
      window.gl_swap_window();
    });

    std::thread::sleep_ms(10);
  }

  timers.print();
}

fn make_shader<'a, 'b:'a>(
  gl: &'a GLContext,
) -> Shader<'b> {
  let vertex_shader: String = format!("
    #version 330 core

    out vec4 world_pos;

    void main() {{
      if (gl_VertexID == 0) {{
        world_pos = vec4(-1, 1, 0, 1);
      }} else if (gl_VertexID == 1) {{
        world_pos = vec4(-1, -1, 0, 1);
      }} else if (gl_VertexID == 2) {{
        world_pos = vec4(1, 1, 0, 1);
      }} else {{
        world_pos = vec4(1, -1, 0, 1);
      }}
      gl_Position = world_pos;
    }}
  ");

  let fragment_shader: String = format!("
    #version 330 core

    uniform samplerBuffer heightmap;

    in vec4 world_pos;

    layout(location=0) out vec4 frag_color;

    void main() {{
      int x = int(round(gl_FragCoord.x));
      float h = texelFetch(heightmap, x).r;
      if (world_pos.y <= h) {{
        frag_color = vec4(1, 0, 0, 1);
      }} else {{
        frag_color = vec4(0, 0, 0, 1);
      }}
    }}
  ");

  let components = vec!(
    (gl::VERTEX_SHADER, vertex_shader),
    (gl::FRAGMENT_SHADER, fragment_shader),
  );

  Shader::new(gl, components.into_iter())
}

fn make_window(sdl: &sdl2::Sdl) -> video::Window {
  video::gl_attr::set_context_profile(video::GLProfile::Core);
  video::gl_attr::set_context_version(3, 3);

  // Open the window as fullscreen at the current resolution.
  let mut window =
    video::WindowBuilder::new(
      &sdl,
      "Perlin 1D",
      WINDOW_WIDTH, WINDOW_HEIGHT,
    );

  let window = window.position_centered();
  window.opengl();

  window.build().unwrap()
}

fn make_heightmap<'a, 'b:'a>(
  gl: &'a mut GLContext,
) -> BufferTexture<'b, f32> {
  let mut ram_heightmap = [0.0; WINDOW_WIDTH as usize];

  let noise = Brownian1::new(perlin1, 1).frequency(1.0 / WINDOW_WIDTH as f32);
  let seed = Seed::new(0);

  for i in 0..WINDOW_WIDTH as usize {
    let h = noise.apply(&seed, &[i as f32]);
    ram_heightmap[i] = h;
  }

  let mut vram_heightmap = BufferTexture::new(gl, gl::R32F, WINDOW_WIDTH as usize);
  vram_heightmap.buffer.push(gl, &ram_heightmap);
  vram_heightmap
}

fn process_events<'a>(
  event_pump: &mut event::EventPump,
) -> bool {
  for event in event_pump.poll_iter() {
    match event {
      Event::Quit {..} => {
        return false;
      },
      Event::AppTerminating {..} => {
        return false;
      },
      _ => {},
    }
  }

  true
}
<|endoftext|>


<commit_before>// File with main method. Can be used to start the generator without
// including it as a library from an external program.

mod map_generator;

fn main() {
  let mut height_map: Vec<int> = Vec::from_fn(1600, |_| 0);

  let number_of_drop_points = 5;
  let min_particles = 100;
  let max_particles = 400;
  let number_of_passes = 4;
  let particle_stability_radius = 1;

  let drops = create_drop_points(number_of_drop_points);

  for i in drops.iter() {
    println!("{}", i);
  }

  // for i in height_map.iter() {
  //   println!("t {}", i);
  // }
}

fn create_drop_points(number_of_drop_points: uint) -> Box<Vec<int>> {
  let mut drops: Vec<int> = Vec::with_capacity(number_of_drop_points);

  for _ in range(1, number_of_drop_points + 1) {
    drops.push(10);
  }

  box drops
}
<commit_msg>Number of points per drop is now randomly generated<commit_after>// File with main method. Can be used to start the generator without
// including it as a library from an external program.
use std::rand::Rng;
use std::rand;

fn main() {
  let mut height_map: Vec<int> = Vec::from_fn(1600, |_| 0);

  let number_of_drop_points = 5;
  let min_particles = 100;
  let max_particles = 400;
  let number_of_passes = 4;
  let particle_stability_radius = 1;

  let drops = create_drop_points(number_of_drop_points);

  for i in drops.iter() {
    println!("{}", i);
  }

  // for i in height_map.iter() {
  //   println!("t {}", i);
  // }
}

fn create_drop_points(number_of_drop_points: uint) -> Box<Vec<int>> {
  let mut drops: Vec<int> = Vec::with_capacity(number_of_drop_points);
  let mut rng = rand::task_rng();

  for _ in range(1, number_of_drop_points + 1) {
    drops.push(rng.gen_range(100, 400));
  }

  box drops
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate colored;
extern crate tdo_core;
extern crate tdo_export;

#[macro_use]
mod macros;
mod cli;
mod filesystem;

use std::env;
use colored::*;
use clap::Shell;
mod subcommands;
use std::process::exit;
use tdo_core::{tdo, error};

#[allow(unused_variables)]
fn main() {
    // initialize the clap App handle
    // let yml = load_yaml!("cli.yml");
    let app = cli::cli().get_matches();

    let save_path = match env::home_dir() {
        Some(path) => path.join(".tdo/list.json"),
        None => {
            errorprint!("You seem to have no home directory. Unfortunately this is required \
                      in order to use tdo.");
            exit(1);
        }
    };
    let mut tdo: tdo::Tdo = match tdo::Tdo::load(save_path.to_str().unwrap()) {
        Ok(loaded) => loaded,
        Err(error::Error(error::ErrorKind::StorageError(
            error::storage_error::ErrorKind::FileNotFound), _)) => tdo::Tdo::new(),
        Err(error::Error(error::ErrorKind::StorageError(
            error::storage_error::ErrorKind::FileCorrupted), _)) => {
            errorprint!("The saved JSON could not be parsed.");
            errorprint!("Please fix the saved json file manually or delete it to continue.");
            exit(1);
        }
        Err(error::Error(error::ErrorKind::StorageError(
            error::storage_error::ErrorKind::UnableToConvert), _)) => {
            errorprint!("The File could not be converted to the new version automatically.");
            errorprint!("Please fix the saved json file manually or delete it to continue.");
            exit(1);
        }
        Err(e) => {
            println!("{:?}", e);
            panic!();
        }
    };

    match app.subcommand {
        None => {
            match app.value_of("task") {
                Some(task_string) => subcommands::add(&mut tdo, task_string, app.value_of("list")),
                None => subcommands::print_out(&tdo, false),
            }
        }
        Some(_) => {
            match app.subcommand() {
                ("all", Some(_)) => subcommands::print_out(&tdo, true),
                ("add", Some(sub_m)) => {
                    let task_string = sub_m.value_of("task").unwrap();
                    subcommands::add(&mut tdo, task_string, sub_m.value_of("list"));
                }
                ("edit", Some(sub_m)) => {
                    let id: u32 = match sub_m.value_of("id").unwrap().parse() {
                        Ok(id) => id,
                        Err(_) => {
                            errorprint!("id must be va valid integer.");
                            exit(1);
                        }
                    };
                    subcommands::edit(&mut tdo, id);
                }
                ("done", Some(sub_m)) => {
                    let id: u32 = match sub_m.value_of("id").unwrap().parse() {
                        Ok(id) => id,
                        Err(_) => {
                            errorprint!("id must be va valid integer.");
                            exit(1);
                        }
                    };
                    subcommands::done(&mut tdo, id);
                }
                ("newlist", Some(sub_m)) => {
                    let new_list = match sub_m.value_of("listname") {
                        Some(name) => name,
                        None => {
                            errorprint!("listname could not be parsed.");
                            exit(1);
                        }
                    };
                    subcommands::newlist(&mut tdo, new_list);
                }
                ("move", Some(sub_m)) => {
                    let id: u32 = match sub_m.value_of("id").unwrap().parse() {
                        Ok(id) => id,
                        Err(_) => {
                            errorprint!("id must be va valid integer.");
                            exit(1);
                        }
                    };
                    subcommands::move_todo(&mut tdo, id, sub_m.value_of("listname").unwrap());
                }
                ("remove", Some(sub_m)) => {
                    let list_name = match sub_m.value_of("listname") {
                        Some(name) => name,
                        None => {
                            errorprint!("listname could not be parsed.");
                            exit(1);
                        }
                    };
                    subcommands::remove(&mut tdo, list_name);
                }
                ("completions", Some(sub_m)) => {
                    if let Some(shell) = sub_m.value_of("shell") {
                        cli::cli().gen_completions_to("tdo",
                                                      shell.parse::<Shell>().unwrap(),
                                                      &mut std::io::stdout());
                    }
                }
                ("github", Some(sub_m)) => {
                    match sub_m.subcommand {
                        None => {
                            let repo = sub_m.value_of("repository").unwrap();
                            let title = sub_m.value_of("title").unwrap();
                            subcommands::github(&mut tdo, repo, title, sub_m.value_of("body"));
                        }
                        Some(_) => {
                            match sub_m.subcommand() {
                                ("set", Some(subs)) => {
                                    subcommands::github_set(&mut tdo, subs.value_of("token"))
                                }
                                _ => println!("{:?}", sub_m),
                            }
                        }
                    }
                }
                ("clean", Some(sub_m)) => subcommands::clean(&mut tdo, sub_m.value_of("listname")),
                ("lists", Some(_)) => subcommands::lists(&tdo),
                ("export", Some(sub_m)) => {
                    let filepath = match sub_m.value_of("destination") {
                        Some(path) => path,
                        None => {
                            errorprint!("destination could not be parsed");
                            exit(1);
                        }
                    };
                    subcommands::export(&tdo, filepath, sub_m.is_present("undone"));
                }
                ("reset", Some(_)) => {
                    match subcommands::reset(&mut tdo) {
                        Some(x) => tdo = x,
                        None => {}
                    }
                }
                _ => println!("{}", app.usage()),
            }
        }
    }

    let target = match filesystem::validate_target_file(save_path.to_str().unwrap()) {
        Ok(path) => path,
        Err(e) => {
            errorprint!(e);
            return;
        }
    };
    match tdo.save(target.to_str().unwrap()) {
        Err(e) => errorprint!(e),
        _ => {}
    }
}
<commit_msg>add min length for optional add, close #10<commit_after>#[macro_use]
extern crate clap;
extern crate colored;
extern crate tdo_core;
extern crate tdo_export;

#[macro_use]
mod macros;
mod cli;
mod filesystem;

use std::env;
use colored::*;
use clap::Shell;
mod subcommands;
use std::process::exit;
use tdo_core::{tdo, error};

static TDO_MIN_LEN: u32 = 5;

#[allow(unused_variables)]
fn main() {
    let app = cli::cli().get_matches();
    let save_path = match env::home_dir() {
        Some(path) => path.join(".tdo/list.json"),
        None => {
            errorprint!("You seem to have no home directory. Unfortunately this is required \
                      in order to use tdo.");
            exit(1);
        }
    };
    let mut tdo: tdo::Tdo = match tdo::Tdo::load(save_path.to_str().unwrap()) {
        Ok(loaded) => loaded,
        Err(error::Error(error::ErrorKind::StorageError(
            error::storage_error::ErrorKind::FileNotFound), _)) => tdo::Tdo::new(),
        Err(error::Error(error::ErrorKind::StorageError(
            error::storage_error::ErrorKind::FileCorrupted), _)) => {
            errorprint!("The saved JSON could not be parsed.");
            errorprint!("Please fix the saved json file manually or delete it to continue.");
            exit(1);
        }
        Err(error::Error(error::ErrorKind::StorageError(
            error::storage_error::ErrorKind::UnableToConvert), _)) => {
            errorprint!("The File could not be converted to the new version automatically.");
            errorprint!("Please fix the saved json file manually or delete it to continue.");
            exit(1);
        }
        Err(e) => {
            println!("{:?}", e);
            panic!();
        }
    };

    match app.subcommand {
        None => {
            match app.value_of("task") {
                Some(task_string) => {
                    if task_string.len() >= TDO_MIN_LEN as usize {
                        subcommands::add(&mut tdo, task_string, app.value_of("list"));
                    } else {
                        errorprint!(format!("The todo has to be at least {} characters long.",
                                            TDO_MIN_LEN));
                        println!("If you want to add a todo with less than {} characters use `tdo \
                                  add` instead",
                                 TDO_MIN_LEN)
                    }
                }
                None => subcommands::print_out(&tdo, false),
            }
        }
        Some(_) => {
            match app.subcommand() {
                ("all", Some(_)) => subcommands::print_out(&tdo, true),
                ("add", Some(sub_m)) => {
                    let task_string = sub_m.value_of("task").unwrap();
                    subcommands::add(&mut tdo, task_string, sub_m.value_of("list"));
                }
                ("edit", Some(sub_m)) => {
                    let id: u32 = match sub_m.value_of("id").unwrap().parse() {
                        Ok(id) => id,
                        Err(_) => {
                            errorprint!("id must be va valid integer.");
                            exit(1);
                        }
                    };
                    subcommands::edit(&mut tdo, id);
                }
                ("done", Some(sub_m)) => {
                    let id: u32 = match sub_m.value_of("id").unwrap().parse() {
                        Ok(id) => id,
                        Err(_) => {
                            errorprint!("id must be va valid integer.");
                            exit(1);
                        }
                    };
                    subcommands::done(&mut tdo, id);
                }
                ("newlist", Some(sub_m)) => {
                    let new_list = match sub_m.value_of("listname") {
                        Some(name) => name,
                        None => {
                            errorprint!("listname could not be parsed.");
                            exit(1);
                        }
                    };
                    subcommands::newlist(&mut tdo, new_list);
                }
                ("move", Some(sub_m)) => {
                    let id: u32 = match sub_m.value_of("id").unwrap().parse() {
                        Ok(id) => id,
                        Err(_) => {
                            errorprint!("id must be va valid integer.");
                            exit(1);
                        }
                    };
                    subcommands::move_todo(&mut tdo, id, sub_m.value_of("listname").unwrap());
                }
                ("remove", Some(sub_m)) => {
                    let list_name = match sub_m.value_of("listname") {
                        Some(name) => name,
                        None => {
                            errorprint!("listname could not be parsed.");
                            exit(1);
                        }
                    };
                    subcommands::remove(&mut tdo, list_name);
                }
                ("completions", Some(sub_m)) => {
                    if let Some(shell) = sub_m.value_of("shell") {
                        cli::cli().gen_completions_to("tdo",
                                                      shell.parse::<Shell>().unwrap(),
                                                      &mut std::io::stdout());
                    }
                }
                ("github", Some(sub_m)) => {
                    match sub_m.subcommand {
                        None => {
                            let repo = sub_m.value_of("repository").unwrap();
                            let title = sub_m.value_of("title").unwrap();
                            subcommands::github(&mut tdo, repo, title, sub_m.value_of("body"));
                        }
                        Some(_) => {
                            match sub_m.subcommand() {
                                ("set", Some(subs)) => {
                                    subcommands::github_set(&mut tdo, subs.value_of("token"))
                                }
                                _ => println!("{:?}", sub_m),
                            }
                        }
                    }
                }
                ("clean", Some(sub_m)) => subcommands::clean(&mut tdo, sub_m.value_of("listname")),
                ("lists", Some(_)) => subcommands::lists(&tdo),
                ("export", Some(sub_m)) => {
                    let filepath = match sub_m.value_of("destination") {
                        Some(path) => path,
                        None => {
                            errorprint!("destination could not be parsed");
                            exit(1);
                        }
                    };
                    subcommands::export(&tdo, filepath, sub_m.is_present("undone"));
                }
                ("reset", Some(_)) => {
                    match subcommands::reset(&mut tdo) {
                        Some(x) => tdo = x,
                        None => {}
                    }
                }
                _ => println!("{}", app.usage()),
            }
        }
    }
    let target = match filesystem::validate_target_file(save_path.to_str().unwrap()) {
        Ok(path) => path,
        Err(e) => {
            errorprint!(e);
            return;
        }
    };
    match tdo.save(target.to_str().unwrap()) {
        Err(e) => errorprint!(e),
        _ => {}
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::collections::HashMap;

extern crate clap;
use clap::{Arg, App, SubCommand};
extern crate toml;

extern crate reqwest;
use reqwest::header::Authorization;

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

extern crate glob;
use glob::glob;

extern crate libc;
#[derive(Deserialize, Debug)]
struct Config {
    token: String,
    org: String,
    team: String,
    #[serde(default="default_endpoint")]
    endpoint: String,
    #[serde(default="default_home")]
    home: String,
    #[serde(default="default_gid")]
    gid: u64,
    #[serde(default="default_sh")]
    sh: String,
    group: Option<String>,
    #[serde(default="default_cache_duration")]
    cache_duration: u64,
    #[serde(default="default_cert_path")]
    cert_path: String
}

fn default_endpoint() -> String { String::from("https://api.github.com") }
fn default_home() -> String { String::from("/home/{}") }
fn default_gid() -> u64 { 2000 }
fn default_sh() -> String { String::from("/bin/bash") }
fn default_cache_duration() -> u64 { 3600 }
fn default_cert_path() -> String { String::from("/etc/ssl/certs/ca-certificates.crt") }

#[derive(Serialize, Deserialize, Debug, Clone)]
struct Team {
    id: u64,
    name: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct Member {
    id: u64,
    login: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct PublicKey {
    id: u64,
    key: String,
}

#[derive(Debug)]
enum CliError {
    Serde(serde_json::Error),
    Reqwest(reqwest::Error),
    Io(std::io::Error),
}

impl From<serde_json::Error> for CliError {fn from(err: serde_json::Error) -> CliError { CliError::Serde(err) }}
impl From<reqwest::Error> for CliError {fn from(err: reqwest::Error) -> CliError { CliError::Reqwest(err) }}
impl From<std::io::Error> for CliError {fn from(err: std::io::Error) -> CliError { CliError::Io(err) }}

fn main() {

    let matches = App::new("ghteam-auth")
                      .version("0.1")
                      .author("Yasuyuki YAMADA <yasuyuki.ymd@gmail.com>")
                      .about("")
                      .arg(Arg::with_name("config")
                               .short("c")
                               .long("config")
                               .value_name("FILE")
                               .help("Sets a custom config file (toml)")
                               .takes_value(true))
                      .arg(Arg::with_name("v")
                               .short("v")
                               .multiple(true)
                               .help("Sets the level of verbosity"))
                      .subcommand(SubCommand::with_name("key")
                                             .about("get user public key")
                                             .arg(Arg::with_name("USER")
                                                      .required(true)
                                                      .index(1)
                                                      .help("user name")))
                      .subcommand(SubCommand::with_name("pam")
                                             .about("execute pam check")
                                             .arg(Arg::with_name("USER")
                                                      .required(false)
                                                      .index(1)
                                                      .help("user name")))
                      .subcommand(SubCommand::with_name("passwd")
                                             .about("get passwd"))
                      .subcommand(SubCommand::with_name("shadow")
                                             .about("get shadow"))
                      .subcommand(SubCommand::with_name("group")
                                             .about("get group"))
                      .subcommand(SubCommand::with_name("refresh")
                                             .about("refresh cache"))
                      .get_matches();

    let configpath = matches.value_of("config").unwrap_or("/etc/ghteam-auth.conf");
    let client = create_github_client(configpath).unwrap();

    if let Some(matches) = matches.subcommand_matches("key") {
        client.print_user_public_key(matches.value_of("USER").unwrap()).unwrap();
    } else if let Some(_) = matches.subcommand_matches("passwd") {
        client.print_passwd().unwrap();
    } else if let Some(_) = matches.subcommand_matches("shadow") {
        client.print_shadow().unwrap();
    } else if let Some(_) = matches.subcommand_matches("group") {
        client.print_group().unwrap();
    } else if let Some(_) = matches.subcommand_matches("refresh") {
        client.clear_all_caches().unwrap();
    } else if let Some(_) = matches.subcommand_matches("pam") {
        match std::env::var("PAM_USER") {
            Ok(user) => {
                if client.check_pam(&user).unwrap() { std::process::exit(0); }
                else { std::process::exit(1) }
            }
            Err(e) => println!("couldn't interpret PAM_USER: {}", e),
        }
    }

}

fn create_github_client( configpath: &str ) -> Result<GithubClient, CliError> {
    let mut file = File::open(configpath)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();
    let config = toml::from_str::<Config>(contents.as_str()).unwrap();
    match std::env::var("SSL_CERT_FILE") {
        Ok(_) => (),
        Err(_) => std::env::set_var("SSL_CERT_FILE", config.cert_path.clone()),
    }
    let client = reqwest::Client::new()?;
    Ok(GithubClient::new(client, config))
}

struct GithubClient {
    client: reqwest::Client,
    conf: Config
}

impl GithubClient {
    fn new(client:reqwest::Client, conf:Config) -> GithubClient {
        GithubClient {client:client, conf:conf}
    }

    fn load_content_from_cache(&self, url:&String) -> Result<(std::fs::Metadata,String),CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push(url.as_str());
        let metadata = std::fs::metadata(path.to_str().unwrap())?;
        let mut f = File::open(path.to_str().unwrap())?;
        let mut content = String::new();
        f.read_to_string(&mut content)?;
        Ok((metadata,content))
    }

    fn store_content_to_cache(&self, url:&String, content:&String) -> Result<(),CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push(url.as_str());
        let mut dirpath = path.clone(); dirpath.pop();
        std::fs::create_dir_all(dirpath)?;
        let mut f = File::create(path.to_str().unwrap())?;
        f.write(content.as_bytes())?;
        Ok(())
    }

    fn get_content_from_url(&self, url:&String) -> Result<String,CliError> {
        let token = String::from("token ") + self.conf.token.clone().as_str();
        let res = self.client.get(url.as_str()).header(Authorization(token)).send();
        let mut content = String::new();
        res?.read_to_string(&mut content)?;
        self.store_content_to_cache(url,&content)?;
        Ok(content)
    }

    fn get_content(&self, url:&String) -> Result<String,CliError> {
        match self.load_content_from_cache(url) {
            Ok((metadata,cache_content)) => {
                match std::time::SystemTime::now().duration_since(metadata.modified()?) {
                    Ok(caching_duration) => {
                        if caching_duration.as_secs() > self.conf.cache_duration {
                            match self.get_content_from_url(url) {
                                Ok(content_from_url) => Ok(content_from_url),
                                Err(_) => Ok(cache_content)
                            }
                        } else {
                            Ok(cache_content)
                        }
                    },
                    Err(_) => {
                        Ok(cache_content)
                    }
                }
            },
            Err(_) => self.get_content_from_url(url)
        }
    }

    fn print_user_public_key(&self, user:&str) -> Result<(), CliError> {
        let keys = self.get_user_public_key(user)?;
        println!("{}", keys);
        Ok(())
    }

    fn get_user_public_key(&self, user:&str) -> Result<String, CliError> {
        let url = format!("{}/users/{}/keys", self.conf.endpoint, user);
        let content = self.get_content(&url);
        let keys = serde_json::from_str::<Vec<PublicKey>>(content?.as_str())?;
        Ok(keys.iter().map(|k|{k.key.clone()}).collect::<Vec<String>>().join("\n"))
    }

    fn check_pam(&self, user:&String) -> Result<bool, CliError> {
        let (_,members) = self.get_team_members()?;
        Ok(members.contains_key(user))
    }

    fn print_passwd(&self) -> Result<(), CliError> {
        let (_,members) = self.get_team_members()?;
        for member in members.values() {
            println!("{}", self.create_passwd_line(&member));
        }
        Ok(())
    }

    fn print_shadow(&self) -> Result<(), CliError> {
        let (_,members) = self.get_team_members()?;
        for member in members.values() {
            println!("{}", self.create_shadow_line(&member));
        }
        Ok(())
    }

    fn print_group(&self) -> Result<(), CliError> {
        let (team,members) = self.get_team_members()?;
        println!("{}", self.create_group_line(&team.name, self.conf.gid, &members));
        Ok(())
    }

    fn create_passwd_line(&self, member:&Member) -> String {
        format!("{login}:x:{uid}:{gid}:user@{org}:{home}:{sh}",
                login=member.login,
                uid=member.id,
                gid=self.conf.gid,
                org=self.conf.org,
                home=self.conf.home.replace("{}",member.login.as_str()),
                sh=self.conf.sh,
                )
    }

    fn create_shadow_line(&self, member:&Member) -> String {
        format!("{login}:!!:::::::", login=member.login )
    }

    fn create_group_line(&self, name:&String, id:u64, members:&HashMap<String,Member>) -> String {
        format!("{name}:x:{id}:{members}", name=name, id=id,
                members=members.values().map(|m|{m.login.clone()}).collect::<Vec<String>>().join(","))
    }

    fn get_team_members(&self) -> Result<(Team,HashMap<String,Member>),CliError> {
        let teams:HashMap<String,Team> = self.get_teams()?;
        if let Some(team) = teams.get(&self.conf.team.clone()) {
            Ok((team.clone(),self.get_members(team.id)?))
        } else {
            Err(CliError::from(std::io::Error::new(std::io::ErrorKind::NotFound, "Team not found")))
        }
    }

    fn get_teams(&self) -> Result<HashMap<String,Team>, CliError> {
        let url = format!("{}/orgs/{}/teams",self.conf.endpoint, self.conf.org);
        let content = self.get_content(&url)?;
        let teams = serde_json::from_str::<Vec<Team>>(content.as_str())?;
        let mut team_map = HashMap::new();
        for team in teams { team_map.insert(team.name.clone(), team); }
        Ok(team_map)
    }

    fn get_members(&self, mid:u64) -> Result<HashMap<String,Member>, CliError> {
        let url = format!("{}/teams/{}/members",self.conf.endpoint.clone(), mid);
        let content = self.get_content(&url)?;
        let members = serde_json::from_str::<Vec<Member>>(content.as_str())?;
        let mut member_map = HashMap::new();
        for member in members { member_map.insert(member.login.clone(), member); }
        Ok(member_map)
    }

    fn clear_all_caches(&self) -> Result<(), CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push("**");
        path.push("*");
        for entry in glob(&path.to_str().unwrap()).unwrap() {
            match entry {
                Ok(path) => {if path.is_file() {std::fs::remove_file(path)?}},
                Err(e) => println!("{:?}", e),
            }
        }
        Ok(())
    }

}

#[repr(C)]
#[allow(missing_copy_implementations)]
pub struct Passwd {
    name:   *mut libc::c_char,
    pass:   *mut libc::c_char,
    uid:    libc::uid_t,
    gid:    libc::gid_t,
    gecos:  *mut libc::c_char,
    home:   *mut libc::c_char,
    sh:     *mut libc::c_char,
}
<commit_msg>Change the way to get config path<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::collections::HashMap;

extern crate clap;
use clap::{Arg, App, SubCommand};
extern crate toml;

extern crate reqwest;
use reqwest::header::Authorization;

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

extern crate glob;
use glob::glob;

extern crate libc;
#[derive(Deserialize, Debug)]
struct Config {
    token: String,
    org: String,
    team: String,
    #[serde(default="default_endpoint")]
    endpoint: String,
    #[serde(default="default_home")]
    home: String,
    #[serde(default="default_gid")]
    gid: u64,
    #[serde(default="default_sh")]
    sh: String,
    group: Option<String>,
    #[serde(default="default_cache_duration")]
    cache_duration: u64,
    #[serde(default="default_cert_path")]
    cert_path: String
}

fn default_endpoint() -> String { String::from("https://api.github.com") }
fn default_home() -> String { String::from("/home/{}") }
fn default_gid() -> u64 { 2000 }
fn default_sh() -> String { String::from("/bin/bash") }
fn default_cache_duration() -> u64 { 3600 }
fn default_cert_path() -> String { String::from("/etc/ssl/certs/ca-certificates.crt") }

#[derive(Serialize, Deserialize, Debug, Clone)]
struct Team {
    id: u64,
    name: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct Member {
    id: u64,
    login: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct PublicKey {
    id: u64,
    key: String,
}

#[derive(Debug)]
enum CliError {
    Serde(serde_json::Error),
    Reqwest(reqwest::Error),
    Io(std::io::Error),
}

impl From<serde_json::Error> for CliError {fn from(err: serde_json::Error) -> CliError { CliError::Serde(err) }}
impl From<reqwest::Error> for CliError {fn from(err: reqwest::Error) -> CliError { CliError::Reqwest(err) }}
impl From<std::io::Error> for CliError {fn from(err: std::io::Error) -> CliError { CliError::Io(err) }}

fn main() {

    let matches = App::new("ghteam-auth")
                      .version("0.1")
                      .author("Yasuyuki YAMADA <yasuyuki.ymd@gmail.com>")
                      .about("")
                      .arg(Arg::with_name("v")
                               .short("v")
                               .multiple(true)
                               .help("Sets the level of verbosity"))
                      .subcommand(SubCommand::with_name("key")
                                             .about("get user public key")
                                             .arg(Arg::with_name("USER")
                                                      .required(true)
                                                      .index(1)
                                                      .help("user name")))
                      .subcommand(SubCommand::with_name("pam")
                                             .about("execute pam check")
                                             .arg(Arg::with_name("USER")
                                                      .required(false)
                                                      .index(1)
                                                      .help("user name")))
                      .subcommand(SubCommand::with_name("passwd")
                                             .about("get passwd"))
                      .subcommand(SubCommand::with_name("shadow")
                                             .about("get shadow"))
                      .subcommand(SubCommand::with_name("group")
                                             .about("get group"))
                      .subcommand(SubCommand::with_name("refresh")
                                             .about("refresh cache"))
                      .get_matches();

    let configpath = std::env::var("GHTEAMAUTH_CONFIG").unwrap_or(String::from("/etc/ghteam-auth.conf"));
    let client = create_github_client(configpath.as_str()).unwrap();

    if let Some(matches) = matches.subcommand_matches("key") {
        client.print_user_public_key(matches.value_of("USER").unwrap()).unwrap();
    } else if let Some(_) = matches.subcommand_matches("passwd") {
        client.print_passwd().unwrap();
    } else if let Some(_) = matches.subcommand_matches("shadow") {
        client.print_shadow().unwrap();
    } else if let Some(_) = matches.subcommand_matches("group") {
        client.print_group().unwrap();
    } else if let Some(_) = matches.subcommand_matches("refresh") {
        client.clear_all_caches().unwrap();
    } else if let Some(_) = matches.subcommand_matches("pam") {
        match std::env::var("PAM_USER") {
            Ok(user) => {
                if client.check_pam(&user).unwrap() { std::process::exit(0); }
                else { std::process::exit(1) }
            }
            Err(e) => println!("couldn't interpret PAM_USER: {}", e),
        }
    }

}

fn create_github_client( configpath: &str ) -> Result<GithubClient, CliError> {
    let mut file = File::open(configpath)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();
    let config = toml::from_str::<Config>(contents.as_str()).unwrap();
    match std::env::var("SSL_CERT_FILE") {
        Ok(_) => (),
        Err(_) => std::env::set_var("SSL_CERT_FILE", config.cert_path.clone()),
    }
    let client = reqwest::Client::new()?;
    Ok(GithubClient::new(client, config))
}

struct GithubClient {
    client: reqwest::Client,
    conf: Config
}

impl GithubClient {
    fn new(client:reqwest::Client, conf:Config) -> GithubClient {
        GithubClient {client:client, conf:conf}
    }

    fn load_content_from_cache(&self, url:&String) -> Result<(std::fs::Metadata,String),CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push(url.as_str());
        let metadata = std::fs::metadata(path.to_str().unwrap())?;
        let mut f = File::open(path.to_str().unwrap())?;
        let mut content = String::new();
        f.read_to_string(&mut content)?;
        Ok((metadata,content))
    }

    fn store_content_to_cache(&self, url:&String, content:&String) -> Result<(),CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push(url.as_str());
        let mut dirpath = path.clone(); dirpath.pop();
        std::fs::create_dir_all(dirpath)?;
        let mut f = File::create(path.to_str().unwrap())?;
        f.write(content.as_bytes())?;
        Ok(())
    }

    fn get_content_from_url(&self, url:&String) -> Result<String,CliError> {
        let token = String::from("token ") + self.conf.token.clone().as_str();
        let res = self.client.get(url.as_str()).header(Authorization(token)).send();
        let mut content = String::new();
        res?.read_to_string(&mut content)?;
        self.store_content_to_cache(url,&content)?;
        Ok(content)
    }

    fn get_content(&self, url:&String) -> Result<String,CliError> {
        match self.load_content_from_cache(url) {
            Ok((metadata,cache_content)) => {
                match std::time::SystemTime::now().duration_since(metadata.modified()?) {
                    Ok(caching_duration) => {
                        if caching_duration.as_secs() > self.conf.cache_duration {
                            match self.get_content_from_url(url) {
                                Ok(content_from_url) => Ok(content_from_url),
                                Err(_) => Ok(cache_content)
                            }
                        } else {
                            Ok(cache_content)
                        }
                    },
                    Err(_) => {
                        Ok(cache_content)
                    }
                }
            },
            Err(_) => self.get_content_from_url(url)
        }
    }

    fn print_user_public_key(&self, user:&str) -> Result<(), CliError> {
        let keys = self.get_user_public_key(user)?;
        println!("{}", keys);
        Ok(())
    }

    fn get_user_public_key(&self, user:&str) -> Result<String, CliError> {
        let url = format!("{}/users/{}/keys", self.conf.endpoint, user);
        let content = self.get_content(&url);
        let keys = serde_json::from_str::<Vec<PublicKey>>(content?.as_str())?;
        Ok(keys.iter().map(|k|{k.key.clone()}).collect::<Vec<String>>().join("\n"))
    }

    fn check_pam(&self, user:&String) -> Result<bool, CliError> {
        let (_,members) = self.get_team_members()?;
        Ok(members.contains_key(user))
    }

    fn print_passwd(&self) -> Result<(), CliError> {
        let (_,members) = self.get_team_members()?;
        for member in members.values() {
            println!("{}", self.create_passwd_line(&member));
        }
        Ok(())
    }

    fn print_shadow(&self) -> Result<(), CliError> {
        let (_,members) = self.get_team_members()?;
        for member in members.values() {
            println!("{}", self.create_shadow_line(&member));
        }
        Ok(())
    }

    fn print_group(&self) -> Result<(), CliError> {
        let (team,members) = self.get_team_members()?;
        println!("{}", self.create_group_line(&team.name, self.conf.gid, &members));
        Ok(())
    }

    fn create_passwd_line(&self, member:&Member) -> String {
        format!("{login}:x:{uid}:{gid}:user@{org}:{home}:{sh}",
                login=member.login,
                uid=member.id,
                gid=self.conf.gid,
                org=self.conf.org,
                home=self.conf.home.replace("{}",member.login.as_str()),
                sh=self.conf.sh,
                )
    }

    fn create_shadow_line(&self, member:&Member) -> String {
        format!("{login}:!!:::::::", login=member.login )
    }

    fn create_group_line(&self, name:&String, id:u64, members:&HashMap<String,Member>) -> String {
        format!("{name}:x:{id}:{members}", name=name, id=id,
                members=members.values().map(|m|{m.login.clone()}).collect::<Vec<String>>().join(","))
    }

    fn get_team_members(&self) -> Result<(Team,HashMap<String,Member>),CliError> {
        let teams:HashMap<String,Team> = self.get_teams()?;
        if let Some(team) = teams.get(&self.conf.team.clone()) {
            Ok((team.clone(),self.get_members(team.id)?))
        } else {
            Err(CliError::from(std::io::Error::new(std::io::ErrorKind::NotFound, "Team not found")))
        }
    }

    fn get_teams(&self) -> Result<HashMap<String,Team>, CliError> {
        let url = format!("{}/orgs/{}/teams",self.conf.endpoint, self.conf.org);
        let content = self.get_content(&url)?;
        let teams = serde_json::from_str::<Vec<Team>>(content.as_str())?;
        let mut team_map = HashMap::new();
        for team in teams { team_map.insert(team.name.clone(), team); }
        Ok(team_map)
    }

    fn get_members(&self, mid:u64) -> Result<HashMap<String,Member>, CliError> {
        let url = format!("{}/teams/{}/members",self.conf.endpoint.clone(), mid);
        let content = self.get_content(&url)?;
        let members = serde_json::from_str::<Vec<Member>>(content.as_str())?;
        let mut member_map = HashMap::new();
        for member in members { member_map.insert(member.login.clone(), member); }
        Ok(member_map)
    }

    fn clear_all_caches(&self) -> Result<(), CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push("**");
        path.push("*");
        for entry in glob(&path.to_str().unwrap()).unwrap() {
            match entry {
                Ok(path) => {if path.is_file() {std::fs::remove_file(path)?}},
                Err(e) => println!("{:?}", e),
            }
        }
        Ok(())
    }

}

#[repr(C)]
#[allow(missing_copy_implementations)]
pub struct Passwd {
    name:   *mut libc::c_char,
    pass:   *mut libc::c_char,
    uid:    libc::uid_t,
    gid:    libc::gid_t,
    gecos:  *mut libc::c_char,
    home:   *mut libc::c_char,
    sh:     *mut libc::c_char,
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::env;
use std::fs;
use std::io::{BufReader, BufRead};

extern crate git2;
extern crate glob;
extern crate rustc_serialize;
extern crate tiny_http;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";
static INDEX_LOCAL_PATH: &'static str = "crates.io-index";

#[derive(RustcDecodable)]
#[allow(dead_code)]
struct CrateInfo {
    name: String,
    vers: String,
    deps: Vec<DepInfo>,
    cksum: String,
    features: HashMap<String, Vec<String>>,
    yanked: bool,
}

#[derive(RustcDecodable)]
#[allow(dead_code)]
struct DepInfo {
    name: String,
    req: String,
    features: Vec<String>,
    optional: bool,
    default_features: bool,
    target: Option<String>,
    kind: Option<String>
}

fn build_dependency_map() -> HashMap<String, Vec<String>> {
    let mut match_options = glob::MatchOptions::new();
    match_options.require_literal_leading_dot = true;

    let index_paths1 = glob::glob_with("crates.io-index/*/*/*", &match_options).unwrap();
    let index_paths2 = glob::glob_with("crates.io-index/[12]/*", &match_options).unwrap();

    let index_paths = index_paths1.chain(index_paths2);

    let mut map = HashMap::new();

    for glob_result in index_paths {
        let index_path = glob_result.unwrap();
        let file = fs::File::open(&index_path).unwrap();
        let last_line = BufReader::new(file).lines().last().unwrap().unwrap();
        let crate_info: CrateInfo = rustc_serialize::json::decode(&last_line).unwrap();
        let deps_names = crate_info.deps.iter().map(|d| d.name.clone()).collect();
        map.insert(crate_info.name, deps_names);
    }

    map
}

fn main() {
    if fs::metadata(INDEX_LOCAL_PATH).is_err() {
        println!("Cloning crates.io-index");
        git2::Repository::clone(INDEX_GIT_URL, INDEX_LOCAL_PATH).unwrap();
    }

    let dep_map = build_dependency_map();

    let port = match env::var("PORT") {
        Ok(p) => p.parse::<u16>().unwrap(),
        Err(..) => 8000,
    };

    let server = tiny_http::ServerBuilder::new().with_port(port).build().unwrap();

    println!("Server listening on port {}", port);
    for req in server.incoming_requests() {
        let response = match dep_map.get(req.get_url().trim_left_matches("/")) {
            Some(d) => d.iter().fold(String::new(), |acc, item| acc + ", " + &item),
            None => String::from("could not find crate"),
        };

        let response = tiny_http::Response::from_string(response);
        req.respond(response);
    }
}
<commit_msg>Add function that will build DOT<commit_after>use std::collections::HashMap;
use std::env;
use std::fs;
use std::io::{BufReader, BufRead};

extern crate git2;
extern crate glob;
extern crate rustc_serialize;
extern crate tiny_http;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";
static INDEX_LOCAL_PATH: &'static str = "crates.io-index";

#[derive(RustcDecodable)]
#[allow(dead_code)]
struct CrateInfo {
    name: String,
    vers: String,
    deps: Vec<DepInfo>,
    cksum: String,
    features: HashMap<String, Vec<String>>,
    yanked: bool,
}

#[derive(RustcDecodable)]
#[allow(dead_code)]
struct DepInfo {
    name: String,
    req: String,
    features: Vec<String>,
    optional: bool,
    default_features: bool,
    target: Option<String>,
    kind: Option<String>
}

fn build_dependency_map() -> HashMap<String, Vec<String>> {
    let mut match_options = glob::MatchOptions::new();
    match_options.require_literal_leading_dot = true;

    let index_paths1 = glob::glob_with("crates.io-index/*/*/*", &match_options).unwrap();
    let index_paths2 = glob::glob_with("crates.io-index/[12]/*", &match_options).unwrap();

    let index_paths = index_paths1.chain(index_paths2);

    let mut map = HashMap::new();

    for glob_result in index_paths {
        let index_path = glob_result.unwrap();
        let file = fs::File::open(&index_path).unwrap();
        let last_line = BufReader::new(file).lines().last().unwrap().unwrap();
        let crate_info: CrateInfo = rustc_serialize::json::decode(&last_line).unwrap();
        let deps_names = crate_info.deps.iter().map(|d| d.name.clone()).collect();
        map.insert(crate_info.name, deps_names);
    }

    map
}

fn build_dot(crate_name: &str, mut crate_deps: Vec<String>, dep_map: &HashMap<String, Vec<String>>) -> String {
    while let Some(crate_dep) = crate_deps.pop() {
        println!("{}", crate_dep);
    }
    String::from("FIXME")
}

fn main() {
    if fs::metadata(INDEX_LOCAL_PATH).is_err() {
        println!("Cloning crates.io-index");
        git2::Repository::clone(INDEX_GIT_URL, INDEX_LOCAL_PATH).unwrap();
    }

    let mut dep_map = build_dependency_map();

    let port = match env::var("PORT") {
        Ok(p) => p.parse::<u16>().unwrap(),
        Err(..) => 8000,
    };

    let server = tiny_http::ServerBuilder::new().with_port(port).build().unwrap();

    println!("Server listening on port {}", port);
    for req in server.incoming_requests() {
        let response = match dep_map.get(req.get_url().trim_left_matches("/")) {
            Some(d) => {
                build_dot(req.get_url().trim_left_matches("/"), d.clone(), &dep_map)
            },
            None => String::from("could not find crate"),
        };

        let response = tiny_http::Response::from_string(response);
        req.respond(response);
    }
}
<|endoftext|>