<commit_before>// heap.rs

//! Utility functions and algorithms for minimun heaps

/// I implement this as a trait.
///
/// If I was only interested in heap_sort, I'd
/// write something like
/// fn heap_sort<T: Ord>(&mut Vec<T>) {
///      fn min_heapify<T: Ord>(&mut Vec<T>) { ...
///      }
///      ...
/// }

use std::fmt::{Show};
use std::ptr::{swap};
use std::vec::{Vec};

pub trait Heap {
    fn heap_sort(&mut self);
    fn min_heapify(&mut self, uint, uint);
    fn build_min_heap(&mut self);
    fn left(&self, uint) -> uint;
    fn right(&self, uint) -> uint;
    fn parent(&self, uint) -> uint;
    fn swap(&mut self, uint, uint);
}

impl <T: Ord + Clone + Show> Heap for Vec<T> {

    fn heap_sort(&mut self) {
        self.build_min_heap();
        for i in range(1, self.len()).rev()  {
            self.swap(0, i);
            self.min_heapify(0, i);
        }
    }

    fn min_heapify(&mut self, i: uint, j: uint) {
        let l = self.left(i);
        let r = self.right(i);
        let mut smallest = i;
        if l < j && self.get(l) > self.get(smallest) {
            smallest = l;
        }
        if r < j && self.get(r) > self.get(smallest) {
            smallest = r;
        }
        if smallest != i {
            self.swap(i, smallest);
            self.min_heapify(smallest, j);
        }
    }

    fn build_min_heap(&mut self) {
        let self_len = self.len();
        for i in range(0, self_len / 2 + 1).rev() {
            self.min_heapify(i, self_len);
        }
    }

    fn left(&self, i: uint) -> uint {
        2 * i + 1
    }

    fn right(&self, i: uint) -> uint {
        2 * i + 2
    }

    fn parent(&self, i: uint) -> uint {
        i / 2
    }

    fn swap(&mut self, i: uint, j: uint) {
        unsafe{
            let ptr_to_i: *mut T = self.get_mut(i);
            let ptr_to_j: *mut T = self.get_mut(j);
            swap(ptr_to_i, ptr_to_j);
        }
    }

}
<commit_msg>removed debug traits<commit_after>// heap.rs

//! Utility functions and algorithms for minimun heaps

/// I implement this as a trait.
///
/// If I was only interested in heap_sort, I'd
/// write something like
/// fn heap_sort<T: Ord>(&mut Vec<T>) {
///      fn min_heapify<T: Ord>(&mut Vec<T>) { ...
///      }
///      ...
/// }

use std::fmt::{Show};
use std::ptr::{swap};
use std::vec::{Vec};

pub trait Heap {
    fn heap_sort(&mut self);
    fn min_heapify(&mut self, uint, uint);
    fn build_min_heap(&mut self);
    fn left(&self, uint) -> uint;
    fn right(&self, uint) -> uint;
    fn parent(&self, uint) -> uint;
    fn swap(&mut self, uint, uint);
}

impl <T: Ord> Heap for Vec<T> {

    fn heap_sort(&mut self) {
        self.build_min_heap();
        for i in range(1, self.len()).rev()  {
            self.swap(0, i);
            self.min_heapify(0, i);
        }
    }

    fn min_heapify(&mut self, i: uint, j: uint) {
        let l = self.left(i);
        let r = self.right(i);
        let mut smallest = i;
        if l < j && self.get(l) > self.get(smallest) {
            smallest = l;
        }
        if r < j && self.get(r) > self.get(smallest) {
            smallest = r;
        }
        if smallest != i {
            self.swap(i, smallest);
            self.min_heapify(smallest, j);
        }
    }

    fn build_min_heap(&mut self) {
        let self_len = self.len();
        for i in range(0, self_len / 2 + 1).rev() {
            self.min_heapify(i, self_len);
        }
    }

    fn left(&self, i: uint) -> uint {
        2 * i + 1
    }

    fn right(&self, i: uint) -> uint {
        2 * i + 2
    }

    fn parent(&self, i: uint) -> uint {
        i / 2
    }

    fn swap(&mut self, i: uint, j: uint) {
        unsafe{
            let ptr_to_i: *mut T = self.get_mut(i);
            let ptr_to_j: *mut T = self.get_mut(j);
            swap(ptr_to_i, ptr_to_j);
        }
    }

}
<|endoftext|>


<commit_before>use elsa::FrozenMap;
use fluent::{FluentBundle, FluentResource};
use fluent_fallback::Localization;
use fluent_langneg;
use regex::Regex;
use rust_embed::RustEmbed;
use std::{env, fs, io, iter, path, vec};
use std::collections::HashMap;
use unic_langid::LanguageIdentifier;

static FTL_RESOURCE: &str = "cli.ftl";

#[derive(RustEmbed)]
#[folder = "assets/"]
struct Asset;

#[derive(Debug)]
pub struct Locale {
    pub negotiated: Vec<LanguageIdentifier>,
}

impl Locale {
    pub fn negotiate(language: String) -> Locale {
        let language = normalize_lang(language);
        let available = self::list_available_locales();
        let requested = fluent_langneg::accepted_languages::parse(&language);
        let default: LanguageIdentifier = crate::DEFAULT_LOCALE.parse().unwrap();
        let negotiated = fluent_langneg::negotiate_languages(
            &requested,
            &available,
            Some(&default),
            fluent_langneg::NegotiationStrategy::Filtering,
        ).iter().map(|x| *x).cloned().collect();
        // println!("PRELOADS: {:#?}", preloads);
        Locale {
            negotiated
        }
    }
}

/// Strip off any potential system locale encoding on the end of LC_LANG
fn normalize_lang(input: String) -> String {
    let re = Regex::new(r"\..*$").unwrap();
    re.replace(&input, "").to_string()
}

// https://github.com/projectfluent/fluent-rs/blob/c9e45651/fluent-resmgr/examples/simple-resmgr.rs#L35
pub fn list_available_locales() -> Vec<LanguageIdentifier> {
    let mut embeded = vec![];
    for asset in Asset::iter() {
        let asset_name = asset.to_string();
        let path = path::Path::new(&asset_name);
        let mut components = path.components();
        if let Some(path::Component::Normal(part)) = components.next() {
            let bytes = part.to_str().unwrap().as_bytes();
            if let Ok(langid) = LanguageIdentifier::from_bytes(bytes) {
                if let Some(path::Component::Normal(part)) = components.next() {
                    if part.to_str().unwrap() == self::FTL_RESOURCE {
                        embeded.push(langid);
                    }
                }
            }

        }
    }
    embeded.dedup();
    embeded
}

pub fn get_str(key: &str) -> &str {
    "bob"
    /*

    let resources: FrozenMap<String, Box<FluentResource>> = FrozenMap::new();
    let mut res_path_scheme = env::current_dir().expect("Failed to retireve current dir.");
    res_path_scheme.push("resources");
    res_path_scheme.push("{locale}");
    res_path_scheme.push("{res_id}");
    let res_path_scheme = res_path_scheme.to_str().unwrap();
    let generate_messages = |res_ids: &[String]| {
        let mut resolved_locales = locales.iter();
        let res_mgr = &resources;
        let res_ids = res_ids.to_vec();

        iter::from_fn(move || {
            resolved_locales.next().map(|locale| {
                let mut bundle = FluentBundle::new(vec![locale.clone()]);
                let res_path = res_path_scheme.replace("{locale}", &locale.to_string());

                for res_id in &res_ids {
                    let path = res_path.replace("{res_id}", res_id);
                    let res = res_mgr.get(&path).unwrap_or_else(|| {
                        let source = crate::read_file(&path).unwrap();
                        let res = FluentResource::try_new(source).unwrap();
                        res_mgr.insert(path.to_string(), Box::new(res))
                    });
                    bundle.add_resource(res).unwrap();
                }
                bundle
            })
        })
    };
    let loc = Localization::new(
        // FLUENT_RESOURCES.iter().map(|s| s.to_string()).collect(),
        generate_messages,
    );

    let value = loc.format_value(key, None);
    &value
        */
}
<commit_msg>chore(cli): Get Fluent translation working from assets<commit_after>use elsa::FrozenMap;
use fluent::{FluentBundle, FluentResource};
use fluent_fallback::Localization;
use fluent_langneg;
use regex::Regex;
use rust_embed::RustEmbed;
use std::{env, fs, io, iter, path, str, vec};
use std::collections::HashMap;
use unic_langid::LanguageIdentifier;

static FTL_RESOURCES: &[&str] = &["cli.ftl"];

#[derive(RustEmbed)]
#[folder = "assets/"]
struct Asset;

#[derive(Debug)]
pub struct Locale {
    pub negotiated: Vec<LanguageIdentifier>,
}

impl Locale {
    pub fn negotiate(language: String) -> Locale {
        let language = normalize_lang(language);
        let available = self::list_available_locales();
        let requested = fluent_langneg::accepted_languages::parse(&language);
        let default: LanguageIdentifier = crate::DEFAULT_LOCALE.parse().unwrap();
        let negotiated = fluent_langneg::negotiate_languages(
            &requested,
            &available,
            Some(&default),
            fluent_langneg::NegotiationStrategy::Filtering,
        ).iter().map(|x| *x).cloned().collect();
        Locale {
            negotiated
        }
    }

    pub fn translate(&self, key: &str) -> String {
        let mut res_path_scheme = path::PathBuf::new();
        res_path_scheme.push("{locale}");
        res_path_scheme.push("{res_id}");
        let generate_messages = |res_ids: &[String]| {
        let mut resolved_locales = self.negotiated.iter();
            let res_path_scheme = res_path_scheme.to_str().unwrap();
            let res_ids = res_ids.to_vec();

            iter::from_fn(move || {
                resolved_locales.next().map(|locale| {
                    let x = vec![locale.clone()];
                    let mut bundle = FluentBundle::new(&x);
                    let res_path = res_path_scheme.replace("{locale}", &locale.to_string());
                    for res_id in &res_ids {
                        let path = res_path.replace("{res_id}", res_id);
                        if let Some(source) = Asset::get(&path) {
                            let data = str::from_utf8(source.as_ref()).unwrap();
                            let res = FluentResource::try_new(data.to_string()).unwrap();
                            bundle.add_resource(res).unwrap();
                        }
                    }
                    bundle
                })
            })
        };
        let loc = Localization::new(
            FTL_RESOURCES.iter().map(|s| s.to_string()).collect(),
            generate_messages,
        );
        let value: String = loc.format_value(key, None).to_string();
        value
    }
}

