<commit_before>// Future TimeSteward API goals:
//
// – groups
// I made up API functions for this before, but I'm not sure they were perfect.
// We can use RowId's for group ids, but what kinds of things can be stored IN a group? Previously I said only RowId's could, which doesn't seem ideal. I think it would work to allow anything hashable. That would basically make a group behave like a HashSet. But then, why not make it behave like a HashMap instead? But accessor itself already behaves like a HashMap over RowId's – the essential thing groups do is to allow iterating particular subsets of that HashMap.
//
// – conveniences for serializing snapshots (not sure what)
//
// – be able to construct a new TimeSteward from any snapshot
// Issues: should snapshots expose the predictors? Also, the predictors can't be serialized. So you'd probably actually have to construct a TimeSteward from snapshot + predictors. This requires a way to iterate all fields (and group data if we add groups) in a snapshot, which is similar to the previous 2 items (iterating the whole set, which is a special case of iterating a subset; and serializing requires you to iterate everything as well)
//
// – parallelism support for predictors and events
// When an event or predictor gets invalidated while it is still running, it would be nice for it to save time by exiting early.
// Moreover, it would probably be more efficient to discard invalidated fields than to preserve them for predictors/events that are in process. The natural way for the accessors to handle this is to have get() return None, which would mean that you can never safely unwrap() the result. We could provide a "unwrap or return" macro.
//
// – Optimization features
// one possibility: user can provide a function FieldId->[(PredictorId, RowId)] that lists predictors you KNOW will be invalidated by a change to that field, then have that predictor run its get() calls with an input called "promise_inferred" or something so that we don't spend time and memory recording the dependency
// another: a predictor might have a costly computation to find the exact time of a future event, which it won't need to do if it gets invalidated long before that time comes. For that, we can provide a defer_until(time) method
//
//
//

#![feature(unboxed_closures, fn_traits, specialization)]
#![feature(pub_restricted)]
// #![feature (plugin, custom_derive)]
// #![plugin (serde_macros)]
// #![plugin (quickcheck_macros)]

extern crate rand;
extern crate nalgebra;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate bincode;
extern crate crossbeam;
#[macro_use]
extern crate quickcheck;

macro_rules! printlnerr(
    ($($arg:tt)*) => { {use std::io::Write;
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

/// Used by TimeSteward implementations.
///
/// These are public in case someone wants to try implementing a TimeSteward
/// outside of this crate, sharing some of the details with my own implementations.
/// However, anything inside this module should be
/// considered very unstable at present.
#[macro_use]
pub mod implementation_support {
  #[macro_use]
  pub mod list_of_types;
  pub mod insert_only;
  pub mod data_structures;
  #[macro_use]
  pub mod common;
}

mod deterministic_random_id;
pub use deterministic_random_id::*;
#[macro_use]
mod api;
pub use api::*;
pub use implementation_support::list_of_types::{ColumnType, EventType, PredictorType};

#[macro_use]
pub mod stewards {
  pub mod inefficient_flat;
  pub mod memoized_flat;
  pub mod amortized;

  pub mod flat_to_inefficient_full;
  pub mod crossverified;
  pub mod simply_synchronized;
}

#[macro_use]
pub mod support {
  pub mod rounding_error_tolerant_math;
  pub mod time_functions;
  pub mod collision_detection;
}
<commit_msg>fix warning<commit_after>// Future TimeSteward API goals:
//
// – groups
// I made up API functions for this before, but I'm not sure they were perfect.
// We can use RowId's for group ids, but what kinds of things can be stored IN a group? Previously I said only RowId's could, which doesn't seem ideal. I think it would work to allow anything hashable. That would basically make a group behave like a HashSet. But then, why not make it behave like a HashMap instead? But accessor itself already behaves like a HashMap over RowId's – the essential thing groups do is to allow iterating particular subsets of that HashMap.
//
// – conveniences for serializing snapshots (not sure what)
//
// – be able to construct a new TimeSteward from any snapshot
// Issues: should snapshots expose the predictors? Also, the predictors can't be serialized. So you'd probably actually have to construct a TimeSteward from snapshot + predictors. This requires a way to iterate all fields (and group data if we add groups) in a snapshot, which is similar to the previous 2 items (iterating the whole set, which is a special case of iterating a subset; and serializing requires you to iterate everything as well)
//
// – parallelism support for predictors and events
// When an event or predictor gets invalidated while it is still running, it would be nice for it to save time by exiting early.
// Moreover, it would probably be more efficient to discard invalidated fields than to preserve them for predictors/events that are in process. The natural way for the accessors to handle this is to have get() return None, which would mean that you can never safely unwrap() the result. We could provide a "unwrap or return" macro.
//
// – Optimization features
// one possibility: user can provide a function FieldId->[(PredictorId, RowId)] that lists predictors you KNOW will be invalidated by a change to that field, then have that predictor run its get() calls with an input called "promise_inferred" or something so that we don't spend time and memory recording the dependency
// another: a predictor might have a costly computation to find the exact time of a future event, which it won't need to do if it gets invalidated long before that time comes. For that, we can provide a defer_until(time) method
//
//
//

#![feature(unboxed_closures, fn_traits, specialization)]
// #![feature (plugin, custom_derive)]
// #![plugin (serde_macros)]
// #![plugin (quickcheck_macros)]

extern crate rand;
extern crate nalgebra;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate bincode;
extern crate crossbeam;
#[macro_use]
extern crate quickcheck;

macro_rules! printlnerr(
    ($($arg:tt)*) => { {use std::io::Write;
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

/// Used by TimeSteward implementations.
///
/// These are public in case someone wants to try implementing a TimeSteward
/// outside of this crate, sharing some of the details with my own implementations.
/// However, anything inside this module should be
/// considered very unstable at present.
#[macro_use]
pub mod implementation_support {
  #[macro_use]
  pub mod list_of_types;
  pub mod insert_only;
  pub mod data_structures;
  #[macro_use]
  pub mod common;
}

mod deterministic_random_id;
pub use deterministic_random_id::*;
#[macro_use]
mod api;
pub use api::*;
pub use implementation_support::list_of_types::{ColumnType, EventType, PredictorType};

#[macro_use]
pub mod stewards {
  pub mod inefficient_flat;
  pub mod memoized_flat;
  pub mod amortized;

  pub mod flat_to_inefficient_full;
  pub mod crossverified;
  pub mod simply_synchronized;
}

#[macro_use]
pub mod support {
  pub mod rounding_error_tolerant_math;
  pub mod time_functions;
  pub mod collision_detection;
}
<|endoftext|>


<commit_before>#![feature(test)]

#[cfg(test)]
extern crate asm6502;

#[cfg(test)]
extern crate rand;

#[cfg(test)]
extern crate test;

extern crate byteorder;
extern crate cpu6502;
extern crate rs_nes_macros;

mod apu;
mod cart;
mod input;
mod interconnect;
mod ppu;
mod rom;

pub use crate::{
    apu::Apu,
    cart::{Cart, Nrom128, Nrom256, Uxrom},
    input::{Button, IInput, Input},
    interconnect::NesInterconnect,
    ppu::{IPpu, Ppu, SpriteRenderer, Vram},
    rom::NesRom,
};
use cpu6502::cpu::Cpu;

#[cfg(test)]
mod mocks {
    pub use crate::{
        apu::mocks::ApuMock,
        cart::mocks::CartMock,
        input::mocks::InputMock,
        ppu::mocks::{MockSpriteRenderer, MockVram, PpuMock},
    };
}

pub fn load_cart<C: Cart>(
    cart: C,
) -> Result<Box<Cpu<NesInterconnect<Ppu<Vram, SpriteRenderer>, Apu, Input, C>>>, &'static str> {
    let vram = Vram::new();
    let ppu = Ppu::new(vram);
    let input = Input::default();
    let apu = Apu::default();
    let mem = NesInterconnect::new(cart, ppu, input, apu);
    let mut cpu = Box::new(Cpu::new(mem, 0x00));
    cpu.reset();
    Ok(cpu)
}
<commit_msg>Use unstable box feature to avoid intermediate stack allocation<commit_after>#![feature(box_syntax, test)]

#[cfg(test)]
extern crate asm6502;

#[cfg(test)]
extern crate rand;

#[cfg(test)]
extern crate test;

extern crate byteorder;
extern crate cpu6502;
extern crate rs_nes_macros;

mod apu;
mod cart;
mod input;
mod interconnect;
mod ppu;
mod rom;

pub use crate::{
    apu::Apu,
    cart::{Cart, Nrom128, Nrom256, Uxrom},
    input::{Button, IInput, Input},
    interconnect::NesInterconnect,
    ppu::{IPpu, Ppu, SpriteRenderer, Vram},
    rom::NesRom,
};
use cpu6502::cpu::Cpu;

#[cfg(test)]
mod mocks {
    pub use crate::{
        apu::mocks::ApuMock,
        cart::mocks::CartMock,
        input::mocks::InputMock,
        ppu::mocks::{MockSpriteRenderer, MockVram, PpuMock},
    };
}

pub fn load_cart<C: Cart>(
    cart: C,
) -> Result<Box<Cpu<NesInterconnect<Ppu<Vram, SpriteRenderer>, Apu, Input, C>>>, &'static str> {
    let vram = Vram::new();
    let ppu = Ppu::new(vram);
    let input = Input::default();
    let apu = Apu::default();
    let mut cpu = box Cpu::new(NesInterconnect::new(cart, ppu, input, apu), 0x00);
    cpu.reset();
    Ok(cpu)
}
<|endoftext|>


<commit_before>#![feature(plugin_registrar)]
#![feature(quote)]
#![feature(rustc_private)]
#![feature(slice_patterns)]

extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::Registry;
use syntax::abi::Abi;
use syntax::ast::{
    Constness, Expr, ExprKind, FnDecl, FunctionRetTy, Generics, Ident, ItemKind, Lifetime, Path,
    TokenTree, Unsafety
};
use syntax::codemap::{DUMMY_SP, Span, Spanned};
use syntax::ext::base::{DummyResult, ExtCtxt, MacEager, MacResult};
use syntax::ext::build::AstBuilder;
use syntax::parse::PResult;
use syntax::parse::common::seq_sep_trailing_allowed;
use syntax::parse::parser::{Parser, PathParsingMode};
use syntax::parse::token::intern;
use syntax::parse::token::keywords::Keyword;
use syntax::parse::token::{DelimToken, Token};
use syntax::ptr::P;
use syntax::util::small_vector::SmallVector;

type ItemInfo = (Ident, ItemKind);

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("plague", plague_macro);
}

pub fn plague_macro<'cx>(cx: &'cx mut ExtCtxt, span: Span, tts: &[TokenTree]) -> Box<MacResult + 'cx> {
    let mut parser = cx.new_parser_from_tts(tts);

    match parse_plague(&mut parser) {
        Ok((params, fn_, should_panic)) => {
            match make_plague(cx, &mut parser, params, fn_, should_panic) {
                Ok(r) => r,
                Err(mut err) => {
                    err.emit();
                    DummyResult::any(span)
                }
            }
        }
        Err(mut err) => {
            err.emit();
            DummyResult::any(span)
        }
    }
}

enum FnKind {
    Decl {
        name: Ident,
        fn_: ItemKind,
        span: Span,
    },
    Path(Path)
}

fn parse_plague<'a>(parser: &mut Parser<'a>) -> PResult<'a, (Spanned<Vec<Param>>, FnKind, bool)> {
    try!(parser.expect_keyword(Keyword::For));

    let params = try!(parser.parse_seq(
        &Token::OpenDelim(DelimToken::Bracket),
        &Token::CloseDelim(DelimToken::Bracket),
        seq_sep_trailing_allowed(Token::Comma),
        parse_param
    ));

    try!(expect_keyword(parser, "test"));

    let should_panic = parser.eat(&Token::Not);

    let result = if parser.look_ahead(1, Token::is_ident) {
        try!(parse_fn_decl(parser))
    }
    else {
        try!(parse_fn_use(parser))
    };

    if !parser.eat(&Token::Eof) {
        parser.span_err(parser.span, &format!("expected end of macro, got `{}`", parser. this_token_to_string()));
    }

    Ok((params, result, should_panic))
}

