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

// This test case tests the incremental compilation hash (ICH) implementation
// for function interfaces.

// The general pattern followed here is: Change one thing between rev1 and rev2
// and make sure that the hash has changed, then change nothing between rev2 and
// rev3 and make sure that the hash has not changed.

// must-compile-successfully
// revisions: cfail1 cfail2 cfail3
// compile-flags: -Z query-dep-graph

#![allow(warnings)]
#![feature(conservative_impl_trait)]
#![feature(intrinsics)]
#![feature(linkage)]
#![feature(rustc_attrs)]
#![crate_type="rlib"]

// Add Parameter ---------------------------------------------------------------

#[cfg(cfail1)]
fn add_parameter() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn add_parameter(p: i32) {}

// Add Return Type -------------------------------------------------------------

#[cfg(cfail1)]
fn add_return_type() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn add_return_type() -> () {}

// Change Parameter Type -------------------------------------------------------

#[cfg(cfail1)]
fn type_of_parameter(p: i32) {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn type_of_parameter(p: i64) {}

// Change Parameter Type Reference ---------------------------------------------

#[cfg(cfail1)]
fn type_of_parameter_ref(p: &i32) {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn type_of_parameter_ref(p: &mut i32) {}

// Change Parameter Order ------------------------------------------------------

#[cfg(cfail1)]
fn order_of_parameters(p1: i32, p2: i64) {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn order_of_parameters(p2: i64, p1: i32) {}

// Unsafe ----------------------------------------------------------------------

#[cfg(cfail1)]
fn make_unsafe() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
unsafe fn make_unsafe() {}

// Extern ----------------------------------------------------------------------

#[cfg(cfail1)]
fn make_extern() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
extern fn make_extern() {}

// Extern C Extern Rust-Intrinsic ----------------------------------------------

#[cfg(cfail1)]
extern "C" fn make_intrinsic() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
extern "rust-intrinsic" fn make_intrinsic() {}

// Type Parameter --------------------------------------------------------------

#[cfg(cfail1)]
fn type_parameter() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn type_parameter<T>() {}

// Lifetime Parameter ----------------------------------------------------------

#[cfg(cfail1)]
fn lifetime_parameter() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn lifetime_parameter<'a>() {}

// Trait Bound -----------------------------------------------------------------

#[cfg(cfail1)]
fn trait_bound<T>() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn trait_bound<T: Eq>() {}

// Builtin Bound ---------------------------------------------------------------

#[cfg(cfail1)]
fn builtin_bound<T>() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn builtin_bound<T: Send>() {}

// Lifetime Bound --------------------------------------------------------------

#[cfg(cfail1)]
fn lifetime_bound<'a, T>() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn lifetime_bound<'a, T: 'a>() {}

// Second Trait Bound ----------------------------------------------------------

#[cfg(cfail1)]
fn second_trait_bound<T: Eq>() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn second_trait_bound<T: Eq + Clone>() {}

// Second Builtin Bound --------------------------------------------------------

#[cfg(cfail1)]
fn second_builtin_bound<T: Send>() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn second_builtin_bound<T: Send + Sized>() {}

// Second Lifetime Bound -------------------------------------------------------

#[cfg(cfail1)]
fn second_lifetime_bound<'a, 'b, T: 'a>() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn second_lifetime_bound<'a, 'b, T: 'a + 'b>() {}

// Inline ----------------------------------------------------------------------

#[cfg(cfail1)]
fn inline() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[inline]
fn inline() {}

// Inline Never ----------------------------------------------------------------

#[cfg(cfail1)]
#[inline(always)]
fn inline_never() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[inline(never)]
fn inline_never() {}

// No Mangle -------------------------------------------------------------------

#[cfg(cfail1)]
fn no_mangle() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[no_mangle]
fn no_mangle() {}

// Linkage ---------------------------------------------------------------------

#[cfg(cfail1)]
fn linkage() {}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[linkage="weak_odr"]
fn linkage() {}

// Return Impl Trait -----------------------------------------------------------

#[cfg(cfail1)]
fn return_impl_trait() -> i32 {
    0
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn return_impl_trait() -> impl Clone {
    0
}

// Change Return Impl Trait ----------------------------------------------------

#[cfg(cfail1)]
fn change_return_impl_trait() -> impl Clone {
    0u32
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
fn change_return_impl_trait() -> impl Copy {
    0u32
}

// Change Return Type Indirectly -----------------------------------------------

struct ReferencedType1;
struct ReferencedType2;

mod change_return_type_indirectly {
    #[cfg(cfail1)]
    use super::ReferencedType1 as ReturnType;
    #[cfg(not(cfail1))]
    use super::ReferencedType2 as ReturnType;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    fn indirect_return_type() -> ReturnType {
        ReturnType {}
    }
}

// Change Parameter Type Indirectly --------------------------------------------

mod change_parameter_type_indirectly {
    #[cfg(cfail1)]
    use super::ReferencedType1 as ParameterType;
    #[cfg(not(cfail1))]
    use super::ReferencedType2 as ParameterType;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    fn indirect_parameter_type(p: ParameterType) {}
}

// Change Trait Bound Indirectly -----------------------------------------------

trait ReferencedTrait1 {}
trait ReferencedTrait2 {}

mod change_trait_bound_indirectly {
    #[cfg(cfail1)]
    use super::ReferencedTrait1 as Trait;
    #[cfg(not(cfail1))]
    use super::ReferencedTrait2 as Trait;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    fn indirect_trait_bound<T: Trait>(p: T) {}
}

// Change Trait Bound Indirectly In Where Clause -------------------------------

mod change_trait_bound_indirectly_in_where_clause {
    #[cfg(cfail1)]
    use super::ReferencedTrait1 as Trait;
    #[cfg(not(cfail1))]
    use super::ReferencedTrait2 as Trait;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    fn indirect_trait_bound_where<T>(p: T) where T: Trait {}
}
<commit_msg>Update function interface fingerprint hash tests<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// This test case tests the incremental compilation hash (ICH) implementation
// for function interfaces.

// The general pattern followed here is: Change one thing between rev1 and rev2
// and make sure that the hash has changed, then change nothing between rev2 and
// rev3 and make sure that the hash has not changed.

// must-compile-successfully
// revisions: cfail1 cfail2 cfail3
// compile-flags: -Z query-dep-graph

#![allow(warnings)]
#![feature(conservative_impl_trait)]
#![feature(intrinsics)]
#![feature(linkage)]
#![feature(rustc_attrs)]
#![crate_type="rlib"]

// Add Parameter ---------------------------------------------------------------

#[cfg(cfail1)]
pub fn add_parameter() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")]
#[rustc_clean(cfg="cfail3")]
pub fn add_parameter(p: i32) {}

// Add Return Type -------------------------------------------------------------

#[cfg(cfail1)]
pub fn add_return_type() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody")]
#[rustc_clean(cfg="cfail3")]
pub fn add_return_type() -> () {}

// Change Parameter Type -------------------------------------------------------

#[cfg(cfail1)]
pub fn type_of_parameter(p: i32) {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")]
#[rustc_clean(cfg="cfail3")]
pub fn type_of_parameter(p: i64) {}

// Change Parameter Type Reference ---------------------------------------------

#[cfg(cfail1)]
pub fn type_of_parameter_ref(p: &i32) {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")]
#[rustc_clean(cfg="cfail3")]
pub fn type_of_parameter_ref(p: &mut i32) {}

// Change Parameter Order ------------------------------------------------------

#[cfg(cfail1)]
pub fn order_of_parameters(p1: i32, p2: i64) {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")]
#[rustc_clean(cfg="cfail3")]
pub fn order_of_parameters(p2: i64, p1: i32) {}

// Unsafe ----------------------------------------------------------------------

#[cfg(cfail1)]
pub fn make_unsafe() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")]
#[rustc_clean(cfg="cfail3")]
pub unsafe fn make_unsafe() {}

// Extern ----------------------------------------------------------------------

#[cfg(cfail1)]
pub fn make_extern() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, TypeckTables, FnSignature")]
#[rustc_clean(cfg="cfail3")]
pub extern fn make_extern() {}

// Extern C Extern Rust-Intrinsic ----------------------------------------------

#[cfg(cfail1)]
pub extern "C" fn make_intrinsic() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, TypeckTables, FnSignature")]
#[rustc_clean(cfg="cfail3")]
pub extern "rust-intrinsic" fn make_intrinsic() {}

// Type Parameter --------------------------------------------------------------

#[cfg(cfail1)]
pub fn type_parameter() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, GenericsOfItem, TypeOfItem, PredicatesOfItem")]
#[rustc_clean(cfg="cfail3")]
pub fn type_parameter<T>() {}

// Lifetime Parameter ----------------------------------------------------------

#[cfg(cfail1)]
pub fn lifetime_parameter() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, GenericsOfItem")]
#[rustc_clean(cfg="cfail3")]
pub fn lifetime_parameter<'a>() {}

// Trait Bound -----------------------------------------------------------------

#[cfg(cfail1)]
pub fn trait_bound<T>() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, PredicatesOfItem")]
#[rustc_clean(cfg="cfail3")]
pub fn trait_bound<T: Eq>() {}

// Builtin Bound ---------------------------------------------------------------

#[cfg(cfail1)]
pub fn builtin_bound<T>() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, PredicatesOfItem")]
#[rustc_clean(cfg="cfail3")]
pub fn builtin_bound<T: Send>() {}

// Lifetime Bound --------------------------------------------------------------

#[cfg(cfail1)]
pub fn lifetime_bound<'a, T>() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, GenericsOfItem, TypeOfItem, PredicatesOfItem")]
#[rustc_clean(cfg="cfail3")]
pub fn lifetime_bound<'a, T: 'a>() {}

// Second Trait Bound ----------------------------------------------------------

#[cfg(cfail1)]
pub fn second_trait_bound<T: Eq>() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, PredicatesOfItem")]
#[rustc_clean(cfg="cfail3")]
pub fn second_trait_bound<T: Eq + Clone>() {}

// Second Builtin Bound --------------------------------------------------------

#[cfg(cfail1)]
pub fn second_builtin_bound<T: Send>() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, PredicatesOfItem")]
#[rustc_clean(cfg="cfail3")]
pub fn second_builtin_bound<T: Send + Sized>() {}

// Second Lifetime Bound -------------------------------------------------------

#[cfg(cfail1)]
pub fn second_lifetime_bound<'a, 'b, T: 'a>() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, GenericsOfItem, TypeOfItem, PredicatesOfItem")]
#[rustc_clean(cfg="cfail3")]
pub fn second_lifetime_bound<'a, 'b, T: 'a + 'b>() {}

// Inline ----------------------------------------------------------------------

#[cfg(cfail1)]
pub fn inline() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody")]
#[rustc_clean(cfg="cfail3")]
#[inline]
pub fn inline() {}

// Inline Never ----------------------------------------------------------------

#[cfg(cfail1)]
#[inline(always)]
pub fn inline_never() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody")]
#[rustc_clean(cfg="cfail3")]
#[inline(never)]
pub fn inline_never() {}

// No Mangle -------------------------------------------------------------------

#[cfg(cfail1)]
pub fn no_mangle() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody")]
#[rustc_clean(cfg="cfail3")]
#[no_mangle]
pub fn no_mangle() {}

// Linkage ---------------------------------------------------------------------

#[cfg(cfail1)]
pub fn linkage() {}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody")]
#[rustc_clean(cfg="cfail3")]
#[linkage="weak_odr"]
pub fn linkage() {}

// Return Impl Trait -----------------------------------------------------------

#[cfg(cfail1)]
pub fn return_impl_trait() -> i32 {
    0
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody, TypeckTables, FnSignature")]
#[rustc_clean(cfg="cfail3")]
pub fn return_impl_trait() -> impl Clone {
    0
}

// Change Return Impl Trait ----------------------------------------------------

#[cfg(cfail1)]
pub fn change_return_impl_trait() -> impl Clone {
    0u32
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="Hir, HirBody")]
#[rustc_clean(cfg="cfail3")]
pub fn change_return_impl_trait() -> impl Copy {
    0u32
}

// Change Return Type Indirectly -----------------------------------------------

pub struct ReferencedType1;
pub struct ReferencedType2;

pub mod change_return_type_indirectly {
    #[cfg(cfail1)]
    use super::ReferencedType1 as ReturnType;
    #[cfg(not(cfail1))]
    use super::ReferencedType2 as ReturnType;

    #[rustc_clean(cfg="cfail2", except="Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")]
    #[rustc_clean(cfg="cfail3")]
    pub fn indirect_return_type() -> ReturnType {
        ReturnType {}
    }
}

// Change Parameter Type Indirectly --------------------------------------------

pub mod change_parameter_type_indirectly {
    #[cfg(cfail1)]
    use super::ReferencedType1 as ParameterType;
    #[cfg(not(cfail1))]
    use super::ReferencedType2 as ParameterType;

    #[rustc_clean(cfg="cfail2", except="Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")]
    #[rustc_clean(cfg="cfail3")]
    pub fn indirect_parameter_type(p: ParameterType) {}
}

// Change Trait Bound Indirectly -----------------------------------------------

pub trait ReferencedTrait1 {}
pub trait ReferencedTrait2 {}

pub mod change_trait_bound_indirectly {
    #[cfg(cfail1)]
    use super::ReferencedTrait1 as Trait;
    #[cfg(not(cfail1))]
    use super::ReferencedTrait2 as Trait;

    #[rustc_clean(cfg="cfail2", except="Hir, HirBody, PredicatesOfItem")]
    #[rustc_clean(cfg="cfail3")]
    pub fn indirect_trait_bound<T: Trait>(p: T) {}
}

// Change Trait Bound Indirectly In Where Clause -------------------------------

pub mod change_trait_bound_indirectly_in_where_clause {
    #[cfg(cfail1)]
    use super::ReferencedTrait1 as Trait;
    #[cfg(not(cfail1))]
    use super::ReferencedTrait2 as Trait;

    #[rustc_clean(cfg="cfail2", except="Hir, HirBody, PredicatesOfItem")]
    #[rustc_clean(cfg="cfail3")]
    pub fn indirect_trait_bound_where<T>(p: T) where T: Trait {}
}
<|endoftext|>


<commit_before>use ansi_term::{ANSIString, Colour, Style};
use config::Config;

/// Merges in the default values for the program
pub fn merge_defaults(c: &mut Config) {
    c.set_default("global.modules",
                     vec!["exit_code", "directory", "git", "prompt"])
        .unwrap();
    c.set_default("global.foreground", "bright_white").unwrap();
    c.set_default("global.background", "blue").unwrap();
    c.set_default("global.style", "default").unwrap();
    c.set_default("global.separator", "").unwrap();
    c.set_default("global.padding_left", " ").unwrap();
    c.set_default("global.padding_right", " ").unwrap();

    c.set_default("modules.directory.max_depth", 4).unwrap();

    c.set_default("modules.exit_code.bg_success", "green").unwrap();
    c.set_default("modules.exit_code.bg_error", "red").unwrap();

    // c.set_default("modules.git.symbol_clean", "").unwrap();
    c.set_default("modules.git.symbol_insertion", "+").unwrap();
    c.set_default("modules.git.symbol_deletion", "-").unwrap();
    // c.set_default("modules.git.symbol_push", "⇡").unwrap();
    // c.set_default("modules.git.symbol_pull", "⇣").unwrap();
    c.set_default("modules.git.show_diff_stats", true).unwrap();

    c.set_default("modules.prompt.output", "$").unwrap();
    c.set_default("modules.prompt.bg_success", "green").unwrap();
    c.set_default("modules.prompt.bg_error", "red").unwrap();
}

/// Generic formatting method
pub fn format_module<'a>(c: &mut Config,
                         name: &'a str,
                         output: Option<String>,
                         last_successful: Option<&str>)
                         -> (Option<&'a str>, Option<ANSIString<'static>>) {
    // Formatting was not successful if there was nothing to format
    if c.get_str(&format!("modules.{}.output", name)).is_none() && output.is_none() {
        return (None, None);
    }

    // Get config options
    let fg = c.get_str(&format!("modules.{}.foreground", name))
        .unwrap_or_else(|| c.get_str("global.foreground").unwrap_or_default());
    let fg = string_to_colour(fg);

    let bg = c.get_str(&format!("modules.{}.background", name))
        .unwrap_or_else(|| c.get_str("global.background").unwrap_or_default());
    let bg = string_to_colour(bg);

    let padding_left = c.get_str(&format!("modules.{}.padding_left", name))
        .unwrap_or_else(|| c.get_str("global.padding_left").unwrap_or_default());
    let padding_right = c.get_str(&format!("modules.{}.padding_right", name))
        .unwrap_or_else(|| c.get_str("global.padding_right").unwrap_or_default());
    let separator = c.get_str(&format!("modules.{}.separator", name))
        .unwrap_or_else(|| c.get_str("global.separator").unwrap_or_default());

    let main_style = c.get_str(&format!("modules.{}.style", name))
        .unwrap_or_else(|| c.get_str("global.style").unwrap_or_default());
    let main_style = string_to_style(main_style).on(bg).fg(fg);

    // Override the output if there is "output" in this module's config
    let output = if let Some(s) = c.get_str(&format!("modules.{}.output", name)) {
        s
    } else {
        output.unwrap()
    };

    // Format the main content
    let mut content = format!("\\[{}\\]{}{}{}\\[{}\\]",
                              main_style.prefix(),
                              padding_left,
                              output,
                              padding_right,
                              main_style.suffix());

    // Format the separator
    let main_style = main_style.on(fg).fg(bg);
    if let Some(name) = last_successful {
        // There is a visible module that comes after this one
        let next_bg = c.get_str(&format!("modules.{}.background", name))
            .unwrap_or_else(|| c.get_str("global.background").unwrap_or_default());
        let next_bg = string_to_colour(next_bg);

        content = format!("{}\\[{}\\]{}\\[{}\\]",
                          content,
                          main_style.on(next_bg).prefix(),
                          separator,
                          main_style.on(next_bg).suffix());
    } else {
        // This is the final module
        content = format!("{}\\[{}\\]{}\\[{}\\]",
                          content,
                          bg.prefix(),
                          separator,
                          bg.suffix());
    }

    (Some(name), Some(ANSIString::from(content)))
}

// Converts a string (from the config file) to a Colour
// See: https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg
fn string_to_colour(s: String) -> Colour {
    if let Ok(i) = s.parse::<u8>() {
        return Colour::Fixed(i);
    }

    let s = s.to_lowercase();
    match s.as_ref() {
        "black" => Colour::Fixed(0),
        "bright_black" => Colour::Fixed(8),
        "red" => Colour::Fixed(1),
        "bright_red" => Colour::Fixed(9),
        "green" => Colour::Fixed(2),
        "bright_green" => Colour::Fixed(10),
        "yellow" => Colour::Fixed(3),
        "bright_yellow" => Colour::Fixed(11),
        "blue" => Colour::Fixed(4),
        "bright_blue" => Colour::Fixed(12),
        "purple" => Colour::Fixed(5),
        "bright_purple" => Colour::Fixed(13),
        "cyan" => Colour::Fixed(6),
        "bright_cyan" => Colour::Fixed(14),
        "white" => Colour::Fixed(7),
        "bright_white" => Colour::Fixed(15),
        _ => panic!("Invalid color option: {} in config file!", s),
    }
}

fn string_to_style(s: String) -> Style {
    let s = s.to_lowercase();
    match s.as_ref() {
        "default" | "" | "normal" => Style::new(),
        "bold" => Style::new().bold(),
        "dimmed" => Style::new().dimmed(),
        "italic" => Style::new().italic(),
        "underline" => Style::new().underline(),
        "blink" => Style::new().blink(),
        "reverse" => Style::new().reverse(),
        "hidden" => Style::new().hidden(),
        "strikethrough" => Style::new().strikethrough(),
        _ => panic!("Unknown style property: {} in config file!", s),
    }
}

pub fn format_module_prompt<'a>(c: &mut Config,
                                last_successful: Option<&'a str>,
                                exit_code: &str)
                                -> (Option<&'a str>, Option<ANSIString<'static>>) {
    let bg = match exit_code.as_ref() {
        "0" => c.get_str("modules.prompt.bg_success").unwrap_or_default(),
        _ => c.get_str("modules.prompt.bg_error").unwrap_or_default(),
    };
    c.set("modules.prompt.background", bg).unwrap();

    let output = c.get_str("modules.prompt.output").unwrap_or_default();

    format_module(c, "prompt", Some(output), last_successful)
}

pub fn format_module_exit_code<'a>(c: &mut Config,
                                   last_successful: Option<&'a str>,
                                   exit_code: &str)
                                   -> (Option<&'a str>, Option<ANSIString<'static>>) {
    let bg = match exit_code.as_ref() {
        "0" => c.get_str("modules.exit_code.bg_success").unwrap_or_default(),
        _ => c.get_str("modules.exit_code.bg_error").unwrap_or_default(),
    };
    c.set("modules.exit_code.background", bg).unwrap();

    format_module(c, "exit_code", Some(exit_code.to_string()), last_successful)
}

pub fn format_module_directory<'a>(c: &mut Config,
                                   last_successful: Option<&'a str>)
                                   -> (Option<&'a str>, Option<ANSIString<'static>>) {
    use std::env;
    use std::path::PathBuf;

    let home = env::var("HOME").unwrap();
    let cwd = env::current_dir().unwrap();

    // Convert "/home/user/directory" to "~/directory"
    let mut shortened_cwd: PathBuf;
    if let Ok(stripped_cwd) = cwd.strip_prefix(&home) {
        shortened_cwd = PathBuf::from("~").join(stripped_cwd);
    } else {
        shortened_cwd = env::current_dir().unwrap();
    }

    let depth = shortened_cwd.components().count();

    // Max number of directories we want to see
    let max_depth = c.get_int("modules.directory.max_depth").unwrap_or_default() as usize;

    if depth > max_depth {
        let comp_iter = shortened_cwd.clone();
        let comp_iter = comp_iter.components();

        shortened_cwd = PathBuf::new();
        for (i, component) in comp_iter.enumerate() {
            if i < (max_depth / 2) || i >= (depth - (max_depth / 2)) {
                shortened_cwd.push(component.as_os_str());
            } else if i == (max_depth / 2) {
                shortened_cwd.push("...");
            }
        }
    }

    format_module(c,
                  "directory",
                  Some(format!("{}", shortened_cwd.display())),
                  last_successful)
}

pub fn format_module_git<'a>(c: &mut Config,
                             last_successful: Option<&'a str>)
                             -> (Option<&'a str>, Option<ANSIString<'static>>) {
    use git2::Repository;
    use std::env;

    let mut output = String::new();

    let repo = Repository::discover(env::current_dir().unwrap());
    if let Ok(repo) = repo {
        if let Ok(reference) = repo.head() {
            // Current branch name
            output.push_str(reference.shorthand().unwrap());

            let show_diffs = c.get_bool("modules.git.show_diff_stats").unwrap_or_default();
            // Insertions and deletions
            if show_diffs {
                if let Ok(diff) = repo.diff_index_to_workdir(None, None) {
                    if let Ok(stats) = diff.stats() {
                        if stats.files_changed() > 0 {
                            let symbol_deletion = c.get_str("modules.git.symbol_deletion")
                                .unwrap_or_default();
                            let symbol_insertion = c.get_str("modules.git.symbol_insertion")
                                .unwrap_or_default();

                            output.push_str(&format!(" ({}{}, {}{})",
                                                     symbol_deletion,
                                                     stats.deletions(),
                                                     symbol_insertion,
                                                     stats.insertions()));
                        }
                    }
                }
            }
        }
    }

    if output.is_empty() {
        return (None, None);
    }

    // let symbol_clean = c.get_str("modules.git.symbol_clean").unwrap_or_default();
    // let symbol_push = c.get_str("modules.git.symbol_push").unwrap_or_default();
    // let symbol_pull = c.get_str("modules.git.symbol_pull").unwrap_or_default();

    format_module(c, "git", Some(output), last_successful)
}

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

    #[test]
    fn test_string_to_colour() {
        const CONTENT: &'static str = "hi";

        struct Test<'a> {
            input: &'static str,
            expected: &'a str,
        }

        let tests = [Test {
                         input: "green",
                         expected: &format!("\x1B[38;5;2m{}\x1B[0m", CONTENT),
                     },
                     Test {
                         input: "bright_green",
                         expected: &format!("\x1B[38;5;10m{}\x1B[0m", CONTENT),
                     }];

        for test in &tests {
            let result = string_to_colour(test.input.to_string());
            let result = format!("{}", result.paint(CONTENT));

            assert_eq!(test.expected, result);
        }
    }

    #[test]
    #[should_panic]
    fn test_string_to_colour_invalid_input() {
        struct Test {
            input: &'static str,
        }

        let tests = [Test { input: "green" }, Test { input: "invalid" }];

        for test in &tests {
            string_to_colour(test.input.to_string());
        }
    }
}
<commit_msg>refactor: reduce the amount of nested if-let statements<commit_after>use ansi_term::{ANSIString, Colour, Style};
use config::Config;

/// Merges in the default values for the program
pub fn merge_defaults(c: &mut Config) {
    c.set_default("global.modules",
                     vec!["exit_code", "directory", "git", "prompt"])
        .unwrap();
    c.set_default("global.foreground", "bright_white").unwrap();
    c.set_default("global.background", "blue").unwrap();
    c.set_default("global.style", "default").unwrap();
    c.set_default("global.separator", "").unwrap();
    c.set_default("global.padding_left", " ").unwrap();
    c.set_default("global.padding_right", " ").unwrap();

    c.set_default("modules.directory.max_depth", 4).unwrap();

    c.set_default("modules.exit_code.bg_success", "green").unwrap();
    c.set_default("modules.exit_code.bg_error", "red").unwrap();

    // c.set_default("modules.git.symbol_clean", "").unwrap();
    c.set_default("modules.git.symbol_insertion", "+").unwrap();
    c.set_default("modules.git.symbol_deletion", "-").unwrap();
    c.set_default("modules.git.symbol_push", "⇡").unwrap();
    // c.set_default("modules.git.symbol_pull", "⇣").unwrap();
    c.set_default("modules.git.show_diff_stats", true).unwrap();
    c.set_default("modules.git.show_unpushed", true).unwrap();

    c.set_default("modules.prompt.output", "$").unwrap();
    c.set_default("modules.prompt.bg_success", "green").unwrap();
    c.set_default("modules.prompt.bg_error", "red").unwrap();
}

/// Generic formatting method
pub fn format_module<'a>(c: &mut Config,
                         name: &'a str,
                         output: Option<String>,
                         last_successful: Option<&str>)
                         -> (Option<&'a str>, Option<ANSIString<'static>>) {
    // Formatting was not successful if there was nothing to format
    if c.get_str(&format!("modules.{}.output", name)).is_none() && output.is_none() {
        return (None, None);
    }

    // Get config options
    let fg = c.get_str(&format!("modules.{}.foreground", name))
        .unwrap_or_else(|| c.get_str("global.foreground").unwrap_or_default());
    let fg = string_to_colour(fg);

    let bg = c.get_str(&format!("modules.{}.background", name))
        .unwrap_or_else(|| c.get_str("global.background").unwrap_or_default());
    let bg = string_to_colour(bg);

    let padding_left = c.get_str(&format!("modules.{}.padding_left", name))
        .unwrap_or_else(|| c.get_str("global.padding_left").unwrap_or_default());
    let padding_right = c.get_str(&format!("modules.{}.padding_right", name))
        .unwrap_or_else(|| c.get_str("global.padding_right").unwrap_or_default());
    let separator = c.get_str(&format!("modules.{}.separator", name))
        .unwrap_or_else(|| c.get_str("global.separator").unwrap_or_default());

    let main_style = c.get_str(&format!("modules.{}.style", name))
        .unwrap_or_else(|| c.get_str("global.style").unwrap_or_default());
    let main_style = string_to_style(main_style).on(bg).fg(fg);

    // Override the output if there is "output" in this module's config
    let output = if let Some(s) = c.get_str(&format!("modules.{}.output", name)) {
        s
    } else {
        output.unwrap()
    };

    // Format the main content
    let mut content = format!("\\[{}\\]{}{}{}\\[{}\\]",
                              main_style.prefix(),
                              padding_left,
                              output,
                              padding_right,
                              main_style.suffix());

    // Format the separator
    let main_style = main_style.on(fg).fg(bg);
    if let Some(name) = last_successful {
        // There is a visible module that comes after this one
        let next_bg = c.get_str(&format!("modules.{}.background", name))
            .unwrap_or_else(|| c.get_str("global.background").unwrap_or_default());
        let next_bg = string_to_colour(next_bg);

        content = format!("{}\\[{}\\]{}\\[{}\\]",
                          content,
                          main_style.on(next_bg).prefix(),
                          separator,
                          main_style.on(next_bg).suffix());
    } else {
        // This is the final module
        content = format!("{}\\[{}\\]{}\\[{}\\]",
                          content,
                          bg.prefix(),
                          separator,
                          bg.suffix());
    }

    (Some(name), Some(ANSIString::from(content)))
}

// Converts a string (from the config file) to a Colour
// See: https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg
fn string_to_colour(s: String) -> Colour {
    if let Ok(i) = s.parse::<u8>() {
        Colour::Fixed(i)
    } else {
        let s = s.to_lowercase();
        match s.as_ref() {
            "black" => Colour::Fixed(0),
            "bright_black" => Colour::Fixed(8),
            "red" => Colour::Fixed(1),
            "bright_red" => Colour::Fixed(9),
            "green" => Colour::Fixed(2),
            "bright_green" => Colour::Fixed(10),
            "yellow" => Colour::Fixed(3),
            "bright_yellow" => Colour::Fixed(11),
            "blue" => Colour::Fixed(4),
            "bright_blue" => Colour::Fixed(12),
            "purple" => Colour::Fixed(5),
            "bright_purple" => Colour::Fixed(13),
            "cyan" => Colour::Fixed(6),
            "bright_cyan" => Colour::Fixed(14),
            "white" => Colour::Fixed(7),
            "bright_white" => Colour::Fixed(15),
            _ => panic!("Invalid color option: {} in config file!", s),
        }
    }
}

fn string_to_style(s: String) -> Style {
    let s = s.to_lowercase();
    match s.as_ref() {
        "default" | "" | "normal" => Style::new(),
        "bold" => Style::new().bold(),
        "dimmed" => Style::new().dimmed(),
        "italic" => Style::new().italic(),
        "underline" => Style::new().underline(),
        "blink" => Style::new().blink(),
        "reverse" => Style::new().reverse(),
        "hidden" => Style::new().hidden(),
        "strikethrough" => Style::new().strikethrough(),
        _ => panic!("Unknown style property: {} in config file!", s),
    }
}

pub fn format_module_prompt<'a>(c: &mut Config,
                                last_successful: Option<&'a str>,
                                exit_code: &str)
                                -> (Option<&'a str>, Option<ANSIString<'static>>) {
    let bg = match exit_code.as_ref() {
        "0" => c.get_str("modules.prompt.bg_success").unwrap_or_default(),
        _ => c.get_str("modules.prompt.bg_error").unwrap_or_default(),
    };
    c.set("modules.prompt.background", bg).unwrap();

    let output = c.get_str("modules.prompt.output").unwrap_or_default();

    format_module(c, "prompt", Some(output), last_successful)
}

pub fn format_module_exit_code<'a>(c: &mut Config,
                                   last_successful: Option<&'a str>,
                                   exit_code: &str)
                                   -> (Option<&'a str>, Option<ANSIString<'static>>) {
    let bg = match exit_code.as_ref() {
        "0" => c.get_str("modules.exit_code.bg_success").unwrap_or_default(),
        _ => c.get_str("modules.exit_code.bg_error").unwrap_or_default(),
    };
    c.set("modules.exit_code.background", bg).unwrap();

    format_module(c, "exit_code", Some(exit_code.to_string()), last_successful)
}