/// Strip off any potential system locale encoding on the end of LC_LANG
fn normalize_lang(input: String) -> String {
    let re = Regex::new(r"\..*$").unwrap();
    re.replace(&input, "").to_string()
}

// https://github.com/projectfluent/fluent-rs/blob/c9e45651/fluent-resmgr/examples/simple-resmgr.rs#L35
pub fn list_available_locales() -> Vec<LanguageIdentifier> {
    let mut embeded = vec![];
    for asset in Asset::iter() {
        let asset_name = asset.to_string();
        let path = path::Path::new(&asset_name);
        let mut components = path.components();
        if let Some(path::Component::Normal(part)) = components.next() {
            let bytes = part.to_str().unwrap().as_bytes();
            if let Ok(langid) = LanguageIdentifier::from_bytes(bytes) {
                if let Some(path::Component::Normal(part)) = components.next() {
                    if self::FTL_RESOURCES.iter().any(|v| v == &part.to_str().unwrap()) {
                        embeded.push(langid);
                    }
                }
            }

        }
    }
    embeded.dedup();
    embeded
}
<|endoftext|>


<commit_before>use std::fmt;
use std::str;

const ISBN_13_MULTIPLIERS: [u32; 13] = [1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1];

#[derive(Debug)]
pub struct Isbn {
    raw: String,
    values: Vec<u32>
}

#[derive(Debug)]
pub struct IsbnParseError {
    raw: String,
    error_type: IsbnParseErrorType,
}

#[derive(Debug)]
pub enum IsbnParseErrorType {
    FailedCheck10,
    FailedCheck13,
    WrongLength,
}

impl IsbnParseError {
    fn from_raw<T: Into<String>>(error_type: IsbnParseErrorType, s: T) -> IsbnParseError {
        IsbnParseError {
            raw: s.into(),
            error_type: error_type,
        }
    }
}

impl str::FromStr for Isbn {
    type Err = IsbnParseError;

    fn from_str(s: &str) -> Result<Isbn, Self::Err> {
        let values: Vec<_> = s.chars().filter_map(|c| as_value(c)).collect();
        match values.len() {
            10 => match check_10(&values) {
                true => Ok(Isbn { raw: s.to_owned(), values: values }),
                false => Err(IsbnParseError::from_raw(IsbnParseErrorType::FailedCheck10, s)),
            },
            13 => match check_13(&values) {
                true => Ok(Isbn { raw: s.to_owned(), values: values }),
                false => Err(IsbnParseError::from_raw(IsbnParseErrorType::FailedCheck13, s)),
            },
            _ => Err(IsbnParseError::from_raw(IsbnParseErrorType::WrongLength, s)),
        }
    }
}

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

fn check_10(s: &[u32]) -> bool {
    s.iter().cloned().enumerate().map(|(idx, n)| n * (10 - idx as u32)).sum::<u32>() % 11 == 0
}

fn check_13(s: &[u32]) -> bool {
    s.iter().zip(ISBN_13_MULTIPLIERS.iter()).map(|(a, b)| a * b).sum::<u32>() % 10 == 0
}

fn as_value(c: char) -> Option<u32> {
    match c {
        '0' => Some(0),
        '1' => Some(1),
        '2' => Some(2),
        '3' => Some(3),
        '4' => Some(4),
        '5' => Some(5),
        '6' => Some(6),
        '7' => Some(7),
        '8' => Some(8),
        '9' => Some(9),
        _ => None
    }
}

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

    #[test]
    fn isnb_10_good() {
        "99921-58-10-7".parse::<Isbn>().unwrap();
    }

    #[test]
    #[should_panic]
    fn isbn_10_bad() {
        "99921-58-10-8".parse::<Isbn>().unwrap();
    }

    #[test]
    fn isbn_13_good() {
        "978-0-306-40615-7".parse::<Isbn>().unwrap();
    }

    #[test]
    #[should_panic]
    fn isbn_13_bad() {
        "978-0-306-40615-8".parse::<Isbn>().unwrap();
    }
}
<commit_msg>Scouting<commit_after>use std::fmt;
use std::str;

const ISBN_13_MULTIPLIERS: [u32; 13] = [1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1];

#[derive(Debug)]
pub struct Isbn {
    raw: String,
    values: Vec<u32>
}

#[derive(Debug)]
pub struct IsbnParseError {
    raw: String,
    error_type: IsbnParseErrorType,
}

#[derive(Debug)]
pub enum IsbnParseErrorType {
    FailedCheck10,
    FailedCheck13,
    WrongLength,
}

impl IsbnParseError {
    fn from_raw<T: Into<String>>(error_type: IsbnParseErrorType, s: T) -> IsbnParseError {
        IsbnParseError {
            raw: s.into(),
            error_type: error_type,
        }
    }
}

impl str::FromStr for Isbn {
    type Err = IsbnParseError;

    fn from_str(s: &str) -> Result<Isbn, Self::Err> {
        let values: Vec<_> = s.chars().filter_map(|c| as_value(c)).collect();
        match values.len() {
            10 => match check_10(&values) {
                true => Ok(Isbn { raw: s.to_owned(), values: values }),
                false => Err(IsbnParseError::from_raw(IsbnParseErrorType::FailedCheck10, s)),
            },
            13 => match check_13(&values) {
                true => Ok(Isbn { raw: s.to_owned(), values: values }),
                false => Err(IsbnParseError::from_raw(IsbnParseErrorType::FailedCheck13, s)),
            },
            _ => Err(IsbnParseError::from_raw(IsbnParseErrorType::WrongLength, s)),
        }
    }
}

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

fn check_10(s: &[u32]) -> bool {
    s.iter().cloned().enumerate().map(|(idx, n)| n * (10 - idx as u32)).sum::<u32>() % 11 == 0
}

fn check_13(s: &[u32]) -> bool {
    s.iter().zip(ISBN_13_MULTIPLIERS.iter()).map(|(a, b)| a * b).sum::<u32>() % 10 == 0
}

fn as_value(c: char) -> Option<u32> {
    match c {
        '0' => Some(0),
        '1' => Some(1),
        '2' => Some(2),
        '3' => Some(3),
        '4' => Some(4),
        '5' => Some(5),
        '6' => Some(6),
        '7' => Some(7),
        '8' => Some(8),
        '9' => Some(9),
        _ => None
    }
}

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

    #[test]
    fn isnb_10_good() {
        "99921-58-10-7".parse::<Isbn>().unwrap();
    }

    #[test]
    #[should_panic]
    fn isbn_10_bad() {
        "99921-58-10-8".parse::<Isbn>().unwrap();
    }

    #[test]
    fn isbn_13_good() {
        "978-0-306-40615-7".parse::<Isbn>().unwrap();
    }

    #[test]
    #[should_panic]
    fn isbn_13_bad() {
        "978-0-306-40615-8".parse::<Isbn>().unwrap();
    }
}
<|endoftext|>


<commit_before>extern crate serialize;

use benchmark::Metric;
use collections::HashMap;
use file::{read,write};
use hash::Hashes;
use language::Language;
use serialize::Decodable;
use serialize::json;

pub fn parse_language_file(language_file: &Path) -> Language {
    let mut decoder = match json::from_str(read(language_file).as_slice()) {
        Err(_) => fail!("{} is invalid json", language_file.display()),
        Ok(json) => json::Decoder::new(json),
    };

    match Decodable::decode(&mut decoder) {
        Err(_) => fail!("couldn't decode {}", language_file.display()),
        Ok(language) => language,
    }
}

pub fn load_hashes(id: &str) -> Hashes {
    let file = Path::new(format!("hashes/{}.json", id));

    if file.exists() {
        match json::from_str(read(&file).as_slice()) {
            Err(_) => HashMap::new(),
            Ok(json) => {
                match Decodable::decode(&mut json::Decoder::new(json)) {
                    Err(_) => HashMap::new(),
                    Ok(map) => map,
                }
            }
        }
    } else {
        HashMap::new()
    }
}

pub fn load_metrics(id: &str) -> Vec<Metric> {
    let file = Path::new(format!("metrics/{}.json", id));

    if file.exists() {
        match json::from_str(read(&file).as_slice()) {
            Err(_) => Vec::new(),
            Ok(json) => {
                match Decodable::decode(&mut json::Decoder::new(json)) {
                    Err(_) => Vec::new(),
                    Ok(map) => map,
                }
            }
        }
    } else {
        Vec::new()
    }
}

pub fn save_hashes(id: &str, hashes: &Hashes) {
    let hashes_file = Path::new(format!("hashes/{}.json", id));

    write(&hashes_file, json::Encoder::str_encode(hashes).as_slice());
}

pub fn update_metrics(id: &str, mut new_metrics: Vec<Metric>) {
    let metrics_file = Path::new(format!("metrics/{}.json", id));
    let mut old_metrics = load_metrics(id);
    let mut metrics = Vec::new();

    old_metrics.sort_by(|a, b| {
        a.language().cmp(&b.language())
    });
    new_metrics.sort_by(|a, b| {
        a.language().cmp(&b.language())
    });

    loop {
        match (old_metrics.pop(), new_metrics.pop()) {
            (None, None) => break,
            (Some(old), None) => {
                metrics.push(old);
            },
            (None, Some(new)) => {
                metrics.push(new);
            },
            (Some(old), Some(new)) => {
                match old.language().cmp(&new.language()) {
                    Less => {
                        metrics.push(old);
                        new_metrics.push(new);
                    },
                    Equal => {
                        let diff = (new.median() / old.median() - 1.0) * 100.0;

                        if new.min() > old.max() {
                            println!("* {} improved by {:.2}%",
                                     new.language(),
                                     diff)
                        } else if new.max() < old.min() {
                            println!("* {} regressed by {:.2}%",
                                     new.language(),
                                     -diff)
                        }

                        metrics.push(new);
                    },
                    Greater => {
                        metrics.push(new);
                        old_metrics.push(old);
                    },
                }
            }
        }
    }

    metrics.sort_by(|a, b| {
        ((1000.0 * a.median()) as u64).cmp(&((1000.0 * b.median()) as u64))
    });

    write(&metrics_file, json::Encoder::str_encode(&metrics).as_slice());
}
<commit_msg>eulermark: fix logic in update_metrics()<commit_after>extern crate serialize;