type Param = (Option<Lifetime>, P<Expr>, Option<P<Expr>>);

fn parse_param<'a>(parser: &mut Parser<'a>) -> PResult<'a, Param> {
    let name = try!(parser.parse_opt_lifetime());
    let expr = try!(parser.parse_expr());

    let ret = if parser.eat(&Token::RArrow) {
        Some(try!(parser.parse_expr()))
    }
    else {
        None
    };

    Ok((name, expr, ret))
}

fn parse_fn_use<'a>(parser: &mut Parser<'a>) -> PResult<'a, FnKind> {
    let path = try!(parser.parse_path(PathParsingMode::NoTypesAllowed));

    Ok(FnKind::Path(path))
}

fn parse_fn_decl<'a>(parser: &mut Parser<'a>) -> PResult<'a, FnKind> {
    let mut span = parser.span;
    let (constness, unsafety, abi) = try!(parser.parse_fn_front_matter());

    // Yep, copy-pasted pieces from libsyntax
    let ident = try!(parser.parse_ident());
    let mut generics = try!(parser.parse_generics());
    let decl = try!(parser.parse_fn_decl(false));
    generics.where_clause = try!(parser.parse_where_clause());
    let body = try!(parser.parse_block());
    let fn_ = ItemKind::Fn(decl, unsafety, constness, abi, generics, body);

    span.hi = parser.last_span.hi;

    Ok(FnKind::Decl{ name: ident, fn_: fn_, span: span })
}

fn expect_keyword<'a>(parser: &mut Parser<'a>, kw: &str) -> PResult<'a, ()> {
    match parser.parse_ident() {
        Ok(test_ident) if test_ident.name.as_str() == kw => Ok(()),
        Ok(ident) => {
            Err(parser.fatal(&format!("expected `test`, found `{}`", ident)))
        }
        Err(mut err) => {
            err.cancel();
            Err(parser.fatal(&format!("expected `test`, found `{}`", parser.this_token_to_string())))
        }
    }
}

fn make_plague<'cx, 'a>(
    cx: &'cx mut ExtCtxt,
    parser: &mut Parser<'a>,
    params: Spanned<Vec<Param>>,
    fn_: FnKind,
    should_panic: bool
) -> PResult<'a, Box<MacResult + 'cx>> {
    if params.node.is_empty() {
        cx.span_err(params.span, "empty parametrized tests are useless");
    }

    let mut fns = Vec::with_capacity(params.node.len());

    let (ident, fn_) = match fn_ {
        FnKind::Decl { name, fn_, span } => {
            let unused = quote_meta_item!(cx, allow(unused));
            let unused = cx.attribute(span, unused);
            fns.push(cx.item(span, name, vec![unused], fn_));

            (name, cx.expr_ident(span, name))
        }
        FnKind::Path(path) => {
            let name = path.segments.iter().last().unwrap().identifier;
            (name, cx.expr_path(path))
        }
    };

    let attributes = if should_panic {
        vec![
            cx.attribute(DUMMY_SP, quote_meta_item!(cx, test)),
            cx.attribute(DUMMY_SP, quote_meta_item!(cx, should_panic)),
        ]
    }
    else {
        vec![cx.attribute(DUMMY_SP, quote_meta_item!(cx, test))]
    };

    let span = params.span;
    for (i, param) in params.node.iter().enumerate() {
        let params = try!(make_params(parser, &param.1));
        let fn_ = make_test_fn(cx, span, fn_.clone(), params, &param.2);

        let name = if let Some(name) = param.0 {
            format!("{}{}", ident.name, name.name)
        }
        else {
            format!("{}#{}", ident.name, i)
        };

        fns.push(cx.item(
            span,
            Ident::new(intern(&name), ident.ctxt),
            attributes.clone(),
            fn_
        ));
    }

    Ok(MacEager::items(SmallVector::many(fns)))
}

fn make_test_fn<'cx>(
    cx: &'cx mut ExtCtxt,
    span: Span,
    fn_: P<Expr>,
    params: Vec<P<Expr>>,
    ret: &Option<P<Expr>>,
) -> ItemKind {
    let call = cx.expr_call(span, fn_, params);
    let call = if let Some(ref exp_ret) = *ret {
        quote_expr!(cx, {
            let exp = $exp_ret;
            let got = $call;

            if !(got == exp) {
                panic!("test failed: got `{:?}`, expected `{:?}`", got, exp);
            }
        })
    }
    else {
        call
    };

    let block = cx.block_expr(call);

    ItemKind::Fn(
        P(FnDecl { inputs: vec![], output: FunctionRetTy::Default(DUMMY_SP), variadic: false }),
        Unsafety::Normal,
        Constness::NotConst,
        Abi::Rust,
        Generics::default(),
        block
    )
}

fn make_params<'a>(parser: &mut Parser<'a>, params: &P<Expr>) -> PResult<'a, Vec<P<Expr>>> {
    if let ExprKind::Tup(ref params) = params.node {
        Ok(params.clone())
    }
    else {
        Err(parser.span_fatal(params.span, "expected tuple literal"))
    }
}
<commit_msg>Rustup to 1.8.0-nightly (0ef8d4260 2016-02-24)<commit_after>#![feature(plugin_registrar)]
#![feature(quote)]
#![feature(rustc_private)]
#![feature(slice_patterns)]

extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::Registry;
use syntax::abi::Abi;
use syntax::ast::{
    Constness, Expr, ExprKind, FnDecl, FunctionRetTy, Generics, Ident, ItemKind, Lifetime, Path,
    TokenTree, Unsafety
};
use syntax::codemap::{DUMMY_SP, Span, Spanned};
use syntax::ext::base::{DummyResult, ExtCtxt, MacEager, MacResult};
use syntax::ext::build::AstBuilder;
use syntax::parse::PResult;
use syntax::parse::common::SeqSep;
use syntax::parse::parser::{Parser, PathParsingMode};
use syntax::parse::token::intern;
use syntax::parse::token::keywords::Keyword;
use syntax::parse::token::{DelimToken, Token};
use syntax::ptr::P;
use syntax::util::small_vector::SmallVector;

type ItemInfo = (Ident, ItemKind);

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("plague", plague_macro);
}

pub fn plague_macro<'cx>(cx: &'cx mut ExtCtxt, span: Span, tts: &[TokenTree]) -> Box<MacResult + 'cx> {
    let mut parser = cx.new_parser_from_tts(tts);

    match parse_plague(&mut parser) {
        Ok((params, fn_, should_panic)) => {
            match make_plague(cx, &mut parser, params, fn_, should_panic) {
                Ok(r) => r,
                Err(mut err) => {
                    err.emit();
                    DummyResult::any(span)
                }
            }
        }
        Err(mut err) => {
            err.emit();
            DummyResult::any(span)
        }
    }
}

enum FnKind {
    Decl {
        name: Ident,
        fn_: ItemKind,
        span: Span,
    },
    Path(Path)
}