pub fn format_module_directory<'a>(c: &mut Config,
                                   last_successful: Option<&'a str>)
                                   -> (Option<&'a str>, Option<ANSIString<'static>>) {
    use std::env;
    use std::path::PathBuf;

    let home = env::var("HOME").unwrap();
    let cwd = env::current_dir().unwrap();

    // Convert "/home/user/directory" to "~/directory"
    let mut shortened_cwd: PathBuf;
    if let Ok(stripped_cwd) = cwd.strip_prefix(&home) {
        shortened_cwd = PathBuf::from("~").join(stripped_cwd);
    } else {
        shortened_cwd = env::current_dir().unwrap();
    }

    let depth = shortened_cwd.components().count();

    // Max number of directories we want to see
    let max_depth = c.get_int("modules.directory.max_depth").unwrap_or_default() as usize;

    if depth > max_depth {
        let comp_iter = shortened_cwd.clone();
        let comp_iter = comp_iter.components();

        shortened_cwd = PathBuf::new();
        for (i, component) in comp_iter.enumerate() {
            if i < (max_depth / 2) || i >= (depth - (max_depth / 2)) {
                shortened_cwd.push(component.as_os_str());
            } else if i == (max_depth / 2) {
                shortened_cwd.push("...");
            }
        }
    }

    format_module(c,
                  "directory",
                  Some(format!("{}", shortened_cwd.display())),
                  last_successful)
}