use benchmark::Metric;
use collections::HashMap;
use file::{read,write};
use hash::Hashes;
use language::Language;
use serialize::Decodable;
use serialize::json;

pub fn parse_language_file(language_file: &Path) -> Language {
    let mut decoder = match json::from_str(read(language_file).as_slice()) {
        Err(_) => fail!("{} is invalid json", language_file.display()),
        Ok(json) => json::Decoder::new(json),
    };

    match Decodable::decode(&mut decoder) {
        Err(_) => fail!("couldn't decode {}", language_file.display()),
        Ok(language) => language,
    }
}

pub fn load_hashes(id: &str) -> Hashes {
    let file = Path::new(format!("hashes/{}.json", id));

    if file.exists() {
        match json::from_str(read(&file).as_slice()) {
            Err(_) => HashMap::new(),
            Ok(json) => {
                match Decodable::decode(&mut json::Decoder::new(json)) {
                    Err(_) => HashMap::new(),
                    Ok(map) => map,
                }
            }
        }
    } else {
        HashMap::new()
    }
}

pub fn load_metrics(id: &str) -> Vec<Metric> {
    let file = Path::new(format!("metrics/{}.json", id));

    if file.exists() {
        match json::from_str(read(&file).as_slice()) {
            Err(_) => Vec::new(),
            Ok(json) => {
                match Decodable::decode(&mut json::Decoder::new(json)) {
                    Err(_) => Vec::new(),
                    Ok(map) => map,
                }
            }
        }
    } else {
        Vec::new()
    }
}

pub fn save_hashes(id: &str, hashes: &Hashes) {
    let hashes_file = Path::new(format!("hashes/{}.json", id));

    write(&hashes_file, json::Encoder::str_encode(hashes).as_slice());
}

pub fn update_metrics(id: &str, mut new_metrics: Vec<Metric>) {
    let metrics_file = Path::new(format!("metrics/{}.json", id));
    let mut old_metrics = load_metrics(id);
    let mut metrics = Vec::new();

    old_metrics.sort_by(|a, b| {
        a.language().cmp(&b.language())
    });
    new_metrics.sort_by(|a, b| {
        a.language().cmp(&b.language())
    });

    loop {
        match (old_metrics.pop(), new_metrics.pop()) {
            (None, None) => break,
            (Some(old), None) => {
                metrics.push(old);
            },
            (None, Some(new)) => {
                metrics.push(new);
            },
            (Some(old), Some(new)) => {
                match old.language().cmp(&new.language()) {
                    Less => {
                        metrics.push(new);
                        old_metrics.push(old);
                    },
                    Equal => {
                        let diff = (new.median() / old.median() - 1.0) * 100.0;

                        if new.min() > old.max() {
                            println!("* {} improved by {:.2}%",
                                     new.language(),
                                     diff)
                        } else if new.max() < old.min() {
                            println!("* {} regressed by {:.2}%",
                                     new.language(),
                                     -diff)
                        }

                        metrics.push(new);
                    },
                    Greater => {
                        metrics.push(old);
                        new_metrics.push(new);
                    },
                }
            }
        }
    }

    metrics.sort_by(|a, b| {
        ((1000.0 * a.median()) as u64).cmp(&((1000.0 * b.median()) as u64))
    });

    write(&metrics_file, json::Encoder::str_encode(&metrics).as_slice());
}
<|endoftext|>


<commit_before>use std::fmt;

#[allow(dead_code)]
#[derive(Copy, Clone, Debug)]
pub enum Sym {
    Add,
    Sub,
    Mul,
    Div,
}

impl fmt::Display for Sym {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let symbol = match self {
            &Sym::Add => "+",
            &Sym::Sub => "-",
            &Sym::Mul => "*",
            &Sym::Div => "/"
        };
        write!(f, "{}", symbol)
    }
}

#[allow(dead_code)]
#[derive(Debug)]
pub enum Node<T> {
    Num(T),
    Sym(Sym),
    List(List<T>),
}

impl<T> Clone for Node<T> where T : Clone {
    fn clone(&self) -> Self {
        match self {
            &Node::Num(ref t) => Node::Num(t.clone()),
            &Node::Sym(ref t) => Node::Sym(t.clone()),
            &Node::List(ref t) => Node::List(t.clone())
        }
    }
}

impl<T> fmt::Display for Node<T> where T : fmt::Display {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Node::Num(ref t) => write!(f, "{}", t),
            &Node::Sym(ref t) => write!(f, "{}", t),
            &Node::List(ref t) => write!(f, "({})", t),
        }
    }
}

#[derive(Debug)]
pub struct List<T> {
    pub elems : Vec<Node<T>>
}

impl<T> List<T> {
    pub fn new() -> List<T> {
        List::<T> {
            elems : Vec::<_>::new()
        }
    }
}

impl<T> Clone for List<T> where T : Clone {
    fn clone(&self) -> Self {
        List::<T> {
            elems : self.elems.clone()
        }
    }
}

impl<T> fmt::Display for List<T> where T : fmt::Display {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "( ");
        for e in &self.elems {
            write!(f, "{} ", e);
        }
        write!(f, ")")
    }
}

// impl<T> Iterator for List<T> {
//     type Item = Node<T>;
//
//     fn next(&mut self) -> Option<Node<T>> {
//         unimplemented!();
//     }
// }
<commit_msg>Add list iterator<commit_after>#![allow(dead_code)]

use std::fmt;
use std::slice;

#[derive(Copy, Clone, Debug)]
pub enum Sym {
    Add,
    Sub,
    Mul,
    Div,
}

impl fmt::Display for Sym {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let symbol = match self {
            &Sym::Add => "+",
            &Sym::Sub => "-",
            &Sym::Mul => "*",
            &Sym::Div => "/"
        };
        write!(f, "{}", symbol)
    }
}

#[derive(Debug)]
pub enum Node<T> {
    Num(T),
    Sym(Sym),
    List(List<T>),
}

impl<T> Clone for Node<T> where T : Clone {
    fn clone(&self) -> Self {
        match self {
            &Node::Num(ref t) => Node::Num(t.clone()),
            &Node::Sym(ref t) => Node::Sym(t.clone()),
            &Node::List(ref t) => Node::List(t.clone())
        }
    }
}

impl<T> fmt::Display for Node<T> where T : fmt::Display {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Node::Num(ref t) => write!(f, "{}", t),
            &Node::Sym(ref t) => write!(f, "{}", t),
            &Node::List(ref t) => write!(f, "({})", t),
        }
    }
}

#[derive(Debug)]
pub struct List<T> {
    pub elems : Vec<Node<T>>
}

impl<T> List<T> {
    pub fn new() -> List<T> {
        List::<T> {
            elems : Vec::<_>::new()
        }
    }

    pub fn iter(&self) -> Iter<T> {
        self.elems.iter()
    }
}

impl<T> Clone for List<T> where T : Clone {
    fn clone(&self) -> Self {
        List::<T> {
            elems : self.elems.clone()
        }
    }
}

impl<T> fmt::Display for List<T> where T : fmt::Display {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "( ");
        for e in &self.elems {
            write!(f, "{} ", e);
        }
        write!(f, ")")
    }
}

pub type Iter<'a, T> = slice::Iter<'a, Node<T>>;
<|endoftext|>


<commit_before>// Copyright (C) 2018, Cloudflare, Inc.
// Copyright (C) 2018, Alessandro Ghedini
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#[macro_use]
extern crate log;

use std::net;

use std::collections::HashMap;

use ring::rand::*;

const LOCAL_CONN_ID_LEN: usize = 16;

const MAX_DATAGRAM_SIZE: usize = 1452;

const USAGE: &str = "Usage:
  server [options]
  server -h | --help

Options:
  --listen <addr>   Listen on the given IP:port [default: 127.0.0.1:4433]
  --cert <file>     TLS certificate path [default: examples/cert.crt]
  --key <file>      TLS certificate key path [default: examples/cert.key]
  --root <dir>      Root directory [default: examples/root/]
  --name <str>      Name of the server [default: quic.tech]
  -h --help         Show this screen.
";

type ConnMap = HashMap<Vec<u8>, (net::SocketAddr, Box<quiche::Connection>)>;