fn parse_plague<'a>(parser: &mut Parser<'a>) -> PResult<'a, (Spanned<Vec<Param>>, FnKind, bool)> {
    try!(parser.expect_keyword(Keyword::For));

    let params = try!(parser.parse_seq(
        &Token::OpenDelim(DelimToken::Bracket),
        &Token::CloseDelim(DelimToken::Bracket),
        SeqSep::trailing_allowed(Token::Comma),
        parse_param
    ));

    try!(expect_keyword(parser, "test"));

    let should_panic = parser.eat(&Token::Not);

    let result = if parser.look_ahead(1, Token::is_ident) {
        try!(parse_fn_decl(parser))
    }
    else {
        try!(parse_fn_use(parser))
    };

    if !parser.eat(&Token::Eof) {
        parser.span_err(parser.span, &format!("expected end of macro, got `{}`", parser. this_token_to_string()));
    }

    Ok((params, result, should_panic))
}

type Param = (Option<Lifetime>, P<Expr>, Option<P<Expr>>);

fn parse_param<'a>(parser: &mut Parser<'a>) -> PResult<'a, Param> {
    let name = try!(parser.parse_opt_lifetime());
    let expr = try!(parser.parse_expr());

    let ret = if parser.eat(&Token::RArrow) {
        Some(try!(parser.parse_expr()))
    }
    else {
        None
    };

    Ok((name, expr, ret))
}

fn parse_fn_use<'a>(parser: &mut Parser<'a>) -> PResult<'a, FnKind> {
    let path = try!(parser.parse_path(PathParsingMode::NoTypesAllowed));

    Ok(FnKind::Path(path))
}

fn parse_fn_decl<'a>(parser: &mut Parser<'a>) -> PResult<'a, FnKind> {
    let mut span = parser.span;
    let (constness, unsafety, abi) = try!(parser.parse_fn_front_matter());

    // Yep, copy-pasted pieces from libsyntax
    let ident = try!(parser.parse_ident());
    let mut generics = try!(parser.parse_generics());
    let decl = try!(parser.parse_fn_decl(false));
    generics.where_clause = try!(parser.parse_where_clause());
    let body = try!(parser.parse_block());
    let fn_ = ItemKind::Fn(decl, unsafety, constness, abi, generics, body);

    span.hi = parser.last_span.hi;

    Ok(FnKind::Decl{ name: ident, fn_: fn_, span: span })
}

fn expect_keyword<'a>(parser: &mut Parser<'a>, kw: &str) -> PResult<'a, ()> {
    match parser.parse_ident() {
        Ok(test_ident) if test_ident.name.as_str() == kw => Ok(()),
        Ok(ident) => {
            Err(parser.fatal(&format!("expected `test`, found `{}`", ident)))
        }
        Err(mut err) => {
            err.cancel();
            Err(parser.fatal(&format!("expected `test`, found `{}`", parser.this_token_to_string())))
        }
    }
}

fn make_plague<'cx, 'a>(
    cx: &'cx mut ExtCtxt,
    parser: &mut Parser<'a>,
    params: Spanned<Vec<Param>>,
    fn_: FnKind,
    should_panic: bool
) -> PResult<'a, Box<MacResult + 'cx>> {
    if params.node.is_empty() {
        cx.span_err(params.span, "empty parametrized tests are useless");
    }

    let mut fns = Vec::with_capacity(params.node.len());

    let (ident, fn_) = match fn_ {
        FnKind::Decl { name, fn_, span } => {
            let unused = quote_meta_item!(cx, allow(unused));
            let unused = cx.attribute(span, unused);
            fns.push(cx.item(span, name, vec![unused], fn_));

            (name, cx.expr_ident(span, name))
        }
        FnKind::Path(path) => {
            let name = path.segments.iter().last().unwrap().identifier;
            (name, cx.expr_path(path))
        }
    };

    let attributes = if should_panic {
        vec![
            cx.attribute(DUMMY_SP, quote_meta_item!(cx, test)),
            cx.attribute(DUMMY_SP, quote_meta_item!(cx, should_panic)),
        ]
    }
    else {
        vec![cx.attribute(DUMMY_SP, quote_meta_item!(cx, test))]
    };

    let span = params.span;
    for (i, param) in params.node.iter().enumerate() {
        let params = try!(make_params(parser, &param.1));
        let fn_ = make_test_fn(cx, span, fn_.clone(), params, &param.2);

        let name = if let Some(name) = param.0 {
            format!("{}{}", ident.name, name.name)
        }
        else {
            format!("{}#{}", ident.name, i)
        };

        fns.push(cx.item(
            span,
            Ident::new(intern(&name), ident.ctxt),
            attributes.clone(),
            fn_
        ));
    }

    Ok(MacEager::items(SmallVector::many(fns)))
}

fn make_test_fn<'cx>(
    cx: &'cx mut ExtCtxt,
    span: Span,
    fn_: P<Expr>,
    params: Vec<P<Expr>>,
    ret: &Option<P<Expr>>,
) -> ItemKind {
    let call = cx.expr_call(span, fn_, params);
    let call = if let Some(ref exp_ret) = *ret {
        quote_expr!(cx, {
            let exp = $exp_ret;
            let got = $call;

            if !(got == exp) {
                panic!("test failed: got `{:?}`, expected `{:?}`", got, exp);
            }
        })
    }
    else {
        call
    };

    let block = cx.block_expr(call);

    ItemKind::Fn(
        P(FnDecl { inputs: vec![], output: FunctionRetTy::Default(DUMMY_SP), variadic: false }),
        Unsafety::Normal,
        Constness::NotConst,
        Abi::Rust,
        Generics::default(),
        block
    )
}

fn make_params<'a>(parser: &mut Parser<'a>, params: &P<Expr>) -> PResult<'a, Vec<P<Expr>>> {
    if let ExprKind::Tup(ref params) = params.node {
        Ok(params.clone())
    }
    else {
        Err(parser.span_fatal(params.span, "expected tuple literal"))
    }
}
<|endoftext|>


<commit_before>
#![doc="A generics based scientific computing library for Rust

# Introduction

This library aims to provide scientific computing functionality in Rust.
Current focus is to provide a comprehensive API with simple straight-forward
implementations. Different modules cover functionality
covering matrices, linear algebra, signal processing and statistics.

# Implementation

The implementation's aim to take the best advantage
of language features in Rust, yet avoid getting too much into
heavy degree of performance optimization. We do take
advantage of Rust features like generic programming,
immutable by default approach, type traits, iterators,
amongst others. This is a pure Rust implementation.
There is no integration planned at the moment with
C libraries like BLAS or LAPACK.

"]

#![feature(unsafe_destructor, globs)]
#![feature(phase)]
#[phase(plugin, link)] extern crate log;

pub mod discrete{
    #![doc="Discrete mathematics
    "]

    pub use self::modular::*;

    mod modular;

}

pub mod matrix {
    #![doc="Fundamental matrix structures
    "]

    pub use self::element::*;
    pub use self::error::*;
    pub use self::iter::*;
    pub use self::matrix::*;
    pub use self::random::*;
    pub use self::constructors::*;
    pub use self::view::*;
    pub use self::traits::*;

    mod element;
    mod error;
    mod iter;
    mod matrix;
    mod random;
    mod constructors;
    mod view;
    mod traits;
    // for internal use only
    pub mod testdata;
}

pub mod linalg {
    #![doc="Linear algebra algorithms
    "]
    pub use self::gauss_elim::*;
    pub use self::det::*;
    pub use self::error::*;

    mod gauss_elim;
    mod det;
    mod error;
}

pub mod stat {
    #![doc="Statistics
    "]
}

pub mod opt {
    #![doc="Optimization
    "]
    pub mod lp {
    #![doc="Linear programming
    "]
    }
    pub mod ls {
    #![doc="Least squares
    "]
    }
    pub mod cvx {
    #![doc="Convex optimization
    "]
    }
}

pub mod signal {
    #![doc="Signal processing
    "]
}

pub mod image {
    #![doc="Image processing
    "]
}

pub mod audio {
    #![doc="Audio signal processing
    "]
}
<commit_msg>Introduced dx (data exchange) module<commit_after>
#![doc="A generics based scientific computing library for Rust

# Introduction

This library aims to provide scientific computing functionality in Rust.
Current focus is to provide a comprehensive API with simple straight-forward
implementations. Different modules cover functionality
covering matrices, linear algebra, signal processing and statistics.

# Implementation

The implementation's aim to take the best advantage
of language features in Rust, yet avoid getting too much into
heavy degree of performance optimization. We do take
advantage of Rust features like generic programming,
immutable by default approach, type traits, iterators,
amongst others. This is a pure Rust implementation.
There is no integration planned at the moment with
C libraries like BLAS or LAPACK.

"]

#![feature(unsafe_destructor, globs)]
#![feature(phase)]
#[phase(plugin, link)] extern crate log;

pub mod discrete{
    #![doc="Discrete mathematics
    "]

    pub use self::modular::*;

    mod modular;

}

pub mod matrix {
    #![doc="Fundamental matrix structures
    "]

    pub use self::element::*;
    pub use self::error::*;
    pub use self::iter::*;
    pub use self::matrix::*;
    pub use self::random::*;
    pub use self::constructors::*;
    pub use self::view::*;
    pub use self::traits::*;

    mod element;
    mod error;
    mod iter;
    mod matrix;
    mod random;
    mod constructors;
    mod view;
    mod traits;
    // for internal use only
    pub mod testdata;
}

pub mod linalg {
    #![doc="Linear algebra algorithms
    "]
    pub use self::gauss_elim::*;
    pub use self::det::*;
    pub use self::error::*;

    mod gauss_elim;
    mod det;
    mod error;
}

pub mod stat {
    #![doc="Statistics
    "]
}

pub mod opt {
    #![doc="Optimization
    "]
    pub mod lp {
    #![doc="Linear programming
    "]
    }
    pub mod ls {
    #![doc="Least squares
    "]
    }
    pub mod cvx {
    #![doc="Convex optimization
    "]
    }
}

pub mod signal {
    #![doc="Signal processing
    "]
}

pub mod image {
#![doc="Image processing
"]
}