pub fn format_module_git<'a>(c: &mut Config,
                             last_successful: Option<&'a str>)
                             -> (Option<&'a str>, Option<ANSIString<'static>>) {
    use git2::{Branch, Error, Oid, Reference, Repository};
    use std::env;

    let mut output = String::new();

    if let Ok(repo) = Repository::discover(env::current_dir().unwrap_or_default()) {
        let local = repo.head().unwrap();

        // Output current branch name
        output.push_str(local.shorthand().unwrap());

        let local = Branch::wrap(local);

        // Show local insertions and deletions
        let show_diffs = c.get_bool("modules.git.show_diff_stats").unwrap_or_default();
        if show_diffs {
            let diff_stats = repo.diff_index_to_workdir(None, None).unwrap();
            let diff_stats = diff_stats.stats().unwrap();

            if diff_stats.files_changed() > 0 {
                let symbol_deletion = c.get_str("modules.git.symbol_deletion").unwrap_or_default();
                let symbol_insertion = c.get_str("modules.git.symbol_insertion")
                    .unwrap_or_default();

                output.push_str(&format!(" ({}{}, {}{})",
                                         symbol_deletion,
                                         diff_stats.deletions(),
                                         symbol_insertion,
                                         diff_stats.insertions()));
            }
        }

        // Show unpushed commits
        let show_unpushed = c.get_bool("modules.git.show_unpushed").unwrap_or_default();
        if show_unpushed {
            if let Ok(upstream) = local.upstream() {
                println!("We have an upstream!");
            }
        }
    }

    // let repo: Rc<Result<Repository, Error>> = Rc::from(Repository::discover(env::current_dir()
    //                                                                             .unwrap()));
    // let local: Option<Reference> = match repo.clone().borrow() {
    //     Ok(r) => if let Ok(e) = r.head() { Some(e) } else { None },
    //     _ => None,
    // };

    /*     if let Ok(repo) = repo {
        if let Ok(local) = repo.head() {
            // Current branch name
            output.push_str(local.shorthand().unwrap());

            let show_diffs = c.get_bool("modules.git.show_diff_stats").unwrap_or_default();
            // Insertions and deletions
            if show_diffs {
                if let Ok(diff) = repo.diff_index_to_workdir(None, None) {
                    if let Ok(stats) = diff.stats() {
                        if stats.files_changed() > 0 {
                            let symbol_deletion = c.get_str("modules.git.symbol_deletion")
                                .unwrap_or_default();
                            let symbol_insertion = c.get_str("modules.git.symbol_insertion")
                                .unwrap_or_default();

                            output.push_str(&format!(" ({}{}, {}{})",
                                                     symbol_deletion,
                                                     stats.deletions(),
                                                     symbol_insertion,
                                                     stats.insertions()));
                        }
                    }
                }
            }

            let show_unpushed = c.get_bool("modules.git.show_unpushed").unwrap_or_default();
            // Unpushed commits
            if show_unpushed {
                let local_branch = Branch::wrap(local);
                if let Ok(upstream) = local_branch.upstream() {
                    let upstream_oid = Oid::from_str(upstream.name().unwrap().unwrap()).unwrap();
                    let local_oid = Oid::from_str(local_branch.name().unwrap().unwrap()).unwrap();
                    if let Ok((a, b)) = repo.graph_ahead_behind(local_oid, upstream_oid) {
                        let symbol_push = c.get_str("modules.git.symbol_push").unwrap_or_default();
                        println!("(a, b): ({}, {})", a, b);
                    }
                }
            }
        }
    } */

    if output.is_empty() {
        (None, None)
    } else {
        format_module(c, "git", Some(output), last_successful)
    }
    // let symbol_clean = c.get_str("modules.git.symbol_clean").unwrap_or_default();
    // let symbol_pull = c.get_str("modules.git.symbol_pull").unwrap_or_default();
}

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

    #[test]
    fn test_string_to_colour() {
        const CONTENT: &'static str = "hi";

        struct Test<'a> {
            input: &'static str,
            expected: &'a str,
        }

        let tests = [Test {
                         input: "green",
                         expected: &format!("\x1B[38;5;2m{}\x1B[0m", CONTENT),
                     },
                     Test {
                         input: "bright_green",
                         expected: &format!("\x1B[38;5;10m{}\x1B[0m", CONTENT),
                     }];

        for test in &tests {
            let result = string_to_colour(test.input.to_string());
            let result = format!("{}", result.paint(CONTENT));

            assert_eq!(test.expected, result);
        }
    }

    #[test]
    #[should_panic]
    fn test_string_to_colour_invalid_input() {
        struct Test {
            input: &'static str,
        }

        let tests = [Test { input: "green" }, Test { input: "invalid" }];

        for test in &tests {
            string_to_colour(test.input.to_string());
        }
    }
}
<|endoftext|>


