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

use session::config::Options;

use std::fs;
use std::io::{self, StderrLock, Write};
use std::time::{Duration, Instant};

macro_rules! define_categories {
    ($($name:ident,)*) => {
        #[derive(Clone, Copy, Debug, PartialEq, Eq)]
        pub enum ProfileCategory {
            $($name),*
        }

        #[allow(nonstandard_style)]
        struct Categories<T> {
            $($name: T),*
        }

        impl<T: Default> Categories<T> {
            fn new() -> Categories<T> {
                Categories {
                    $($name: T::default()),*
                }
            }
        }

        impl<T> Categories<T> {
            fn get(&self, category: ProfileCategory) -> &T {
                match category {
                    $(ProfileCategory::$name => &self.$name),*
                }
            }

            fn set(&mut self, category: ProfileCategory, value: T) {
                match category {
                    $(ProfileCategory::$name => self.$name = value),*
                }
            }
        }

        struct CategoryData {
            times: Categories<u64>,
            query_counts: Categories<(u64, u64)>,
        }

        impl CategoryData {
            fn new() -> CategoryData {
                CategoryData {
                    times: Categories::new(),
                    query_counts: Categories::new(),
                }
            }

            fn print(&self, lock: &mut StderrLock<'_>) {
                writeln!(lock, "| Phase            | Time (ms)      | Queries        | Hits (%) |")
                    .unwrap();
                writeln!(lock, "| ---------------- | -------------- | -------------- | -------- |")
                    .unwrap();

                $(
                    let (hits, total) = self.query_counts.$name;
                    let (hits, total) = if total > 0 {
                        (format!("{:.2}",
                        (((hits as f32) / (total as f32)) * 100.0)), total.to_string())
                    } else {
                        (String::new(), String::new())
                    };

                    writeln!(
                        lock,
                        "| {0: <16} | {1: <14} | {2: <14} | {3: <8} |",
                        stringify!($name),
                        self.times.$name / 1_000_000,
                        total,
                        hits
                    ).unwrap();
                )*
            }

            fn json(&self) -> String {
                let mut json = String::from("[");

                $(
                    let (hits, total) = self.query_counts.$name;

                    //normalize hits to 0%
                    let hit_percent =
                        if total > 0 {
                            ((hits as f32) / (total as f32)) * 100.0
                        } else {
                            0.0
                        };

                    json.push_str(&format!(
                        "{{ \"category\": \"{}\", \"time_ms\": {},\
                            \"query_count\": {}, \"query_hits\": {} }},",
                        stringify!($name),
                        self.times.$name / 1_000_000,
                        total,
                        format!("{:.2}", hit_percent)
                    ));
                )*

                //remove the trailing ',' character
                json.pop();

                json.push(']');

                json
            }
        }
    }
}

define_categories! {
    Parsing,
    Expansion,
    TypeChecking,
    BorrowChecking,
    Codegen,
    Linking,
    Other,
}

pub struct SelfProfiler {
    timer_stack: Vec<ProfileCategory>,
    data: CategoryData,
    current_timer: Instant,
}

impl SelfProfiler {
    pub fn new() -> SelfProfiler {
        let mut profiler = SelfProfiler {
            timer_stack: Vec::new(),
            data: CategoryData::new(),
            current_timer: Instant::now(),
        };

        profiler.start_activity(ProfileCategory::Other);

        profiler
    }

    pub fn start_activity(&mut self, category: ProfileCategory) {
        match self.timer_stack.last().cloned() {
            None => {
                self.current_timer = Instant::now();
            },
            Some(current_category) if current_category == category => {
                //since the current category is the same as the new activity's category,
                //we don't need to do anything with the timer, we just need to push it on the stack
            }
            Some(current_category) => {
                let elapsed = self.stop_timer();

                //record the current category's time
                let new_time = self.data.times.get(current_category) + elapsed;
                self.data.times.set(current_category, new_time);
            }
        }

        //push the new category
        self.timer_stack.push(category);
    }

    pub fn record_query(&mut self, category: ProfileCategory) {
        let (hits, total) = *self.data.query_counts.get(category);
        self.data.query_counts.set(category, (hits, total + 1));
    }

    pub fn record_query_hit(&mut self, category: ProfileCategory) {
        let (hits, total) = *self.data.query_counts.get(category);
        self.data.query_counts.set(category, (hits + 1, total));
    }

    pub fn end_activity(&mut self, category: ProfileCategory) {
        match self.timer_stack.pop() {
            None => bug!("end_activity() was called but there was no running activity"),
            Some(c) =>
                assert!(
                    c == category,
                    "end_activity() was called but a different activity was running"),
        }

        //check if the new running timer is in the same category as this one
        //if it is, we don't need to do anything
        if let Some(c) = self.timer_stack.last() {
            if *c == category {
                return;
            }
        }

        //the new timer is different than the previous,
        //so record the elapsed time and start a new timer
        let elapsed = self.stop_timer();
        let new_time = self.data.times.get(category) + elapsed;
        self.data.times.set(category, new_time);
    }

    fn stop_timer(&mut self) -> u64 {
        let elapsed = if cfg!(windows) {
            // On Windows, timers don't always appear to be monotonic (see #51648)
            // which can lead to panics when calculating elapsed time.
            // Work around this by testing to see if the current time is less than
            // our recorded time, and if it is, just returning 0.
            let now = Instant::now();
            if self.current_timer >= now {
                Duration::new(0, 0)
            } else {
                self.current_timer.elapsed()
            }
        } else {
            self.current_timer.elapsed()
        };

        self.current_timer = Instant::now();

        (elapsed.as_secs() * 1_000_000_000) + (elapsed.subsec_nanos() as u64)
    }

    pub fn print_results(&mut self, opts: &Options) {
        self.end_activity(ProfileCategory::Other);

        assert!(
            self.timer_stack.is_empty(),
            "there were timers running when print_results() was called");

        let out = io::stderr();
        let mut lock = out.lock();

        let crate_name =
            opts.crate_name
            .as_ref()
            .map(|n| format!(" for {}", n))
            .unwrap_or_default();

        writeln!(lock, "Self profiling results{}:", crate_name).unwrap();
        writeln!(lock).unwrap();

        self.data.print(&mut lock);

        writeln!(lock).unwrap();
        writeln!(lock, "Optimization level: {:?}", opts.optimize).unwrap();

        let incremental = if opts.incremental.is_some() { "on" } else { "off" };
        writeln!(lock, "Incremental: {}", incremental).unwrap();
    }

    pub fn save_results(&self, opts: &Options) {
        let category_data = self.data.json();
        let compilation_options =
            format!("{{ \"optimization_level\": \"{:?}\", \"incremental\": {} }}",
                    opts.optimize,
                    if opts.incremental.is_some() { "true" } else { "false" });

        let json = format!("{{ \"category_data\": {}, \"compilation_options\": {} }}",
                        category_data,
                        compilation_options);

        fs::write("self_profiler_results.json", json).unwrap();
    }
}
<commit_msg>Rollup merge of #56702 - wesleywiser:calc_total_time_stats, r=michaelwoerister<commit_after>// Copyright 2018 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.

use session::config::Options;

use std::fs;
use std::io::{self, StderrLock, Write};
use std::time::{Duration, Instant};

macro_rules! define_categories {
    ($($name:ident,)*) => {
        #[derive(Clone, Copy, Debug, PartialEq, Eq)]
        pub enum ProfileCategory {
            $($name),*
        }

        #[allow(nonstandard_style)]
        struct Categories<T> {
            $($name: T),*
        }

        impl<T: Default> Categories<T> {
            fn new() -> Categories<T> {
                Categories {
                    $($name: T::default()),*
                }
            }
        }

        impl<T> Categories<T> {
            fn get(&self, category: ProfileCategory) -> &T {
                match category {
                    $(ProfileCategory::$name => &self.$name),*
                }
            }

            fn set(&mut self, category: ProfileCategory, value: T) {
                match category {
                    $(ProfileCategory::$name => self.$name = value),*
                }
            }
        }

        struct CategoryData {
            times: Categories<u64>,
            query_counts: Categories<(u64, u64)>,
        }

        impl CategoryData {
            fn new() -> CategoryData {
                CategoryData {
                    times: Categories::new(),
                    query_counts: Categories::new(),
                }
            }

            fn print(&self, lock: &mut StderrLock<'_>) {
                writeln!(lock, "| Phase            | Time (ms)      \
                                | Time (%) | Queries        | Hits (%)")
                    .unwrap();
                writeln!(lock, "| ---------------- | -------------- \
                                | -------- | -------------- | --------")
                    .unwrap();

                let total_time = ($(self.times.$name + )* 0) as f32;

                $(
                    let (hits, total) = self.query_counts.$name;
                    let (hits, total) = if total > 0 {
                        (format!("{:.2}",
                        (((hits as f32) / (total as f32)) * 100.0)), total.to_string())
                    } else {
                        (String::new(), String::new())
                    };

                    writeln!(
                        lock,
                        "| {0: <16} | {1: <14} | {2: <8.2} | {3: <14} | {4: <8}",
                        stringify!($name),
                        self.times.$name / 1_000_000,
                        ((self.times.$name as f32) / total_time) * 100.0,
                        total,
                        hits,
                    ).unwrap();
                )*
            }

            fn json(&self) -> String {
                let mut json = String::from("[");

                $(
                    let (hits, total) = self.query_counts.$name;

                    //normalize hits to 0%
                    let hit_percent =
                        if total > 0 {
                            ((hits as f32) / (total as f32)) * 100.0
                        } else {
                            0.0
                        };

                    json.push_str(&format!(
                        "{{ \"category\": \"{}\", \"time_ms\": {},\
                            \"query_count\": {}, \"query_hits\": {} }},",
                        stringify!($name),
                        self.times.$name / 1_000_000,
                        total,
                        format!("{:.2}", hit_percent)
                    ));
                )*

                //remove the trailing ',' character
                json.pop();

                json.push(']');

                json
            }
        }
    }
}

define_categories! {
    Parsing,
    Expansion,
    TypeChecking,
    BorrowChecking,
    Codegen,
    Linking,
    Other,
}

pub struct SelfProfiler {
    timer_stack: Vec<ProfileCategory>,
    data: CategoryData,
    current_timer: Instant,
}

impl SelfProfiler {
    pub fn new() -> SelfProfiler {
        let mut profiler = SelfProfiler {
            timer_stack: Vec::new(),
            data: CategoryData::new(),
            current_timer: Instant::now(),
        };

        profiler.start_activity(ProfileCategory::Other);

        profiler
    }

    pub fn start_activity(&mut self, category: ProfileCategory) {
        match self.timer_stack.last().cloned() {
            None => {
                self.current_timer = Instant::now();
            },
            Some(current_category) if current_category == category => {
                //since the current category is the same as the new activity's category,
                //we don't need to do anything with the timer, we just need to push it on the stack
            }
            Some(current_category) => {
                let elapsed = self.stop_timer();

                //record the current category's time
                let new_time = self.data.times.get(current_category) + elapsed;
                self.data.times.set(current_category, new_time);
            }
        }

        //push the new category
        self.timer_stack.push(category);
    }