pub mod audio {
#![doc="Audio signal processing
"]
}

pub mod dx {
#![doc="Data exchange

This module and its submodules intend to provide
functions for exchanging scientific data in different
formats.

Initial targets are:

* HDF (Hierarchical Data Format)
* MAT (MATLAB format)

# Remarks

At the moment, the graphics capabilities
do not exist within SciRust. In order
to create graphics, one needs to write
data generated in a SciRust program
and save it in a suitable format
so that it can be imported in systems like
SciPy etc. The graphics facilities of those
systems can then be used.

"]

}<|endoftext|>


<commit_before>extern crate libc;

use libc::{c_char, c_int, strlen};
use std::ffi::{NulError, CString, CStr};
use std::string::FromUtf8Error;

const MAX_USERNAME: c_int = 256;

fn c_to_string(raw: *const c_char) -> Option<String> {
    let c_str = unsafe{CStr::from_ptr(raw)};
    let c_string = std::str::from_utf8(c_str.to_bytes());
    match c_string {
        Ok(c) => Some(c.to_string()),
        Err(_) => None,
    }
}

// TODO: We can do better here. The man pages indicate the specific
// errors we may receive. For example, krb5_aname_to_localname returns
// either KRB5_LNAME_NOTRANS or KRB5_CONFIG_NOTENUFSPACE.
#[derive(Debug)]
pub enum Error {
    Krb5(Krb5Error),
    FromUtf8(FromUtf8Error),
    Nul(NulError),
}

#[derive(Debug)]
pub struct Krb5Error {
    major: c_int,
    message: String,
}

impl Krb5Error {
    fn new(major: c_int) -> Krb5Error {
        let message = format!("Kerberos Error: {}", major).to_string();
        Krb5Error{major: major, message: message}
    }
    fn from_context(context: &Context, major: c_int) -> Krb5Error {
        let message = context.error_message(major);
        match message {
            Some(msg) => Krb5Error{major: major, message: msg},
            None => Krb5Error::new(major),
        }
    }
    fn description(&self) -> &str {
        self.message.as_ref()
    }
}

impl std::fmt::Display for Krb5Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.message)
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match *self {
            Error::FromUtf8(ref e) => e.fmt(f),
            Error::Nul(ref e) => e.fmt(f),
            Error::Krb5(ref e) => e.fmt(f),
        }
    }
}
impl std::error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::FromUtf8(ref e) => e.description(),
            Error::Nul(ref e) => e.description(),
            // TODO: Find a way to get this to return e.as_str(). The
            // problem is that it must be an &str, and if we take a
            // ref to e.as_str(), the borrow doesn't last long enough.
            // Error::Krb5(ref e) => e.as_str().as_ref(),
            Error::Krb5(ref e) => e.description(),
        }
    }
    fn cause(&self) -> Option<&std::error::Error> {
        match *self {
            Error::FromUtf8(ref e) => Some(e as &std::error::Error),
            Error::Nul(ref e) => Some(e as &std::error::Error),
            Error::Krb5(_) => None,
        }
    }
}

impl From<NulError> for Error {
    fn from(e: NulError) -> Error {
        Error::Nul(e)
    }
}

impl From<FromUtf8Error> for Error {
    fn from(e: FromUtf8Error) -> Error {
        Error::FromUtf8(e)
    }
}

pub type Result<T> = std::result::Result<T, Error>;

// From krb5.h:
//  struct _krb5_context;
//  typedef struct _krb5_context * krb5_context;
//  This is opaque in the c header file.
#[allow(non_camel_case_types)]
#[repr(C)]
struct krb5_context;

#[allow(raw_pointer_derive)]
#[derive(Debug)]
pub struct Context {
    ctx: *mut krb5_context,
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe{
            krb5_free_context(self.ctx)
        }
    }
}

impl Context {
    pub fn new() -> Result<Context> {
        let mut kcontext: *mut krb5_context = std::ptr::null_mut();
        let err = unsafe {krb5_init_context(&mut kcontext)};
        if err == 0 {
            Ok(Context{ctx: kcontext})
        } else {
            Err(Error::Krb5(Krb5Error::new(err)))
        }
    }

    fn error_message(&self, code: c_int) -> Option<String> {
        let raw = unsafe{krb5_get_error_message(self.ctx, code)};
        unsafe{krb5_clear_error_message(self.ctx)};
        let res = c_to_string(raw);
        unsafe{krb5_free_error_message(self.ctx, raw)};
        res
    }

    // TODO: evaluate if it's appropriate to return a CString, an
    // OsString, or something else. It probably doesn't make sense to
    // require Utf8 encoding in this library.
    pub fn localname(&self, name: &str) -> Result<String> {
        let mut princ = Principal::new(self);
        let cname = try!(CString::new(name.as_bytes()));
        let err = unsafe {krb5_parse_name(self.ctx, cname.as_ptr(), &mut princ.princ)};
        if err != 0 {
            return Err(Error::Krb5(Krb5Error::from_context(self, err)))
        }

        let mut lname: Vec<u8> = Vec::with_capacity(MAX_USERNAME as usize);
        unsafe {lname.set_len((MAX_USERNAME - 1) as usize)};
        lname.push('\0' as u8);
        let err = unsafe {krb5_aname_to_localname(self.ctx,
                                                  princ.princ,
                                                  MAX_USERNAME - 1,
                                                  &mut lname[..])};
        if err != 0 {
            return Err(Error::Krb5(Krb5Error::from_context(self, err)));
        }

        // Need to find the length (position of the NUL put in place by
        // krb5_aname_to_lname to indicate the end of the string and
        // truncate the Vec<u8> to that size so that we can convert it
        // it to a String
        let len = unsafe {strlen(lname.as_ptr() as *const i8)};
        lname.truncate(len as usize);

        Ok(try!(String::from_utf8(lname)))
    }
}

// TODO: Do we want to make a Principal struct which wraps
// krb5_principal so that it can become a first class citizen with
// it's own Drop? If we do, we'll be able to actually use them to do
// other things at some time. Unfortunately, the mechanism by which
// it's freed would require us to capture a reference to the Context
// within the Principal struct so it's available.
// From krb5.h:
//  typedef struct krb5_principal_data {
//      krb5_magic magic;
//      krb5_data realm;
//      krb5_data *data;            /**< An array of strings */
//      krb5_int32 length;
//      krb5_int32 type;
//  } krb5_principal_data;
//  typedef krb5_principal_data * krb5_principal;
// Note: I'm leaving this as opaque because we don't actually use its
// contents at all.
#[allow(non_camel_case_types)]
#[repr(C)]
struct krb5_principal;
pub struct Principal<'a> {
    princ: *mut krb5_principal,
    ctx: &'a Context,
}

impl<'a> Principal<'a> {
    // TODO: Should the constructor take a principal name and handle
    // calling krb5_parse_name for it? Should it not require a Context
    // to be passed in, and initialize one?
    fn new(ctx: &Context) -> Principal {
        Principal{princ: std::ptr::null_mut(), ctx: ctx}
    }
}

impl<'a> Drop for Principal<'a> {
    fn drop(&mut self) {
        unsafe {krb5_free_principal(self.ctx.ctx, self.princ)}
    }
}

#[link(name = "krb5")]
extern "C" {
    // From krb5.h:
    //  krb5_error_code KRB5_CALLCONV
    //  krb5_init_context(krb5_context *context);
    fn krb5_init_context(context: *mut *mut krb5_context) -> c_int;

    // From krb5.h:
    //  void KRB5_CALLCONV
    //  krb5_free_context(krb5_context context);
    fn krb5_free_context(context: *mut krb5_context);

    // From krb5.h:
    //  krb5_error_code KRB5_CALLCONV
    //  krb5_parse_name(krb5_context context,
    //                  const char *name,
    //                  krb5_principal *nprincipal);
    fn krb5_parse_name(context: *mut krb5_context,
                       name: *const c_char,
                       principal: *mut *mut krb5_principal) -> c_int;

    // From krb5.h:
    //  void KRB5_CALLCONV
    //  krb5_free_principal(krb5_context context,
    //                      krb5_principal val);
    fn krb5_free_principal(context: *mut krb5_context,
                           val: *mut krb5_principal);

    // From krb5.h:
    //  krb5_error_code KRB5_CALLCONV
    //  krb5_aname_to_localname(krb5_context context,
    //                          krb5_const_principal aname,
    //                          int lnsize_in,
    //                          char *lname);
    fn krb5_aname_to_localname(context: *mut krb5_context,
                               aname: *mut krb5_principal,
                               size: c_int,
                               lname: *mut [u8]) -> c_int;

    // From krb5.h:
    //   const char * KRB5_CALLCONV
    //   krb5_get_error_message(krb5_context ctx,
    //                          krb5_error_code code);
    fn krb5_get_error_message(context: *mut krb5_context,
                              code: c_int) -> *const c_char;

    // From krb5.h:
    //   void KRB5_CALLCONV
    //   krb5_clear_error_message(krb5_context ctx);
    fn krb5_clear_error_message(context: *mut krb5_context);

    // From krb5.h:
    //   void KRB5_CALLCONV
    //   krb5_free_error_message(krb5_context ctx,
    //                           const char *msg);
    fn krb5_free_error_message(context: *mut krb5_context,
                               message: *const c_char);
}
<commit_msg>Avoid unnecessary matching<commit_after>extern crate libc;

use libc::{c_char, c_int, strlen};
use std::ffi::{NulError, CString, CStr};
use std::string::FromUtf8Error;

const MAX_USERNAME: c_int = 256;

fn c_to_string(raw: *const c_char) -> Option<String> {
    std::str::from_utf8(unsafe{CStr::from_ptr(raw)}.to_bytes())
        .ok()
        .map(|o| o.to_string())
}