<commit_before>use std::net::{UdpSocket, SocketAddr};
use std::collections::HashMap;

use fcp_cryptoauth::{CAWrapper, PublicKey, SecretKey, Credentials};

use switch_packet::SwitchPacket;
use operation::Director;
use plumbing::NetworkAdapterTrait;

pub struct UdpPeer<PeerId: Clone> {
    pub ca_session: CAWrapper<PeerId>,
    pub addr: SocketAddr,
}

pub struct UdpAdapter<PeerId: Clone> {
    pub sock: UdpSocket,
    pub my_pk: PublicKey,
    pub my_sk: SecretKey,
    pub allowed_peers: HashMap<Credentials, PeerId>,
    pub peers: HashMap<Director, UdpPeer<PeerId>>,
}

impl<PeerId: Clone> UdpAdapter<PeerId> {
    pub fn new(
            sock: UdpSocket,
            my_pk: PublicKey,
            my_sk: SecretKey,
            allowed_peers: HashMap<Credentials, PeerId>,
            peers: HashMap<Director, UdpPeer<PeerId>>,
            )
            -> UdpAdapter<PeerId> {
        UdpAdapter {
            sock: sock,
            my_pk: my_pk,
            my_sk: my_sk,
            allowed_peers: allowed_peers,
            peers: peers,
        }
    }

    // Find what interface a UDP packet is coming from, using its emitted
    // IP address.
    fn get_incoming_director_and_open(&mut self, from_addr: SocketAddr, buf: Vec<u8>)
            -> (Director, Vec<Vec<u8>>) {
        for (director, peer) in self.peers.iter_mut() {
            if peer.addr == from_addr {
                let messages = peer.ca_session.unwrap_message(buf).unwrap();
                return (*director, messages);
            }
        }

        // Not a known interface; create one
        let director = (0..0b1000).filter(|candidate| !self.peers.contains_key(&candidate)).next().unwrap();
        let (ca_session, message) = CAWrapper::new_incoming_connection(self.my_pk.clone(), self.my_sk.clone(), Credentials::None, Some(self.allowed_peers.clone()), None, buf).unwrap();
        let peer = UdpPeer { ca_session: ca_session, addr: from_addr };
        self.peers.insert(director, peer);
        (director, vec![message])
    }

    /// Called when a UDP packet is received.
    fn on_outer_ca_message(&mut self, from_addr: SocketAddr, buf: Vec<u8>)
            -> (Director, Vec<SwitchPacket>) {
        let (director, messages) = self.get_incoming_director_and_open(from_addr, buf);
        (director, messages.into_iter().map(|raw| SwitchPacket { raw: raw }).collect())
    }
}

impl<PeerId: Clone> NetworkAdapterTrait for UdpAdapter<PeerId> {
    fn send_to(&mut self, to: Director, packet: &SwitchPacket) {
        let (addr, datagrams) = {
            let peer = self.peers.get_mut(&to).unwrap();
            let datagrams = peer.ca_session.wrap_message(&packet.raw);
            (peer.addr, datagrams)
        };
        for datagram in datagrams {
            self.sock.send_to(&datagram, addr).unwrap();
        }
    }

    fn recv_from(&mut self) -> (Director, Vec<SwitchPacket>) {
        let mut buf = vec![0u8; 4096];
        let (nb_bytes, addr) = self.sock.recv_from(&mut buf).unwrap();
        assert!(nb_bytes < 4096);
        buf.truncate(nb_bytes);
        self.on_outer_ca_message(addr, buf)
    }

}
<commit_msg>Rename variable<commit_after>use std::net::{UdpSocket, SocketAddr};
use std::collections::HashMap;

use fcp_cryptoauth::{CAWrapper, PublicKey, SecretKey, Credentials};

use switch_packet::SwitchPacket;
use operation::Director;
use plumbing::NetworkAdapterTrait;

pub struct UdpPeer<PeerId: Clone> {
    pub ca_session: CAWrapper<PeerId>,
    pub addr: SocketAddr,
}

pub struct UdpAdapter<PeerId: Clone> {
    pub sock: UdpSocket,
    pub my_pk: PublicKey,
    pub my_sk: SecretKey,
    pub allowed_peers: HashMap<Credentials, PeerId>,
    pub peers: HashMap<Director, UdpPeer<PeerId>>,
}

impl<PeerId: Clone> UdpAdapter<PeerId> {
    pub fn new(
            sock: UdpSocket,
            my_pk: PublicKey,
            my_sk: SecretKey,
            allowed_peers: HashMap<Credentials, PeerId>,
            peers: HashMap<Director, UdpPeer<PeerId>>,
            )
            -> UdpAdapter<PeerId> {
        UdpAdapter {
            sock: sock,
            my_pk: my_pk,
            my_sk: my_sk,
            allowed_peers: allowed_peers,
            peers: peers,
        }
    }

    // Find what interface a UDP packet is coming from, using its emitted
    // IP address.
    fn get_incoming_director_and_open(&mut self, from_addr: SocketAddr, datagram: Vec<u8>)
            -> (Director, Vec<Vec<u8>>) {
        for (director, peer) in self.peers.iter_mut() {
            if peer.addr == from_addr {
                let messages = peer.ca_session.unwrap_message(datagram).unwrap();
                return (*director, messages);
            }
        }

        // Not a known interface; create one
        let director = (0..0b1000).filter(|candidate| !self.peers.contains_key(&candidate)).next().unwrap();
        let (ca_session, message) = CAWrapper::new_incoming_connection(self.my_pk.clone(), self.my_sk.clone(), Credentials::None, Some(self.allowed_peers.clone()), None, datagram).unwrap();
        let peer = UdpPeer { ca_session: ca_session, addr: from_addr };
        self.peers.insert(director, peer);
        (director, vec![message])
    }

    /// Called when a UDP packet is received.
    fn on_outer_ca_message(&mut self, from_addr: SocketAddr, datagram: Vec<u8>)
            -> (Director, Vec<SwitchPacket>) {
        let (director, messages) = self.get_incoming_director_and_open(from_addr, datagram);
        (director, messages.into_iter().map(|raw| SwitchPacket { raw: raw }).collect())
    }
}

impl<PeerId: Clone> NetworkAdapterTrait for UdpAdapter<PeerId> {
    fn send_to(&mut self, to: Director, packet: &SwitchPacket) {
        let (addr, datagrams) = {
            let peer = self.peers.get_mut(&to).unwrap();
            let datagrams = peer.ca_session.wrap_message(&packet.raw);
            (peer.addr, datagrams)
        };
        for datagram in datagrams {
            self.sock.send_to(&datagram, addr).unwrap();
        }
    }

    fn recv_from(&mut self) -> (Director, Vec<SwitchPacket>) {
        let mut datagram = vec![0u8; 4096];
        let (nb_bytes, addr) = self.sock.recv_from(&mut datagram).unwrap();
        assert!(nb_bytes < 4096);
        datagram.truncate(nb_bytes);
        self.on_outer_ca_message(addr, datagram)
    }

}
<|endoftext|>