    pub fn record_query(&mut self, category: ProfileCategory) {
        let (hits, total) = *self.data.query_counts.get(category);
        self.data.query_counts.set(category, (hits, total + 1));
    }

    pub fn record_query_hit(&mut self, category: ProfileCategory) {
        let (hits, total) = *self.data.query_counts.get(category);
        self.data.query_counts.set(category, (hits + 1, total));
    }

    pub fn end_activity(&mut self, category: ProfileCategory) {
        match self.timer_stack.pop() {
            None => bug!("end_activity() was called but there was no running activity"),
            Some(c) =>
                assert!(
                    c == category,
                    "end_activity() was called but a different activity was running"),
        }

        //check if the new running timer is in the same category as this one
        //if it is, we don't need to do anything
        if let Some(c) = self.timer_stack.last() {
            if *c == category {
                return;
            }
        }

        //the new timer is different than the previous,
        //so record the elapsed time and start a new timer
        let elapsed = self.stop_timer();
        let new_time = self.data.times.get(category) + elapsed;
        self.data.times.set(category, new_time);
    }

    fn stop_timer(&mut self) -> u64 {
        let elapsed = if cfg!(windows) {
            // On Windows, timers don't always appear to be monotonic (see #51648)
            // which can lead to panics when calculating elapsed time.
            // Work around this by testing to see if the current time is less than
            // our recorded time, and if it is, just returning 0.
            let now = Instant::now();
            if self.current_timer >= now {
                Duration::new(0, 0)
            } else {
                self.current_timer.elapsed()
            }
        } else {
            self.current_timer.elapsed()
        };

        self.current_timer = Instant::now();

        (elapsed.as_secs() * 1_000_000_000) + (elapsed.subsec_nanos() as u64)
    }

    pub fn print_results(&mut self, opts: &Options) {
        self.end_activity(ProfileCategory::Other);

        assert!(
            self.timer_stack.is_empty(),
            "there were timers running when print_results() was called");

        let out = io::stderr();
        let mut lock = out.lock();

        let crate_name =
            opts.crate_name
            .as_ref()
            .map(|n| format!(" for {}", n))
            .unwrap_or_default();

        writeln!(lock, "Self profiling results{}:", crate_name).unwrap();
        writeln!(lock).unwrap();

        self.data.print(&mut lock);

        writeln!(lock).unwrap();
        writeln!(lock, "Optimization level: {:?}", opts.optimize).unwrap();

        let incremental = if opts.incremental.is_some() { "on" } else { "off" };
        writeln!(lock, "Incremental: {}", incremental).unwrap();
    }

    pub fn save_results(&self, opts: &Options) {
        let category_data = self.data.json();
        let compilation_options =
            format!("{{ \"optimization_level\": \"{:?}\", \"incremental\": {} }}",
                    opts.optimize,
                    if opts.incremental.is_some() { "true" } else { "false" });

        let json = format!("{{ \"category_data\": {}, \"compilation_options\": {} }}",
                        category_data,
                        compilation_options);

        fs::write("self_profiler_results.json", json).unwrap();
    }
}
<|endoftext|>


<commit_before><commit_msg>Optimize neighbor temporary variable declarations<commit_after><|endoftext|>


<commit_before><commit_msg>added benches/benches.rs<commit_after>#![feature(test)]
#[macro_use]
extern crate adapton ;

use std::mem::replace;
use std::rc::Rc;

use adapton::adapton_syntax::* ;
use adapton::adapton_sigs::* ;
use adapton::adapton_state::* ;

pub fn fact<'r> (st:&'r mut AdaptonState, x:Rc<u64>, _:() ) -> Rc<u64> {
    if *x == 0 { Rc::new(1) } else {
        let res = fact(st, Rc::new(*x-1), ());
        Rc::new(*x * *res)
    }
}

pub fn run_fact (x:u64) -> u64 {
    let mut st = AdaptonState::new() ;
    let t = st.thunk(ArtIdChoice::Structural,
                     prog_pt!(fact),
                     Rc::new(Box::new(fact)),
                     Rc::new(x), ()) ;
    *(st.force(&t))
}

#[cfg(test)]
mod tests {
    extern crate test;
    use super::*;
    use self::test::Bencher;

    #[test]
    fn it_works() {
        assert_eq!(120 as u64, run_fact(5));
    }

    #[bench]
    fn bench_fact_5(b: &mut Bencher) {
        b.iter(|| run_fact(5));
    }
}
<|endoftext|>


<commit_before><commit_msg>Implement SuccDouble for type int<commit_after><|endoftext|>


<commit_before><commit_msg>Add `sine` example<commit_after>extern crate rsoundio;

use std::f32::consts::PI;
use std::thread;
use std::time::Duration;

fn main() {
    let f = 440f32;
    let cycle_len = (48_000 as f32 / f) as usize;
    let phi = 2.0 * f * PI / 48_000 as f32;
    let mut pos = 0;
    let samples: Vec<f32> = (pos..cycle_len)
                                .map(|i| (phi * i as f32).sin())
                                .collect();
    // create an audio context
    let sio = rsoundio::SoundIo::new();
    sio.set_app_name("rsoundio").unwrap();
    // connect to the default audio backend
    sio.connect().unwrap();
    println!("Connected to backend: {}", sio.current_backend().unwrap());
    sio.flush_events();
    // get default output device
    let dev = sio.default_output_device().unwrap();
    assert!(dev.probe_error().is_none());
    println!("Using output device: {}", dev);
    // create output stream
    let mut out = dev.create_outstream().unwrap();
    assert!(out.set_name("rsoundio-example-sine").is_ok());
    out.set_format(rsoundio::ffi::SioFormat::Float32LE).unwrap();
    println!("Output format: {}", out.format().unwrap());

    // register callbacks
    out.register_write_callback(Box::new(|out: rsoundio::OutStream,
                                          min_frame_count: i32,
                                          max_frame_count: i32| {
        let l: Vec<f32> = samples.iter()
                                 .cycle()
                                 .take(max_frame_count as usize + pos)
                                 .skip(pos)
                                 .map(|s| *s)
                                 .collect();
        pos = (max_frame_count as usize + pos) % cycle_len;
        let r = l.clone();
        let frames = vec![l, r];
        out.write_stream_f32(min_frame_count, &frames).unwrap();
    }));
    out.register_underflow_callback(Box::new(|out: rsoundio::OutStream| {
        println!("Underflow in {} occured!", out.name().unwrap())
    }));
    out.register_error_callback(Box::new(|out: rsoundio::OutStream,
                                          err: rsoundio::ffi::SioError| {
        println!("{} error: {}", out.name().unwrap(), err)
    }));

    // open output stream
    out.open().unwrap();
    let sr = out.sample_rate();
    println!("Sample rate: {}", sr);

    //out.layout_error().unwrap();
    let layout = out.layout();
    println!("Output channel layout: {}", layout);
    // start audio output (now the `write_callback` will be called periodically)
    assert!(out.start().is_none());
    thread::sleep(Duration::new(3, 0));
    println!("Pause for 1s");
    out.pause();
    thread::sleep(Duration::new(1, 0));
    println!("Unpausing");
    out.unpause();
    thread::sleep(Duration::new(3, 0));
    out.destroy()
}
<|endoftext|>


<commit_before><commit_msg>Added a snowman example<commit_after>extern crate turtle;

use std::f64::consts::PI;

use turtle::Turtle;

fn main() {
    let mut turtle = Turtle::new();

    turtle.pen_up();
    turtle.set_speed("fastest");
    turtle.backward(250.0);
    turtle.left(90.0);
    turtle.pen_down();
    turtle.set_speed(6);

    for &radius in [120.0, 80.0, 60.0].into_iter() {
        circle(&mut turtle, radius);

        turtle.set_speed("fastest");
        turtle.pen_up();
        turtle.right(90.0);
        turtle.forward(radius * 2.0);
        turtle.left(90.0);
        turtle.pen_down();
        turtle.set_speed(6);
    }

    turtle.hide();
}