// TODO: We can do better here. The man pages indicate the specific
// errors we may receive. For example, krb5_aname_to_localname returns
// either KRB5_LNAME_NOTRANS or KRB5_CONFIG_NOTENUFSPACE.
#[derive(Debug)]
pub enum Error {
    Krb5(Krb5Error),
    FromUtf8(FromUtf8Error),
    Nul(NulError),
}

#[derive(Debug)]
pub struct Krb5Error {
    major: c_int,
    message: String,
}

impl Krb5Error {
    fn new(major: c_int) -> Krb5Error {
        let message = format!("Kerberos Error: {}", major).to_string();
        Krb5Error{major: major, message: message}
    }
    fn from_context(context: &Context, major: c_int) -> Krb5Error {
        let message = context.error_message(major);
        match message {
            Some(msg) => Krb5Error{major: major, message: msg},
            None => Krb5Error::new(major),
        }
    }
    fn description(&self) -> &str {
        self.message.as_ref()
    }
}

impl std::fmt::Display for Krb5Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.message)
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match *self {
            Error::FromUtf8(ref e) => e.fmt(f),
            Error::Nul(ref e) => e.fmt(f),
            Error::Krb5(ref e) => e.fmt(f),
        }
    }
}
impl std::error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::FromUtf8(ref e) => e.description(),
            Error::Nul(ref e) => e.description(),
            Error::Krb5(ref e) => e.description(),
        }
    }
    fn cause(&self) -> Option<&std::error::Error> {
        match *self {
            Error::FromUtf8(ref e) => Some(e as &std::error::Error),
            Error::Nul(ref e) => Some(e as &std::error::Error),
            Error::Krb5(_) => None,
        }
    }
}

impl From<NulError> for Error {
    fn from(e: NulError) -> Error {
        Error::Nul(e)
    }
}

impl From<FromUtf8Error> for Error {
    fn from(e: FromUtf8Error) -> Error {
        Error::FromUtf8(e)
    }
}

pub type Result<T> = std::result::Result<T, Error>;

// From krb5.h:
//  struct _krb5_context;
//  typedef struct _krb5_context * krb5_context;
//  This is opaque in the c header file.
#[allow(non_camel_case_types)]
#[repr(C)]
struct krb5_context;

#[allow(raw_pointer_derive)]
#[derive(Debug)]
pub struct Context {
    ctx: *mut krb5_context,
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe{
            krb5_free_context(self.ctx)
        }
    }
}

impl Context {
    pub fn new() -> Result<Context> {
        let mut kcontext: *mut krb5_context = std::ptr::null_mut();
        let err = unsafe {krb5_init_context(&mut kcontext)};
        if err == 0 {
            Ok(Context{ctx: kcontext})
        } else {
            Err(Error::Krb5(Krb5Error::new(err)))
        }
    }

    fn error_message(&self, code: c_int) -> Option<String> {
        let raw = unsafe{krb5_get_error_message(self.ctx, code)};
        unsafe{krb5_clear_error_message(self.ctx)};
        let res = c_to_string(raw);
        unsafe{krb5_free_error_message(self.ctx, raw)};
        res
    }

    // TODO: evaluate if it's appropriate to return a CString, an
    // OsString, or something else. It probably doesn't make sense to
    // require Utf8 encoding in this library.
    pub fn localname(&self, name: &str) -> Result<String> {
        let mut princ = Principal::new(self);
        let cname = try!(CString::new(name.as_bytes()));
        let err = unsafe {krb5_parse_name(self.ctx, cname.as_ptr(), &mut princ.princ)};
        if err != 0 {
            return Err(Error::Krb5(Krb5Error::from_context(self, err)))
        }

        let mut lname: Vec<u8> = Vec::with_capacity(MAX_USERNAME as usize);
        unsafe {lname.set_len((MAX_USERNAME - 1) as usize)};
        lname.push('\0' as u8);
        let err = unsafe {krb5_aname_to_localname(self.ctx,
                                                  princ.princ,
                                                  MAX_USERNAME - 1,
                                                  &mut lname[..])};
        if err != 0 {
            return Err(Error::Krb5(Krb5Error::from_context(self, err)));
        }

        // Need to find the length (position of the NUL put in place by
        // krb5_aname_to_lname to indicate the end of the string and
        // truncate the Vec<u8> to that size so that we can convert it
        // it to a String
        let len = unsafe {strlen(lname.as_ptr() as *const i8)};
        lname.truncate(len as usize);

        Ok(try!(String::from_utf8(lname)))
    }
}

// TODO: Do we want to make a Principal struct which wraps
// krb5_principal so that it can become a first class citizen with
// it's own Drop? If we do, we'll be able to actually use them to do
// other things at some time. Unfortunately, the mechanism by which
// it's freed would require us to capture a reference to the Context
// within the Principal struct so it's available.
// From krb5.h:
//  typedef struct krb5_principal_data {
//      krb5_magic magic;
//      krb5_data realm;
//      krb5_data *data;            /**< An array of strings */
//      krb5_int32 length;
//      krb5_int32 type;
//  } krb5_principal_data;
//  typedef krb5_principal_data * krb5_principal;
// Note: I'm leaving this as opaque because we don't actually use its
// contents at all.
#[allow(non_camel_case_types)]
#[repr(C)]
struct krb5_principal;
pub struct Principal<'a> {
    princ: *mut krb5_principal,
    ctx: &'a Context,
}

impl<'a> Principal<'a> {
    // TODO: Should the constructor take a principal name and handle
    // calling krb5_parse_name for it? Should it not require a Context
    // to be passed in, and initialize one?
    fn new(ctx: &Context) -> Principal {
        Principal{princ: std::ptr::null_mut(), ctx: ctx}
    }
}

impl<'a> Drop for Principal<'a> {
    fn drop(&mut self) {
        unsafe {krb5_free_principal(self.ctx.ctx, self.princ)}
    }
}

#[link(name = "krb5")]
extern "C" {
    // From krb5.h:
    //  krb5_error_code KRB5_CALLCONV
    //  krb5_init_context(krb5_context *context);
    fn krb5_init_context(context: *mut *mut krb5_context) -> c_int;

    // From krb5.h:
    //  void KRB5_CALLCONV
    //  krb5_free_context(krb5_context context);
    fn krb5_free_context(context: *mut krb5_context);

    // From krb5.h:
    //  krb5_error_code KRB5_CALLCONV
    //  krb5_parse_name(krb5_context context,
    //                  const char *name,
    //                  krb5_principal *nprincipal);
    fn krb5_parse_name(context: *mut krb5_context,
                       name: *const c_char,
                       principal: *mut *mut krb5_principal) -> c_int;

    // From krb5.h:
    //  void KRB5_CALLCONV
    //  krb5_free_principal(krb5_context context,
    //                      krb5_principal val);
    fn krb5_free_principal(context: *mut krb5_context,
                           val: *mut krb5_principal);

    // From krb5.h:
    //  krb5_error_code KRB5_CALLCONV
    //  krb5_aname_to_localname(krb5_context context,
    //                          krb5_const_principal aname,
    //                          int lnsize_in,
    //                          char *lname);
    fn krb5_aname_to_localname(context: *mut krb5_context,
                               aname: *mut krb5_principal,
                               size: c_int,
                               lname: *mut [u8]) -> c_int;

    // From krb5.h:
    //   const char * KRB5_CALLCONV
    //   krb5_get_error_message(krb5_context ctx,
    //                          krb5_error_code code);
    fn krb5_get_error_message(context: *mut krb5_context,
                              code: c_int) -> *const c_char;

    // From krb5.h:
    //   void KRB5_CALLCONV
    //   krb5_clear_error_message(krb5_context ctx);
    fn krb5_clear_error_message(context: *mut krb5_context);

    // From krb5.h:
    //   void KRB5_CALLCONV
    //   krb5_free_error_message(krb5_context ctx,
    //                           const char *msg);
    fn krb5_free_error_message(context: *mut krb5_context,
                               message: *const c_char);
}
<|endoftext|>


<commit_before>//! [aurelius](https://github.com/euclio/aurelius) is a complete solution for rendering and
//! previewing markdown.
//!
//! This crate provides a server that can render and update an HTML preview of markdown without a
//! client-side refresh. The server listens for both WebSocket and HTTP connections on arbitrary
//! ports. Upon receiving an HTTP request, the server renders a page containing a markdown preview.
//! Client-side JavaScript then initiates a WebSocket connection which allows the server to push
//! changes to the client.
//!
//! This crate was designed to power [vim-markdown-composer], a markdown preview plugin for
//! [Neovim](http://neovim.io), but it may be used to implement similar plugins for any editor.
//! See [vim-markdown-composer] for a usage example.
//!
//! aurelius follows stable Rust. However, the API currently unstable and may change without
//! warning.
//!
//! # Acknowledgments
//! This crate is inspired by suan's
//! [instant-markdown-d](https://github.com/suan/instant-markdown-d).
//!
//! # Why the name?
//! "Aurelius" is a Roman *gens* (family name) shared by many famous Romans, including emperor
//! Marcus Aurelius, one of the "Five Good Emperors." The gens itself originates from the Latin
//! *aureus* meaning "golden." Also, tell me that "Markdown Aurelius" isn't a great pun.
//!
//! [Aurelia (gens) on Wikipedia](https://en.wikipedia.org/wiki/Aurelia_(gens)).
//!
//! [vim-markdown-composer]: https://github.com/euclio/vim-markdown-composer

#![deny(missing_docs)]

extern crate chan;
extern crate handlebars_iron;
extern crate iron;
extern crate mount;
extern crate pulldown_cmark;
extern crate serde;
extern crate staticfile;
extern crate url;
extern crate websocket as websockets;

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate log;

#[macro_use]
extern crate serde_json;

pub mod browser;
pub mod markdown;

mod http;
mod websocket;