<commit_before>use std::borrow::Cow;
use std::collections::HashMap;

use serde_json::value::Value as Json;

use crate::block::BlockContext;
use crate::context::{merge_json, Context};
use crate::error::RenderError;
use crate::json::path::Path;
use crate::output::Output;
use crate::registry::Registry;
use crate::render::{Decorator, Evaluable, RenderContext, Renderable};
use crate::template::Template;

pub(crate) const PARTIAL_BLOCK: &str = "@partial-block";

fn find_partial<'reg: 'rc, 'rc: 'a, 'a>(
    rc: &'a RenderContext<'reg, 'rc>,
    r: &'reg Registry<'reg>,
    d: &Decorator<'reg, 'rc>,
    name: &str,
) -> Result<Option<Cow<'a, Template>>, RenderError> {
    if let Some(ref partial) = rc.get_partial(name) {
        return Ok(Some(Cow::Borrowed(partial)));
    }

    if let Some(tpl) = r.get_or_load_template_optional(name) {
        return tpl.map(|t| Some(t));
    }

    if let Some(tpl) = d.template() {
        return Ok(Some(Cow::Borrowed(tpl)));
    }

    Ok(None)
}

pub fn expand_partial<'reg: 'rc, 'rc>(
    d: &Decorator<'reg, 'rc>,
    r: &'reg Registry<'reg>,
    ctx: &'rc Context,
    rc: &mut RenderContext<'reg, 'rc>,
    out: &mut dyn Output,
) -> Result<(), RenderError> {
    // try eval inline partials first
    if let Some(t) = d.template() {
        t.eval(r, ctx, rc)?;
    }

    let tname = d.name();
    if rc.is_current_template(tname) {
        return Err(RenderError::new("Cannot include self in >"));
    }

    // if tname == PARTIAL_BLOCK
    let partial = find_partial(rc, r, d, tname)?;

    if let Some(t) = partial {
        // clone to avoid lifetime issue
        // FIXME refactor this to avoid
        let mut local_rc = rc.clone();
        let is_partial_block = tname == PARTIAL_BLOCK;

        if is_partial_block {
            local_rc.inc_partial_block_depth();
        }

        let mut block_created = false;

        if let Some(ref base_path) = d.param(0).and_then(|p| p.context_path()) {
            // path given, update base_path
            let mut block = BlockContext::new();
            *block.base_path_mut() = base_path.to_vec();
            block_created = true;
            local_rc.push_block(block);
        } else if !d.hash().is_empty() {
            let mut block = BlockContext::new();
            // hash given, update base_value
            let hash_ctx = d
                .hash()
                .iter()
                .map(|(k, v)| (*k, v.value()))
                .collect::<HashMap<&str, &Json>>();

            let merged_context = merge_json(
                local_rc.evaluate2(ctx, &Path::current())?.as_json(),
                &hash_ctx,
            );
            block.set_base_value(merged_context);
            block_created = true;
            local_rc.push_block(block);
        }

        // @partial-block
        if let Some(pb) = d.template() {
            local_rc.push_partial_block(pb);
        }

        let result = t.render(r, ctx, &mut local_rc, out);

        // cleanup
        if block_created {
            local_rc.pop_block();
        }

        if is_partial_block {
            local_rc.dec_partial_block_depth();
        }

        if d.template().is_some() {
            local_rc.pop_partial_block();
        }

        result
    } else {
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use crate::context::Context;
    use crate::error::RenderError;
    use crate::output::Output;
    use crate::registry::Registry;
    use crate::render::{Helper, RenderContext};

    #[test]
    fn test() {
        let mut handlebars = Registry::new();
        assert!(handlebars
            .register_template_string("t0", "{{> t1}}")
            .is_ok());
        assert!(handlebars
            .register_template_string("t1", "{{this}}")
            .is_ok());
        assert!(handlebars
            .register_template_string("t2", "{{#> t99}}not there{{/t99}}")
            .is_ok());
        assert!(handlebars
            .register_template_string("t3", "{{#*inline \"t31\"}}{{this}}{{/inline}}{{> t31}}")
            .is_ok());
        assert!(handlebars
            .register_template_string(
                "t4",
                "{{#> t5}}{{#*inline \"nav\"}}navbar{{/inline}}{{/t5}}"
            )
            .is_ok());
        assert!(handlebars
            .register_template_string("t5", "include {{> nav}}")
            .is_ok());
        assert!(handlebars
            .register_template_string("t6", "{{> t1 a}}")
            .is_ok());
        assert!(handlebars
            .register_template_string(
                "t7",
                "{{#*inline \"t71\"}}{{a}}{{/inline}}{{> t71 a=\"world\"}}"
            )
            .is_ok());
        assert!(handlebars.register_template_string("t8", "{{a}}").is_ok());
        assert!(handlebars
            .register_template_string("t9", "{{> t8 a=2}}")
            .is_ok());

        assert_eq!(handlebars.render("t0", &1).ok().unwrap(), "1".to_string());
        assert_eq!(
            handlebars.render("t2", &1).ok().unwrap(),
            "not there".to_string()
        );
        assert_eq!(handlebars.render("t3", &1).ok().unwrap(), "1".to_string());
        assert_eq!(
            handlebars.render("t4", &1).ok().unwrap(),
            "include navbar".to_string()
        );
        assert_eq!(
            handlebars
                .render("t6", &btreemap! {"a".to_string() => "2".to_string()})
                .ok()
                .unwrap(),
            "2".to_string()
        );
        assert_eq!(
            handlebars.render("t7", &1).ok().unwrap(),
            "world".to_string()
        );
        assert_eq!(handlebars.render("t9", &1).ok().unwrap(), "2".to_string());
    }

    #[test]
    fn test_include_partial_block() {
        let t0 = "hello {{> @partial-block}}";
        let t1 = "{{#> t0}}inner {{this}}{{/t0}}";

        let mut handlebars = Registry::new();
        assert!(handlebars.register_template_string("t0", t0).is_ok());
        assert!(handlebars.register_template_string("t1", t1).is_ok());

        let r0 = handlebars.render("t1", &true);
        assert_eq!(r0.ok().unwrap(), "hello inner true".to_string());
    }

    #[test]
    fn test_self_inclusion() {
        let t0 = "hello {{> t1}} {{> t0}}";
        let t1 = "some template";
        let mut handlebars = Registry::new();
        assert!(handlebars.register_template_string("t0", t0).is_ok());
        assert!(handlebars.register_template_string("t1", t1).is_ok());

        let r0 = handlebars.render("t0", &true);
        assert!(r0.is_err());
    }

    #[test]
    fn test_issue_143() {
        let main_template = "one{{> two }}three{{> two }}";
        let two_partial = "--- two ---";

        let mut handlebars = Registry::new();
        assert!(handlebars
            .register_template_string("template", main_template)
            .is_ok());
        assert!(handlebars
            .register_template_string("two", two_partial)
            .is_ok());

        let r0 = handlebars.render("template", &true);
        assert_eq!(r0.ok().unwrap(), "one--- two ---three--- two ---");
    }

    #[test]
    fn test_hash_context_outscope() {
        let main_template = "In: {{> p a=2}} Out: {{a}}";
        let p_partial = "{{a}}";

        let mut handlebars = Registry::new();
        assert!(handlebars
            .register_template_string("template", main_template)
            .is_ok());
        assert!(handlebars.register_template_string("p", p_partial).is_ok());

        let r0 = handlebars.render("template", &true);
        assert_eq!(r0.ok().unwrap(), "In: 2 Out: ");
    }

    #[test]
    fn test_partial_context_hash() {
        let mut hbs = Registry::new();
        hbs.register_template_string("one", "This is a test. {{> two name=\"fred\" }}")
            .unwrap();
        hbs.register_template_string("two", "Lets test {{name}}")
            .unwrap();
        assert_eq!(
            "This is a test. Lets test fred",
            hbs.render("one", &0).unwrap()
        );
    }

    #[test]
    fn test_partial_subexpression_context_hash() {
        let mut hbs = Registry::new();
        hbs.register_template_string("one", "This is a test. {{> (x @root) name=\"fred\" }}")
            .unwrap();
        hbs.register_template_string("two", "Lets test {{name}}")
            .unwrap();

        hbs.register_helper(
            "x",
            Box::new(
                |_: &Helper<'_, '_>,
                 _: &Registry<'_>,
                 _: &Context,
                 _: &mut RenderContext<'_, '_>,
                 out: &mut dyn Output|
                 -> Result<(), RenderError> {
                    out.write("two")?;
                    Ok(())
                },
            ),
        );
        assert_eq!(
            "This is a test. Lets test fred",
            hbs.render("one", &0).unwrap()
        );
    }

    #[test]
    fn test_nested_partial_scope() {
        let t = "{{#*inline \"pp\"}}{{a}} {{b}}{{/inline}}{{#each c}}{{> pp a=2}}{{/each}}";
        let data = json!({"c": [{"b": true}, {"b": false}]});

        let mut handlebars = Registry::new();
        assert!(handlebars.register_template_string("t", t).is_ok());
        let r0 = handlebars.render("t", &data);
        assert_eq!(r0.ok().unwrap(), "2 true2 false");
    }

    #[test]
    fn test_nested_partials() {
        let mut handlebars = Registry::new();
        let template1 = "<outer>{{> @partial-block }}</outer>";
        let template2 = "{{#> t1 }}<inner>{{> @partial-block }}</inner>{{/ t1 }}";
        let template3 = "{{#> t2 }}Hello{{/ t2 }}";

        handlebars
            .register_template_string("t1", &template1)
            .unwrap();
        handlebars
            .register_template_string("t2", &template2)
            .unwrap();

        let page = handlebars.render_template(&template3, &json!({})).unwrap();
        assert_eq!("<outer><inner>Hello</inner></outer>", page);
    }

    #[test]
    fn test_up_to_partial_level() {
        let outer = r#"{{>inner name="fruit:" vegetables=fruits}}"#;
        let inner = "{{#each vegetables}}{{../name}} {{this}},{{/each}}";

        let data = json!({ "fruits": ["carrot", "tomato"] });

        let mut handlebars = Registry::new();
        handlebars.register_template_string("outer", outer).unwrap();
        handlebars.register_template_string("inner", inner).unwrap();

        assert_eq!(
            handlebars.render("outer", &data).unwrap(),
            "fruit: carrot,fruit: tomato,"
        );
    }
}
<commit_msg>(fix) clippy warnings<commit_after>use std::borrow::Cow;
use std::collections::HashMap;

use serde_json::value::Value as Json;

use crate::block::BlockContext;
use crate::context::{merge_json, Context};
use crate::error::RenderError;
use crate::json::path::Path;
use crate::output::Output;
use crate::registry::Registry;
use crate::render::{Decorator, Evaluable, RenderContext, Renderable};
use crate::template::Template;

pub(crate) const PARTIAL_BLOCK: &str = "@partial-block";

fn find_partial<'reg: 'rc, 'rc: 'a, 'a>(
    rc: &'a RenderContext<'reg, 'rc>,
    r: &'reg Registry<'reg>,
    d: &Decorator<'reg, 'rc>,
    name: &str,
) -> Result<Option<Cow<'a, Template>>, RenderError> {
    if let Some(ref partial) = rc.get_partial(name) {
        return Ok(Some(Cow::Borrowed(partial)));
    }

    if let Some(tpl) = r.get_or_load_template_optional(name) {
        return tpl.map(Option::Some);
    }

    if let Some(tpl) = d.template() {
        return Ok(Some(Cow::Borrowed(tpl)));
    }

    Ok(None)
}