fn main() {
    let mut buf = [0; 65535];
    let mut out = [0; MAX_DATAGRAM_SIZE];

    env_logger::init();

    let args = docopt::Docopt::new(USAGE)
                      .and_then(|dopt| dopt.parse())
                      .unwrap_or_else(|e| e.exit());

    let socket = net::UdpSocket::bind(args.get_str("--listen")).unwrap();

    let poll = mio::Poll::new().unwrap();
    let mut events = mio::Events::with_capacity(1024);

    let socket = mio::net::UdpSocket::from_socket(socket).unwrap();
    poll.register(&socket, mio::Token(0),
                  mio::Ready::readable(),
                  mio::PollOpt::edge()).unwrap();

    let mut connections = ConnMap::new();

    let mut config = quiche::Config::new(quiche::VERSION_DRAFT17).unwrap();

    config.load_cert_chain_from_pem_file(args.get_str("--cert")).unwrap();
    config.load_priv_key_from_pem_file(args.get_str("--key")).unwrap();

    config.set_application_protos(&[b"h3-17", b"hq-17", b"http/0.9"]).unwrap();

    config.set_idle_timeout(30);
    config.set_max_packet_size(MAX_DATAGRAM_SIZE as u64);
    config.set_initial_max_data(10_000_000);
    config.set_initial_max_stream_data_bidi_local(1_000_000);
    config.set_initial_max_stream_data_bidi_remote(1_000_000);
    config.set_initial_max_streams_bidi(100);
    config.set_initial_max_streams_uni(5);
    config.set_disable_migration(true);

    loop {
        // TODO: use event loop that properly supports timers
        let timeout = connections.values()
                                 .filter_map(|(_, c)| c.timeout())
                                 .min();

        poll.poll(&mut events, timeout).unwrap();

        'read: loop {
            if events.is_empty() {
                debug!("timed out");

                connections.values_mut().for_each(|(_, c)| c.on_timeout());

                break 'read;
            }

            let (len, src) = match socket.recv_from(&mut buf) {
                Ok(v) => v,

                Err(e) => {
                    if e.kind() == std::io::ErrorKind::WouldBlock {
                        debug!("recv() would block");
                        break 'read;
                    }

                    panic!("recv() failed: {:?}", e);
                },
            };

            debug!("got {} bytes", len);

            let pkt_buf = &mut buf[..len];

            let hdr = match quiche::Header::from_slice(pkt_buf, LOCAL_CONN_ID_LEN) {
                Ok(v) => v,

                Err(e) => {
                    error!("Parsing packet header failed: {:?}", e);
                    continue
                }
            };

            trace!("got packet {:?}", hdr);

            if hdr.ty == quiche::Type::VersionNegotiation {
                error!("Version negotiation invalid on the server");
                continue;
            }

            let (_, conn) = if !connections.contains_key(&hdr.dcid) {
                if hdr.ty != quiche::Type::Initial {
                    error!("Packet is not Initial");
                    continue;
                }

                if hdr.version != quiche::VERSION_DRAFT17 {
                    warn!("Doing version negotiation");

                    let len = quiche::negotiate_version(&hdr.scid,
                                                        &hdr.dcid,
                                                        &mut out).unwrap();
                    let out = &out[..len];

                    socket.send_to(out, &src).unwrap();
                    continue;
                }

                let mut scid: [u8; LOCAL_CONN_ID_LEN] = [0; LOCAL_CONN_ID_LEN];
                SystemRandom::new().fill(&mut scid[..]).unwrap();

                // Token is always present in Initial packets.
                let token = hdr.token.as_ref().unwrap();

                if token.is_empty() {
                    warn!("Doing stateless retry");

                    let new_token = mint_token(&hdr, &src);

                    let len = quiche::retry(&hdr.scid, &hdr.dcid, &scid,
                                            &new_token, &mut out).unwrap();
                    let out = &out[..len];

                    socket.send_to(out, &src).unwrap();
                    continue;
                }

                let odcid = validate_token(&src, token);

                if odcid == None {
                    error!("Invalid address validation token");
                    continue;
                }

                debug!("New connection: dcid={} scid={} lcid={}",
                       hex_dump(&hdr.dcid),
                       hex_dump(&hdr.scid),
                       hex_dump(&scid));

                let conn = quiche::accept(&scid, odcid, &mut config).unwrap();

                connections.insert(scid.to_vec(), (src, conn));

                connections.get_mut(&scid[..]).unwrap()
            } else {
                connections.get_mut(&hdr.dcid).unwrap()
            };

            // Process potentially coalesced packets.
            let read = match conn.recv(pkt_buf) {
                Ok(v)  => v,

                Err(quiche::Error::Done) => {
                    debug!("{} done reading", conn.trace_id());
                    break;
                },

                Err(e) => {
                    error!("{} recv failed: {:?}", conn.trace_id(), e);
                    conn.close(false, e.to_wire(), b"fail").unwrap();
                    break 'read;
                },
            };

            debug!("{} processed {} bytes", conn.trace_id(), read);

            let streams: Vec<u64> = conn.readable().collect();
            for s in streams {
                while let Ok((read, fin)) = conn.stream_recv(s, &mut buf) {
                    debug!("{} received {} bytes", conn.trace_id(), read);

                    let stream_buf = &buf[..read];

                    debug!("{} stream {} has {} bytes (fin? {})",
                           conn.trace_id(), s, stream_buf.len(), fin);

                    handle_stream(conn, s, stream_buf, args.get_str("--root"));
                }
            }
        }

        for (peer, conn) in connections.values_mut() {
            loop {
                let write = match conn.send(&mut out) {
                    Ok(v) => v,

                    Err(quiche::Error::Done) => {
                        debug!("{} done writing", conn.trace_id());
                        break;
                    },

                    Err(e) => {
                        error!("{} send failed: {:?}", conn.trace_id(), e);
                        conn.close(false, e.to_wire(), b"fail").unwrap();
                        break;
                    },
                };

                // TODO: coalesce packets.
                socket.send_to(&out[..write], &peer).unwrap();

                debug!("{} written {} bytes", conn.trace_id(), write);
            }
        }

        // Garbage collect closed connections.
        connections.retain(|_, (_, ref mut c)| {
            debug!("Collecting garbage");

            if c.is_closed() {
                info!("{} connection collected {:?}", c.trace_id(), c.stats());
            }

            !c.is_closed()
        });
    }
}

fn handle_stream(conn: &mut quiche::Connection, stream: u64, buf: &[u8], root: &str) {
    if buf.len() > 4 && &buf[..4] == b"GET " {
        let uri = &buf[4..buf.len()];
        let uri = String::from_utf8(uri.to_vec()).unwrap();
        let uri = String::from(uri.lines().next().unwrap());
        let uri = std::path::Path::new(&uri);
        let mut path = std::path::PathBuf::from(root);

        for c in uri.components() {
            if let std::path::Component::Normal(v) = c {
                path.push(v)
            }
        }

        info!("{} got GET request for {:?} on stream {}",
              conn.trace_id(), path, stream);

        let data = std::fs::read(path.as_path())
                    .unwrap_or_else(|_| Vec::from(String::from("Not Found!\r\n")));

        info!("{} sending response of size {} on stream {}",
              conn.trace_id(), data.len(), stream);

        if let Err(e) = conn.stream_send(stream, &data, true) {
            error!("{} stream send failed {:?}", conn.trace_id(), e);
        }
    }
}

fn mint_token(hdr: &quiche::Header, src: &net::SocketAddr) -> Vec<u8> {
    let mut token = Vec::new();

    token.extend_from_slice(b"quiche");

    let addr = match src.ip() {
        std::net::IpAddr::V4(a) => a.octets().to_vec(),
        std::net::IpAddr::V6(a) => a.octets().to_vec(),
    };

    token.extend_from_slice(&addr);
    token.extend_from_slice(&hdr.dcid);

    token
}

fn validate_token<'a>(src: &net::SocketAddr, token: &'a [u8]) -> Option<&'a [u8]> {
    if token.len() < 6 {
        return None;
    }

    if &token[..6] != b"quiche" {
        return None;
    }

    let token = &token[6..];

    let addr = match src.ip() {
        std::net::IpAddr::V4(a) => a.octets().to_vec(),
        std::net::IpAddr::V6(a) => a.octets().to_vec(),
    };

    if token.len() < addr.len() || &token[..addr.len()] != addr.as_slice() {
        return None;
    }

    let token = &token[addr.len()..];

    Some(&token[..])
}

fn hex_dump(buf: &[u8]) -> String {
    let vec: Vec<String> = buf.iter()
                              .map(|b| format!("{:02x}", b))
                              .collect();

    vec.join("")
}
<commit_msg>server: don't change local CID after Retry<commit_after>// Copyright (C) 2018, Cloudflare, Inc.
// Copyright (C) 2018, Alessandro Ghedini
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#[macro_use]
extern crate log;

use std::net;

use std::collections::HashMap;

use ring::rand::*;

const LOCAL_CONN_ID_LEN: usize = 16;

const MAX_DATAGRAM_SIZE: usize = 1452;

const USAGE: &str = "Usage:
  server [options]
  server -h | --help

Options:
  --listen <addr>   Listen on the given IP:port [default: 127.0.0.1:4433]
  --cert <file>     TLS certificate path [default: examples/cert.crt]
  --key <file>      TLS certificate key path [default: examples/cert.key]
  --root <dir>      Root directory [default: examples/root/]
  --name <str>      Name of the server [default: quic.tech]
  -h --help         Show this screen.
";

type ConnMap = HashMap<Vec<u8>, (net::SocketAddr, Box<quiche::Connection>)>;