use std::env;
use std::net::SocketAddr;
use std::io;
use std::path::{Path, PathBuf};

const DEFAULT_HIGHLIGHT_THEME: &'static str = "github";
const DEFAULT_CSS: &'static str = "/_static/vendor/github-markdown-css/github-markdown.css";

/// An instance of the a markdown preview server.
///
/// The server will listen for HTTP and WebSocket connections on arbitrary ports.
///
/// # Examples
///
/// ```no_run
/// use aurelius::Server;
///
/// let listening = Server::new()
///     .initial_markdown("<h1>Hello, world</h1>")
///     .start()
///     .unwrap();
/// ```
#[derive(Debug, Clone)]
pub struct Server {
    initial_markdown: String,
    working_directory: PathBuf,
    highlight_theme: String,
    css: String,
    websocket_port: u16,
    http_port: u16,
}

impl Server {
    /// Create a new markdown preview server.
    pub fn new() -> Self {
        Self::default()
    }

    /// Set the initial markdown to render when starting the server.
    pub fn initial_markdown<S: Into<String>>(&mut self, markdown: S) -> &Self {
        self.initial_markdown = markdown.into();
        self
    }

    /// Set the directory that static files should be served out of.
    ///
    /// Defaults to the process' current working directory.
    pub fn working_directory<D: Into<PathBuf>>(&mut self, directory: D) -> &Self {
        self.working_directory = directory.into();
        self
    }

    /// Set the syntax highlighting theme to use.
    ///
    /// Defaults to the "github" theme.
    pub fn highlight_theme<T: Into<String>>(&mut self, theme: T) -> &Self {
        self.highlight_theme = theme.into();
        self
    }

    /// Set the CSS that should be used to style the markdown.
    ///
    /// Defaults to github's CSS styles.
    pub fn css<C: Into<String>>(&mut self, css: C) -> &Self {
        self.css = css.into();
        self
    }

    /// Set the port to listen for websocket connections on.
    ///
    /// Defaults to an arbitrary port assigned by the OS.
    pub fn websocket_port(&mut self, port: u16) -> &Self {
        self.websocket_port = port;
        self
    }

    /// Set the port to listen for HTTP connections on.
    ///
    /// Defaults to an arbitrary port assigned by the OS.
    pub fn http_port(&mut self, port: u16) -> &Self {
        self.http_port = port;
        self
    }

    /// Starts the server.
    ///
    /// Returns a channel that can be used to send markdown to the server. The markdown will be
    /// sent as HTML to all clients of the websocket server.
    pub fn start(&self) -> io::Result<Listening> {
        let websocket_listening = websocket::Server::new()
            .listen(("localhost", self.websocket_port))?;

        debug!("Starting http_server");
        let assigned_websocket_port = websocket_listening.local_addr()?.port();
        let http_listening = http::Server::new(
            self.working_directory.clone(),
            assigned_websocket_port,
            http::StyleConfig {
                 css: self.css.clone(),
                 highlight_theme: self.highlight_theme.clone(),
            }).listen(("localhost", self.http_port), &self.initial_markdown)?;

        let listening = Listening {
            http_listening: http_listening,
            websocket_listening: websocket_listening,
        };

        Ok(listening)
    }
}

impl Default for Server {
    fn default() -> Self {
        Server {
            working_directory: env::current_dir().unwrap().to_owned(),
            initial_markdown: String::default(),
            highlight_theme: DEFAULT_HIGHLIGHT_THEME.to_string(),
            css: DEFAULT_CSS.to_string(),
            websocket_port: 0,
            http_port: 0,
        }
    }
}

/// A handle to an active preview server.
///
/// The server is listening for HTTP requests on a given port, and broadcasting rendered markdown
/// over a websocket connection on another port.
pub struct Listening {
    http_listening: http::Listening,
    websocket_listening: websocket::Listening,
}
impl Listening {
    /// Returns the socket address that the websocket server is listening on.
    pub fn websocket_addr(&self) -> io::Result<SocketAddr> {
        self.websocket_listening.local_addr()
    }

    /// Returns the socket address that the HTTP server is listening on.
    pub fn http_addr(&self) -> io::Result<SocketAddr> {
        self.http_listening.local_addr()
    }

    /// Changes the "current working directory" of the HTTP server. The HTTP server will serve
    /// static file requests out of the new directory.
    pub fn change_working_directory
(&mut self, dir: P)
        where P: AsRef<Path>
    {
        self.http_listening.change_working_directory(dir);
    }

    /// Publish new markdown to be rendered by the server.
    pub fn send(&self, markdown: &str) {
        let html_sender = self.websocket_listening.html_sender();
        html_sender.send(markdown::to_html(markdown));
    }
}

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

    #[test]
    fn sanity() {
        let server = Server::new();
        server.start().unwrap();
    }
}
<commit_msg>add more logging to server start<commit_after>//! [aurelius](https://github.com/euclio/aurelius) is a complete solution for rendering and
//! previewing markdown.
//!
//! This crate provides a server that can render and update an HTML preview of markdown without a
//! client-side refresh. The server listens for both WebSocket and HTTP connections on arbitrary
//! ports. Upon receiving an HTTP request, the server renders a page containing a markdown preview.
//! Client-side JavaScript then initiates a WebSocket connection which allows the server to push
//! changes to the client.
//!
//! This crate was designed to power [vim-markdown-composer], a markdown preview plugin for
//! [Neovim](http://neovim.io), but it may be used to implement similar plugins for any editor.
//! See [vim-markdown-composer] for a usage example.
//!
//! aurelius follows stable Rust. However, the API currently unstable and may change without
//! warning.
//!
//! # Acknowledgments
//! This crate is inspired by suan's
//! [instant-markdown-d](https://github.com/suan/instant-markdown-d).
//!
//! # Why the name?
//! "Aurelius" is a Roman *gens* (family name) shared by many famous Romans, including emperor
//! Marcus Aurelius, one of the "Five Good Emperors." The gens itself originates from the Latin
//! *aureus* meaning "golden." Also, tell me that "Markdown Aurelius" isn't a great pun.
//!
//! [Aurelia (gens) on Wikipedia](https://en.wikipedia.org/wiki/Aurelia_(gens)).
//!
//! [vim-markdown-composer]: https://github.com/euclio/vim-markdown-composer

#![deny(missing_docs)]

extern crate chan;
extern crate handlebars_iron;
extern crate iron;
extern crate mount;
extern crate pulldown_cmark;
extern crate serde;
extern crate staticfile;
extern crate url;
extern crate websocket as websockets;

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate log;

#[macro_use]
extern crate serde_json;

pub mod browser;
pub mod markdown;

mod http;
mod websocket;

use std::env;
use std::net::SocketAddr;
use std::io;
use std::path::{Path, PathBuf};

const DEFAULT_HIGHLIGHT_THEME: &'static str = "github";
const DEFAULT_CSS: &'static str = "/_static/vendor/github-markdown-css/github-markdown.css";

/// An instance of the a markdown preview server.
///
/// The server will listen for HTTP and WebSocket connections on arbitrary ports.
///
/// # Examples
///
/// ```no_run
/// use aurelius::Server;
///
/// let listening = Server::new()
///     .initial_markdown("<h1>Hello, world</h1>")
///     .start()
///     .unwrap();
/// ```
#[derive(Debug, Clone)]
pub struct Server {
    initial_markdown: String,
    working_directory: PathBuf,
    highlight_theme: String,
    css: String,
    websocket_port: u16,
    http_port: u16,
}

impl Server {
    /// Create a new markdown preview server.
    pub fn new() -> Self {
        Self::default()
    }

    /// Set the initial markdown to render when starting the server.
    pub fn initial_markdown<S: Into<String>>(&mut self, markdown: S) -> &Self {
        self.initial_markdown = markdown.into();
        self
    }

    /// Set the directory that static files should be served out of.
    ///
    /// Defaults to the process' current working directory.
    pub fn working_directory<D: Into<PathBuf>>(&mut self, directory: D) -> &Self {
        self.working_directory = directory.into();
        self
    }

    /// Set the syntax highlighting theme to use.
    ///
    /// Defaults to the "github" theme.
    pub fn highlight_theme<T: Into<String>>(&mut self, theme: T) -> &Self {
        self.highlight_theme = theme.into();
        self
    }

    /// Set the CSS that should be used to style the markdown.
    ///
    /// Defaults to github's CSS styles.
    pub fn css<C: Into<String>>(&mut self, css: C) -> &Self {
        self.css = css.into();
        self
    }

    /// Set the port to listen for websocket connections on.
    ///
    /// Defaults to an arbitrary port assigned by the OS.
    pub fn websocket_port(&mut self, port: u16) -> &Self {
        self.websocket_port = port;
        self
    }

    /// Set the port to listen for HTTP connections on.
    ///
    /// Defaults to an arbitrary port assigned by the OS.
    pub fn http_port(&mut self, port: u16) -> &Self {
        self.http_port = port;
        self
    }

    /// Starts the server.
    ///
    /// Returns a channel that can be used to send markdown to the server. The markdown will be
    /// sent as HTML to all clients of the websocket server.
    pub fn start(&self) -> io::Result<Listening> {
        debug!("starting websocket server");
        let websocket_listening = websocket::Server::new()
            .listen(("localhost", self.websocket_port))?;
        debug!("websockets listening on {}", websocket_listening.local_addr().unwrap());

        debug!("starting http_server");
        let assigned_websocket_port = websocket_listening.local_addr()?.port();
        let http_listening = http::Server::new(
            self.working_directory.clone(),
            assigned_websocket_port,
            http::StyleConfig {
                 css: self.css.clone(),
                 highlight_theme: self.highlight_theme.clone(),
            }).listen(("localhost", self.http_port), &self.initial_markdown)?;
        debug!("http listening on {}", http_listening.local_addr().unwrap());

        let listening = Listening {
            http_listening: http_listening,
            websocket_listening: websocket_listening,
        };

        Ok(listening)
    }
}