fn circle(turtle: &mut Turtle, radius: f64) {
    let degrees = 180.0;

    let circumference = 2.0*PI*radius;
    let step = circumference / degrees;
    let rotation = 360.0 / degrees;

    for _ in 0..degrees as i32 {
        turtle.forward(step);
        turtle.right(rotation);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add problem #12<commit_after>use std;

fn gen_triangles(&trigs: [uint]) {
    alt vec::len(trigs) {
      0u { trigs = [1u]; }
      x  { trigs += [trigs[x - 1u] + x + 1u]; }
    }
}

fn gen_prime(&primes: [u64]) {
    let num = alt vec::last(primes) {
      none       { primes =  [2u64]; ret }
      some(2u64) { primes += [3u64]; ret }
      some(x)    { x + 2u64 }
    };

    while true {
        for p in primes {
            if p * p > num {
                primes += [num];
                ret;
            }
            if num % p == 0u64 {
                break;
            }
        }
        num += 2u64;
    }
    fail;
}

fn div_mult(&num: u64, f: u64) -> u64 {
    let exp = 0u64;
    while (num % f == 0u64) {
        exp += 1u64;
        num /= f;
    }
    ret exp;
}

fn factorize(num: u64, &primes: [u64]) -> [(u64, u64)] {
    let itr = num;
    let result = [];

    for p in primes {
        let exp = div_mult(itr, p);
        if exp > 0u64 {
            result += [(p, exp)];
        }
    }

    while itr != 1u64 {
        gen_prime(primes);
        let p = vec::last_total(primes);
        let exp = div_mult(itr, p);
        if exp > 0u64 {
            result += [(p, exp)];
        }
    }

    ret result;
}

fn num_factors(num: u64, &primes: [u64]) -> u64 {
    let facts = factorize(num, primes);
    ret vec::foldl(1u, facts) { |prod, tuple|
        let (_base, exp) = tuple;
        prod * (exp + 1u)
    };
}

fn main() {
    let trigs  = [];
    let primes = [];
    while true {
        gen_triangles(trigs);
        let t = vec::last_total(trigs);
        let num = num_factors(t, primes);
        if num > 500u {
            std::io::println(#fmt("%u -> %u", t, num_factors(t, primes)));
            break;
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add ID reporting in imag-grep<commit_after><|endoftext|>


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

//! Utilities related to FFI bindings.
//!
//! This module provides utilities to handle data across non-Rust
//! interfaces, like other programming languages and the underlying
//! operating system. It is mainly of use for FFI (Foreign Function
//! Interface) bindings and code that needs to exchange C-like strings
//! with other languages.
//!
//! # Overview
//!
//! Rust represents owned strings with the [`String`] type, and
//! borrowed slices of strings with the [`str`] primitive. Both are
//! always in UTF-8 encoding, and may contain nul bytes in the middle,
//! i.e. if you look at the bytes that make up the string, there may
//! be a `\0` among them. Both `String` and `str` store their length
//! explicitly; there are no nul terminators at the end of strings
//! like in C.
//!
//! C strings are different from Rust strings:
//!
//! * **Encodings** - Rust strings are UTF-8, but C strings may use
//! other encodings. If you are using a string from C, you should
//! check its encoding explicitly, rather than just assuming that it
//! is UTF-8 like you can do in Rust.
//!
//! * **Character size** - C strings may use `char` or `wchar_t`-sized
//! characters; please **note** that C's `char` is different from Rust's.
//! The C standard leaves the actual sizes of those types open to
//! interpretation, but defines different APIs for strings made up of
//! each character type. Rust strings are always UTF-8, so different
//! Unicode characters will be encoded in a variable number of bytes
//! each. The Rust type [`char`] represents a '[Unicode scalar
//! value]', which is similar to, but not the same as, a '[Unicode
//! code point]'.
//!
//! * **Nul terminators and implicit string lengths** - Often, C
//! strings are nul-terminated, i.e. they have a `\0` character at the
//! end. The length of a string buffer is not stored, but has to be
//! calculated; to compute the length of a string, C code must
//! manually call a function like `strlen()` for `char`-based strings,
//! or `wcslen()` for `wchar_t`-based ones. Those functions return
//! the number of characters in the string excluding the nul
//! terminator, so the buffer length is really `len+1` characters.
//! Rust strings don't have a nul terminator; their length is always
//! stored and does not need to be calculated. While in Rust
//! accessing a string's length is a O(1) operation (because the
//! length is stored); in C it is an O(length) operation because the
//! length needs to be computed by scanning the string for the nul
//! terminator.
//!
//! * **Internal nul characters** - When C strings have a nul
//! terminator character, this usually means that they cannot have nul
//! characters in the middle — a nul character would essentially
//! truncate the string. Rust strings *can* have nul characters in
//! the middle, because nul does not have to mark the end of the
//! string in Rust.
//!
//! # Representations of non-Rust strings
//!
//! [`CString`] and [`CStr`] are useful when you need to transfer
//! UTF-8 strings to and from languages with a C ABI, like Python.
//!
//! * **From Rust to C:** [`CString`] represents an owned, C-friendly
//! string: it is nul-terminated, and has no internal nul characters.
//! Rust code can create a `CString` out of a normal string (provided
//! that the string doesn't have nul characters in the middle), and
//! then use a variety of methods to obtain a raw `*mut u8` that can
//! then be passed as an argument to functions which use the C
//! conventions for strings.
//!
//! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
//! is what you would use to wrap a raw `*const u8` that you got from
//! a C function. A `CStr` is guaranteed to be a nul-terminated array
//! of bytes. Once you have a `CStr`, you can convert it to a Rust
//! `&str` if it's valid UTF-8, or lossily convert it by adding
//! replacement characters.
//!
//! [`OsString`] and [`OsStr`] are useful when you need to transfer
//! strings to and from the operating system itself, or when capturing
//! the output of external commands. Conversions between `OsString`,
//! `OsStr` and Rust strings work similarly to those for [`CString`]
//! and [`CStr`].
//!
//! * [`OsString`] represents an owned string in whatever
//! representation the operating system prefers. In the Rust standard
//! library, various APIs that transfer strings to/from the operating
//! system use `OsString` instead of plain strings. For example,
//! [`env::var_os()`] is used to query environment variables; it
//! returns an `Option<OsString>`. If the environment variable exists
//! you will get a `Some(os_string)`, which you can *then* try to
//! convert to a Rust string. This yields a [`Result<>`], so that
//! your code can detect errors in case the environment variable did
//! not in fact contain valid Unicode data.
//!
//! * [`OsStr`] represents a borrowed reference to a string in a
//! format that can be passed to the operating system. It can be
//! converted into an UTF-8 Rust string slice in a similar way to
//! `OsString`.
//!
//! # Conversions
//!
//! ## On Unix
//!
//! On Unix, [`OsStr`] implements the
//! `std::os::unix:ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
//! augments it with two methods, [`from_bytes`] and [`as_bytes`].
//! These do inexpensive conversions from and to UTF-8 byte slices.
//!
//! Additionally, on Unix [`OsString`] implements the
//! `std::os::unix:ffi::`[`OsStringExt`][unix.OsStringExt] trait,
//! which provides [`from_vec`] and [`into_vec`] methods that consume
//! their arguments, and take or produce vectors of [`u8`].
//!
//! ## On Windows
//!
//! On Windows, [`OsStr`] implements the
//! `std::os::windows::ffi::`[`OsStrExt`][windows.OsStrExt] trait,
//! which provides an [`encode_wide`] method. This provides an
//! iterator that can be [`collect`]ed into a vector of [`u16`].
//!
//! Additionally, on Windows [`OsString`] implements the
//! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt]
//! trait, which provides a [`from_wide`] method. The result of this
//! method is an `OsString` which can be round-tripped to a Windows
//! string losslessly.
//!
//! [`String`]: ../string/struct.String.html
//! [`str`]: ../primitive.str.html
//! [`char`]: ../primitive.char.html
//! [`u8`]: ../primitive.u8.html
//! [`u16`]: ../primitive.u16.html
//! [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value
//! [Unicode code point]: http://www.unicode.org/glossary/#code_point
//! [`CString`]: struct.CString.html
//! [`CStr`]: struct.CStr.html
//! [`OsString`]: struct.OsString.html
//! [`OsStr`]: struct.OsStr.html
//! [`env::set_var()`]: ../env/fn.set_var.html
//! [`env::var_os()`]: ../env/fn.var_os.html
//! [`Result<>`]: ../result/enum.Result.html
//! [unix.OsStringExt]: ../os/unix/ffi/trait.OsStringExt.html
//! [`from_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.from_vec
//! [`into_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.into_vec
//! [unix.OsStrExt]: ../os/unix/ffi/trait.OsStrExt.html
//! [`from_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.from_bytes
//! [`as_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.as_bytes
//! [`OsStrExt`]: ../os/unix/ffi/trait.OsStrExt.html
//! [windows.OsStrExt]: ../os/windows/ffi/trait.OsStrExt.html
//! [`encode_wide`]: ../os/windows/ffi/trait.OsStrExt.html#tymethod.encode_wide
//! [`collect`]: ../iter/trait.Iterator.html#method.collect
//! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
//! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide

#![stable(feature = "rust1", since = "1.0.0")]

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::c_str::{CString, CStr, NulError, IntoStringError};
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub use self::c_str::{FromBytesWithNulError};

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::os_str::{OsString, OsStr};

#[stable(feature = "raw_os", since = "1.1.0")]
pub use core::ffi::c_void;

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

//! Utilities related to FFI bindings.
//!
//! This module provides utilities to handle data across non-Rust
//! interfaces, like other programming languages and the underlying
//! operating system. It is mainly of use for FFI (Foreign Function
//! Interface) bindings and code that needs to exchange C-like strings
//! with other languages.
//!
//! # Overview
//!
//! Rust represents owned strings with the [`String`] type, and
//! borrowed slices of strings with the [`str`] primitive. Both are
//! always in UTF-8 encoding, and may contain nul bytes in the middle,
//! i.e. if you look at the bytes that make up the string, there may
//! be a `\0` among them. Both `String` and `str` store their length
//! explicitly; there are no nul terminators at the end of strings
//! like in C.
//!
//! C strings are different from Rust strings:
//!
//! * **Encodings** - Rust strings are UTF-8, but C strings may use
//! other encodings. If you are using a string from C, you should
//! check its encoding explicitly, rather than just assuming that it
//! is UTF-8 like you can do in Rust.
//!
//! * **Character size** - C strings may use `char` or `wchar_t`-sized
//! characters; please **note** that C's `char` is different from Rust's.
//! The C standard leaves the actual sizes of those types open to
//! interpretation, but defines different APIs for strings made up of
//! each character type. Rust strings are always UTF-8, so different
//! Unicode characters will be encoded in a variable number of bytes
//! each. The Rust type [`char`] represents a '[Unicode scalar
//! value]', which is similar to, but not the same as, a '[Unicode
//! code point]'.
//!
//! * **Nul terminators and implicit string lengths** - Often, C
//! strings are nul-terminated, i.e. they have a `\0` character at the
//! end. The length of a string buffer is not stored, but has to be
//! calculated; to compute the length of a string, C code must
//! manually call a function like `strlen()` for `char`-based strings,
//! or `wcslen()` for `wchar_t`-based ones. Those functions return
//! the number of characters in the string excluding the nul
//! terminator, so the buffer length is really `len+1` characters.
//! Rust strings don't have a nul terminator; their length is always
//! stored and does not need to be calculated. While in Rust
//! accessing a string's length is a O(1) operation (because the
//! length is stored); in C it is an O(length) operation because the
//! length needs to be computed by scanning the string for the nul
//! terminator.
//!
//! * **Internal nul characters** - When C strings have a nul
//! terminator character, this usually means that they cannot have nul
//! characters in the middle — a nul character would essentially
//! truncate the string. Rust strings *can* have nul characters in
//! the middle, because nul does not have to mark the end of the
//! string in Rust.
//!
//! # Representations of non-Rust strings
//!
//! [`CString`] and [`CStr`] are useful when you need to transfer
//! UTF-8 strings to and from languages with a C ABI, like Python.
//!
//! * **From Rust to C:** [`CString`] represents an owned, C-friendly
//! string: it is nul-terminated, and has no internal nul characters.
//! Rust code can create a `CString` out of a normal string (provided
//! that the string doesn't have nul characters in the middle), and
//! then use a variety of methods to obtain a raw `*mut u8` that can
//! then be passed as an argument to functions which use the C
//! conventions for strings.
//!
//! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
//! is what you would use to wrap a raw `*const u8` that you got from
//! a C function. A `CStr` is guaranteed to be a nul-terminated array
//! of bytes. Once you have a `CStr`, you can convert it to a Rust
//! `&str` if it's valid UTF-8, or lossily convert it by adding
//! replacement characters.
//!
//! [`OsString`] and [`OsStr`] are useful when you need to transfer
//! strings to and from the operating system itself, or when capturing
//! the output of external commands. Conversions between `OsString`,
//! `OsStr` and Rust strings work similarly to those for [`CString`]
//! and [`CStr`].
//!
//! * [`OsString`] represents an owned string in whatever
//! representation the operating system prefers. In the Rust standard
//! library, various APIs that transfer strings to/from the operating
//! system use `OsString` instead of plain strings. For example,
//! [`env::var_os()`] is used to query environment variables; it
//! returns an `Option<OsString>`. If the environment variable exists
//! you will get a `Some(os_string)`, which you can *then* try to
//! convert to a Rust string. This yields a [`Result<>`], so that
//! your code can detect errors in case the environment variable did
//! not in fact contain valid Unicode data.
//!
//! * [`OsStr`] represents a borrowed reference to a string in a
//! format that can be passed to the operating system. It can be
//! converted into an UTF-8 Rust string slice in a similar way to
//! `OsString`.
//!
//! # Conversions
//!
//! ## On Unix
//!
//! On Unix, [`OsStr`] implements the
//! `std::os::unix::ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
//! augments it with two methods, [`from_bytes`] and [`as_bytes`].
//! These do inexpensive conversions from and to UTF-8 byte slices.
//!
//! Additionally, on Unix [`OsString`] implements the
//! `std::os::unix::ffi::`[`OsStringExt`][unix.OsStringExt] trait,
//! which provides [`from_vec`] and [`into_vec`] methods that consume
//! their arguments, and take or produce vectors of [`u8`].
//!
//! ## On Windows
//!
//! On Windows, [`OsStr`] implements the
//! `std::os::windows::ffi::`[`OsStrExt`][windows.OsStrExt] trait,
//! which provides an [`encode_wide`] method. This provides an
//! iterator that can be [`collect`]ed into a vector of [`u16`].
//!
//! Additionally, on Windows [`OsString`] implements the
//! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt]
//! trait, which provides a [`from_wide`] method. The result of this
//! method is an `OsString` which can be round-tripped to a Windows
//! string losslessly.
//!
//! [`String`]: ../string/struct.String.html
//! [`str`]: ../primitive.str.html
//! [`char`]: ../primitive.char.html
//! [`u8`]: ../primitive.u8.html
//! [`u16`]: ../primitive.u16.html
//! [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value
//! [Unicode code point]: http://www.unicode.org/glossary/#code_point
//! [`CString`]: struct.CString.html
//! [`CStr`]: struct.CStr.html
//! [`OsString`]: struct.OsString.html
//! [`OsStr`]: struct.OsStr.html
//! [`env::set_var()`]: ../env/fn.set_var.html
//! [`env::var_os()`]: ../env/fn.var_os.html
//! [`Result<>`]: ../result/enum.Result.html
//! [unix.OsStringExt]: ../os/unix/ffi/trait.OsStringExt.html
//! [`from_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.from_vec
//! [`into_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.into_vec
//! [unix.OsStrExt]: ../os/unix/ffi/trait.OsStrExt.html
//! [`from_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.from_bytes
//! [`as_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.as_bytes
//! [`OsStrExt`]: ../os/unix/ffi/trait.OsStrExt.html
//! [windows.OsStrExt]: ../os/windows/ffi/trait.OsStrExt.html
//! [`encode_wide`]: ../os/windows/ffi/trait.OsStrExt.html#tymethod.encode_wide
//! [`collect`]: ../iter/trait.Iterator.html#method.collect
//! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
//! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide

#![stable(feature = "rust1", since = "1.0.0")]

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::c_str::{CString, CStr, NulError, IntoStringError};
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub use self::c_str::{FromBytesWithNulError};

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::os_str::{OsString, OsStr};

#[stable(feature = "raw_os", since = "1.1.0")]
pub use core::ffi::c_void;

mod c_str;
mod os_str;
<|endoftext|>


<commit_before><commit_msg>Used AttemptResult for everything now<commit_after><|endoftext|>


<commit_before>#[crate_type = "rlib"];
#[crate_id="github.com/xsleonard/sdl2_image-rs#sdl2_image:0.1"];
#[desc = "SDL2_image bindings and wrappers"];
#[comment = "SDL2_image bindings and wrappers"];
#[license = "MIT"];

extern mod sdl2;

use std::libc::{c_int, c_char};
use std::ptr;
use std::cast;
use std::io;
use sdl2::surface::Surface;
use sdl2::render::Texture;
use sdl2::render::Renderer;
use sdl2::get_error;

// Setup linking for all targets.
#[cfg(target_os="macos")]
mod mac {
    #[cfg(mac_framework)]
    #[link(kind="framework", name="SDL2_image")]
    extern {}

    #[cfg(not(mac_framework))]
    #[link(name="SDL2_image")]
    extern {}
}

#[cfg(target_os="win32")]
#[cfg(target_os="linux")]
#[cfg(target_os="freebsd")]
mod others {
    #[link(name="SDL2_image")]
    extern {}
}

mod ffi;

#[deriving(Clone, Eq, IterBytes, ToStr)]
pub enum InitFlag {
    InitJpg = ffi::IMG_INIT_JPG as int,
    InitPng = ffi::IMG_INIT_PNG as int,
    InitTif = ffi::IMG_INIT_TIF as int,
    InitWebp = ffi::IMG_INIT_WEBP as int,
}

#[deriving(Eq, Clone)]
pub struct ImageVersion {
    major: int,
    minor: int,
    patch: int,
}

impl ToStr for ImageVersion {
    fn to_str(&self) -> ~str {
        format!("{}.{}.{}", self.major, self.minor, self.patch)
    }
}

impl ImageVersion {
    fn from_sdl_version(sv: *ffi::SDL_version) -> ImageVersion {
        unsafe {
            let v = *sv;
            ImageVersion{ major: v.major, minor: v.minor, patch: v.patch }
        }
    }
}

pub trait ImageLoader {
    fn from_file(filename: &str) -> Result<~Surface, ~str>;
    fn from_xpm_array(xpm: **i8) -> Result<~Surface, ~str>;
}

pub trait ImageSaver {
    fn save(&self, filename: &str) -> Result<(), ~str>;
}

impl ImageLoader for Surface {
    fn from_file(filename: &str) -> Result<~Surface, ~str> {
        unsafe {
            let raw = ffi::IMG_Load(filename.to_c_str().unwrap());
            if raw == ptr::null() {
                Err(get_error())
            } else {
                Ok(~Surface { raw: raw, owned: true })
            }
        }
    }

    fn from_xpm_array(xpm: **i8) -> Result<~Surface, ~str> {
        unsafe {
            let raw = ffi::IMG_ReadXPMFromArray(xpm as **c_char);
            if raw == ptr::null() {
                Err(get_error())
            } else {
                Ok(~Surface { raw: raw, owned: true })
            }
        }
    }
}

impl ImageSaver for Surface {
    fn save(&self, filename: &str) -> Result<(), ~str> {
        unsafe {
            let status = ffi::IMG_SavePNG(self.raw,
                                          filename.to_c_str().unwrap());
            if status != 0 {
                Err(get_error())
            } else {
                Ok(())
            }
        }
    }
}

pub trait TextureLoader {
    fn load_texture_from_file(&self, filename: &str) -> Result<~Texture, ~str>;
}

impl TextureLoader for Renderer {
    fn load_texture_from_file(&self,
                              filename: &str) -> Result<~Texture, ~str> {
        unsafe {
            let raw = ffi::IMG_LoadTexture(self.raw,
                                           filename.to_c_str().unwrap());
            if raw == ptr::null() {
                Err(get_error())
            } else {
                Ok(~Texture{ raw: raw, owned: true })
            }
        }
    }
}

pub fn init(flags: &[InitFlag]) -> ~[InitFlag] {
    //! Initializes SDL2_image with InitFlags and returns which
    //! InitFlags were actually used.
    let mut used = ~[];
    unsafe {
        let used_flags = ffi::IMG_Init(
            flags.iter().fold(0, |flags, &flag| {
                flags | flag as ffi::IMG_InitFlags
            })
        );
        for flag in flags.iter() {
            if used_flags & *flag as c_int != 0 {
                used.push(*flag)
            }
        }
    }
    used
}

pub fn quit() {
    //! Teardown the SDL2_Image subsystem
    unsafe { ffi::IMG_Quit(); }
}

pub fn get_linked_version() -> ImageVersion {
    //! Returns the version of the dynamically linked SDL_image library
    unsafe {
        ImageVersion::from_sdl_version(ffi::IMG_Linked_Version())
    }
}

// TODO -- this should be in rust-sdl2
// Most of the sdl2_image API relies on SDL_RWops.

// #[deriving(Eq)]
// pub struct RWops {
//     raw: *SDL_RWops;
//     owned: bool;
// }

// impl Drop for RWops {
//     fn drop(&mut self) {
//         if self.owned {
//             unsafe {
//                 // TODO -- close() returns a c_int error status.
//                 // How do we deal with errors in the destructor?
//                 // Probably either kill the task, or don't implement this
//                 // as a destructor
//                 self.raw.close()
//             }
//         }
//     }
// }
<commit_msg>use Self in trait ImageLoader's static methods to type hint the compiler<commit_after>#[crate_type = "rlib"];
#[crate_id="github.com/xsleonard/sdl2_image-rs#sdl2_image:0.1"];
#[desc = "SDL2_image bindings and wrappers"];
#[comment = "SDL2_image bindings and wrappers"];
#[license = "MIT"];

extern mod sdl2;

use std::libc::{c_int, c_char};
use std::ptr;
use std::cast;
use std::io;
use sdl2::surface::Surface;
use sdl2::render::Texture;
use sdl2::render::Renderer;
use sdl2::get_error;

// Setup linking for all targets.
#[cfg(target_os="macos")]
mod mac {
    #[cfg(mac_framework)]
    #[link(kind="framework", name="SDL2_image")]
    extern {}

    #[cfg(not(mac_framework))]
    #[link(name="SDL2_image")]
    extern {}
}

#[cfg(target_os="win32")]
#[cfg(target_os="linux")]
#[cfg(target_os="freebsd")]
mod others {
    #[link(name="SDL2_image")]
    extern {}
}

mod ffi;

#[deriving(Clone, Eq, IterBytes, ToStr)]
pub enum InitFlag {
    InitJpg = ffi::IMG_INIT_JPG as int,
    InitPng = ffi::IMG_INIT_PNG as int,
    InitTif = ffi::IMG_INIT_TIF as int,
    InitWebp = ffi::IMG_INIT_WEBP as int,
}

#[deriving(Eq, Clone)]
pub struct ImageVersion {
    major: int,
    minor: int,
    patch: int,
}

impl ToStr for ImageVersion {
    fn to_str(&self) -> ~str {
        format!("{}.{}.{}", self.major, self.minor, self.patch)
    }
}

impl ImageVersion {
    fn from_sdl_version(sv: *ffi::SDL_version) -> ImageVersion {
        unsafe {
            let v = *sv;
            ImageVersion{ major: v.major, minor: v.minor, patch: v.patch }
        }
    }
}

pub trait ImageLoader {
    // Self is only returned here to type hint to the compiler.
    // The syntax for type hinting in this case is not yet defined.
    // The intended return value is Result<~Surface, ~str>.
    fn from_file(filename: &str) -> Result<~Self, ~str>;
    fn from_xpm_array(xpm: **i8) -> Result<~Self, ~str>;
}

pub trait ImageSaver {
    fn save(&self, filename: &str) -> Result<(), ~str>;
}

impl ImageLoader for Surface {
    fn from_file(filename: &str) -> Result<~Surface, ~str> {
        unsafe {
            let raw = ffi::IMG_Load(filename.to_c_str().unwrap());
            if raw == ptr::null() {
                Err(get_error())
            } else {
                Ok(~Surface { raw: raw, owned: true })
            }
        }
    }

    fn from_xpm_array(xpm: **i8) -> Result<~Surface, ~str> {
        unsafe {
            let raw = ffi::IMG_ReadXPMFromArray(xpm as **c_char);
            if raw == ptr::null() {
                Err(get_error())
            } else {
                Ok(~Surface { raw: raw, owned: true })
            }
        }
    }
}

impl ImageSaver for Surface {
    fn save(&self, filename: &str) -> Result<(), ~str> {
        unsafe {
            let status = ffi::IMG_SavePNG(self.raw,
                                          filename.to_c_str().unwrap());
            if status != 0 {
                Err(get_error())
            } else {
                Ok(())
            }
        }
    }
}

pub trait TextureLoader {
    fn load_texture_from_file(&self, filename: &str) -> Result<~Texture, ~str>;
}

impl TextureLoader for Renderer {
    fn load_texture_from_file(&self,
                              filename: &str) -> Result<~Texture, ~str> {
        unsafe {
            let raw = ffi::IMG_LoadTexture(self.raw,
                                           filename.to_c_str().unwrap());
            if raw == ptr::null() {
                Err(get_error())
            } else {
                Ok(~Texture{ raw: raw, owned: true })
            }
        }
    }
}

pub fn init(flags: &[InitFlag]) -> ~[InitFlag] {
    //! Initializes SDL2_image with InitFlags and returns which
    //! InitFlags were actually used.
    let mut used = ~[];
    unsafe {
        let used_flags = ffi::IMG_Init(
            flags.iter().fold(0, |flags, &flag| {
                flags | flag as ffi::IMG_InitFlags
            })
        );
        for flag in flags.iter() {
            if used_flags & *flag as c_int != 0 {
                used.push(*flag)
            }
        }
    }
    used
}

pub fn quit() {
    //! Teardown the SDL2_Image subsystem
    unsafe { ffi::IMG_Quit(); }
}

pub fn get_linked_version() -> ImageVersion {
    //! Returns the version of the dynamically linked SDL_image library
    unsafe {
        ImageVersion::from_sdl_version(ffi::IMG_Linked_Version())
    }
}

// TODO -- this should be in rust-sdl2
// Most of the sdl2_image API relies on SDL_RWops.

// #[deriving(Eq)]
// pub struct RWops {
//     raw: *SDL_RWops;
//     owned: bool;
// }

// impl Drop for RWops {
//     fn drop(&mut self) {
//         if self.owned {
//             unsafe {
//                 // TODO -- close() returns a c_int error status.
//                 // How do we deal with errors in the destructor?
//                 // Probably either kill the task, or don't implement this
//                 // as a destructor
//                 self.raw.close()
//             }
//         }
//     }
// }
<|endoftext|>


<commit_before>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Handling log-probabilities.

use std::mem;
use std::f64;

pub use stats::{Prob, LogProb};

/// A factor to convert log-probabilities to PHRED-scale (phred = p * LOG_TO_PHRED_FACTOR).
const LOG_TO_PHRED_FACTOR: f64 = -4.3429448190325175; // -10 * 1 / ln(10)

/// A factor to convert PHRED-scale to log-probabilities (p = phred * PHRED_TO_LOG_FACTOR).
const PHRED_TO_LOG_FACTOR: f64 = -0.23025850929940456; // 1 / (-10 * log10(e))

/// Calculate log(1 - p) with p given in log space without loss of precision as described in
/// http://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf.
pub fn ln_1m_exp(p: LogProb) -> LogProb {
    if p < -0.693 {
        (-p.exp()).ln_1p()
    }
    else {
        (-p.exp_m1()).ln()
    }
}

/// Convert log scale probability to PHRED scale.
pub fn log_to_phred(p: LogProb) -> f64 {
    p * LOG_TO_PHRED_FACTOR
}

/// Convert PHRED scale probability to log scale.
pub fn phred_to_log(p: f64) -> LogProb {
    p * PHRED_TO_LOG_FACTOR
}

/// Calculate the sum of the given probabilities in a numerically stable way (Durbin 1998).
pub fn sum(probs: &[LogProb]) -> LogProb {
    if probs.is_empty() {
        f64::NEG_INFINITY
    }
    else {
        let mut pmax = probs[0];
        let mut imax = 0;
        for (i, &p) in probs.iter().enumerate().skip(1) {
            if p > pmax {
                pmax = p;
                imax = i;
            }
        }
        if pmax == f64::NEG_INFINITY {
            f64::NEG_INFINITY
        }
        else if pmax == f64::INFINITY {
            f64::INFINITY
        }
        else {
            // TODO use sum() once it has been stabilized: .sum::<usize>()
            pmax + (probs.iter().enumerate().filter_map(|(i, p)| if i != imax { Some((p - pmax).exp()) } else { None }).fold(0.0, |s, e| s + e)).ln_1p()
        }
    }
}

/// Calculate the sum of the given probabilities in a numerically stable way (Durbin 1998).
pub fn add(mut p0: LogProb, mut p1: LogProb) -> LogProb {
    if p1 > p0 {
        mem::swap(&mut p0, &mut p1);
    }
    if p0 == f64::NEG_INFINITY {
        f64::NEG_INFINITY
    }
    else if p0 == f64::INFINITY {
        f64::INFINITY
    }
    else {
        p0 + (p1 - p0).exp().ln_1p()
    }
}

/// Calculate the cumulative sum of the given probabilities in a numerically stable way (Durbin 1998).
pub fn cumsum<'a, I: Iterator<Item=&'a LogProb>>(probs: I) -> Vec<LogProb> {
    probs.scan(f64::NEG_INFINITY, |s, p| {
        *s = add(*s, *p);
        Some(*s)
    }).collect()
}

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

    #[test]
    fn test_sum() {
        let probs = [f64::NEG_INFINITY, 0.0, f64::NEG_INFINITY];
        assert_eq!(sum(&probs), 0.0);
    }

    #[test]
    fn test_empty_sum() {
        assert_eq!(sum(&[]), f64::NEG_INFINITY);
    }
}
<commit_msg>Added test for cumsum and take probs by value.<commit_after>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Handling log-probabilities.

use std::mem;
use std::f64;

pub use stats::{Prob, LogProb};

/// A factor to convert log-probabilities to PHRED-scale (phred = p * LOG_TO_PHRED_FACTOR).
const LOG_TO_PHRED_FACTOR: f64 = -4.3429448190325175; // -10 * 1 / ln(10)

/// A factor to convert PHRED-scale to log-probabilities (p = phred * PHRED_TO_LOG_FACTOR).
const PHRED_TO_LOG_FACTOR: f64 = -0.23025850929940456; // 1 / (-10 * log10(e))

/// Calculate log(1 - p) with p given in log space without loss of precision as described in
/// http://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf.
pub fn ln_1m_exp(p: LogProb) -> LogProb {
    if p < -0.693 {
        (-p.exp()).ln_1p()
    }
    else {
        (-p.exp_m1()).ln()
    }
}

/// Convert log scale probability to PHRED scale.
pub fn log_to_phred(p: LogProb) -> f64 {
    p * LOG_TO_PHRED_FACTOR
}

/// Convert PHRED scale probability to log scale.
pub fn phred_to_log(p: f64) -> LogProb {
    p * PHRED_TO_LOG_FACTOR
}

/// Calculate the sum of the given probabilities in a numerically stable way (Durbin 1998).
pub fn sum(probs: &[LogProb]) -> LogProb {
    if probs.is_empty() {
        f64::NEG_INFINITY
    }
    else {
        let mut pmax = probs[0];
        let mut imax = 0;
        for (i, &p) in probs.iter().enumerate().skip(1) {
            if p > pmax {
                pmax = p;
                imax = i;
            }
        }
        if pmax == f64::NEG_INFINITY {
            f64::NEG_INFINITY
        }
        else if pmax == f64::INFINITY {
            f64::INFINITY
        }
        else {
            // TODO use sum() once it has been stabilized: .sum::<usize>()
            pmax + (probs.iter().enumerate().filter_map(|(i, p)| if i != imax { Some((p - pmax).exp()) } else { None }).fold(0.0, |s, e| s + e)).ln_1p()
        }
    }
}

/// Calculate the sum of the given probabilities in a numerically stable way (Durbin 1998).
pub fn add(mut p0: LogProb, mut p1: LogProb) -> LogProb {
    if p1 > p0 {
        mem::swap(&mut p0, &mut p1);
    }
    if p0 == f64::NEG_INFINITY {
        f64::NEG_INFINITY
    }
    else if p0 == f64::INFINITY {
        f64::INFINITY
    }
    else {
        p0 + (p1 - p0).exp().ln_1p()
    }
}

/// Calculate the cumulative sum of the given probabilities in a numerically stable way (Durbin 1998).
pub fn cumsum<'a, I: Iterator<Item=LogProb>>(probs: I) -> Vec<LogProb> {
    probs.scan(f64::NEG_INFINITY, |s, p| {
        *s = add(*s, p);
        Some(*s)
    }).collect()
}

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

    #[test]
    fn test_sum() {
        let probs = [f64::NEG_INFINITY, 0.0, f64::NEG_INFINITY];
        assert_eq!(sum(&probs), 0.0);
    }

    #[test]
    fn test_empty_sum() {
        assert_eq!(sum(&[]), f64::NEG_INFINITY);
    }

    #[test]
    fn test_cumsum() {
        let probs = vec![0.0f64.ln(), 0.01f64.ln(), 0.001f64.ln()];
        assert_eq!(cumsum(probs.into_iter()), [0.0f64.ln(), 0.01f64.ln(), 0.011f64.ln()]);
    }
}
<|endoftext|>


<commit_before><commit_msg>Use a parametric lifetime in 'Responder' example.<commit_after><|endoftext|>


<commit_before><commit_msg>example of interpret with multiple aguments and fn name<commit_after>extern crate parity_wasm;

use std::env::args;

use parity_wasm::{interpreter, ModuleInstanceInterface, RuntimeValue};

fn main() {
    let args: Vec<_> = args().collect();
    if args.len() < 3 {
        println!("Usage: {} <wasm file> <exported func> [<arg>...]", args[0]);
        return;
    }
    let func_name = &args[2];
    let (_, program_args) = args.split_at(3);
    let program_args: Vec<_>  = program_args.iter().enumerate()
        .map(|(i, arg)| RuntimeValue::I32(arg.parse().expect(&format!("Invalid i32 arg at index {}", i))))
        .collect();

    let program = parity_wasm::ProgramInstance::with_env_params(
        interpreter::EnvParams {
            total_stack: 128*1024,
            total_memory: 2*1024*1024,
            allow_memory_growth: false,
        }
    ).expect("Failed to load program");
    let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module");
    let module = program.add_module("main", module, None).expect("Failed to initialize module");

    println!("Result: {:?}", module.execute_export(func_name, program_args.into()));
}
<|endoftext|>


<commit_before><commit_msg>feat: add simple example<commit_after>extern crate futures;
extern crate telegram_bot;
extern crate tokio_core;

use std::env;

use futures::Stream;
use tokio_core::reactor::Core;
use telegram_bot::*;

fn main() {
    let mut core = Core::new().unwrap();

    let token = env::var("TELEGRAM_BOT_TOKEN").unwrap();
    let api = Api::from_token(&core.handle(), &token).unwrap();

    // Fetch new updates via long poll method
    let future = api.stream().for_each(|update| {

        // If the received update contains a new message...
        if let UpdateKind::Message(message) = update.kind {

            // Get sender's first name if available.
            let first_name = match message.from.as_ref() {
                Some(from) => &from.first_name,
                None => return Ok(()) // Skip a message.
            };

            if let MessageKind::Text {ref data, ..} = message.kind {
                // Print received text message to stdout.
                println!("<{}>: {}", first_name, data);

                // Answer message with "Hi".
                api.spawn(&message.text_reply(
                    format!("Hi, {}! You just wrote '{}'", first_name, data)
                ));
            }
        }

        Ok(())
    });

    core.run(future).unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Make derive block cipher key take fixed size input<commit_after><|endoftext|>


<commit_before>export OSMain;
export Msg, BeginDrawing, Draw, AddKeyHandler, Exit;

import azure::*;
import azure::bindgen::*;
import azure::cairo;
import azure::cairo::bindgen::*;
import comm::*;
import dvec::{dvec, extensions};
import azure::cairo::cairo_surface_t;
import gfx::renderer::{Sink};
import dom::event::{Event, ResizeEvent};
import layers::ImageLayer;
import geom::size::Size2D;
import std::cmp::fuzzy_eq;
import vec::push;

type OSMain = chan<Msg>;

enum Msg {
    BeginDrawing(chan<AzDrawTargetRef>),
    Draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
    AddKeyHandler(chan<()>),
    AddEventListener(chan<Event>),
    Exit
}

fn OSMain() -> OSMain {
    do on_osmain::<Msg> |po| {
        do platform::runmain {
            #debug("preparing to enter main loop");
	        mainloop(po);
        }
    }
}

fn mainloop(po: port<Msg>) {
    let key_handlers: @dvec<chan<()>> = @dvec();
    let event_listeners: @dvec<chan<Event>> = @dvec();

    glut::init();
    glut::init_display_mode(glut::DOUBLE);

    let surfaces = @surface_set();

    let window = glut::create_window("Servo");
    glut::reshape_window(window, 800, 600);

    let context = layers::rendergl::init_render_context();

    let image = @layers::layers::Image(0, 0, layers::layers::RGB24Format, ~[]);
    let image_layer = @layers::layers::ImageLayer(image);
    image_layer.common.set_transform
        (image_layer.common.transform.scale(800.0f32, 600.0f32, 1.0f32));

    let scene = @mut layers::scene::Scene(layers::layers::ImageLayerKind(image_layer),
                                          Size2D(800.0f32, 600.0f32));

    let done = @mut false;

    let check_for_messages = fn@() {
        // Handle messages
        #debug("osmain: peeking");
        if po.peek() {
            alt po.recv() {
              AddKeyHandler(key_ch) {
                key_handlers.push(key_ch);
              }
              AddEventListener(event_listener) {
                event_listeners.push(event_listener);
              }
              BeginDrawing(sender) {
                lend_surface(*surfaces, sender);
              }
              Draw(sender, dt) {
                #debug("osmain: received new frame");
                return_surface(*surfaces, dt);
                lend_surface(*surfaces, sender);

                let mut image_data;
                unsafe {
                    let buffer = cairo_image_surface_get_data(surfaces.s1.surf.cairo_surf);
                    image_data = vec::unsafe::from_buf(buffer, 800 * 600 * 4);
                }

                let image =
                    @layers::layers::Image(800, 600, layers::layers::ARGB32Format, image_data);
                image_layer.set_image(image);
              }
              exit {
                *done = true;
              }
            }
        }
    };

    do glut::reshape_func(window) |width, height| {
        check_for_messages();

        #debug("osmain: window resized to %d,%d", width as int, height as int);
        for event_listeners.each |event_listener| {
            event_listener.send(ResizeEvent(width as int, height as int));
        }
    }

    do glut::display_func() {
        check_for_messages();

        #debug("osmain: drawing to screen");

        layers::rendergl::render_scene(context, *scene);
        glut::swap_buffers();
        glut::post_redisplay();
    }

    while !*done {
        #debug("osmain: running GLUT check loop");
        glut::check_loop();
    }

    destroy_surface(surfaces.s1.surf);
    destroy_surface(surfaces.s2.surf);
}

#[doc = "
Implementation to allow the osmain channel to be used as a graphics
sink for the renderer
"]
impl OSMain of Sink for OSMain {
    fn begin_drawing(next_dt: chan<AzDrawTargetRef>) {
        self.send(BeginDrawing(next_dt))
    }
    fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
        self.send(Draw(next_dt, draw_me))
    }
    fn add_event_listener(listener: chan<Event>) {
        self.send(AddEventListener(listener));
    }
}

type surface_set = {
    mut s1: {
        surf: surface,
        have: bool
    },
    mut s2: {
        surf: surface,
        have: bool
    }
};

fn lend_surface(surfaces: surface_set, recvr: chan<AzDrawTargetRef>) {
    // We are in a position to lend out the surface?
    assert surfaces.s1.have;
    // Ok then take it
    let dt1 = surfaces.s1.surf.az_target;
    #debug("osmain: lending surface %?", dt1);
    recvr.send(dt1);
    // Now we don't have it
    surfaces.s1 = {
        have: false
        with surfaces.s1
    };
    // But we (hopefully) have another!
    surfaces.s1 <-> surfaces.s2;
    // Let's look
    assert surfaces.s1.have;
}

fn return_surface(surfaces: surface_set, dt: AzDrawTargetRef) {
    #debug("osmain: returning surface %?", dt);
    // We have room for a return
    assert surfaces.s1.have;
    assert !surfaces.s2.have;
    assert surfaces.s2.surf.az_target == dt;
    // Now we have it again
    surfaces.s2 = {
        have: true
        with surfaces.s2
    };
}

fn surface_set() -> surface_set {
    {
        mut s1: {
            surf: mk_surface(),
            have: true
        },
        mut s2: {
            surf: mk_surface(),
            have: true
        }
    }
}

type surface = {
    cairo_surf: *cairo_surface_t,
    az_target: AzDrawTargetRef
};

fn mk_surface() -> surface {
    let cairo_surf = cairo_image_surface_create(cairo::CAIRO_FORMAT_RGB24, 800, 600);

    assert !ptr::is_null(cairo_surf);

    let azure_target = AzCreateDrawTargetForCairoSurface(cairo_surf);
    assert !ptr::is_null(azure_target);

    {
        cairo_surf: cairo_surf,
        az_target: azure_target
    }
}

fn destroy_surface(+surface: surface) {
    AzReleaseDrawTarget(surface.az_target);
    cairo_surface_destroy(surface.cairo_surf);
}

#[doc = "A function for spawning into the platform's main thread"]
fn on_osmain<T: send>(+f: fn~(comm::port<T>)) -> comm::chan<T> {
    let builder = task::builder();
    let opts = {
        sched: some({
            mode: task::osmain,
            foreign_stack_size: none
        })
        with task::get_opts(builder)
    };
    task::set_opts(builder, opts);
    ret task::run_listener(builder, f);
}

// #[cfg(target_os = "linux")]
mod platform {
    fn runmain(f: fn()) {
        f()
    }
}

<commit_msg>Add some timing for compositing<commit_after>export OSMain;
export Msg, BeginDrawing, Draw, AddKeyHandler, Exit;

import azure::*;
import azure::bindgen::*;
import azure::cairo;
import azure::cairo::bindgen::*;
import comm::*;
import dvec::{dvec, extensions};
import azure::cairo::cairo_surface_t;
import gfx::renderer::{Sink};
import dom::event::{Event, ResizeEvent};
import layers::ImageLayer;
import geom::size::Size2D;
import std::cmp::fuzzy_eq;
import std::time::precise_time_ns;
import vec::push;

type OSMain = chan<Msg>;

enum Msg {
    BeginDrawing(chan<AzDrawTargetRef>),
    Draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
    AddKeyHandler(chan<()>),
    AddEventListener(chan<Event>),
    Exit
}

fn OSMain() -> OSMain {
    do on_osmain::<Msg> |po| {
        do platform::runmain {
            #debug("preparing to enter main loop");
	        mainloop(po);
        }
    }
}

fn time(msg: str, callback: fn()) {
    let start_time = precise_time_ns();
    callback();
    let end_time = precise_time_ns();
    #debug("%s took %u ms", msg, ((end_time - start_time) / 1000000u64) as uint);
}

fn mainloop(po: port<Msg>) {
    let key_handlers: @dvec<chan<()>> = @dvec();
    let event_listeners: @dvec<chan<Event>> = @dvec();

    glut::init();
    glut::init_display_mode(glut::DOUBLE);

    let surfaces = @surface_set();

    let window = glut::create_window("Servo");
    glut::reshape_window(window, 800, 600);

    let context = layers::rendergl::init_render_context();

    let image = @layers::layers::Image(0, 0, layers::layers::RGB24Format, ~[]);
    let image_layer = @layers::layers::ImageLayer(image);
    image_layer.common.set_transform
        (image_layer.common.transform.scale(800.0f32, 600.0f32, 1.0f32));

    let scene = @mut layers::scene::Scene(layers::layers::ImageLayerKind(image_layer),
                                          Size2D(800.0f32, 600.0f32));

    let done = @mut false;

    let check_for_messages = fn@() {
        // Handle messages
        #debug("osmain: peeking");
        if po.peek() {
            alt po.recv() {
              AddKeyHandler(key_ch) {
                key_handlers.push(key_ch);
              }
              AddEventListener(event_listener) {
                event_listeners.push(event_listener);
              }
              BeginDrawing(sender) {
                lend_surface(*surfaces, sender);
              }
              Draw(sender, dt) {
                #debug("osmain: received new frame");
                return_surface(*surfaces, dt);
                lend_surface(*surfaces, sender);

                let mut image_data;
                unsafe {
                    let buffer = cairo_image_surface_get_data(surfaces.s1.surf.cairo_surf);
                    image_data = vec::unsafe::from_buf(buffer, 800 * 600 * 4);
                }

                let image =
                    @layers::layers::Image(800, 600, layers::layers::ARGB32Format, image_data);
                image_layer.set_image(image);
              }
              exit {
                *done = true;
              }
            }
        }
    };

    do glut::reshape_func(window) |width, height| {
        check_for_messages();

        #debug("osmain: window resized to %d,%d", width as int, height as int);
        for event_listeners.each |event_listener| {
            event_listener.send(ResizeEvent(width as int, height as int));
        }
    }

    do glut::display_func() {
        check_for_messages();

        #debug("osmain: drawing to screen");

        do time("compositing") {
            layers::rendergl::render_scene(context, *scene);
        }

        glut::swap_buffers();
        glut::post_redisplay();
    }

    while !*done {
        #debug("osmain: running GLUT check loop");
        glut::check_loop();
    }

    destroy_surface(surfaces.s1.surf);
    destroy_surface(surfaces.s2.surf);
}

#[doc = "
Implementation to allow the osmain channel to be used as a graphics
sink for the renderer
"]
impl OSMain of Sink for OSMain {
    fn begin_drawing(next_dt: chan<AzDrawTargetRef>) {
        self.send(BeginDrawing(next_dt))
    }
    fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
        self.send(Draw(next_dt, draw_me))
    }
    fn add_event_listener(listener: chan<Event>) {
        self.send(AddEventListener(listener));
    }
}

type surface_set = {
    mut s1: {
        surf: surface,
        have: bool
    },
    mut s2: {
        surf: surface,
        have: bool
    }
};

fn lend_surface(surfaces: surface_set, recvr: chan<AzDrawTargetRef>) {
    // We are in a position to lend out the surface?
    assert surfaces.s1.have;
    // Ok then take it
    let dt1 = surfaces.s1.surf.az_target;
    #debug("osmain: lending surface %?", dt1);
    recvr.send(dt1);
    // Now we don't have it
    surfaces.s1 = {
        have: false
        with surfaces.s1
    };
    // But we (hopefully) have another!
    surfaces.s1 <-> surfaces.s2;
    // Let's look
    assert surfaces.s1.have;
}

fn return_surface(surfaces: surface_set, dt: AzDrawTargetRef) {
    #debug("osmain: returning surface %?", dt);
    // We have room for a return
    assert surfaces.s1.have;
    assert !surfaces.s2.have;
    assert surfaces.s2.surf.az_target == dt;
    // Now we have it again
    surfaces.s2 = {
        have: true
        with surfaces.s2
    };
}

fn surface_set() -> surface_set {
    {
        mut s1: {
            surf: mk_surface(),
            have: true
        },
        mut s2: {
            surf: mk_surface(),
            have: true
        }
    }
}

type surface = {
    cairo_surf: *cairo_surface_t,
    az_target: AzDrawTargetRef
};

fn mk_surface() -> surface {
    let cairo_surf = cairo_image_surface_create(cairo::CAIRO_FORMAT_RGB24, 800, 600);

    assert !ptr::is_null(cairo_surf);

    let azure_target = AzCreateDrawTargetForCairoSurface(cairo_surf);
    assert !ptr::is_null(azure_target);

    {
        cairo_surf: cairo_surf,
        az_target: azure_target
    }
}

fn destroy_surface(+surface: surface) {
    AzReleaseDrawTarget(surface.az_target);
    cairo_surface_destroy(surface.cairo_surf);
}

#[doc = "A function for spawning into the platform's main thread"]
fn on_osmain<T: send>(+f: fn~(comm::port<T>)) -> comm::chan<T> {
    let builder = task::builder();
    let opts = {
        sched: some({
            mode: task::osmain,
            foreign_stack_size: none
        })
        with task::get_opts(builder)
    };
    task::set_opts(builder, opts);
    ret task::run_listener(builder, f);
}

// #[cfg(target_os = "linux")]
mod platform {
    fn runmain(f: fn()) {
        f()
    }
}

<|endoftext|>


<commit_before><commit_msg>Add prefix file<commit_after>#![allow(non_upper_case_globals, missing_docs)]
pub const exa: f64 = 1e18;
pub const peta: f64 = 1e15;
pub const tera: f64 = 1e12;
pub const giga: f64 = 1e9;
pub const mega: f64 = 1e6;
pub const kilo: f64 = 1e3;
pub const hecto: f64 = 1e2;
pub const deca: f64 = 1e1;

pub const deci: f64 = 1e-1;
pub const centi: f64 = 1e-2;
pub const milli: f64 = 1e-3;
pub const micro: f64 = 1e-6;
pub const nano: f64 = 1e-9;
pub const pico: f64 = 1e-12;
pub const femto: f64 = 1e-15;
pub const atto: f64 = 1e-18;
<|endoftext|>


<commit_before><commit_msg>Allow backspacing across lines<commit_after><|endoftext|>


<commit_before><commit_msg>Use Iterator in Calc's tokenize() Function<commit_after><|endoftext|>


<commit_before><commit_msg>Advent day6<commit_after><|endoftext|>


<commit_before>extern crate handlebars;
extern crate rustc_serialize;
extern crate pulldown_cmark;

use renderer::html_handlebars::helpers;
use renderer::Renderer;
use book::MDBook;
use book::bookitem::BookItem;
use {utils, theme};

use std::path::{Path, PathBuf};
use std::fs::File;
use std::error::Error;
use std::io::{self, Read, Write};
use std::collections::BTreeMap;

use self::handlebars::{Handlebars, JsonRender};
use self::rustc_serialize::json::{Json, ToJson};
use self::pulldown_cmark::{Parser, html};

pub struct HtmlHandlebars;

impl HtmlHandlebars {
    pub fn new() -> Self {
        HtmlHandlebars
    }
}

impl Renderer for HtmlHandlebars {
    fn render(&self, book: &MDBook) -> Result<(), Box<Error>> {
        debug!("[fn]: render");
        let mut handlebars = Handlebars::new();

        // Load theme
        let theme = theme::Theme::new(book.get_src());

        // Register template
        debug!("[*]: Register handlebars template");
        try!(handlebars.register_template_string("index", try!(String::from_utf8(theme.index))));

        // Register helpers
        debug!("[*]: Register handlebars helpers");
        handlebars.register_helper("toc", Box::new(helpers::toc::RenderToc));
        handlebars.register_helper("previous", Box::new(helpers::navigation::previous));
        handlebars.register_helper("next", Box::new(helpers::navigation::next));

        let mut data = try!(make_data(book));

        // Print version
        let mut print_content: String = String::new();

        // Check if dest directory exists
        debug!("[*]: Check if destination directory exists");
        if let Err(_) = utils::create_path(book.get_dest()) {
            return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Unexpected error when constructing destination path")))
        }

        // Render a file for every entry in the book
        let mut index = true;
        for item in book.iter() {

            match *item {
                BookItem::Chapter(_, ref ch) | BookItem::Affix(ref ch) => {
                    if ch.path != PathBuf::new() {

                        let path = book.get_src().join(&ch.path);

                        debug!("[*]: Opening file: {:?}", path);
                        let mut f = try!(File::open(&path));
                        let mut content: String = String::new();

                        debug!("[*]: Reading file");
                        try!(f.read_to_string(&mut content));

                        // Render markdown using the pulldown-cmark crate
                        content = render_html(&content);
                        print_content.push_str(&content);

                        // Remove content from previous file and render content for this one
                        data.remove("path");
                        match ch.path.to_str() {
                            Some(p) => { data.insert("path".to_owned(), p.to_json()); },
                            None => return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not convert path to str"))),
                        }

                        // Remove content from previous file and render content for this one
                        data.remove("content");
                        data.insert("content".to_owned(), content.to_json());

                        // Remove path to root from previous file and render content for this one
                        data.remove("path_to_root");
                        data.insert("path_to_root".to_owned(), utils::path_to_root(&ch.path).to_json());

                        // Rendere the handlebars template with the data
                        debug!("[*]: Render template");
                        let rendered = try!(handlebars.render("index", &data));

                        debug!("[*]: Create file {:?}", &book.get_dest().join(&ch.path).with_extension("html"));
                        // Write to file
                        let mut file = try!(utils::create_file(&book.get_dest().join(&ch.path).with_extension("html")));
                        output!("[*] Creating {:?} ✓", &book.get_dest().join(&ch.path).with_extension("html"));

                        try!(file.write_all(&rendered.into_bytes()));

                        // Create an index.html from the first element in SUMMARY.md
                        if index {
                            debug!("[*]: index.html");

                            let mut index_file = try!(File::create(book.get_dest().join("index.html")));
                            let mut content = String::new();
                            let _source = try!(File::open(book.get_dest().join(&ch.path.with_extension("html"))))
                                                        .read_to_string(&mut content);

                            // This could cause a problem when someone displays code containing <base href=...>
                            // on the front page, however this case should be very very rare...
                            content = content.lines().filter(|line| !line.contains("<base href=")).collect();

                            try!(index_file.write_all(content.as_bytes()));

                            output!(
                                "[*] Creating index.html from {:?} ✓",
                                book.get_dest().join(&ch.path.with_extension("html"))
                                );
                            index = false;
                        }
                    }
                }
                _ => {}
            }
        }

        // Print version

        // Remove content from previous file and render content for this one
        data.remove("path");
        data.insert("path".to_owned(), "print.md".to_json());

        // Remove content from previous file and render content for this one
        data.remove("content");
        data.insert("content".to_owned(), print_content.to_json());

        // Remove path to root from previous file and render content for this one
        data.remove("path_to_root");
        data.insert("path_to_root".to_owned(), utils::path_to_root(Path::new("print.md")).to_json());

        // Rendere the handlebars template with the data
        debug!("[*]: Render template");
        let rendered = try!(handlebars.render("index", &data));
        let mut file = try!(utils::create_file(&book.get_dest().join("print").with_extension("html")));
        try!(file.write_all(&rendered.into_bytes()));
        output!("[*] Creating print.html ✓");

        // Copy static files (js, css, images, ...)

        debug!("[*] Copy static files");
        // JavaScript
        let mut js_file = try!(File::create(book.get_dest().join("book.js")));
        try!(js_file.write_all(&theme.js));

        // Css
        let mut css_file = try!(File::create(book.get_dest().join("book.css")));
        try!(css_file.write_all(&theme.css));

        // JQuery local fallback
        let mut jquery = try!(File::create(book.get_dest().join("jquery.js")));
        try!(jquery.write_all(&theme.jquery));

        // Font Awesome local fallback
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/css/font-awesome").with_extension("css")));
        try!(font_awesome.write_all(theme::FONT_AWESOME));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.eot")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_EOT));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.svg")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_SVG));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.ttf")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_TTF));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.woff")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.woff2")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF2));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/FontAwesome.ttf")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_TTF));

        // syntax highlighting
        let mut highlight_css = try!(File::create(book.get_dest().join("highlight.css")));
        try!(highlight_css.write_all(&theme.highlight_css));
        let mut tomorrow_night_css = try!(File::create(book.get_dest().join("tomorrow-night.css")));
        try!(tomorrow_night_css.write_all(&theme.tomorrow_night_css));
        let mut highlight_js = try!(File::create(book.get_dest().join("highlight.js")));
        try!(highlight_js.write_all(&theme.highlight_js));

        // Copy all remaining files
        try!(utils::copy_files_except_ext(book.get_src(), book.get_dest(), true, &["md"]));

        Ok(())
    }
}