pub fn expand_partial<'reg: 'rc, 'rc>(
    d: &Decorator<'reg, 'rc>,
    r: &'reg Registry<'reg>,
    ctx: &'rc Context,
    rc: &mut RenderContext<'reg, 'rc>,
    out: &mut dyn Output,
) -> Result<(), RenderError> {
    // try eval inline partials first
    if let Some(t) = d.template() {
        t.eval(r, ctx, rc)?;
    }

    let tname = d.name();
    if rc.is_current_template(tname) {
        return Err(RenderError::new("Cannot include self in >"));
    }

    // if tname == PARTIAL_BLOCK
    let partial = find_partial(rc, r, d, tname)?;

    if let Some(t) = partial {
        // clone to avoid lifetime issue
        // FIXME refactor this to avoid
        let mut local_rc = rc.clone();
        let is_partial_block = tname == PARTIAL_BLOCK;

        if is_partial_block {
            local_rc.inc_partial_block_depth();
        }

        let mut block_created = false;

        if let Some(ref base_path) = d.param(0).and_then(|p| p.context_path()) {
            // path given, update base_path
            let mut block = BlockContext::new();
            *block.base_path_mut() = base_path.to_vec();
            block_created = true;
            local_rc.push_block(block);
        } else if !d.hash().is_empty() {
            let mut block = BlockContext::new();
            // hash given, update base_value
            let hash_ctx = d
                .hash()
                .iter()
                .map(|(k, v)| (*k, v.value()))
                .collect::<HashMap<&str, &Json>>();

            let merged_context = merge_json(
                local_rc.evaluate2(ctx, &Path::current())?.as_json(),
                &hash_ctx,
            );
            block.set_base_value(merged_context);
            block_created = true;
            local_rc.push_block(block);
        }

        // @partial-block
        if let Some(pb) = d.template() {
            local_rc.push_partial_block(pb);
        }

        let result = t.render(r, ctx, &mut local_rc, out);

        // cleanup
        if block_created {
            local_rc.pop_block();
        }

        if is_partial_block {
            local_rc.dec_partial_block_depth();
        }

        if d.template().is_some() {
            local_rc.pop_partial_block();
        }

        result
    } else {
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use crate::context::Context;
    use crate::error::RenderError;
    use crate::output::Output;
    use crate::registry::Registry;
    use crate::render::{Helper, RenderContext};

    #[test]
    fn test() {
        let mut handlebars = Registry::new();
        assert!(handlebars
            .register_template_string("t0", "{{> t1}}")
            .is_ok());
        assert!(handlebars
            .register_template_string("t1", "{{this}}")
            .is_ok());
        assert!(handlebars
            .register_template_string("t2", "{{#> t99}}not there{{/t99}}")
            .is_ok());
        assert!(handlebars
            .register_template_string("t3", "{{#*inline \"t31\"}}{{this}}{{/inline}}{{> t31}}")
            .is_ok());
        assert!(handlebars
            .register_template_string(
                "t4",
                "{{#> t5}}{{#*inline \"nav\"}}navbar{{/inline}}{{/t5}}"
            )
            .is_ok());
        assert!(handlebars
            .register_template_string("t5", "include {{> nav}}")
            .is_ok());
        assert!(handlebars
            .register_template_string("t6", "{{> t1 a}}")
            .is_ok());
        assert!(handlebars
            .register_template_string(
                "t7",
                "{{#*inline \"t71\"}}{{a}}{{/inline}}{{> t71 a=\"world\"}}"
            )
            .is_ok());
        assert!(handlebars.register_template_string("t8", "{{a}}").is_ok());
        assert!(handlebars
            .register_template_string("t9", "{{> t8 a=2}}")
            .is_ok());

        assert_eq!(handlebars.render("t0", &1).ok().unwrap(), "1".to_string());
        assert_eq!(
            handlebars.render("t2", &1).ok().unwrap(),
            "not there".to_string()
        );
        assert_eq!(handlebars.render("t3", &1).ok().unwrap(), "1".to_string());
        assert_eq!(
            handlebars.render("t4", &1).ok().unwrap(),
            "include navbar".to_string()
        );
        assert_eq!(
            handlebars
                .render("t6", &btreemap! {"a".to_string() => "2".to_string()})
                .ok()
                .unwrap(),
            "2".to_string()
        );
        assert_eq!(
            handlebars.render("t7", &1).ok().unwrap(),
            "world".to_string()
        );
        assert_eq!(handlebars.render("t9", &1).ok().unwrap(), "2".to_string());
    }

    #[test]
    fn test_include_partial_block() {
        let t0 = "hello {{> @partial-block}}";
        let t1 = "{{#> t0}}inner {{this}}{{/t0}}";

        let mut handlebars = Registry::new();
        assert!(handlebars.register_template_string("t0", t0).is_ok());
        assert!(handlebars.register_template_string("t1", t1).is_ok());

        let r0 = handlebars.render("t1", &true);
        assert_eq!(r0.ok().unwrap(), "hello inner true".to_string());
    }

    #[test]
    fn test_self_inclusion() {
        let t0 = "hello {{> t1}} {{> t0}}";
        let t1 = "some template";
        let mut handlebars = Registry::new();
        assert!(handlebars.register_template_string("t0", t0).is_ok());
        assert!(handlebars.register_template_string("t1", t1).is_ok());

        let r0 = handlebars.render("t0", &true);
        assert!(r0.is_err());
    }

    #[test]
    fn test_issue_143() {
        let main_template = "one{{> two }}three{{> two }}";
        let two_partial = "--- two ---";

        let mut handlebars = Registry::new();
        assert!(handlebars
            .register_template_string("template", main_template)
            .is_ok());
        assert!(handlebars
            .register_template_string("two", two_partial)
            .is_ok());

        let r0 = handlebars.render("template", &true);
        assert_eq!(r0.ok().unwrap(), "one--- two ---three--- two ---");
    }

    #[test]
    fn test_hash_context_outscope() {
        let main_template = "In: {{> p a=2}} Out: {{a}}";
        let p_partial = "{{a}}";

        let mut handlebars = Registry::new();
        assert!(handlebars
            .register_template_string("template", main_template)
            .is_ok());
        assert!(handlebars.register_template_string("p", p_partial).is_ok());

        let r0 = handlebars.render("template", &true);
        assert_eq!(r0.ok().unwrap(), "In: 2 Out: ");
    }

    #[test]
    fn test_partial_context_hash() {
        let mut hbs = Registry::new();
        hbs.register_template_string("one", "This is a test. {{> two name=\"fred\" }}")
            .unwrap();
        hbs.register_template_string("two", "Lets test {{name}}")
            .unwrap();
        assert_eq!(
            "This is a test. Lets test fred",
            hbs.render("one", &0).unwrap()
        );
    }

    #[test]
    fn test_partial_subexpression_context_hash() {
        let mut hbs = Registry::new();
        hbs.register_template_string("one", "This is a test. {{> (x @root) name=\"fred\" }}")
            .unwrap();
        hbs.register_template_string("two", "Lets test {{name}}")
            .unwrap();

        hbs.register_helper(
            "x",
            Box::new(
                |_: &Helper<'_, '_>,
                 _: &Registry<'_>,
                 _: &Context,
                 _: &mut RenderContext<'_, '_>,
                 out: &mut dyn Output|
                 -> Result<(), RenderError> {
                    out.write("two")?;
                    Ok(())
                },
            ),
        );
        assert_eq!(
            "This is a test. Lets test fred",
            hbs.render("one", &0).unwrap()
        );
    }

    #[test]
    fn test_nested_partial_scope() {
        let t = "{{#*inline \"pp\"}}{{a}} {{b}}{{/inline}}{{#each c}}{{> pp a=2}}{{/each}}";
        let data = json!({"c": [{"b": true}, {"b": false}]});

        let mut handlebars = Registry::new();
        assert!(handlebars.register_template_string("t", t).is_ok());
        let r0 = handlebars.render("t", &data);
        assert_eq!(r0.ok().unwrap(), "2 true2 false");
    }

    #[test]
    fn test_nested_partials() {
        let mut handlebars = Registry::new();
        let template1 = "<outer>{{> @partial-block }}</outer>";
        let template2 = "{{#> t1 }}<inner>{{> @partial-block }}</inner>{{/ t1 }}";
        let template3 = "{{#> t2 }}Hello{{/ t2 }}";

        handlebars
            .register_template_string("t1", &template1)
            .unwrap();
        handlebars
            .register_template_string("t2", &template2)
            .unwrap();

        let page = handlebars.render_template(&template3, &json!({})).unwrap();
        assert_eq!("<outer><inner>Hello</inner></outer>", page);
    }

    #[test]
    fn test_up_to_partial_level() {
        let outer = r#"{{>inner name="fruit:" vegetables=fruits}}"#;
        let inner = "{{#each vegetables}}{{../name}} {{this}},{{/each}}";

        let data = json!({ "fruits": ["carrot", "tomato"] });

        let mut handlebars = Registry::new();
        handlebars.register_template_string("outer", outer).unwrap();
        handlebars.register_template_string("inner", inner).unwrap();

        assert_eq!(
            handlebars.render("outer", &data).unwrap(),
            "fruit: carrot,fruit: tomato,"
        );
    }
}
<|endoftext|>


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

use rand::{self, Rng};

use self::ParseError::*;

const MAX_SIZE: usize = 64;

pub struct PasteID(String);

#[derive(Debug)]
pub enum ParseError {
    LengthTooLong,
    InvalidCharacters,
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            LengthTooLong => write!(f, "ID length too long"),
            InvalidCharacters => write!(f, "ID contains invalid characters"),
        }
    }
}

impl PasteID {
    // Returns a new randomly generated id.
    pub fn new(size: usize) -> PasteID {
        PasteID(strgen::generate(size))
    }

    // returns the filename associated with the id
    pub fn filename(&self) -> String {
        format!("upload/{}", self.0)
    }
}

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

impl FromStr for PasteID {
    type Err = ParseError;
    fn from_str(s: &str) -> Result<PasteID, ParseError> {
        if s.len() > MAX_SIZE {
            return Err(LengthTooLong);
        }

        if !s.as_bytes().iter().all(|&x| strgen::CHARACTERS.contains(&x)) {
            return Err(InvalidCharacters);
        }

        Ok(PasteID(String::from(s)))
    }
}
<commit_msg>finally :sparkles:<commit_after>use std::fmt;
use std::str::{FromStr, from_utf8};

use self::ParseError::*;

use strgen;

const MAX_SIZE: usize = 64;

pub struct PasteID(String);

#[derive(Debug)]
pub enum ParseError {
    LengthTooLong,
    InvalidCharacters,
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            LengthTooLong => write!(f, "ID length too long"),
            InvalidCharacters => write!(f, "ID contains invalid characters"),
        }
    }
}

impl PasteID {
    // Returns a new randomly generated id.
    pub fn new(size: usize) -> PasteID {
        PasteID(String::from(from_utf8(strgen::generate(size).as_slice()).unwrap()))
    }