impl Default for Server {
    fn default() -> Self {
        Server {
            working_directory: env::current_dir().unwrap().to_owned(),
            initial_markdown: String::default(),
            highlight_theme: DEFAULT_HIGHLIGHT_THEME.to_string(),
            css: DEFAULT_CSS.to_string(),
            websocket_port: 0,
            http_port: 0,
        }
    }
}

/// A handle to an active preview server.
///
/// The server is listening for HTTP requests on a given port, and broadcasting rendered markdown
/// over a websocket connection on another port.
pub struct Listening {
    http_listening: http::Listening,
    websocket_listening: websocket::Listening,
}
impl Listening {
    /// Returns the socket address that the websocket server is listening on.
    pub fn websocket_addr(&self) -> io::Result<SocketAddr> {
        self.websocket_listening.local_addr()
    }

    /// Returns the socket address that the HTTP server is listening on.
    pub fn http_addr(&self) -> io::Result<SocketAddr> {
        self.http_listening.local_addr()
    }

    /// Changes the "current working directory" of the HTTP server. The HTTP server will serve
    /// static file requests out of the new directory.
    pub fn change_working_directory
(&mut self, dir: P)
        where P: AsRef<Path>
    {
        self.http_listening.change_working_directory(dir);
    }

    /// Publish new markdown to be rendered by the server.
    pub fn send(&self, markdown: &str) {
        let html_sender = self.websocket_listening.html_sender();
        html_sender.send(markdown::to_html(markdown));
    }
}

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

    #[test]
    fn sanity() {
        let server = Server::new();
        server.start().unwrap();
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
#![feature(concat_idents)]
#![feature(libc)]
#![allow(improper_ctypes)]

extern crate libc;
extern crate num;

pub use eigenvalues::*;
pub use general_eigenvalues::*;
pub use least_squares::*;
pub use linear_equations::*;

#[macro_use]
mod prefix;
mod scalar;
mod types;
pub mod ll;
pub mod matrix;
pub mod linear_equations;
pub mod least_squares;
pub mod eigenvalues;
pub mod general_eigenvalues;
<commit_msg>Remove unused feature<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
#![feature(concat_idents)]
#![allow(improper_ctypes)]

extern crate libc;
extern crate num;

pub use eigenvalues::*;
pub use general_eigenvalues::*;
pub use least_squares::*;
pub use linear_equations::*;

#[macro_use]
mod prefix;
mod scalar;
mod types;
pub mod ll;
pub mod matrix;
pub mod linear_equations;
pub mod least_squares;
pub mod eigenvalues;
pub mod general_eigenvalues;
<|endoftext|>


<commit_before>/// Supply the command line.

use std::fmt;

use clap::{Arg, ArgMatches, App, AppSettings, SubCommand};

// TODO: figure out a way, eventually, to customize arguments based on whatever
// external tools are supplied---without requiring a rebuild. (Compare what
// Cargo does.)
pub fn cli<'a, 'b>(additional_args: &[Arg<'a, 'b>],
                   additional_subcommands: &[App<'a, 'b>])
                   -> ArgMatches<'a> {

  let mut args = vec![];
  args.extend_from_slice(additional_args);

  let mut subcommands = vec![
    generate(),
    new(),
  ];

  subcommands.extend_from_slice(additional_subcommands);

  App::new("SSG(rs)")
    .setting(AppSettings::ArgRequiredElseHelp)
    .version("0.1.0")
    .author(crate_authors!())
    .about("Meets my peculiar needs for generating static sites... *fast*.")
    .subcommands(subcommands)
    .args(&args)
    .get_matches()
}

pub enum Commands {
  Generate,
  New,
  Unspecified,
}

impl fmt::Display for Commands {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match *self {
      Commands::Generate => write!(f, "generate"),
      Commands::New => write!(f, "new"),
      _ => write!(f, "error!!!"),  // TODO: something else!
    }
  }
}

impl<'a> From<&'a str> for Commands {
  fn from(s: &str) -> Commands {
    match s {
      "generate" => Commands::Generate,
      "new" => Commands::New,
      _ => Commands::Unspecified,
    }
  }
}

// -- TODO: I feel like the following should be namespaced somehow?

/// Generate the site.
fn generate<'a, 'b>() -> App<'a, 'b> {
  SubCommand::with_name("generate")
    .about("Generate the site")
    .arg(Arg::with_name("local")
      .help("Use local paths to resources")
      .long("local"))
    .arg(Arg::with_name("serve")
      .short("s")
      .long("serve")
      .alias("server"))
}

/// Generate a new item from a template.
///
/// TODO: different templates will take different args---figure out what the
/// best way to programmatically generate new options for these based on the
/// state of the file system where it's run is, so that e.g. the user (*me*,
/// initially!) can e.g. just specify a location for new templates in the
/// configuration file, drop a template in there, and have the generator pick it
/// up correctly as one of the options.
fn new<'a, 'b>() -> App<'a, 'b> {
  SubCommand::with_name("new")
    .about("Create an item from a template")
    .arg(Arg::with_name("template")
      .help("The name of the template to generate, e.g. `post`")
      .index(1)
      .required(true)
      .possible_values(&["post"]))
    .arg(Arg::with_name("title")
      .help("The title to use in the template")
      .index(2)
      .required(true)
      .takes_value(true))
}
<commit_msg>Include renaming in CLI. :zap:<commit_after>/// Supply the command line.

use std::fmt;

use clap::{Arg, ArgMatches, App, AppSettings, SubCommand};

// TODO: define this as the thing that `cli` actually returns (instead of
// TODO: `ArgMatches`.
struct Args {}

// TODO: figure out a way, eventually, to customize arguments based on whatever
// external tools are supplied---without requiring a rebuild. (Compare what
// Cargo does.)
pub fn cli<'a, 'b>(additional_args: &[Arg<'a, 'b>],
                   additional_subcommands: &[App<'a, 'b>])
                   -> ArgMatches<'a> {

  let mut args = vec![];
  args.extend_from_slice(additional_args);

  let mut subcommands = vec![
    generate(),
    new(),
  ];

  subcommands.extend_from_slice(additional_subcommands);

  App::new("Lightning")
    .setting(AppSettings::ArgRequiredElseHelp)
    .version("0.1.0")
    .author(crate_authors!())
    .about("A fast, reliable, configurable static site generator.")
    .subcommands(subcommands)
    .args(&args)
    .get_matches()
}

pub enum Commands {
  Generate,
  New,
  Unspecified,
}

impl fmt::Display for Commands {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match *self {
      Commands::Generate => write!(f, "generate"),
      Commands::New => write!(f, "new"),
      _ => write!(f, "error!!!"),  // TODO: something else!
    }
  }
}

impl<'a> From<&'a str> for Commands {
  fn from(s: &str) -> Commands {
    match s {
      "generate" => Commands::Generate,
      "new" => Commands::New,
      _ => Commands::Unspecified,
    }
  }
}

// -- TODO: I feel like the following should be namespaced somehow?

/// Generate the site.
fn generate<'a, 'b>() -> App<'a, 'b> {
  SubCommand::with_name("generate")
    .about("Generate the site")
    .arg(Arg::with_name("local")
      .help("Use local paths to resources")
      .long("local"))
    .arg(Arg::with_name("serve")
      .short("s")
      .long("serve")
      .alias("server"))
}

/// Generate a new item from a template.
///
/// TODO: different templates will take different args---figure out what the
/// best way to programmatically generate new options for these based on the
/// state of the file system where it's run is, so that e.g. the user (*me*,
/// initially!) can e.g. just specify a location for new templates in the
/// configuration file, drop a template in there, and have the generator pick it
/// up correctly as one of the options.
fn new<'a, 'b>() -> App<'a, 'b> {
  SubCommand::with_name("new")
    .about("Create an item from a template")
    .arg(Arg::with_name("template")
      .help("The name of the template to generate, e.g. `post`")
      .index(1)
      .required(true)
      .possible_values(&["post"]))
    .arg(Arg::with_name("title")
      .help("The title to use in the template")
      .index(2)
      .required(true)
      .takes_value(true))
}
<|endoftext|>


<commit_before>use todo::list::List;

pub fn delegate(mut path: Path, mut args: Vec<String>) {
    // First argument contains the program / file name,
    // so let's discard it to make postprocessing easier
    if args.len() > 0 {
        args.remove(0);
    }

    path.push("todo.txt");

    match args.len() {
        0 => render_help(),
        1 => dispatch(path, args[0].clone(), None),
        _ => {
            let (action, context) = process_arguments(args);
            dispatch(path, action, context);
        }
    }
}

fn dispatch(path: Path, action: String, context: Option<String>) {
    let mut list = List::new(path);
    list.load();

    match action.as_slice() {
        "list"   => list.index(context),
        "add"    => list.add(context),
        "edit"   => list.edit(context),
        "remove" => list.remove(context),
        "finish" => list.finish(context),
        "count"  => list.count(context),
        _        => println!("There is no action named `{}`.", action)
    }
}

fn process_arguments(mut args: Vec<String>) -> (String, Option<String>) {
    let action = args.remove(0);
    let mut context = "".to_string();
    for arg in args.iter() {
        context.push_str(arg.as_slice());
    }
    (action, Some(context))
}

fn render_help() {
    println!("Print help");
}<commit_msg>Rename a method to something more appropriate<commit_after>use todo::list::List;

pub fn delegate(mut path: Path, mut args: Vec<String>) {
    // First argument contains the program / file name,
    // so let's discard it to make postprocessing easier
    if args.len() > 0 {
        args.remove(0);
    }

    path.push("todo.txt");

    match args.len() {
        0 => render_help(),
        1 => dispatch(path, args[0].clone(), None),
        _ => {
            let (action, context) = parse_arguments(args);
            dispatch(path, action, context);
        }
    }
}