fn make_data(book: &MDBook) -> Result<BTreeMap<String,Json>, Box<Error>> {
    debug!("[fn]: make_data");

    let mut data  = BTreeMap::new();
    data.insert("language".to_owned(), "en".to_json());
    data.insert("title".to_owned(), book.get_title().to_json());

    let mut chapters = vec![];

    for item in book.iter() {
        // Create the data to inject in the template
        let mut chapter = BTreeMap::new();

        match *item {
            BookItem::Affix(ref ch) => {
                chapter.insert("name".to_owned(), ch.name.to_json());
                match ch.path.to_str() {
                    Some(p) => { chapter.insert("path".to_owned(), p.to_json()); },
                    None => return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not convert path to str"))),
                }
            },
            BookItem::Chapter(ref s, ref ch) => {
                chapter.insert("section".to_owned(), s.to_json());
                chapter.insert("name".to_owned(), ch.name.to_json());
                match ch.path.to_str() {
                    Some(p) => { chapter.insert("path".to_owned(), p.to_json()); },
                    None => return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not convert path to str"))),
                }
            },
            BookItem::Spacer => {
                chapter.insert("spacer".to_owned(), "_spacer_".to_json());
            }

        }

        chapters.push(chapter);
    }

    data.insert("chapters".to_owned(), chapters.to_json());

    debug!("[*]: JSON constructed");
    Ok(data)
}