    // returns the filename associated with the id
    pub fn filename(&self) -> String {
        format!("upload/{}", self.0)
    }
}

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

impl FromStr for PasteID {
    type Err = ParseError;
    fn from_str(s: &str) -> Result<PasteID, ParseError> {
        if s.len() > MAX_SIZE {
            return Err(LengthTooLong);
        }

        if !s.as_bytes().iter().all(|&x| strgen::CHARACTERS.contains(&x)) {
            return Err(InvalidCharacters);
        }

        Ok(PasteID(String::from(s)))
    }
}
<|endoftext|>


<commit_before>use chrono::offset::Local;
use chrono::DateTime;

use ::bot::{Bot, Node, RoomEvent};
use super::backend::Backend;

pub struct AddQuote {
    quote_db: Backend,
}

impl AddQuote {
    pub fn new() -> Self {
        Self {
            quote_db: Backend::new()
        }
    }
}

impl<'a> Node<'a> for AddQuote {
    fn handle(&mut self, bot: &Bot, event: RoomEvent) {
        let revent = &event.raw_event;

        if revent.type_ == "m.room.message" &&
            revent.content["msgtype"] == "m.text" {
            let body = revent.content["body"].as_str().unwrap();

            if body.starts_with("addquote ") {
                let qid = self.quote_db.add_quote(&revent.sender, &body[9..]);
                let response = format!("Successfully added quote #{}!", qid);
                bot.reply(&event, &response);
            }

            else if body.starts_with("getquote ") {
                let qid: i32 = (body[9..]).parse().unwrap();
                if let Some((quoter, quote)) = self.quote_db.get_quote(qid) {
                    let datetime: DateTime<Local> = quote.time.into();

                    let response = format!("\"{}\" set by {} {}",
                                           quote.value,
                                           quoter.user_id,
                                           datetime.format("on %Y-%m-%d at %T"));
                    bot.reply(&event, &response);
                } else {
                    bot.reply(&event, "No quote by that id was found");
                }
            }

            else if body.starts_with("randquote") {
                if let Some((quoter, quote)) = self.quote_db.random_quote() {
                    let datetime: DateTime<Local> = quote.time.into();

                    let response = format!("\"{}\" set by {} {}",
                                           quote.value,
                                           quoter.user_id,
                                           datetime.format("on %Y-%m-%d at %T"));
                    bot.reply(&event, &response);
                } else {
                    bot.reply(&event, "No quotes.");
                }
            }
        }
    }
}
<commit_msg>Fix "!addquote sometext" fail because of non int<commit_after>use chrono::offset::Local;
use chrono::DateTime;

use ::bot::{Bot, Node, RoomEvent};
use super::backend::Backend;

pub struct AddQuote {
    quote_db: Backend,
}

impl AddQuote {
    pub fn new() -> Self {
        Self {
            quote_db: Backend::new()
        }
    }
}