fn dispatch(path: Path, action: String, context: Option<String>) {
    let mut list = List::new(path);
    list.load();

    match action.as_slice() {
        "list"   => list.index(context),
        "add"    => list.add(context),
        "edit"   => list.edit(context),
        "remove" => list.remove(context),
        "finish" => list.finish(context),
        "count"  => list.count(context),
        _        => println!("There is no action named `{}`.", action)
    }
}

fn parse_arguments(mut args: Vec<String>) -> (String, Option<String>) {
    let action = args.remove(0);
    let mut context = "".to_string();
    for arg in args.iter() {
        context.push_str(arg.as_slice());
    }
    (action, Some(context))
}

fn render_help() {
    println!("Print help");
}<|endoftext|>


<commit_before>extern crate curl;
extern crate rustc_serialize;

use std::thread;
use std::time::Duration;
use std::env::{self, VarError};
use std::str::FromStr;
use std::num::ParseIntError;
use rustc_serialize::json;
use curl::http;

const USER_AGENT:         &'static str = concat!("travis-after-all/", env!("CARGO_PKG_VERSION"));
const TRAVIS_JOB_NUMBER : &'static str = "TRAVIS_JOB_NUMBER";
const TRAVIS_BUILD_ID:    &'static str = "TRAVIS_BUILD_ID";
const TRAVIS_API_URL:     &'static str = "https://api.travis-ci.org";
const POLLING_INTERVAL:   &'static str = "LEADER_POLLING_INTERVAL";

#[derive(Debug)]
pub enum Error {
    Generic(String),
    NoMatrix,
    NotLeader,
}

impl Error {
    pub fn from_str(message: &str) -> Error {
        Error::Generic(message.into())
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        std::fmt::Debug::fmt(self, f)
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Generic(ref s) => s,
            Error::NoMatrix => "No matrix found. Call `build_matrix` first.",
            Error::NotLeader => "This build is not the leader"
        }
    }
}

impl From<VarError> for Error {
    fn from(err: VarError) -> Error {
        match err {
            VarError::NotPresent => Error::Generic("Environment variable not present".into()),
            VarError::NotUnicode(_) => Error::Generic("Environment variable not valid".into())
        }
    }
}

impl From<ParseIntError> for Error {
    fn from(_err: ParseIntError) -> Error {
        Error::Generic("Can't parse what should be an integer".into())
    }
}

pub struct Build {
    travis_api_url: String,
    build_id: String,
    job_number: String,
    polling_interval: u64,
    matrix: Option<Matrix>,
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct MatrixElement {
    finished_at: Option<String>,
    result: u32,
    number: String,
    id: u32,
}

impl MatrixElement {
    pub fn id(&self) -> u32 {
        self.id
    }

    pub fn is_leader(&self) -> bool {
        is_leader(&self.number)
    }

    pub fn is_succeeded(&self) -> bool {
        self.is_finished() && self.result == 0
    }

    pub fn is_finished(&self) -> bool {
        self.finished_at.is_some()
    }
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct Matrix {
    id: u32,
    matrix: Vec<MatrixElement>,
}

impl Matrix {
    pub fn builds(&self) -> &[MatrixElement] {
        &self.matrix
    }

    pub fn others_finished(&self) -> bool {
        self.matrix.iter()
            .filter(|build| !build.is_leader())
            .all(|build| build.is_finished())
    }
}

pub fn is_leader(job: &str) -> bool {
    job.ends_with('1')
}

impl Build {
    pub fn from_env() -> Result<Build, Error> {
        let build_id = try!(env::var(TRAVIS_BUILD_ID));
        let job_number = try!(env::var(TRAVIS_JOB_NUMBER));

        let polling_interval = match env::var(POLLING_INTERVAL) {
            Err(_) => 5,
            Ok(val) => try!(FromStr::from_str(&val))
        };

        Ok(Build {
            travis_api_url: TRAVIS_API_URL.into(),
            build_id: build_id,
            job_number: job_number,
            polling_interval: polling_interval,
            matrix: None,
        })

    }

    pub fn is_leader(&self) -> bool {
        is_leader(&self.job_number)
    }

    pub fn build_matrix(&mut self) -> &Matrix {
        if self.matrix.is_some() {
            return self.matrix.as_ref().unwrap();
        }
        let url = format!("{}/builds/{}", self.travis_api_url, self.build_id);
        let res = http::handle()
            .get(url)
            .follow_redirects(true)
            .header("User-Agent", USER_AGENT)
            .exec()
            .unwrap();

        let body = String::from_utf8(res.move_body()).unwrap();
        self.matrix = Some(json::decode(&body).unwrap());
        self.matrix.as_ref().unwrap()
    }

    pub fn wait_for_others(&self) -> Result<(), Error> {
        if self.matrix.is_none() {
            return Err(Error::NoMatrix);
        }

        if self.is_leader() {
            return Err(Error::NotLeader)
        }

        let matrix = self.matrix.as_ref().unwrap();
        let dur = Duration::new(self.polling_interval, 0);
        while !matrix.others_finished() {
            thread::sleep(dur);
        }

        Ok(())
    }
}

<commit_msg>Dump body (for test on travis)<commit_after>extern crate curl;
extern crate rustc_serialize;

use std::thread;
use std::time::Duration;
use std::env::{self, VarError};
use std::str::FromStr;
use std::num::ParseIntError;
use rustc_serialize::json;
use curl::http;

const USER_AGENT:         &'static str = concat!("travis-after-all/", env!("CARGO_PKG_VERSION"));
const TRAVIS_JOB_NUMBER : &'static str = "TRAVIS_JOB_NUMBER";
const TRAVIS_BUILD_ID:    &'static str = "TRAVIS_BUILD_ID";
const TRAVIS_API_URL:     &'static str = "https://api.travis-ci.org";
const POLLING_INTERVAL:   &'static str = "LEADER_POLLING_INTERVAL";

#[derive(Debug)]
pub enum Error {
    Generic(String),
    NoMatrix,
    NotLeader,
}

impl Error {
    pub fn from_str(message: &str) -> Error {
        Error::Generic(message.into())
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        std::fmt::Debug::fmt(self, f)
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Generic(ref s) => s,
            Error::NoMatrix => "No matrix found. Call `build_matrix` first.",
            Error::NotLeader => "This build is not the leader"
        }
    }
}

impl From<VarError> for Error {
    fn from(err: VarError) -> Error {
        match err {
            VarError::NotPresent => Error::Generic("Environment variable not present".into()),
            VarError::NotUnicode(_) => Error::Generic("Environment variable not valid".into())
        }
    }
}

impl From<ParseIntError> for Error {
    fn from(_err: ParseIntError) -> Error {
        Error::Generic("Can't parse what should be an integer".into())
    }
}

pub struct Build {
    travis_api_url: String,
    build_id: String,
    job_number: String,
    polling_interval: u64,
    matrix: Option<Matrix>,
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct MatrixElement {
    finished_at: Option<String>,
    result: u32,
    number: String,
    id: u32,
}

impl MatrixElement {
    pub fn id(&self) -> u32 {
        self.id
    }

    pub fn is_leader(&self) -> bool {
        is_leader(&self.number)
    }

    pub fn is_succeeded(&self) -> bool {
        self.is_finished() && self.result == 0
    }

    pub fn is_finished(&self) -> bool {
        self.finished_at.is_some()
    }
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct Matrix {
    id: u32,
    matrix: Vec<MatrixElement>,
}

impl Matrix {
    pub fn builds(&self) -> &[MatrixElement] {
        &self.matrix
    }

    pub fn others_finished(&self) -> bool {
        self.matrix.iter()
            .filter(|build| !build.is_leader())
            .all(|build| build.is_finished())
    }
}

pub fn is_leader(job: &str) -> bool {
    job.ends_with('1')
}

impl Build {
    pub fn from_env() -> Result<Build, Error> {
        let build_id = try!(env::var(TRAVIS_BUILD_ID));
        let job_number = try!(env::var(TRAVIS_JOB_NUMBER));

        let polling_interval = match env::var(POLLING_INTERVAL) {
            Err(_) => 5,
            Ok(val) => try!(FromStr::from_str(&val))
        };

        Ok(Build {
            travis_api_url: TRAVIS_API_URL.into(),
            build_id: build_id,
            job_number: job_number,
            polling_interval: polling_interval,
            matrix: None,
        })

    }

    pub fn is_leader(&self) -> bool {
        is_leader(&self.job_number)
    }

    pub fn build_matrix(&mut self) -> &Matrix {
        if self.matrix.is_some() {
            return self.matrix.as_ref().unwrap();
        }
        let url = format!("{}/builds/{}", self.travis_api_url, self.build_id);
        let res = http::handle()
            .get(url)
            .follow_redirects(true)
            .header("User-Agent", USER_AGENT)
            .exec()
            .unwrap();

        let body = String::from_utf8(res.move_body()).unwrap();
        println!("=== BODY ===");
        println!("{}", body);
        println!("");
        println!("=== /BODY ===");
        self.matrix = Some(json::decode(&body).unwrap());
        self.matrix.as_ref().unwrap()
    }

    pub fn wait_for_others(&self) -> Result<(), Error> {
        if self.matrix.is_none() {
            return Err(Error::NoMatrix);
        }

        if self.is_leader() {
            return Err(Error::NotLeader)
        }

        let matrix = self.matrix.as_ref().unwrap();
        let dur = Duration::new(self.polling_interval, 0);
        while !matrix.others_finished() {
            thread::sleep(dur);
        }

        Ok(())
    }
}

<|endoftext|>