fn main() {
    let mut buf = [0; 65535];
    let mut out = [0; MAX_DATAGRAM_SIZE];

    env_logger::init();

    let args = docopt::Docopt::new(USAGE)
                      .and_then(|dopt| dopt.parse())
                      .unwrap_or_else(|e| e.exit());

    let socket = net::UdpSocket::bind(args.get_str("--listen")).unwrap();

    let poll = mio::Poll::new().unwrap();
    let mut events = mio::Events::with_capacity(1024);

    let socket = mio::net::UdpSocket::from_socket(socket).unwrap();
    poll.register(&socket, mio::Token(0),
                  mio::Ready::readable(),
                  mio::PollOpt::edge()).unwrap();

    let mut connections = ConnMap::new();

    let mut config = quiche::Config::new(quiche::VERSION_DRAFT17).unwrap();

    config.load_cert_chain_from_pem_file(args.get_str("--cert")).unwrap();
    config.load_priv_key_from_pem_file(args.get_str("--key")).unwrap();

    config.set_application_protos(&[b"h3-17", b"hq-17", b"http/0.9"]).unwrap();

    config.set_idle_timeout(30);
    config.set_max_packet_size(MAX_DATAGRAM_SIZE as u64);
    config.set_initial_max_data(10_000_000);
    config.set_initial_max_stream_data_bidi_local(1_000_000);
    config.set_initial_max_stream_data_bidi_remote(1_000_000);
    config.set_initial_max_streams_bidi(100);
    config.set_initial_max_streams_uni(5);
    config.set_disable_migration(true);

    loop {
        // TODO: use event loop that properly supports timers
        let timeout = connections.values()
                                 .filter_map(|(_, c)| c.timeout())
                                 .min();

        poll.poll(&mut events, timeout).unwrap();

        'read: loop {
            if events.is_empty() {
                debug!("timed out");

                connections.values_mut().for_each(|(_, c)| c.on_timeout());

                break 'read;
            }

            let (len, src) = match socket.recv_from(&mut buf) {
                Ok(v) => v,

                Err(e) => {
                    if e.kind() == std::io::ErrorKind::WouldBlock {
                        debug!("recv() would block");
                        break 'read;
                    }

                    panic!("recv() failed: {:?}", e);
                },
            };

            debug!("got {} bytes", len);

            let pkt_buf = &mut buf[..len];

            let hdr = match quiche::Header::from_slice(pkt_buf, LOCAL_CONN_ID_LEN) {
                Ok(v) => v,

                Err(e) => {
                    error!("Parsing packet header failed: {:?}", e);
                    continue
                }
            };

            trace!("got packet {:?}", hdr);

            if hdr.ty == quiche::Type::VersionNegotiation {
                error!("Version negotiation invalid on the server");
                continue;
            }

            let (_, conn) = if !connections.contains_key(&hdr.dcid) {
                if hdr.ty != quiche::Type::Initial {
                    error!("Packet is not Initial");
                    continue;
                }

                if hdr.version != quiche::VERSION_DRAFT17 {
                    warn!("Doing version negotiation");

                    let len = quiche::negotiate_version(&hdr.scid,
                                                        &hdr.dcid,
                                                        &mut out).unwrap();
                    let out = &out[..len];

                    socket.send_to(out, &src).unwrap();
                    continue;
                }

                let mut scid: [u8; LOCAL_CONN_ID_LEN] = [0; LOCAL_CONN_ID_LEN];
                SystemRandom::new().fill(&mut scid[..]).unwrap();

                // Token is always present in Initial packets.
                let token = hdr.token.as_ref().unwrap();

                if token.is_empty() {
                    warn!("Doing stateless retry");

                    let new_token = mint_token(&hdr, &src);

                    let len = quiche::retry(&hdr.scid, &hdr.dcid, &scid,
                                            &new_token, &mut out).unwrap();
                    let out = &out[..len];

                    socket.send_to(out, &src).unwrap();
                    continue;
                }

                let odcid = validate_token(&src, token);

                if odcid == None {
                    error!("Invalid address validation token");
                    continue;
                }

                debug!("New connection: dcid={} scid={}",
                       hex_dump(&hdr.dcid),
                       hex_dump(&hdr.scid));

                let conn = quiche::accept(&hdr.dcid, odcid, &mut config).unwrap();

                connections.insert(hdr.dcid.to_vec(), (src, conn));

                connections.get_mut(&hdr.dcid).unwrap()
            } else {
                connections.get_mut(&hdr.dcid).unwrap()
            };

            // Process potentially coalesced packets.
            let read = match conn.recv(pkt_buf) {
                Ok(v)  => v,

                Err(quiche::Error::Done) => {
                    debug!("{} done reading", conn.trace_id());
                    break;
                },

                Err(e) => {
                    error!("{} recv failed: {:?}", conn.trace_id(), e);
                    conn.close(false, e.to_wire(), b"fail").unwrap();
                    break 'read;
                },
            };

            debug!("{} processed {} bytes", conn.trace_id(), read);

            let streams: Vec<u64> = conn.readable().collect();
            for s in streams {
                while let Ok((read, fin)) = conn.stream_recv(s, &mut buf) {
                    debug!("{} received {} bytes", conn.trace_id(), read);

                    let stream_buf = &buf[..read];

                    debug!("{} stream {} has {} bytes (fin? {})",
                           conn.trace_id(), s, stream_buf.len(), fin);

                    handle_stream(conn, s, stream_buf, args.get_str("--root"));
                }
            }
        }

        for (peer, conn) in connections.values_mut() {
            loop {
                let write = match conn.send(&mut out) {
                    Ok(v) => v,

                    Err(quiche::Error::Done) => {
                        debug!("{} done writing", conn.trace_id());
                        break;
                    },

                    Err(e) => {
                        error!("{} send failed: {:?}", conn.trace_id(), e);
                        conn.close(false, e.to_wire(), b"fail").unwrap();
                        break;
                    },
                };

                // TODO: coalesce packets.
                socket.send_to(&out[..write], &peer).unwrap();

                debug!("{} written {} bytes", conn.trace_id(), write);
            }
        }

        // Garbage collect closed connections.
        connections.retain(|_, (_, ref mut c)| {
            debug!("Collecting garbage");

            if c.is_closed() {
                info!("{} connection collected {:?}", c.trace_id(), c.stats());
            }

            !c.is_closed()
        });
    }
}

fn handle_stream(conn: &mut quiche::Connection, stream: u64, buf: &[u8], root: &str) {
    if buf.len() > 4 && &buf[..4] == b"GET " {
        let uri = &buf[4..buf.len()];
        let uri = String::from_utf8(uri.to_vec()).unwrap();
        let uri = String::from(uri.lines().next().unwrap());
        let uri = std::path::Path::new(&uri);
        let mut path = std::path::PathBuf::from(root);

        for c in uri.components() {
            if let std::path::Component::Normal(v) = c {
                path.push(v)
            }
        }

        info!("{} got GET request for {:?} on stream {}",
              conn.trace_id(), path, stream);

        let data = std::fs::read(path.as_path())
                    .unwrap_or_else(|_| Vec::from(String::from("Not Found!\r\n")));

        info!("{} sending response of size {} on stream {}",
              conn.trace_id(), data.len(), stream);

        if let Err(e) = conn.stream_send(stream, &data, true) {
            error!("{} stream send failed {:?}", conn.trace_id(), e);
        }
    }
}

fn mint_token(hdr: &quiche::Header, src: &net::SocketAddr) -> Vec<u8> {
    let mut token = Vec::new();

    token.extend_from_slice(b"quiche");

    let addr = match src.ip() {
        std::net::IpAddr::V4(a) => a.octets().to_vec(),
        std::net::IpAddr::V6(a) => a.octets().to_vec(),
    };

    token.extend_from_slice(&addr);
    token.extend_from_slice(&hdr.dcid);

    token
}

fn validate_token<'a>(src: &net::SocketAddr, token: &'a [u8]) -> Option<&'a [u8]> {
    if token.len() < 6 {
        return None;
    }

    if &token[..6] != b"quiche" {
        return None;
    }

    let token = &token[6..];

    let addr = match src.ip() {
        std::net::IpAddr::V4(a) => a.octets().to_vec(),
        std::net::IpAddr::V6(a) => a.octets().to_vec(),
    };

    if token.len() < addr.len() || &token[..addr.len()] != addr.as_slice() {
        return None;
    }

    let token = &token[addr.len()..];

    Some(&token[..])
}

fn hex_dump(buf: &[u8]) -> String {
    let vec: Vec<String> = buf.iter()
                              .map(|b| format!("{:02x}", b))
                              .collect();

    vec.join("")
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]

extern crate civet;
extern crate green;
extern crate rustuv;

use std::io::{IoResult,MemReader,MemWriter};
use std::collections::HashMap;

use civet::{Config,Server,Request,Response};

macro_rules! http_write(
    ($dst:expr, $fmt:expr $($arg:tt)*) => (
        try!(write!($dst, concat!($fmt, "\r\n") $($arg)*))
    )
)

fn main() {
    let _a = Server::start(Config { port: 8888, threads: 50 }, handler);
    wait_for_sigint();
}

// libnative doesn't have signal handling yet
fn wait_for_sigint() {
    use std::io::signal::{Listener, Interrupt};
    use std::rt::task::TaskOpts;
    use green::{SchedPool, PoolConfig};

    let mut config = PoolConfig::new();
    config.event_loop_factory = rustuv::event_loop;

    let mut pool = SchedPool::new(config);
    pool.spawn(TaskOpts::new(), proc() {
        let mut l = Listener::new();
        l.register(Interrupt).unwrap();
        l.rx.recv();
    });
    pool.shutdown();
}