fn render_html(text: &str) -> String {
    let mut s = String::with_capacity(text.len() * 3 / 2);
    let p = Parser::new(&text);
    html::push_html(&mut s, p);
    s
}
<commit_msg>Add newlines back in to generated index.html files.<commit_after>extern crate handlebars;
extern crate rustc_serialize;
extern crate pulldown_cmark;

use renderer::html_handlebars::helpers;
use renderer::Renderer;
use book::MDBook;
use book::bookitem::BookItem;
use {utils, theme};

use std::path::{Path, PathBuf};
use std::fs::File;
use std::error::Error;
use std::io::{self, Read, Write};
use std::collections::BTreeMap;

use self::handlebars::{Handlebars, JsonRender};
use self::rustc_serialize::json::{Json, ToJson};
use self::pulldown_cmark::{Parser, html};

pub struct HtmlHandlebars;

impl HtmlHandlebars {
    pub fn new() -> Self {
        HtmlHandlebars
    }
}

impl Renderer for HtmlHandlebars {
    fn render(&self, book: &MDBook) -> Result<(), Box<Error>> {
        debug!("[fn]: render");
        let mut handlebars = Handlebars::new();

        // Load theme
        let theme = theme::Theme::new(book.get_src());

        // Register template
        debug!("[*]: Register handlebars template");
        try!(handlebars.register_template_string("index", try!(String::from_utf8(theme.index))));

        // Register helpers
        debug!("[*]: Register handlebars helpers");
        handlebars.register_helper("toc", Box::new(helpers::toc::RenderToc));
        handlebars.register_helper("previous", Box::new(helpers::navigation::previous));
        handlebars.register_helper("next", Box::new(helpers::navigation::next));

        let mut data = try!(make_data(book));

        // Print version
        let mut print_content: String = String::new();

        // Check if dest directory exists
        debug!("[*]: Check if destination directory exists");
        if let Err(_) = utils::create_path(book.get_dest()) {
            return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Unexpected error when constructing destination path")))
        }

        // Render a file for every entry in the book
        let mut index = true;
        for item in book.iter() {

            match *item {
                BookItem::Chapter(_, ref ch) | BookItem::Affix(ref ch) => {
                    if ch.path != PathBuf::new() {

                        let path = book.get_src().join(&ch.path);

                        debug!("[*]: Opening file: {:?}", path);
                        let mut f = try!(File::open(&path));
                        let mut content: String = String::new();

                        debug!("[*]: Reading file");
                        try!(f.read_to_string(&mut content));

                        // Render markdown using the pulldown-cmark crate
                        content = render_html(&content);
                        print_content.push_str(&content);

                        // Remove content from previous file and render content for this one
                        data.remove("path");
                        match ch.path.to_str() {
                            Some(p) => { data.insert("path".to_owned(), p.to_json()); },
                            None => return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not convert path to str"))),
                        }

                        // Remove content from previous file and render content for this one
                        data.remove("content");
                        data.insert("content".to_owned(), content.to_json());

                        // Remove path to root from previous file and render content for this one
                        data.remove("path_to_root");
                        data.insert("path_to_root".to_owned(), utils::path_to_root(&ch.path).to_json());

                        // Rendere the handlebars template with the data
                        debug!("[*]: Render template");
                        let rendered = try!(handlebars.render("index", &data));

                        debug!("[*]: Create file {:?}", &book.get_dest().join(&ch.path).with_extension("html"));
                        // Write to file
                        let mut file = try!(utils::create_file(&book.get_dest().join(&ch.path).with_extension("html")));
                        output!("[*] Creating {:?} ✓", &book.get_dest().join(&ch.path).with_extension("html"));

                        try!(file.write_all(&rendered.into_bytes()));

                        // Create an index.html from the first element in SUMMARY.md
                        if index {
                            debug!("[*]: index.html");

                            let mut index_file = try!(File::create(book.get_dest().join("index.html")));
                            let mut content = String::new();
                            let _source = try!(File::open(book.get_dest().join(&ch.path.with_extension("html"))))
                                                        .read_to_string(&mut content);

                            // This could cause a problem when someone displays code containing <base href=...>
                            // on the front page, however this case should be very very rare...
                            content = content.lines().filter(|line| !line.contains("<base href=")).map(|line| line.to_string() + "\n").collect();

                            try!(index_file.write_all(content.as_bytes()));

                            output!(
                                "[*] Creating index.html from {:?} ✓",
                                book.get_dest().join(&ch.path.with_extension("html"))
                                );
                            index = false;
                        }
                    }
                }
                _ => {}
            }
        }

        // Print version

        // Remove content from previous file and render content for this one
        data.remove("path");
        data.insert("path".to_owned(), "print.md".to_json());

        // Remove content from previous file and render content for this one
        data.remove("content");
        data.insert("content".to_owned(), print_content.to_json());

        // Remove path to root from previous file and render content for this one
        data.remove("path_to_root");
        data.insert("path_to_root".to_owned(), utils::path_to_root(Path::new("print.md")).to_json());

        // Rendere the handlebars template with the data
        debug!("[*]: Render template");
        let rendered = try!(handlebars.render("index", &data));
        let mut file = try!(utils::create_file(&book.get_dest().join("print").with_extension("html")));
        try!(file.write_all(&rendered.into_bytes()));
        output!("[*] Creating print.html ✓");

        // Copy static files (js, css, images, ...)

        debug!("[*] Copy static files");
        // JavaScript
        let mut js_file = try!(File::create(book.get_dest().join("book.js")));
        try!(js_file.write_all(&theme.js));

        // Css
        let mut css_file = try!(File::create(book.get_dest().join("book.css")));
        try!(css_file.write_all(&theme.css));

        // JQuery local fallback
        let mut jquery = try!(File::create(book.get_dest().join("jquery.js")));
        try!(jquery.write_all(&theme.jquery));

        // Font Awesome local fallback
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/css/font-awesome").with_extension("css")));
        try!(font_awesome.write_all(theme::FONT_AWESOME));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.eot")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_EOT));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.svg")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_SVG));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.ttf")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_TTF));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.woff")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.woff2")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF2));
        let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/FontAwesome.ttf")));
        try!(font_awesome.write_all(theme::FONT_AWESOME_TTF));

        // syntax highlighting
        let mut highlight_css = try!(File::create(book.get_dest().join("highlight.css")));
        try!(highlight_css.write_all(&theme.highlight_css));
        let mut tomorrow_night_css = try!(File::create(book.get_dest().join("tomorrow-night.css")));
        try!(tomorrow_night_css.write_all(&theme.tomorrow_night_css));
        let mut highlight_js = try!(File::create(book.get_dest().join("highlight.js")));
        try!(highlight_js.write_all(&theme.highlight_js));

        // Copy all remaining files
        try!(utils::copy_files_except_ext(book.get_src(), book.get_dest(), true, &["md"]));

        Ok(())
    }
}