impl<'a> Node<'a> for AddQuote {
    fn handle(&mut self, bot: &Bot, event: RoomEvent) {
        let revent = &event.raw_event;

        if revent.type_ == "m.room.message" &&
            revent.content["msgtype"] == "m.text" {
            let body = revent.content["body"].as_str().unwrap();

            if body.starts_with("addquote ") {
                let qid = self.quote_db.add_quote(&revent.sender, &body[9..]);
                let response = format!("Successfully added quote #{}!", qid);
                bot.reply(&event, &response);
            }

            else if body.starts_with("getquote ") {
                match body[9..].parse() {
                    Ok(qid) => {
                        if let Some((quoter, quote)) = self.quote_db.get_quote(qid) {
                            let datetime: DateTime<Local> = quote.time.into();

                            let response = format!("\"{}\" set by {} {}",
                                                   quote.value, quoter.user_id,
                                                   datetime.format("on %Y-%m-%d at %T"));
                            bot.reply(&event, &response)
                        } else {
                            bot.reply(&event, "No quote by that id was found")
                        }
                    },
                    Err(e) => bot.reply(&event, "Invalid quote id"),
                };
            }

            else if body.starts_with("randquote") {
                if let Some((quoter, quote)) = self.quote_db.random_quote() {
                    let datetime: DateTime<Local> = quote.time.into();

                    let response = format!("\"{}\" set by {} {}",
                                           quote.value,
                                           quoter.user_id,
                                           datetime.format("on %Y-%m-%d at %T"));
                    bot.reply(&event, &response);
                } else {
                    bot.reply(&event, "No quotes.");
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use data_types;
use gl;
use libc;
use std::{fmt, mem, ptr};
use std::collections::HashMap;
use std::sync::Arc;
use texture;
use {Display, DisplayImpl, Texture};

struct Shader {
    display: Arc<DisplayImpl>,
    id: gl::types::GLuint,
}

impl Drop for Shader {
    fn drop(&mut self) {
        let id = self.id.clone();
        self.display.context.exec(proc(gl, _state) {
            gl.DeleteShader(id);
        });
    }
}

/// A combinaison of shaders linked together.
pub struct Program {
    program: Arc<ProgramImpl>
}

/// Error that can be triggered when creating a `Program`.
#[deriving(Clone, Show)]
pub enum ProgramCreationError {
    /// Error while compiling one of the shaders.
    CompilationError(String),

    /// Error while linking the program.
    LinkingError(String),

    /// `glCreateProgram` failed.
    ProgramCreationFailure,

    /// One of the request shader type is not supported by the backend.
    ///
    /// Usually the case of geometry shaders.
    ShaderTypeNotSupported,
}

impl Program {
    /// Builds a new program.
    ///
    /// A program is a group of shaders linked together.
    ///
    /// # Parameters
    ///
    /// - `vertex_shader`: Source code of the vertex shader.
    /// - `fragment_shader`: Source code of the fragment shader.
    /// - `geometry_shader`: Source code of the geometry shader.
    ///
    /// # Example
    ///
    /// ```no_run
    /// # let display: glium::Display = unsafe { std::mem::uninitialized() };
    /// # let vertex_source = ""; let fragment_source = ""; let geometry_source = "";
    /// let program = glium::Program::new(&display, vertex_source, fragment_source, Some(geometry_source));
    /// ```
    ///
    #[experimental = "The list of shaders and the result error will probably change"]
    pub fn new(display: &Display, vertex_shader: &str, fragment_shader: &str,
               geometry_shader: Option<&str>) -> Result<Program, ProgramCreationError>
    {
        let mut shaders_store = Vec::new();
        shaders_store.push(try!(build_shader(display, gl::VERTEX_SHADER, vertex_shader)));
        match geometry_shader {
            Some(gs) => shaders_store.push(try!(build_geometry_shader(display, gs))),
            None => ()
        }
        shaders_store.push(try!(build_shader(display, gl::FRAGMENT_SHADER, fragment_shader)));

        let mut shaders_ids = Vec::new();
        for sh in shaders_store.iter() {
            shaders_ids.push(sh.id);
        }

        let (tx, rx) = channel();
        display.context.context.exec(proc(gl, _state) {
            unsafe {
                let id = gl.CreateProgram();
                if id == 0 {
                    tx.send(Err(ProgramCreationFailure));
                    return;
                }

                // attaching shaders
                for sh in shaders_ids.iter() {
                    gl.AttachShader(id, sh.clone());
                }

                // linking and checking for errors
                gl.LinkProgram(id);
                {   let mut link_success: gl::types::GLint = mem::uninitialized();
                    gl.GetProgramiv(id, gl::LINK_STATUS, &mut link_success);
                    if link_success == 0 {
                        match gl.GetError() {
                            gl::NO_ERROR => (),
                            gl::INVALID_VALUE => {
                                tx.send(Err(LinkingError(format!("glLinkProgram triggered GL_INVALID_VALUE"))));
                                return;
                            },
                            gl::INVALID_OPERATION => {
                                tx.send(Err(LinkingError(format!("glLinkProgram triggered GL_INVALID_OPERATION"))));
                                return;
                            },
                            _ => {
                                tx.send(Err(LinkingError(format!("glLinkProgram triggered an unknown error"))));
                                return;
                            }
                        };

                        let mut error_log_size: gl::types::GLint = mem::uninitialized();
                        gl.GetProgramiv(id, gl::INFO_LOG_LENGTH, &mut error_log_size);

                        let mut error_log: Vec<u8> = Vec::with_capacity(error_log_size as uint);
                        gl.GetProgramInfoLog(id, error_log_size, &mut error_log_size, error_log.as_mut_slice().as_mut_ptr() as *mut gl::types::GLchar);
                        error_log.set_len(error_log_size as uint);

                        let msg = String::from_utf8(error_log).unwrap();
                        tx.send(Err(LinkingError(msg)));
                        return;
                    }
                }

                tx.send(Ok(id));
            }
        });

        let id = try!(rx.recv());

        let (tx, rx) = channel();
        display.context.context.exec(proc(gl, _state) {
            unsafe {
                // reflecting program uniforms
                let mut uniforms = HashMap::new();

                let mut active_uniforms: gl::types::GLint = mem::uninitialized();
                gl.GetProgramiv(id, gl::ACTIVE_UNIFORMS, &mut active_uniforms);

                for uniform_id in range(0, active_uniforms) {
                    let mut uniform_name_tmp: Vec<u8> = Vec::with_capacity(64);
                    let mut uniform_name_tmp_len = 63;

                    let mut data_type: gl::types::GLenum = mem::uninitialized();
                    let mut data_size: gl::types::GLint = mem::uninitialized();
                    gl.GetActiveUniform(id, uniform_id as gl::types::GLuint, uniform_name_tmp_len, &mut uniform_name_tmp_len, &mut data_size, &mut data_type, uniform_name_tmp.as_mut_slice().as_mut_ptr() as *mut gl::types::GLchar);
                    uniform_name_tmp.set_len(uniform_name_tmp_len as uint);

                    let uniform_name = String::from_utf8(uniform_name_tmp).unwrap();
                    let location = gl.GetUniformLocation(id, uniform_name.to_c_str().unwrap());

                    uniforms.insert(uniform_name, (location, data_type, data_size));
                }

                tx.send(Arc::new(uniforms));
            }
        });

        Ok(Program {
            program: Arc::new(ProgramImpl {
                display: display.context.clone(),
                shaders: shaders_store,
                id: id,
                uniforms: rx.recv(),
            })
        })
    }
}

impl fmt::Show for Program {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::FormatError> {
        (format!("Program #{}", self.program.id)).fmt(formatter)
    }
}

pub fn get_program_id(program: &Program) -> gl::types::GLuint {
    program.program.id
}

pub fn get_uniforms_locations(program: &Program) -> Arc<HashMap<String, (gl::types::GLint, gl::types::GLenum, gl::types::GLint)>> {
    program.program.uniforms.clone()
}

struct ProgramImpl {
    display: Arc<DisplayImpl>,
    #[allow(dead_code)]
    shaders: Vec<Arc<Shader>>,
    id: gl::types::GLuint,
    uniforms: Arc<HashMap<String, (gl::types::GLint, gl::types::GLenum, gl::types::GLint)>>     // location, type and size of each uniform, ordered by name
}

impl Drop for ProgramImpl {
    fn drop(&mut self) {
        let id = self.id.clone();
        self.display.context.exec(proc(gl, state) {
            if state.program == id {
                gl.UseProgram(0);
                state.program = 0;
            }

            gl.DeleteProgram(id);
        });
    }
}

/// Builds an individual shader.
fn build_shader<S: ToCStr>(display: &Display, shader_type: gl::types::GLenum, source_code: S)
    -> Result<Arc<Shader>, ProgramCreationError>
{
    let source_code = source_code.to_c_str();

    let (tx, rx) = channel();
    display.context.context.exec(proc(gl, _state) {
        unsafe {
            let id = gl.CreateShader(shader_type);

            if id == 0 {
                tx.send(Err(ShaderTypeNotSupported));
                return;
            }

            gl.ShaderSource(id, 1, [ source_code.as_ptr() ].as_ptr(), ptr::null());
            gl.CompileShader(id);

            // checking compilation success
            let compilation_success = {
                let mut compilation_success: gl::types::GLint = mem::uninitialized();
                gl.GetShaderiv(id, gl::COMPILE_STATUS, &mut compilation_success);
                compilation_success
            };

            if compilation_success == 0 {
                // compilation error
                let mut error_log_size: gl::types::GLint = mem::uninitialized();
                gl.GetShaderiv(id, gl::INFO_LOG_LENGTH, &mut error_log_size);

                let mut error_log: Vec<u8> = Vec::with_capacity(error_log_size as uint);
                gl.GetShaderInfoLog(id, error_log_size, &mut error_log_size, error_log.as_mut_slice().as_mut_ptr() as *mut gl::types::GLchar);
                error_log.set_len(error_log_size as uint);

                let msg = String::from_utf8(error_log).unwrap();
                tx.send(Err(CompilationError(msg)));
                return;
            }

            tx.send(Ok(id));
        }
    });

    rx.recv().map(|id| {
        Arc::new(Shader {
            display: display.context.clone(),
            id: id
        })
    })
}

#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
fn build_geometry_shader<S: ToCStr>(display: &Display, source_code: S)
    -> Result<Arc<Shader>, ProgramCreationError>
{
    build_shader(display, gl::GEOMETRY_SHADER, source_code)
}

#[cfg(target_os = "android")]
fn build_geometry_shader<S: ToCStr>(display: &Display, source_code: S)
    -> Result<Arc<Shader>, ProgramCreationError>
{
    Err(ShaderTypeNotSupported)
}
<commit_msg>Remove ProgramImpl<commit_after>use data_types;
use gl;
use libc;
use std::{fmt, mem, ptr};
use std::collections::HashMap;
use std::sync::Arc;
use texture;
use {Display, DisplayImpl, Texture};

struct Shader {
    display: Arc<DisplayImpl>,
    id: gl::types::GLuint,
}

impl Drop for Shader {
    fn drop(&mut self) {
        let id = self.id.clone();
        self.display.context.exec(proc(gl, _state) {
            gl.DeleteShader(id);
        });
    }
}

/// A combinaison of shaders linked together.
pub struct Program {
    display: Arc<DisplayImpl>,
    #[allow(dead_code)]
    shaders: Vec<Arc<Shader>>,
    id: gl::types::GLuint,
    uniforms: Arc<HashMap<String, (gl::types::GLint, gl::types::GLenum, gl::types::GLint)>>     // location, type and size of each uniform, ordered by name
}

/// Error that can be triggered when creating a `Program`.
#[deriving(Clone, Show)]
pub enum ProgramCreationError {
    /// Error while compiling one of the shaders.
    CompilationError(String),

    /// Error while linking the program.
    LinkingError(String),

    /// `glCreateProgram` failed.
    ProgramCreationFailure,

    /// One of the request shader type is not supported by the backend.
    ///
    /// Usually the case of geometry shaders.
    ShaderTypeNotSupported,
}

impl Program {
    /// Builds a new program.
    ///
    /// A program is a group of shaders linked together.
    ///
    /// # Parameters
    ///
    /// - `vertex_shader`: Source code of the vertex shader.
    /// - `fragment_shader`: Source code of the fragment shader.
    /// - `geometry_shader`: Source code of the geometry shader.
    ///
    /// # Example
    ///
    /// ```no_run
    /// # let display: glium::Display = unsafe { std::mem::uninitialized() };
    /// # let vertex_source = ""; let fragment_source = ""; let geometry_source = "";
    /// let program = glium::Program::new(&display, vertex_source, fragment_source, Some(geometry_source));
    /// ```
    ///
    #[experimental = "The list of shaders and the result error will probably change"]
    pub fn new(display: &Display, vertex_shader: &str, fragment_shader: &str,
               geometry_shader: Option<&str>) -> Result<Program, ProgramCreationError>
    {
        let mut shaders_store = Vec::new();
        shaders_store.push(try!(build_shader(display, gl::VERTEX_SHADER, vertex_shader)));
        match geometry_shader {
            Some(gs) => shaders_store.push(try!(build_geometry_shader(display, gs))),
            None => ()
        }
        shaders_store.push(try!(build_shader(display, gl::FRAGMENT_SHADER, fragment_shader)));

        let mut shaders_ids = Vec::new();
        for sh in shaders_store.iter() {
            shaders_ids.push(sh.id);
        }

        let (tx, rx) = channel();
        display.context.context.exec(proc(gl, _state) {
            unsafe {
                let id = gl.CreateProgram();
                if id == 0 {
                    tx.send(Err(ProgramCreationFailure));
                    return;
                }

                // attaching shaders
                for sh in shaders_ids.iter() {
                    gl.AttachShader(id, sh.clone());
                }

                // linking and checking for errors
                gl.LinkProgram(id);
                {   let mut link_success: gl::types::GLint = mem::uninitialized();
                    gl.GetProgramiv(id, gl::LINK_STATUS, &mut link_success);
                    if link_success == 0 {
                        match gl.GetError() {
                            gl::NO_ERROR => (),
                            gl::INVALID_VALUE => {
                                tx.send(Err(LinkingError(format!("glLinkProgram triggered GL_INVALID_VALUE"))));
                                return;
                            },
                            gl::INVALID_OPERATION => {
                                tx.send(Err(LinkingError(format!("glLinkProgram triggered GL_INVALID_OPERATION"))));
                                return;
                            },
                            _ => {
                                tx.send(Err(LinkingError(format!("glLinkProgram triggered an unknown error"))));
                                return;
                            }
                        };

                        let mut error_log_size: gl::types::GLint = mem::uninitialized();
                        gl.GetProgramiv(id, gl::INFO_LOG_LENGTH, &mut error_log_size);

                        let mut error_log: Vec<u8> = Vec::with_capacity(error_log_size as uint);
                        gl.GetProgramInfoLog(id, error_log_size, &mut error_log_size, error_log.as_mut_slice().as_mut_ptr() as *mut gl::types::GLchar);
                        error_log.set_len(error_log_size as uint);

                        let msg = String::from_utf8(error_log).unwrap();
                        tx.send(Err(LinkingError(msg)));
                        return;
                    }
                }

                tx.send(Ok(id));
            }
        });

        let id = try!(rx.recv());

        let (tx, rx) = channel();
        display.context.context.exec(proc(gl, _state) {
            unsafe {
                // reflecting program uniforms
                let mut uniforms = HashMap::new();

                let mut active_uniforms: gl::types::GLint = mem::uninitialized();
                gl.GetProgramiv(id, gl::ACTIVE_UNIFORMS, &mut active_uniforms);

                for uniform_id in range(0, active_uniforms) {
                    let mut uniform_name_tmp: Vec<u8> = Vec::with_capacity(64);
                    let mut uniform_name_tmp_len = 63;

                    let mut data_type: gl::types::GLenum = mem::uninitialized();
                    let mut data_size: gl::types::GLint = mem::uninitialized();
                    gl.GetActiveUniform(id, uniform_id as gl::types::GLuint, uniform_name_tmp_len, &mut uniform_name_tmp_len, &mut data_size, &mut data_type, uniform_name_tmp.as_mut_slice().as_mut_ptr() as *mut gl::types::GLchar);
                    uniform_name_tmp.set_len(uniform_name_tmp_len as uint);

                    let uniform_name = String::from_utf8(uniform_name_tmp).unwrap();
                    let location = gl.GetUniformLocation(id, uniform_name.to_c_str().unwrap());

                    uniforms.insert(uniform_name, (location, data_type, data_size));
                }

                tx.send(Arc::new(uniforms));
            }
        });

        Ok(Program {
            display: display.context.clone(),
            shaders: shaders_store,
            id: id,
            uniforms: rx.recv(),
        })
    }
}

impl fmt::Show for Program {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::FormatError> {
        (format!("Program #{}", self.id)).fmt(formatter)
    }
}

pub fn get_program_id(program: &Program) -> gl::types::GLuint {
    program.id
}

pub fn get_uniforms_locations(program: &Program) -> Arc<HashMap<String, (gl::types::GLint, gl::types::GLenum, gl::types::GLint)>> {
    program.uniforms.clone()
}

impl Drop for Program {
    fn drop(&mut self) {
        let id = self.id.clone();
        self.display.context.exec(proc(gl, state) {
            if state.program == id {
                gl.UseProgram(0);
                state.program = 0;
            }

            gl.DeleteProgram(id);
        });
    }
}

/// Builds an individual shader.
fn build_shader<S: ToCStr>(display: &Display, shader_type: gl::types::GLenum, source_code: S)
    -> Result<Arc<Shader>, ProgramCreationError>
{
    let source_code = source_code.to_c_str();

    let (tx, rx) = channel();
    display.context.context.exec(proc(gl, _state) {
        unsafe {
            let id = gl.CreateShader(shader_type);

            if id == 0 {
                tx.send(Err(ShaderTypeNotSupported));
                return;
            }

            gl.ShaderSource(id, 1, [ source_code.as_ptr() ].as_ptr(), ptr::null());
            gl.CompileShader(id);

            // checking compilation success
            let compilation_success = {
                let mut compilation_success: gl::types::GLint = mem::uninitialized();
                gl.GetShaderiv(id, gl::COMPILE_STATUS, &mut compilation_success);
                compilation_success
            };

            if compilation_success == 0 {
                // compilation error
                let mut error_log_size: gl::types::GLint = mem::uninitialized();
                gl.GetShaderiv(id, gl::INFO_LOG_LENGTH, &mut error_log_size);

                let mut error_log: Vec<u8> = Vec::with_capacity(error_log_size as uint);
                gl.GetShaderInfoLog(id, error_log_size, &mut error_log_size, error_log.as_mut_slice().as_mut_ptr() as *mut gl::types::GLchar);
                error_log.set_len(error_log_size as uint);

                let msg = String::from_utf8(error_log).unwrap();
                tx.send(Err(CompilationError(msg)));
                return;
            }

            tx.send(Ok(id));
        }
    });

    rx.recv().map(|id| {
        Arc::new(Shader {
            display: display.context.clone(),
            id: id
        })
    })
}

#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
fn build_geometry_shader<S: ToCStr>(display: &Display, source_code: S)
    -> Result<Arc<Shader>, ProgramCreationError>
{
    build_shader(display, gl::GEOMETRY_SHADER, source_code)
}

#[cfg(target_os = "android")]
fn build_geometry_shader<S: ToCStr>(display: &Display, source_code: S)
    -> Result<Arc<Shader>, ProgramCreationError>
{
    Err(ShaderTypeNotSupported)
}
<|endoftext|>