fn handler(req: &mut Request) -> IoResult<Response> {
    let mut res = MemWriter::with_capacity(10000);

    http_write!(res, "");
    http_write!(res, "
Method: {}
", req.method());
    http_write!(res, "
URL: {}
", req.url());
    http_write!(res, "
HTTP: {}
", req.http_version());
    http_write!(res, "
Remote IP: {}
", req.remote_ip());
    http_write!(res, "
Remote Port: {}
", req.remote_port());
    http_write!(res, "
Remote User: {}
", req.remote_user());
    http_write!(res, "
Query String: {}
", req.query_string());
    http_write!(res, "
SSL?: {}
", req.is_ssl());
    http_write!(res, "
Header Count: {}
", req.count_headers());
    http_write!(res, "
User Agent: {}
", req.headers().find("User-Agent"));
    http_write!(res, "
Input: {}
", try!(req.read_to_str()));

    http_write!(res, "
Headers

");

    for (key, value) in req.headers().iter() {
        http_write!(res, "
{} = {}
", key, value);
    }

    http_write!(res, "
");

    let mut headers = HashMap::new();
    headers.insert("Content-Type".to_str(), "text/html".to_str());

    let body = MemReader::new(res.unwrap());

    Ok(Response::new(200, headers, body))
}
<commit_msg>Only spawn one OS thread for green tasks<commit_after>#![feature(macro_rules)]

extern crate civet;
extern crate green;
extern crate rustuv;

use std::io::{IoResult,MemReader,MemWriter};
use std::collections::HashMap;

use civet::{Config,Server,Request,Response};

macro_rules! http_write(
    ($dst:expr, $fmt:expr $($arg:tt)*) => (
        try!(write!($dst, concat!($fmt, "\r\n") $($arg)*))
    )
)

fn main() {
    let _a = Server::start(Config { port: 8888, threads: 50 }, handler);
    wait_for_sigint();
}

// libnative doesn't have signal handling yet
fn wait_for_sigint() {
    use std::io::signal::{Listener, Interrupt};
    use std::rt::task::TaskOpts;
    use green::{SchedPool, PoolConfig};

    let mut config = PoolConfig::new();
    config.event_loop_factory = rustuv::event_loop;
    config.threads = 1;

    let mut pool = SchedPool::new(config);
    pool.spawn(TaskOpts::new(), proc() {
        let mut l = Listener::new();
        l.register(Interrupt).unwrap();
        l.rx.recv();
    });
    pool.shutdown();
}

fn handler(req: &mut Request) -> IoResult<Response> {
    let mut res = MemWriter::with_capacity(10000);

    http_write!(res, "");
    http_write!(res, "
Method: {}
", req.method());
    http_write!(res, "
URL: {}
", req.url());
    http_write!(res, "
HTTP: {}
", req.http_version());
    http_write!(res, "
Remote IP: {}
", req.remote_ip());
    http_write!(res, "
Remote Port: {}
", req.remote_port());
    http_write!(res, "
Remote User: {}
", req.remote_user());
    http_write!(res, "
Query String: {}
", req.query_string());
    http_write!(res, "
SSL?: {}
", req.is_ssl());
    http_write!(res, "
Header Count: {}
", req.count_headers());
    http_write!(res, "
User Agent: {}
", req.headers().find("User-Agent"));
    http_write!(res, "
Input: {}
", try!(req.read_to_str()));

    http_write!(res, "
Headers

");

    for (key, value) in req.headers().iter() {
        http_write!(res, "
{} = {}
", key, value);
    }

    http_write!(res, "
");

    let mut headers = HashMap::new();
    headers.insert("Content-Type".to_str(), "text/html".to_str());

    let body = MemReader::new(res.unwrap());

    Ok(Response::new(200, headers, body))
}
<|endoftext|>


<commit_before>extern crate regex;

fn main() {
	// Execute script from the command line
}

fn parse(code: &str) -> Vec<&str> {
	// code.to_string()

	// let parsedCode = code.replace(" (", "(").replace("( ", "(").replace("(", " ( ").replace()
	parsedCode.as_slice().split(" ").collect()
}

fn format_code(code: &str) -> &str {
	let leftParenRe = regex::Regex::new(r"\s*\(\s*").unwrap();
	let rightParenRe = regex::Regex::new(r"\s*\)\s*").unwrap();
	let partialParsedCode = leftParenRe.replace_all(&code, " ( ");
	(rightParenRe.replace_all(&partialParsedCode," ) ")).as_slice()
}

fn tokenize() {

}

fn read_from_tokens() {

}

#[test]
fn it_works() {
	let input = "(begin (define r 10) (* pi (* r r)))";
	let parsedCode = parse(input);
	println!("{}", parsedCode);
}
<commit_msg>sort of works now<commit_after>extern crate regex;

fn main() {
	println!("!!!!");
	let input = "(begin (define r 10) (* pi (* r r)))";
	let parsed_code = parse(input);
	println!("{}", parsed_code);
	// Execute script from the command line
}

fn parse(code: &str) -> String {
	// code.to_string()
	let left_paren_re = regex::Regex::new(r"\s*\(\s*").unwrap();
	let right_paren_re = regex::Regex::new(r"\s*\)\s*").unwrap();
	let partial_parsed_code = left_paren_re.replace_all(&code, " ( ");
	let parsed_code = right_paren_re.replace_all(&partial_parsed_code," ) ");
	// let parsed_code = code.replace(" (", "(").replace("( ", "(").replace("(", " ( ").replace()
	let final_string : String = parsed_code.split(" ").collect();
	final_string.clone()
}

// fn tokenize() {

// }

// fn read_from_tokens() {

// }

#[test]
<|endoftext|>


<commit_before>mod cpu;

fn main() {
    let cpu = cpu::Core::new(64);
    println!("Hello, CPU at {}", cpu.pc);
}

// cpu state (all registers, flags etc.)
// initialize
//      m68ki_build_opcode_table();
//		m68ki_jump(0);
//		REG_SP = m68ki_read_imm_32();
//		REG_PC = m68ki_read_imm_32();
//		m68ki_jump(REG_PC);

// execute instruction (modifies CPU state)
/*
			/* Record previous program counter */
			REG_PPC = REG_PC;

			/* Read an instruction and call its handler */
			REG_IR = m68ki_read_imm_16();
			// include all 64k entries?
			m68ki_instruction_jump_table[REG_IR]();
			USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
*/

<commit_msg>Output simple CPU state<commit_after>mod cpu;

use std::io::Result;
use std::io::prelude::*;
use std::fs::File;

fn main() {
	let cpu = cpu::Core::new(64);
	println!("Hello, CPU at {}", cpu.pc);
	match write_data(&cpu) {
		Ok(_) => return (),
		Err(e) => panic!(e),
	};
}

fn write_data(core: &cpu::Core) -> Result<()> {
	let mut buffer = try!(File::create("cpustate.txt"));
	try!(write!(buffer, "{:04x} {:04x} {:04x}", core.pc, core.sp, core.status_register()));
	Ok(())
}

// cpu state (all registers, flags etc.)
// initialize
//      m68ki_build_opcode_table();
//		m68ki_jump(0);
//		REG_SP = m68ki_read_imm_32();
//		REG_PC = m68ki_read_imm_32();
//		m68ki_jump(REG_PC);

// execute instruction (modifies CPU state)
/*
			/* Record previous program counter */
			REG_PPC = REG_PC;

			/* Read an instruction and call its handler */
			REG_IR = m68ki_read_imm_16();
			// include all 64k entries?
			m68ki_instruction_jump_table[REG_IR]();
			USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
*/

<|endoftext|>


<commit_before>#![cfg_attr(test, allow(dead_code))]

// TODO revisit these after 1.0.0beta
#![feature(core)]
#![feature(io)]
#![feature(os)]
#![feature(path)]
#![feature(rand)]

extern crate shader_version;
extern crate input;
extern crate event;
extern crate graphics;
extern crate sdl2_window;
extern crate window;
extern crate opengl_graphics;
extern crate quack;

extern crate chip8_vm;

use std::cell::RefCell;
use sdl2_window::Sdl2Window;
use window::WindowSettings;
use opengl_graphics::{
    Gl,
};

use std::os;
use std::old_io::File;
use std::old_io::BufReader;
// use std::time::duration::Duration;
use quack::Set;
// use input::keyboard::Key;
use input::Button;

use chip8_vm::vm::Vm;

const TITLE: &'static str = "Chip8";
const BEEP_TITLE: &'static str = "♬ Chip8 ♬";

const INTRO_ROM: &'static [u8] = include_bytes!("intro/intro.ch8");

fn main() {
    let mut vm = Vm::new();

    let mut rom: Option<File> = None;

    if os::args().len() > 1 {
        if let Ok(f) = File::open(&Path::new(os::args()[1].clone())) {
            rom = Some(f);
        } else {
            println!("Could not open rom {}", os::args()[1]);
        }
    }

    let intro_reader = &mut BufReader::new(INTRO_ROM) as &mut Reader;
    let mut rom_reader = match &mut rom {
        &mut Some(ref mut r) => r as &mut Reader,
        _ => {
            println!("You can provide a path to a chip8 binary to interpret it.");
            intro_reader
        }
    };

    match vm.load_rom(rom_reader) {
        Ok(size) => println!("Loaded rom size: {}", size),
        Err(e) => {
            println!("Error loading rom: {}", e);
            return;
        }
    }

    let (width, height) = (800, 400);
    let opengl = shader_version::OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: TITLE.to_string(),
            size: [width, height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let ref mut gl = Gl::new(opengl);
    let window = RefCell::new(window);

    fn keymap(k: Option<Button>) -> Option<u8> {
        use input::Key::*;
        if let Some(Button::Keyboard(k)) = k {
            return match k {
                D1 => Some(0x1),
                D2 => Some(0x2),
                D3 => Some(0x3),

                Q  => Some(0x4),
                W  => Some(0x5),
                E  => Some(0x6),

                A  => Some(0x7),
                S  => Some(0x8),
                D  => Some(0x9),

                Z  => Some(0xA),
                X  => Some(0x0),
                C  => Some(0xB),

                D4 => Some(0xC),
                R  => Some(0xD),
                F  => Some(0xE),
                V  => Some(0xF),

                _ => None
            }
        }
        return None
    }

    for e in event::events(&window) {
        use event::{ ReleaseEvent, UpdateEvent, PressEvent, RenderEvent };

        if let Some(args) = e.update_args() {
            vm.step(args.dt as f32);
            if vm.beeping() {
                (*window.borrow_mut()).window.set_title(BEEP_TITLE);
            } else {
                (*window.borrow_mut()).window.set_title(TITLE);
            }
        }
        if let Some(args) = e.render_args() {
            use graphics::*;
            gl.draw([0, 0, args.width as i32, args.height as i32], |&mut: c, gl| {
                graphics::clear([0.0, 0.0, 0.0, 1.0], gl);
                let r = Rectangle::new([1.0, 1.0, 1.0, 1.0]);
                let off = Color([0.0, 0.0, 0.0, 1.0]);
                let on = Color([1.0, 1.0, 1.0, 1.0]);

                let w = args.width as f64 / 64.0;
                let h = args.height as f64 / 32.0;

                for (y,row) in vm.screen_rows().enumerate() {
                    for (x,byte) in row.iter().enumerate() {
                        let x = x as f64 * w;
                        let y = y as f64 * h;
                        r.set(match *byte { 0 => off, _ => on })
                        .draw([x, y, w, h], &c, gl);
                    }
                }
            });
        }
        if let Some(keynum) = keymap(e.press_args()) {
            vm.set_key(keynum);
        }
        if let Some(keynum) = keymap(e.release_args()) {
            vm.unset_key(keynum);
        }
    }
}
<commit_msg>Remove `rand` feature gate, it was required for `chip8_vm`<commit_after>#![cfg_attr(test, allow(dead_code))]

// TODO revisit these after 1.0.0beta
#![feature(core)]
#![feature(io)]
#![feature(os)]
#![feature(path)]

extern crate shader_version;
extern crate input;
extern crate event;
extern crate graphics;
extern crate sdl2_window;
extern crate window;
extern crate opengl_graphics;
extern crate quack;

extern crate chip8_vm;

use std::cell::RefCell;
use sdl2_window::Sdl2Window;
use window::WindowSettings;
use opengl_graphics::{
    Gl,
};

use std::os;
use std::old_io::File;
use std::old_io::BufReader;
// use std::time::duration::Duration;
use quack::Set;
// use input::keyboard::Key;
use input::Button;

use chip8_vm::vm::Vm;

const TITLE: &'static str = "Chip8";
const BEEP_TITLE: &'static str = "♬ Chip8 ♬";

const INTRO_ROM: &'static [u8] = include_bytes!("intro/intro.ch8");

fn main() {
    let mut vm = Vm::new();

    let mut rom: Option<File> = None;

    if os::args().len() > 1 {
        if let Ok(f) = File::open(&Path::new(os::args()[1].clone())) {
            rom = Some(f);
        } else {
            println!("Could not open rom {}", os::args()[1]);
        }
    }

    let intro_reader = &mut BufReader::new(INTRO_ROM) as &mut Reader;
    let mut rom_reader = match &mut rom {
        &mut Some(ref mut r) => r as &mut Reader,
        _ => {
            println!("You can provide a path to a chip8 binary to interpret it.");
            intro_reader
        }
    };

    match vm.load_rom(rom_reader) {
        Ok(size) => println!("Loaded rom size: {}", size),
        Err(e) => {
            println!("Error loading rom: {}", e);
            return;
        }
    }

    let (width, height) = (800, 400);
    let opengl = shader_version::OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: TITLE.to_string(),
            size: [width, height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let ref mut gl = Gl::new(opengl);
    let window = RefCell::new(window);

    fn keymap(k: Option<Button>) -> Option<u8> {
        use input::Key::*;
        if let Some(Button::Keyboard(k)) = k {
            return match k {
                D1 => Some(0x1),
                D2 => Some(0x2),
                D3 => Some(0x3),

                Q  => Some(0x4),
                W  => Some(0x5),
                E  => Some(0x6),

                A  => Some(0x7),
                S  => Some(0x8),
                D  => Some(0x9),

                Z  => Some(0xA),
                X  => Some(0x0),
                C  => Some(0xB),

                D4 => Some(0xC),
                R  => Some(0xD),
                F  => Some(0xE),
                V  => Some(0xF),

                _ => None
            }
        }
        return None
    }

    for e in event::events(&window) {
        use event::{ ReleaseEvent, UpdateEvent, PressEvent, RenderEvent };

        if let Some(args) = e.update_args() {
            vm.step(args.dt as f32);
            if vm.beeping() {
                (*window.borrow_mut()).window.set_title(BEEP_TITLE);
            } else {
                (*window.borrow_mut()).window.set_title(TITLE);
            }
        }
        if let Some(args) = e.render_args() {
            use graphics::*;
            gl.draw([0, 0, args.width as i32, args.height as i32], |&mut: c, gl| {
                graphics::clear([0.0, 0.0, 0.0, 1.0], gl);
                let r = Rectangle::new([1.0, 1.0, 1.0, 1.0]);
                let off = Color([0.0, 0.0, 0.0, 1.0]);
                let on = Color([1.0, 1.0, 1.0, 1.0]);

                let w = args.width as f64 / 64.0;
                let h = args.height as f64 / 32.0;

                for (y,row) in vm.screen_rows().enumerate() {
                    for (x,byte) in row.iter().enumerate() {
                        let x = x as f64 * w;
                        let y = y as f64 * h;
                        r.set(match *byte { 0 => off, _ => on })
                        .draw([x, y, w, h], &c, gl);
                    }
                }
            });
        }
        if let Some(keynum) = keymap(e.press_args()) {
            vm.set_key(keynum);
        }
        if let Some(keynum) = keymap(e.release_args()) {
            vm.unset_key(keynum);
        }
    }
}
<|endoftext|>


<commit_before>#![feature(plugin, proc_macro)]
#![plugin(maud_macros)]

extern crate iron;
extern crate maud;
extern crate persistent;
extern crate pulldown_cmark;
#[macro_use]
extern crate router;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate urlencoded;

use iron::modifiers::Redirect;
use iron::prelude::*;
use iron::status;
use iron::typemap::Key;
use router::Router;
use persistent::State;
use std::sync::{Arc, RwLock};
use urlencoded::UrlEncodedQuery;

mod user;
mod views;

use user::Users;

#[derive(Copy, Clone)]
struct UsersKey;
impl Key for UsersKey { type Value = Users; }

fn main() {
    let mut router = Router::new();
    router.get("/", home, "home");
    router.get("/user/:id", user, "user");
    router.get("/search", search, "search");
    router.get("*", not_found, "not_found");

    fn home(r: &mut Request) -> IronResult<Response> {
        let body = views::home(r);
        Ok(Response::with((status::Ok, body)))
    }

    fn user(r: &mut Request) -> IronResult<Response> {
        let route = r.extensions.get::<Router>().unwrap();
        let id = route.find("id").unwrap();
        let users = r.extensions.get::<State<UsersKey>>().unwrap();
        match users.read().unwrap().get(id) {
            Some(user) => {
                let body = views::user(r, id, &user);
                Ok(Response::with((status::Ok, body)))
            }
            None => {
                let body = views::user_not_found(r, id);
                Ok(Response::with((status::NotFound, body)))
            },
        }
    }

    fn search(r: &mut Request) -> IronResult<Response> {
        let id: Option<String> = r.get_ref::<UrlEncodedQuery>().ok()
            .and_then(|query| query.get("q"))
            .and_then(|q| q.first().cloned());
        if let Some(id) = id {
            let users = r.extensions.get::<State<UsersKey>>().unwrap();
            let users = users.read().unwrap();
            if users.get(&id).is_some() {
                let url = url_for!(r, "user", "id" => id);
                Ok(Response::with((status::Found, Redirect(url))))
            } else {
                let body = views::user_not_found(r, &id);
                Ok(Response::with((status::NotFound, body)))
            }
        } else {
            not_found(r)
        }
    }

    fn not_found(r: &mut Request) -> IronResult<Response> {
        let body = views::not_found(r);
        Ok(Response::with((status::NotFound, body)))
    }

    let mut chain = Chain::new(router);
    chain.link({
        let users = Users::load("rustaceans.org/data").unwrap();
        let state = State::<UsersKey>::from(Arc::new(RwLock::new(users)));
        (state.clone(), state)
    });

    println!("Starting on port 8344...");
    Iron::new(chain).http("0.0.0.0:8344").unwrap();
}
<commit_msg>Bind to localhost instead of 0.0.0.0<commit_after>#![feature(plugin, proc_macro)]
#![plugin(maud_macros)]

extern crate iron;
extern crate maud;
extern crate persistent;
extern crate pulldown_cmark;
#[macro_use]
extern crate router;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate urlencoded;

use iron::modifiers::Redirect;
use iron::prelude::*;
use iron::status;
use iron::typemap::Key;
use router::Router;
use persistent::State;
use std::sync::{Arc, RwLock};
use urlencoded::UrlEncodedQuery;

mod user;
mod views;

use user::Users;

#[derive(Copy, Clone)]
struct UsersKey;
impl Key for UsersKey { type Value = Users; }

fn main() {
    let mut router = Router::new();
    router.get("/", home, "home");
    router.get("/user/:id", user, "user");
    router.get("/search", search, "search");
    router.get("*", not_found, "not_found");

    fn home(r: &mut Request) -> IronResult<Response> {
        let body = views::home(r);
        Ok(Response::with((status::Ok, body)))
    }

    fn user(r: &mut Request) -> IronResult<Response> {
        let route = r.extensions.get::<Router>().unwrap();
        let id = route.find("id").unwrap();
        let users = r.extensions.get::<State<UsersKey>>().unwrap();
        match users.read().unwrap().get(id) {
            Some(user) => {
                let body = views::user(r, id, &user);
                Ok(Response::with((status::Ok, body)))
            }
            None => {
                let body = views::user_not_found(r, id);
                Ok(Response::with((status::NotFound, body)))
            },
        }
    }

    fn search(r: &mut Request) -> IronResult<Response> {
        let id: Option<String> = r.get_ref::<UrlEncodedQuery>().ok()
            .and_then(|query| query.get("q"))
            .and_then(|q| q.first().cloned());
        if let Some(id) = id {
            let users = r.extensions.get::<State<UsersKey>>().unwrap();
            let users = users.read().unwrap();
            if users.get(&id).is_some() {
                let url = url_for!(r, "user", "id" => id);
                Ok(Response::with((status::Found, Redirect(url))))
            } else {
                let body = views::user_not_found(r, &id);
                Ok(Response::with((status::NotFound, body)))
            }
        } else {
            not_found(r)
        }
    }

    fn not_found(r: &mut Request) -> IronResult<Response> {
        let body = views::not_found(r);
        Ok(Response::with((status::NotFound, body)))
    }

    let mut chain = Chain::new(router);
    chain.link({
        let users = Users::load("rustaceans.org/data").unwrap();
        let state = State::<UsersKey>::from(Arc::new(RwLock::new(users)));
        (state.clone(), state)
    });

    println!("Starting on localhost:8344...");
    Iron::new(chain).http("localhost:8344").unwrap();
}
<|endoftext|>


<commit_before>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]

#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
use rustc::session::{config, Session};
use rustc::session::config::{Input, ErrorOutputType};
use std::path::PathBuf;
use std::process::Command;
use syntax::ast;

use clippy_lints::utils::cargo;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        ClippyCompilerCalls {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(&mut self,
                      matches: &getopts::Matches,
                      sopts: &config::Options,
                      cfg: &ast::CrateConfig,
                      descriptions: &rustc_errors::registry::Registry,
                      output: ErrorOutputType)
                      -> Compilation {
        self.default.early_callback(matches, sopts, cfg, descriptions, output)
    }
    fn no_input(&mut self,
                matches: &getopts::Matches,
                sopts: &config::Options,
                cfg: &ast::CrateConfig,
                odir: &Option<PathBuf>,
                ofile: &Option<PathBuf>,
                descriptions: &rustc_errors::registry::Registry)
                -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(matches, sopts, cfg, odir, ofile, descriptions)
    }
    fn late_callback(&mut self,
                     matches: &getopts::Matches,
                     sess: &Session,
                     cfg: &ast::CrateConfig,
                     input: &Input,
                     odir: &Option<PathBuf>,
                     ofile: &Option<PathBuf>)
                     -> Compilation {
        self.default.late_callback(matches, sess, cfg, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(state.session, state.krate.as_ref().expect("at this compilation stage the krate must be parsed"));
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry { early_lint_passes,
                                                           late_lint_passes,
                                                           lint_groups,
                                                           llvm_passes,
                                                           attributes,
                                                           mir_passes,
                                                           .. } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.mir_passes.borrow_mut().extend(mir_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

use std::path::Path;

pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    let dep_path = env::current_dir().expect("current dir is not readable").join("target").join("debug").join("deps");

    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
    let sys_root = if let (Some(home), Some(toolchain)) = (home, toolchain) {
        format!("{}/toolchains/{}", home, toolchain)
    } else {
        option_env!("SYSROOT")
            .map(|s| s.to_owned())
            .or(Command::new("rustc")
                .arg("--print")
                .arg("sysroot")
                .output()
                .ok()
                .and_then(|out| String::from_utf8(out.stdout).ok())
                .map(|s| s.trim().to_owned()))
            .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust")
    };

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        // this arm is executed on the initial call to `cargo clippy`
        let manifest_path = std::env::args().skip(2).find(|val| val.starts_with("--manifest-path="));
        let mut metadata = cargo::metadata(manifest_path).expect("could not obtain cargo metadata");
        assert_eq!(metadata.version, 1);
        for target in metadata.packages.remove(0).targets {
            let args = std::env::args().skip(2);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                } else if first == "bin" {
                    if let Err(code) = process(vec!["--bin".to_owned(), target.name].into_iter().chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    } else {
        // this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC` env var set to itself

        // this conditional check for the --sysroot flag is there so users can call `cargo-clippy` directly
        // without having to pass --sysroot or anything
        let args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
            env::args().collect()
        } else {
            env::args().chain(Some("--sysroot".to_owned())).chain(Some(sys_root)).collect()
        };
        // this check ensures that dependencies are built but not linted and the final crate is
        // linted but not built
        let mut ccc = ClippyCompilerCalls::new(env::args().any(|s| s == "-Zno-trans"));
        let (result, _) = rustc_driver::run_compiler(&args, &mut ccc);

        if let Err(err_count) = result {
            if err_count > 0 {
                std::process::exit(1);
            }
        }
    }
}

fn process<P, I>(old_args: I, dep_path: P, sysroot: &str) -> Result<(), i32>
    where P: AsRef<Path>,
          I: Iterator<Item = String>
{

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("-L".to_owned());
    args.push(dep_path.as_ref().to_string_lossy().into_owned());
    args.push(String::from("--sysroot"));
    args.push(sysroot.to_owned());
    args.push("-Zno-trans".to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn().expect("could not run cargo")
        .wait().expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<commit_msg>Rustup to *rustc 1.13.0-nightly (cbe4de78e 2016-09-05)*<commit_after>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]

#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
use rustc::session::{config, Session};
use rustc::session::config::{Input, ErrorOutputType};
use std::path::PathBuf;
use std::process::Command;
use syntax::ast;

use clippy_lints::utils::cargo;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        ClippyCompilerCalls {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(&mut self,
                      matches: &getopts::Matches,
                      sopts: &config::Options,
                      cfg: &ast::CrateConfig,
                      descriptions: &rustc_errors::registry::Registry,
                      output: ErrorOutputType)
                      -> Compilation {
        self.default.early_callback(matches, sopts, cfg, descriptions, output)
    }
    fn no_input(&mut self,
                matches: &getopts::Matches,
                sopts: &config::Options,
                cfg: &ast::CrateConfig,
                odir: &Option<PathBuf>,
                ofile: &Option<PathBuf>,
                descriptions: &rustc_errors::registry::Registry)
                -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(matches, sopts, cfg, odir, ofile, descriptions)
    }
    fn late_callback(&mut self,
                     matches: &getopts::Matches,
                     sess: &Session,
                     cfg: &ast::CrateConfig,
                     input: &Input,
                     odir: &Option<PathBuf>,
                     ofile: &Option<PathBuf>)
                     -> Compilation {
        self.default.late_callback(matches, sess, cfg, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(state.session, state.krate.as_ref().expect("at this compilation stage the krate must be parsed").span);
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry { early_lint_passes,
                                                           late_lint_passes,
                                                           lint_groups,
                                                           llvm_passes,
                                                           attributes,
                                                           mir_passes,
                                                           .. } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.mir_passes.borrow_mut().extend(mir_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

use std::path::Path;

pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    let dep_path = env::current_dir().expect("current dir is not readable").join("target").join("debug").join("deps");

    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
    let sys_root = if let (Some(home), Some(toolchain)) = (home, toolchain) {
        format!("{}/toolchains/{}", home, toolchain)
    } else {
        option_env!("SYSROOT")
            .map(|s| s.to_owned())
            .or(Command::new("rustc")
                .arg("--print")
                .arg("sysroot")
                .output()
                .ok()
                .and_then(|out| String::from_utf8(out.stdout).ok())
                .map(|s| s.trim().to_owned()))
            .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust")
    };

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        // this arm is executed on the initial call to `cargo clippy`
        let manifest_path = std::env::args().skip(2).find(|val| val.starts_with("--manifest-path="));
        let mut metadata = cargo::metadata(manifest_path).expect("could not obtain cargo metadata");
        assert_eq!(metadata.version, 1);
        for target in metadata.packages.remove(0).targets {
            let args = std::env::args().skip(2);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                } else if first == "bin" {
                    if let Err(code) = process(vec!["--bin".to_owned(), target.name].into_iter().chain(args), &dep_path, &sys_root) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    } else {
        // this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC` env var set to itself

        // this conditional check for the --sysroot flag is there so users can call `cargo-clippy` directly
        // without having to pass --sysroot or anything
        let args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
            env::args().collect()
        } else {
            env::args().chain(Some("--sysroot".to_owned())).chain(Some(sys_root)).collect()
        };
        // this check ensures that dependencies are built but not linted and the final crate is
        // linted but not built
        let mut ccc = ClippyCompilerCalls::new(env::args().any(|s| s == "-Zno-trans"));
        let (result, _) = rustc_driver::run_compiler(&args, &mut ccc);

        if let Err(err_count) = result {
            if err_count > 0 {
                std::process::exit(1);
            }
        }
    }
}

fn process<P, I>(old_args: I, dep_path: P, sysroot: &str) -> Result<(), i32>
    where P: AsRef<Path>,
          I: Iterator<Item = String>
{

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("-L".to_owned());
    args.push(dep_path.as_ref().to_string_lossy().into_owned());
    args.push(String::from("--sysroot"));
    args.push(sysroot.to_owned());
    args.push("-Zno-trans".to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn().expect("could not run cargo")
        .wait().expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<|endoftext|>


<commit_before>extern crate glutin_window;
extern crate graphics;
extern crate itertools;
extern crate opengl_graphics;
extern crate piston;
extern crate rand;

mod drawing;
mod game;
mod models;
mod traits;

use glutin_window::GlutinWindow;
use opengl_graphics::{GlGraphics, OpenGL};
use piston::event::{Event, Events, EventLoop, RenderEvent};
use piston::input::{Button, Input};
use piston::window::WindowSettings;

use drawing::Size;
use game::Game;

fn main() {
    // Initialization stuff
    let opengl = OpenGL::_3_2;

    let window: GlutinWindow =
        WindowSettings::new("Rocket", [1024, 600])
            .exit_on_esc(true)
            .opengl(opengl)
            .samples(8)
            .into();

    let mut gl = GlGraphics::new(opengl);

    // The game object
    let mut game = Game::new(Size::new(1024.0, 600.0));

    // Event handling
    for e in window.events().ups(60).max_fps(60) {
        match e {
            Event::Input(Input::Press(Button::Keyboard(key))) => {
                game.key_press(key);
            }

            Event::Input(Input::Release(Button::Keyboard(key))) => {
                game.key_release(key);
            }

            Event::Render(args) => {
                gl.draw(args.viewport(), |c, g| game.render(c, g));
            }

            Event::Update(args) => {
                game.update(args.dt);
            }

            _ => {}
        }
    }
}
<commit_msg>Changed OpenGL version to 2.1 to support older hardware<commit_after>extern crate glutin_window;
extern crate graphics;
extern crate itertools;
extern crate opengl_graphics;
extern crate piston;
extern crate rand;

mod drawing;
mod game;
mod models;
mod traits;

use glutin_window::GlutinWindow;
use opengl_graphics::{GlGraphics, OpenGL};
use piston::event::{Event, Events, EventLoop, RenderEvent};
use piston::input::{Button, Input};
use piston::window::WindowSettings;

use drawing::Size;
use game::Game;

fn main() {
    // Initialization stuff
    let opengl = OpenGL::_2_1;

    let window: GlutinWindow =
        WindowSettings::new("Rocket", [1024, 600])
            .exit_on_esc(true)
            .opengl(opengl)
            .samples(8)
            .into();

    let mut gl = GlGraphics::new(opengl);

    // The game object
    let mut game = Game::new(Size::new(1024.0, 600.0));

    // Event handling
    for e in window.events().ups(60).max_fps(60) {
        match e {
            Event::Input(Input::Press(Button::Keyboard(key))) => {
                game.key_press(key);
            }

            Event::Input(Input::Release(Button::Keyboard(key))) => {
                game.key_release(key);
            }

            Event::Render(args) => {
                gl.draw(args.viewport(), |c, g| game.render(c, g));
            }

            Event::Update(args) => {
                game.update(args.dt);
            }

            _ => {}
        }
    }
}
<|endoftext|>


<commit_before>extern crate hyper;

use std::io::Write;

use hyper::Server;
use hyper::server::Request;
use hyper::server::Response;
use hyper::net::Fresh;

fn hello(_: Request, res: Response<Fresh>) {
   let mut res = res.start().unwrap();
   res.write_all(b"Hello World!").unwrap();
   res.end().unwrap();
}

fn main() {
   Server::http(hello).listen("127.0.0.1:3000").unwrap();
}
<commit_msg>Checking out HTTPS.<commit_after>extern crate hyper;

use std::io::Write;
use std::path::Path;

use hyper::Server;
use hyper::server::Request;
use hyper::server::Response;
use hyper::net::Fresh;

fn hello(_: Request, res: Response<Fresh>) {
   let mut res = res.start().unwrap();
   res.write_all(b"Hello World!").unwrap();
   res.end().unwrap();
}

fn main() {
   let server = Server::https(
      hello,
      Path::new("/opt/ssl/site.crt"),
      Path::new("/opt/ssl/site.key"),
   ).listen("0.0.0.0:443").unwrap();
}
<|endoftext|>