fn make_data(book: &MDBook) -> Result<BTreeMap<String,Json>, Box<Error>> {
    debug!("[fn]: make_data");

    let mut data  = BTreeMap::new();
    data.insert("language".to_owned(), "en".to_json());
    data.insert("title".to_owned(), book.get_title().to_json());

    let mut chapters = vec![];

    for item in book.iter() {
        // Create the data to inject in the template
        let mut chapter = BTreeMap::new();

        match *item {
            BookItem::Affix(ref ch) => {
                chapter.insert("name".to_owned(), ch.name.to_json());
                match ch.path.to_str() {
                    Some(p) => { chapter.insert("path".to_owned(), p.to_json()); },
                    None => return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not convert path to str"))),
                }
            },
            BookItem::Chapter(ref s, ref ch) => {
                chapter.insert("section".to_owned(), s.to_json());
                chapter.insert("name".to_owned(), ch.name.to_json());
                match ch.path.to_str() {
                    Some(p) => { chapter.insert("path".to_owned(), p.to_json()); },
                    None => return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not convert path to str"))),
                }
            },
            BookItem::Spacer => {
                chapter.insert("spacer".to_owned(), "_spacer_".to_json());
            }

        }

        chapters.push(chapter);
    }

    data.insert("chapters".to_owned(), chapters.to_json());

    debug!("[*]: JSON constructed");
    Ok(data)
}

fn render_html(text: &str) -> String {
    let mut s = String::with_capacity(text.len() * 3 / 2);
    let p = Parser::new(&text);
    html::push_html(&mut s, p);
    s
}
<|endoftext|>


<commit_before><commit_msg>bind the range to a name<commit_after><|endoftext|>


<commit_before><commit_msg>Show we basically import journeys too.<commit_after><|endoftext|>


<commit_before><commit_msg>result map<commit_after>use std::num::ParseIntError;

fn double_number(s: &str) -> Result<i32, ParseIntError> {
    match s.parse::<i32>() {
        Ok(n) => Ok(n * 2),
        Err(e) => Err(e)
    }
}

fn double_with_map(s: &str) -> Result<i32, ParseIntError> {
    s.parse::<i32>().map(|n| n*2)
}

type AliasedResult<T> = Result<T, ParseIntError>;

fn double_with_alias(s: &str) -> AliasedResult<i32> {
    s.parse::<i32>().map(|n| n*2)
}

fn main() {
    println!("Double 10: {:?}", double_number("10"));
    println!("Double tt: {:?}", double_number("tt"));

    println!("Double 20: {:?}", double_number("20"));

    println!("Double 20: {:?}", double_with_alias("20"));
}<|endoftext|>


<commit_before><commit_msg>an empy message<commit_after><|endoftext|>


<commit_before><commit_msg>blank message<commit_after><|endoftext|>