<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::io::Write;

use syn;

use crate::bindgen::cdecl;
use crate::bindgen::config::{Config, Layout};
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
use crate::bindgen::dependencies::Dependencies;
use crate::bindgen::ir::{
    AnnotationSet, Cfg, ConditionWrite, Documentation, GenericPath, Path, PrimitiveType,
    ToCondition, Type,
};
use crate::bindgen::library::Library;
use crate::bindgen::monomorph::Monomorphs;
use crate::bindgen::rename::{IdentifierType, RenameRule};
use crate::bindgen::reserved;
use crate::bindgen::utilities::{find_first_some, IterHelpers};
use crate::bindgen::writer::{Source, SourceWriter};

#[derive(Debug, Clone)]
pub struct Function {
    pub path: Path,
    /// Path to the self-type of the function
    /// If the function is a method, this will contain the path of the type in the impl block
    pub self_type_path: Option<Path>,
    pub ret: Type,
    pub args: Vec<(String, Type)>,
    pub extern_decl: bool,
    pub cfg: Option<Cfg>,
    pub annotations: AnnotationSet,
    pub documentation: Documentation,
}

impl Function {
    pub fn load(
        path: Path,
        self_type_path: Option<&Path>,
        sig: &syn::Signature,
        extern_decl: bool,
        attrs: &[syn::Attribute],
        mod_cfg: Option<&Cfg>,
    ) -> Result<Function, String> {
        let mut args = sig.inputs.iter().try_skip_map(|x| x.as_ident_and_type())?;

        let mut ret = match sig.output {
            syn::ReturnType::Default => Type::Primitive(PrimitiveType::Void),
            syn::ReturnType::Type(_, ref ty) => {
                Type::load(ty)?.unwrap_or_else(|| Type::Primitive(PrimitiveType::Void))
            }
        };

        if let Some(self_path) = self_type_path {
            for (_, ref mut ty) in &mut args {
                ty.replace_self_with(self_path);
            }
            ret.replace_self_with(self_path);
        }

        Ok(Function {
            path,
            self_type_path: self_type_path.cloned(),
            ret,
            args,
            extern_decl,
            cfg: Cfg::append(mod_cfg, Cfg::load(attrs)),
            annotations: AnnotationSet::load(attrs)?,
            documentation: Documentation::load(attrs),
        })
    }

    pub fn swift_name(&self) -> String {
        // If the symbol name starts with the type name, separate the two components with '.'
        // so that Swift recognises the association between the method and the type
        let (ref type_prefix, ref type_name) = match self.self_type_path {
            Some(ref type_name) => {
                let type_name = type_name.to_string();
                if !self.path.name().starts_with(&type_name) {
                    return self.path.to_string();
                }
                (format!("{}.", type_name), type_name)
            }
            None => ("".to_string(), "".to_string()),
        };

        let item_name = self
            .path
            .name()
            .trim_start_matches(type_name)
            .trim_start_matches('_');

        let item_args = {
            let mut items = vec![];
            for (arg, _) in self.args.iter() {
                items.push(format!("{}:", arg.as_str()));
            }
            items.join("")
        };
        format!("{}{}({})", type_prefix, item_name, item_args)
    }

    pub fn path(&self) -> &Path {
        &self.path
    }

    pub fn simplify_standard_types(&mut self) {
        self.ret.simplify_standard_types();
        for &mut (_, ref mut ty) in &mut self.args {
            ty.simplify_standard_types();
        }
    }

    pub fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
        self.ret.add_dependencies(library, out);
        for &(_, ref ty) in &self.args {
            ty.add_dependencies(library, out);
        }
    }

    pub fn add_monomorphs(&self, library: &Library, out: &mut Monomorphs) {
        self.ret.add_monomorphs(library, out);
        for &(_, ref ty) in &self.args {
            ty.add_monomorphs(library, out);
        }
    }

    pub fn mangle_paths(&mut self, monomorphs: &Monomorphs) {
        self.ret.mangle_paths(monomorphs);
        for &mut (_, ref mut ty) in &mut self.args {
            ty.mangle_paths(monomorphs);
        }
    }

    pub fn resolve_declaration_types(&mut self, resolver: &DeclarationTypeResolver) {
        self.ret.resolve_declaration_types(resolver);
        for &mut (_, ref mut ty) in &mut self.args {
            ty.resolve_declaration_types(resolver);
        }
    }

    pub fn rename_for_config(&mut self, config: &Config) {
        // Rename the types used in arguments
        let generic_params = Default::default();
        self.ret.rename_for_config(config, &generic_params);
        for &mut (_, ref mut ty) in &mut self.args {
            ty.rename_for_config(config, &generic_params);
        }

        // Apply rename rules to argument names
        let rules = [
            self.annotations.parse_atom::<RenameRule>("rename-all"),
            config.function.rename_args,
        ];

        if let Some(r) = find_first_some(&rules) {
            self.args = self
                .args
                .iter()
                .map(|x| (r.apply(&x.0, IdentifierType::FunctionArg), x.1.clone()))
                .collect()
        }

        // Escape C/C++ reserved keywords used in argument names
        for args in &mut self.args {
            reserved::escape(&mut args.0);
        }
    }
}

impl Source for Function {
    fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
        fn write_1<W: Write>(func: &Function, config: &Config, out: &mut SourceWriter<W>) {
            let prefix = config.function.prefix(&func.annotations);
            let postfix = config.function.postfix(&func.annotations);

            let condition = func.cfg.to_condition(config);
            condition.write_before(config, out);

            func.documentation.write(config, out);

            if func.extern_decl {
                out.write("extern ");
            } else {
                if let Some(ref prefix) = prefix {
                    write!(out, "{} ", prefix);
                }
                if func.annotations.must_use {
                    if let Some(ref anno) = config.function.must_use {
                        write!(out, "{} ", anno);
                    }
                }
            }
            cdecl::write_func(out, &func, false, config);

            if !func.extern_decl {
                if let Some(ref postfix) = postfix {
                    write!(out, " {}", postfix);
                }
            }

            if let Some(ref swift_name_macro) = config.function.swift_name_macro {
                write!(out, " {}({})", swift_name_macro, func.swift_name());
            }

            out.write(";");

            condition.write_after(config, out);
        }

        fn write_2<W: Write>(func: &Function, config: &Config, out: &mut SourceWriter<W>) {
            let prefix = config.function.prefix(&func.annotations);
            let postfix = config.function.postfix(&func.annotations);

            let condition = func.cfg.to_condition(config);

            condition.write_before(config, out);

            func.documentation.write(config, out);

            if func.extern_decl {
                out.write("extern ");
            } else {
                if let Some(ref prefix) = prefix {
                    write!(out, "{}", prefix);
                    out.new_line();
                }
                if func.annotations.must_use {
                    if let Some(ref anno) = config.function.must_use {
                        write!(out, "{}", anno);
                        out.new_line();
                    }
                }
            }
            cdecl::write_func(out, &func, true, config);
            if !func.extern_decl {
                if let Some(ref postfix) = postfix {
                    out.new_line();
                    write!(out, "{}", postfix);
                }
            }

            if let Some(ref swift_name_macro) = config.function.swift_name_macro {
                write!(out, " {}({})", swift_name_macro, func.swift_name());
            }

            out.write(";");

            condition.write_after(config, out);
        };

        let option_1 = out.measure(|out| write_1(self, config, out));

        if (config.function.args == Layout::Auto && option_1 <= config.line_length)
            || config.function.args == Layout::Horizontal
        {
            write_1(self, config, out);
        } else {
            write_2(self, config, out);
        }
    }
}

pub trait SynFnArgHelpers {
    fn as_ident_and_type(&self) -> Result<Option<(String, Type)>, String>;
}

fn gen_self_type(receiver: &syn::Receiver) -> Type {
    let self_ty = Type::Path(GenericPath::self_path());
    match receiver.reference {
        Some(_) => match receiver.mutability {
            Some(_) => Type::Ptr(Box::new(self_ty)),
            None => Type::ConstPtr(Box::new(self_ty)),
        },
        None => self_ty,
    }
}

impl SynFnArgHelpers for syn::FnArg {
    fn as_ident_and_type(&self) -> Result<Option<(String, Type)>, String> {
        match *self {
            syn::FnArg::Typed(syn::PatType {
                ref pat, ref ty, ..
            }) => match **pat {
                syn::Pat::Ident(syn::PatIdent { ref ident, .. }) => {
                    let ty = match Type::load(ty)? {
                        Some(x) => x,
                        None => return Ok(None),
                    };
                    Ok(Some((ident.to_string(), ty)))
                }
                _ => Err("Parameter has an unsupported type.".to_owned()),
            },
            syn::FnArg::Receiver(ref receiver) => {
                Ok(Some(("self".to_string(), gen_self_type(receiver))))
            }
        }
    }
}
<commit_msg>Do not accept array as function arguments<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::io::Write;

use syn;

use crate::bindgen::cdecl;
use crate::bindgen::config::{Config, Layout};
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
use crate::bindgen::dependencies::Dependencies;
use crate::bindgen::ir::{
    AnnotationSet, Cfg, ConditionWrite, Documentation, GenericPath, Path, PrimitiveType,
    ToCondition, Type,
};
use crate::bindgen::library::Library;
use crate::bindgen::monomorph::Monomorphs;
use crate::bindgen::rename::{IdentifierType, RenameRule};
use crate::bindgen::reserved;
use crate::bindgen::utilities::{find_first_some, IterHelpers};
use crate::bindgen::writer::{Source, SourceWriter};

#[derive(Debug, Clone)]
pub struct Function {
    pub path: Path,
    /// Path to the self-type of the function
    /// If the function is a method, this will contain the path of the type in the impl block
    pub self_type_path: Option<Path>,
    pub ret: Type,
    pub args: Vec<(String, Type)>,
    pub extern_decl: bool,
    pub cfg: Option<Cfg>,
    pub annotations: AnnotationSet,
    pub documentation: Documentation,
}

impl Function {
    pub fn load(
        path: Path,
        self_type_path: Option<&Path>,
        sig: &syn::Signature,
        extern_decl: bool,
        attrs: &[syn::Attribute],
        mod_cfg: Option<&Cfg>,
    ) -> Result<Function, String> {
        let mut args = sig.inputs.iter().try_skip_map(|x| x.as_ident_and_type())?;

        let mut ret = match sig.output {
            syn::ReturnType::Default => Type::Primitive(PrimitiveType::Void),
            syn::ReturnType::Type(_, ref ty) => {
                Type::load(ty)?.unwrap_or_else(|| Type::Primitive(PrimitiveType::Void))
            }
        };

        if let Some(self_path) = self_type_path {
            for (_, ref mut ty) in &mut args {
                ty.replace_self_with(self_path);
            }
            ret.replace_self_with(self_path);
        }

        Ok(Function {
            path,
            self_type_path: self_type_path.cloned(),
            ret,
            args,
            extern_decl,
            cfg: Cfg::append(mod_cfg, Cfg::load(attrs)),
            annotations: AnnotationSet::load(attrs)?,
            documentation: Documentation::load(attrs),
        })
    }

    pub fn swift_name(&self) -> String {
        // If the symbol name starts with the type name, separate the two components with '.'
        // so that Swift recognises the association between the method and the type
        let (ref type_prefix, ref type_name) = match self.self_type_path {
            Some(ref type_name) => {
                let type_name = type_name.to_string();
                if !self.path.name().starts_with(&type_name) {
                    return self.path.to_string();
                }
                (format!("{}.", type_name), type_name)
            }
            None => ("".to_string(), "".to_string()),
        };

        let item_name = self
            .path
            .name()
            .trim_start_matches(type_name)
            .trim_start_matches('_');

        let item_args = {
            let mut items = vec![];
            for (arg, _) in self.args.iter() {
                items.push(format!("{}:", arg.as_str()));
            }
            items.join("")
        };
        format!("{}{}({})", type_prefix, item_name, item_args)
    }

    pub fn path(&self) -> &Path {
        &self.path
    }

    pub fn simplify_standard_types(&mut self) {
        self.ret.simplify_standard_types();
        for &mut (_, ref mut ty) in &mut self.args {
            ty.simplify_standard_types();
        }
    }

    pub fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
        self.ret.add_dependencies(library, out);
        for &(_, ref ty) in &self.args {
            ty.add_dependencies(library, out);
        }
    }

    pub fn add_monomorphs(&self, library: &Library, out: &mut Monomorphs) {
        self.ret.add_monomorphs(library, out);
        for &(_, ref ty) in &self.args {
            ty.add_monomorphs(library, out);
        }
    }

    pub fn mangle_paths(&mut self, monomorphs: &Monomorphs) {
        self.ret.mangle_paths(monomorphs);
        for &mut (_, ref mut ty) in &mut self.args {
            ty.mangle_paths(monomorphs);
        }
    }

    pub fn resolve_declaration_types(&mut self, resolver: &DeclarationTypeResolver) {
        self.ret.resolve_declaration_types(resolver);
        for &mut (_, ref mut ty) in &mut self.args {
            ty.resolve_declaration_types(resolver);
        }
    }

    pub fn rename_for_config(&mut self, config: &Config) {
        // Rename the types used in arguments
        let generic_params = Default::default();
        self.ret.rename_for_config(config, &generic_params);
        for &mut (_, ref mut ty) in &mut self.args {
            ty.rename_for_config(config, &generic_params);
        }

        // Apply rename rules to argument names
        let rules = [
            self.annotations.parse_atom::<RenameRule>("rename-all"),
            config.function.rename_args,
        ];

        if let Some(r) = find_first_some(&rules) {
            self.args = self
                .args
                .iter()
                .map(|x| (r.apply(&x.0, IdentifierType::FunctionArg), x.1.clone()))
                .collect()
        }

        // Escape C/C++ reserved keywords used in argument names
        for args in &mut self.args {
            reserved::escape(&mut args.0);
        }
    }
}

impl Source for Function {
    fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
        fn write_1<W: Write>(func: &Function, config: &Config, out: &mut SourceWriter<W>) {
            let prefix = config.function.prefix(&func.annotations);
            let postfix = config.function.postfix(&func.annotations);

            let condition = func.cfg.to_condition(config);
            condition.write_before(config, out);

            func.documentation.write(config, out);

            if func.extern_decl {
                out.write("extern ");
            } else {
                if let Some(ref prefix) = prefix {
                    write!(out, "{} ", prefix);
                }
                if func.annotations.must_use {
                    if let Some(ref anno) = config.function.must_use {
                        write!(out, "{} ", anno);
                    }
                }
            }
            cdecl::write_func(out, &func, false, config);

            if !func.extern_decl {
                if let Some(ref postfix) = postfix {
                    write!(out, " {}", postfix);
                }
            }

            if let Some(ref swift_name_macro) = config.function.swift_name_macro {
                write!(out, " {}({})", swift_name_macro, func.swift_name());
            }

            out.write(";");

            condition.write_after(config, out);
        }

        fn write_2<W: Write>(func: &Function, config: &Config, out: &mut SourceWriter<W>) {
            let prefix = config.function.prefix(&func.annotations);
            let postfix = config.function.postfix(&func.annotations);

            let condition = func.cfg.to_condition(config);

            condition.write_before(config, out);

            func.documentation.write(config, out);

            if func.extern_decl {
                out.write("extern ");
            } else {
                if let Some(ref prefix) = prefix {
                    write!(out, "{}", prefix);
                    out.new_line();
                }
                if func.annotations.must_use {
                    if let Some(ref anno) = config.function.must_use {
                        write!(out, "{}", anno);
                        out.new_line();
                    }
                }
            }
            cdecl::write_func(out, &func, true, config);
            if !func.extern_decl {
                if let Some(ref postfix) = postfix {
                    out.new_line();
                    write!(out, "{}", postfix);
                }
            }

            if let Some(ref swift_name_macro) = config.function.swift_name_macro {
                write!(out, " {}({})", swift_name_macro, func.swift_name());
            }

            out.write(";");

            condition.write_after(config, out);
        };

        let option_1 = out.measure(|out| write_1(self, config, out));

        if (config.function.args == Layout::Auto && option_1 <= config.line_length)
            || config.function.args == Layout::Horizontal
        {
            write_1(self, config, out);
        } else {
            write_2(self, config, out);
        }
    }
}

pub trait SynFnArgHelpers {
    fn as_ident_and_type(&self) -> Result<Option<(String, Type)>, String>;
}

fn gen_self_type(receiver: &syn::Receiver) -> Type {
    let self_ty = Type::Path(GenericPath::self_path());
    match receiver.reference {
        Some(_) => match receiver.mutability {
            Some(_) => Type::Ptr(Box::new(self_ty)),
            None => Type::ConstPtr(Box::new(self_ty)),
        },
        None => self_ty,
    }
}

impl SynFnArgHelpers for syn::FnArg {
    fn as_ident_and_type(&self) -> Result<Option<(String, Type)>, String> {
        match *self {
            syn::FnArg::Typed(syn::PatType {
                ref pat, ref ty, ..
            }) => match **pat {
                syn::Pat::Ident(syn::PatIdent { ref ident, .. }) => {
                    let ty = match Type::load(ty)? {
                        Some(x) => {
                            if let Type::Array(_, _) = x {
                                return Err(
                                    "Array as function arguments are not supported".to_owned()
                                );
                            }
                            x
                        }
                        None => return Ok(None),
                    };
                    Ok(Some((ident.to_string(), ty)))
                }
                _ => Err("Parameter has an unsupported type.".to_owned()),
            },
            syn::FnArg::Receiver(ref receiver) => {
                Ok(Some(("self".to_string(), gen_self_type(receiver))))
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate sdl2;

fn main() {
    let sdl_context = sdl2::init().unwrap();
    let joystick_subsystem = sdl_context.joystick().unwrap();

    let available =
        match joystick_subsystem.num_joysticks() {
            Ok(n)  => n,
            Err(e) => panic!("can't enumerate joysticks: {}", e),
        };

    println!("{} joysticks available", available);

    let mut joystick = None;

    // Iterate over all available joysticks and stop once we manage to
    // open one.
    for id in 0..available {
        match joystick_subsystem.open(id) {
            Ok(c) => {
                println!("Success: opened \"{}\"", c.name());
                joystick = Some(c);
                break;
            },
            Err(e) => println!("failed: {:?}", e),
        }
    }

    if joystick.is_none() {
        panic!("Couldn't open any joystick");
    };

    for event in sdl_context.event_pump().unwrap().wait_iter() {
        use sdl2::event::Event;

        match event {
            Event::JoyAxisMotion{ axis_idx, value: val, .. } => {
                // Axis motion is an absolute value in the range
                // [-32768, 32767]. Let's simulate a very rough dead
                // zone to ignore spurious events.
                let dead_zone = 10_000;
                if val > dead_zone || val < -dead_zone {
                    println!("Axis {} moved to {}", axis_idx, val);
                }
            }
            Event::JoyButtonDown{ button_idx, .. } =>
                println!("Button {} down", button_idx),
            Event::JoyButtonUp{ button_idx, .. } =>
                println!("Button {} up", button_idx),
            Event::JoyHatMotion{ hat_idx, state, .. } =>
                println!("Hat {} moved to {:?}", hat_idx, state),
            Event::Quit{..} => break,
            _ => (),
        }
    }
}
<commit_msg>Use `power_level` in the joystick example<commit_after>extern crate sdl2;

fn main() {
    let sdl_context = sdl2::init().unwrap();
    let joystick_subsystem = sdl_context.joystick().unwrap();

    let available =
        match joystick_subsystem.num_joysticks() {
            Ok(n)  => n,
            Err(e) => panic!("can't enumerate joysticks: {}", e),
        };

    println!("{} joysticks available", available);

    let mut joystick = None;

    // Iterate over all available joysticks and stop once we manage to
    // open one.
    for id in 0..available {
        match joystick_subsystem.open(id) {
            Ok(c) => {
                println!("Success: opened \"{}\"", c.name());
                joystick = Some(c);
                break;
            },
            Err(e) => println!("failed: {:?}", e),
        }
    }

    // Print the joystick's power level, if a joystick was found.
    match joystick {
        Some(j) => {
            println!("\"{}\" power level: {:?}", j.name(), j.power_level().unwrap());
        },
        None => panic!("Couldn't open any joystick"),
    }

    for event in sdl_context.event_pump().unwrap().wait_iter() {
        use sdl2::event::Event;

        match event {
            Event::JoyAxisMotion{ axis_idx, value: val, .. } => {
                // Axis motion is an absolute value in the range
                // [-32768, 32767]. Let's simulate a very rough dead
                // zone to ignore spurious events.
                let dead_zone = 10_000;
                if val > dead_zone || val < -dead_zone {
                    println!("Axis {} moved to {}", axis_idx, val);
                }
            }
            Event::JoyButtonDown{ button_idx, .. } =>
                println!("Button {} down", button_idx),
            Event::JoyButtonUp{ button_idx, .. } =>
                println!("Button {} up", button_idx),
            Event::JoyHatMotion{ hat_idx, state, .. } =>
                println!("Hat {} moved to {:?}", hat_idx, state),
            Event::Quit{..} => break,
            _ => (),
        }
    }
}
<|endoftext|>


<commit_before>use super::*;

#[test]
fn stream_basic()
{
    let sink = Sink::new();
    let stream = sink.stream();
    let rx = stream.channel();
    let signal = stream.hold(0);

    sink.send(42);
    sink.send(33);
    sink.feed(0..5);

    let result: Vec<i32> = rx.try_iter().collect();
    assert_eq!(result, [42, 33, 0, 1, 2, 3, 4]);
    assert_eq!(signal.sample(), 4);
}

#[test]
fn signal_basic()
{
    let signal = Signal::constant(42);
    assert_eq!(signal.sample(), 42);
    signal.sample_with(|val| assert_eq!(*val, 42));

    let val = 33;
    let signal = Signal::from_fn(move || val);
    assert_eq!(signal.sample(), val);

    let sink = Sink::new();
    let signal = sink.stream().hold(0).map(|a| *a * 2);
    sink.send(2);
    sink.send(4);
    assert_eq!(signal.sample(), 8);
}

fn vec_cons<T: Clone>(mut v: Vec<T>, x: Cow<T>) -> Vec<T> { v.push(x.into_owned()); v }

#[test]
fn stream_operations()
{
    let sink: Sink<i32> = Sink::new();
    let stream = sink.stream();

    let s_string = stream.map(|a| a.to_string()).fold(vec![], vec_cons);
    let s_odd = stream.filter(|a| *a % 2 != 0).fold(vec![], vec_cons);
    let s_even_half = stream.filter_map(|a| if *a % 2 == 0 { Some(*a / 2) } else { None }).fold(vec![], vec_cons);
    let (pos, neg) = stream.map(|a| if *a > 0 { Ok(*a) } else { Err(*a) }).split();
    let s_pos = pos.fold(vec![], vec_cons);
    let s_neg = neg.fold(vec![], vec_cons);
    let s_merged = pos.merge(&neg.map(|a| -*a)).fold(vec![], vec_cons);
    let s_accum = stream.fold(vec![], vec_cons).snapshot(&stream, |s, _| s.into_owned()).fold(vec![], vec_cons);

    sink.feed(vec![5, 8, 13, -2, 42, -33]);

    assert_eq!(s_string.sample(), ["5", "8", "13", "-2", "42", "-33"]);
    assert_eq!(s_odd.sample(), [5, 13, -33]);
    assert_eq!(s_even_half.sample(), [4, -1, 21]);
    assert_eq!(s_pos.sample(), [5, 8, 13, 42]);
    assert_eq!(s_neg.sample(), [-2, -33]);
    assert_eq!(s_merged.sample(), [5, 8, 13, 2, 42, 33]);
    assert_eq!(s_accum.sample(), [vec![5], vec![5, 8], vec![5, 8, 13], vec![5, 8, 13, -2], vec![5, 8, 13, -2, 42], vec![5, 8, 13, -2, 42, -33]]);
}

#[cfg(feature="either")]
#[test]
fn merge_with()
{
    let sink1: Sink<i32> = Sink::new();
    let sink2: Sink<f32> = Sink::new();
    let stream: Stream<Result<_, _>> = sink1.stream().merge_with(&sink2.stream(), |e| e.either(|l| Ok(*l), |r| Err(*r)));
    let result = stream.fold(vec![], vec_cons);

    sink1.send(1);
    sink2.send(2.0);
    sink1.send(3);
    sink1.send(4);
    sink2.send(5.0);

    assert_eq!(result.sample(), [Ok(1), Err(2.0), Ok(3), Ok(4), Err(5.0)]);
}

#[test]
fn stream_channel()
{
    let sink = Sink::new();
    let rx = sink.stream().channel();

    let thread = std::thread::spawn(move || {
        let mut sum = 0;
        while let Some(val) = rx.recv().unwrap()
        {
            sum += val;
        }
        sum
    });
    sink.feed((1..100).map(Some));
    sink.send(None);

    let result = thread.join().unwrap();
    assert_eq!(result, 4950);
}

#[test]
fn stream_switch()
{
    let stream_sink = Sink::new();
    let sink1 = Sink::new();
    let sink2 = Sink::new();

    let switched = stream_sink.stream().switch();
    let events = switched.channel();

    sink1.send(1);
    sink2.send(2);

    stream_sink.send(sink2.stream());
    sink1.send(3);
    sink2.send(4);
    assert_eq!(events.try_recv(), Ok(4));

    stream_sink.send(sink1.stream());
    sink1.send(5);
    sink2.send(6);
    assert_eq!(events.try_recv(), Ok(5));
}

#[test]
fn signal_switch()
{
    let signal_sink = Sink::new();
    let switched = signal_sink.stream().hold(Signal::constant(0)).switch();

    signal_sink.send(Signal::constant(1));
    assert_eq!(switched.sample(), 1);

    signal_sink.send(Signal::constant(2));
    assert_eq!(switched.sample(), 2);
}
<commit_msg>added test case to detect unnecesary cloning<commit_after>use super::*;
use std::fmt::Debug;

#[test]
fn stream_basic()
{
    let sink = Sink::new();
    let stream = sink.stream();
    let rx = stream.channel();
    let signal = stream.hold(0);

    sink.send(42);
    sink.send(33);
    sink.feed(0..5);

    let result: Vec<i32> = rx.try_iter().collect();
    assert_eq!(result, [42, 33, 0, 1, 2, 3, 4]);
    assert_eq!(signal.sample(), 4);
}

#[test]
fn signal_basic()
{
    let signal = Signal::constant(42);
    assert_eq!(signal.sample(), 42);
    signal.sample_with(|val| assert_eq!(*val, 42));

    let val = 33;
    let signal = Signal::from_fn(move || val);
    assert_eq!(signal.sample(), val);

    let sink = Sink::new();
    let signal = sink.stream().hold(0).map(|a| *a * 2);
    sink.send(2);
    sink.send(4);
    assert_eq!(signal.sample(), 8);
}

fn vec_cons<T: Clone>(mut v: Vec<T>, x: Cow<T>) -> Vec<T> { v.push(x.into_owned()); v }

#[test]
fn stream_operations()
{
    let sink: Sink<i32> = Sink::new();
    let stream = sink.stream();

    let s_string = stream.map(|a| a.to_string()).fold(vec![], vec_cons);
    let s_odd = stream.filter(|a| *a % 2 != 0).fold(vec![], vec_cons);
    let s_even_half = stream.filter_map(|a| if *a % 2 == 0 { Some(*a / 2) } else { None }).fold(vec![], vec_cons);
    let (pos, neg) = stream.map(|a| if *a > 0 { Ok(*a) } else { Err(*a) }).split();
    let s_pos = pos.fold(vec![], vec_cons);
    let s_neg = neg.fold(vec![], vec_cons);
    let s_merged = pos.merge(&neg.map(|a| -*a)).fold(vec![], vec_cons);
    let s_accum = stream.fold(vec![], vec_cons).snapshot(&stream, |s, _| s.into_owned()).fold(vec![], vec_cons);

    sink.feed(vec![5, 8, 13, -2, 42, -33]);

    assert_eq!(s_string.sample(), ["5", "8", "13", "-2", "42", "-33"]);
    assert_eq!(s_odd.sample(), [5, 13, -33]);
    assert_eq!(s_even_half.sample(), [4, -1, 21]);
    assert_eq!(s_pos.sample(), [5, 8, 13, 42]);
    assert_eq!(s_neg.sample(), [-2, -33]);
    assert_eq!(s_merged.sample(), [5, 8, 13, 2, 42, 33]);
    assert_eq!(s_accum.sample(), [vec![5], vec![5, 8], vec![5, 8, 13], vec![5, 8, 13, -2], vec![5, 8, 13, -2, 42], vec![5, 8, 13, -2, 42, -33]]);
}

#[cfg(feature="either")]
#[test]
fn merge_with()
{
    let sink1: Sink<i32> = Sink::new();
    let sink2: Sink<f32> = Sink::new();
    let stream: Stream<Result<_, _>> = sink1.stream().merge_with(&sink2.stream(), |e| e.either(|l| Ok(*l), |r| Err(*r)));
    let result = stream.fold(vec![], vec_cons);

    sink1.send(1);
    sink2.send(2.0);
    sink1.send(3);
    sink1.send(4);
    sink2.send(5.0);

    assert_eq!(result.sample(), [Ok(1), Err(2.0), Ok(3), Ok(4), Err(5.0)]);
}

#[test]
fn stream_channel()
{
    let sink = Sink::new();
    let rx = sink.stream().channel();

    let thread = std::thread::spawn(move || {
        let mut sum = 0;
        while let Some(val) = rx.recv().unwrap()
        {
            sum += val;
        }
        sum
    });
    sink.feed((1..100).map(Some));
    sink.send(None);

    let result = thread.join().unwrap();
    assert_eq!(result, 4950);
}

#[test]
fn stream_switch()
{
    let stream_sink = Sink::new();
    let sink1 = Sink::new();
    let sink2 = Sink::new();

    let switched = stream_sink.stream().switch();
    let events = switched.channel();

    sink1.send(1);
    sink2.send(2);

    stream_sink.send(sink2.stream());
    sink1.send(3);
    sink2.send(4);
    assert_eq!(events.try_recv(), Ok(4));

    stream_sink.send(sink1.stream());
    sink1.send(5);
    sink2.send(6);
    assert_eq!(events.try_recv(), Ok(5));
}

#[test]
fn signal_switch()
{
    let signal_sink = Sink::new();
    let switched = signal_sink.stream().hold(Signal::constant(0)).switch();

    signal_sink.send(Signal::constant(1));
    assert_eq!(switched.sample(), 1);

    signal_sink.send(Signal::constant(2));
    assert_eq!(switched.sample(), 2);
}

#[derive(Debug)]
struct Storage<T>(Vec<T>);

impl<T> Storage<T>
{
    fn new() -> Self { Storage(Vec::new()) }
    fn push(mut self, a: T) -> Self { self.0.push(a); self }
}

impl<T: Debug> Clone for Storage<T>
{
    fn clone(&self) -> Self { panic!("storage cloned! {:?}", self.0) }
}

#[test]
fn cloning()
{
    let sink = Sink::new();
    let accum = sink.stream().fold(Storage::new(), |a, v| a.push(*v));

    sink.feed(0..5);
    accum.sample_with(|res| assert_eq!(res.0, [0, 1, 2, 3, 4]));
}
<|endoftext|>


<commit_before>extern crate collections;

use soundex::Soundex;

mod soundex;

fn check_soundex(word: ~str, expected: ~str) {
    let soundex = Soundex::new();
    assert_eq!(soundex.encode(word), expected);
}

#[test]
fn soundex_encoding_retains_sole_letter_of_one_letter_word() {
    check_soundex(~"A", ~"A000");
}

#[test]
fn soundex_encoding_pads_with_zeros_to_ensure_three_digits() {
    check_soundex(~"I", ~"I000");
}

#[test]
fn soundex_encoding_replaces_constants_with_appropriate_digits() {
    check_soundex(~"Ax", ~"A200");
}

#[test]
fn soundex_encoding_ignores_non_alphabetics() {
    check_soundex(~"A#", ~"A000");
}

#[test]
fn soundex_encoding_replaces_multiple_consonants_with_digits() {
    check_soundex(~"Acdl", ~"A234");
}

#[test]
fn soundex_encoding_limits_length_to_four_characters() {
    let soundex = Soundex::new();
    assert_eq!(soundex.encode("Dcdlb").len(), 4);
}
<commit_msg>Test that vowel like letters are skipped.<commit_after>extern crate collections;

use soundex::Soundex;

mod soundex;

fn check_soundex(word: ~str, expected: ~str) {
    let soundex = Soundex::new();
    assert_eq!(soundex.encode(word), expected);
}

#[test]
fn soundex_encoding_retains_sole_letter_of_one_letter_word() {
    check_soundex(~"A", ~"A000");
}

#[test]
fn soundex_encoding_pads_with_zeros_to_ensure_three_digits() {
    check_soundex(~"I", ~"I000");
}

#[test]
fn soundex_encoding_replaces_constants_with_appropriate_digits() {
    check_soundex(~"Ax", ~"A200");
}

#[test]
fn soundex_encoding_ignores_non_alphabetics() {
    check_soundex(~"A#", ~"A000");
}

#[test]
fn soundex_encoding_replaces_multiple_consonants_with_digits() {
    check_soundex(~"Acdl", ~"A234");
}

#[test]
fn soundex_encoding_limits_length_to_four_characters() {
    let soundex = Soundex::new();
    assert_eq!(soundex.encode("Dcdlb").len(), 4);
}

#[test]
fn soundex_encoding_ignores_vowel_like_letters() {
   check_soundex(~"Baeiouhycdl", ~"B234");
}
<|endoftext|>


<commit_before>/* Copyright 2016 Jordan Miner
 *
 * Licensed under the MIT license <LICENSE or
 * http://opensource.org/licenses/MIT>. This file may not be copied,
 * modified, or distributed except according to those terms.
 */

#[macro_use]
extern crate clear_coat;
extern crate iup_sys;
extern crate smallvec;

use std::rc::Rc;
use iup_sys::*;
use smallvec::SmallVec;

use clear_coat::*;
use clear_coat::common_attrs_cbs::*;

struct CursorsCanvas {
    canvas: Canvas,
}

impl CursorsCanvas {
    pub fn new() -> Self {
        CursorsCanvas {
            canvas: Canvas::new(),
        }
    }
}

impl CursorAttribute for CursorsCanvas {}

unsafe impl Control for CursorsCanvas {
    fn handle(&self) -> *mut Ihandle {
        self.canvas.handle()
    }
}

fn create_cursors_page() -> Box<Control> {
    let cursors_canvas = Rc::new(CursorsCanvas::new());

    let radios_info = [
        ("None", Cursor::None),
        ("Arrow", Cursor::Arrow),
        ("Busy", Cursor::Busy),
        ("Cross", Cursor::Cross),
        ("Hand", Cursor::Hand),
        ("Help", Cursor::Help),
        ("Move", Cursor::Move),
        ("ResizeN", Cursor::ResizeN),
        ("ResizeS", Cursor::ResizeS),
        ("ResizeNS", Cursor::ResizeNS),
        ("ResizeW", Cursor::ResizeW),
        ("ResizeE", Cursor::ResizeE),
        ("ResizeWE", Cursor::ResizeWE),
        ("ResizeNE", Cursor::ResizeNE),
        ("ResizeSW", Cursor::ResizeSW),
        ("ResizeNW", Cursor::ResizeNW),
        ("ResizeSE", Cursor::ResizeSE),
        ("Text", Cursor::Text),
    ];

    let mut radios = SmallVec::<[Toggle; 32]>::new();
    for &(text, cur) in radios_info.iter() {
        let toggle = Toggle::new();
        toggle.set_title(text);
        let cursors_canvas2 = cursors_canvas.clone();
        toggle.action_event().add(move |checked| {
            if checked { cursors_canvas2.set_cursor(cur); }
        });
        radios.push(toggle);
    }
    // The arrow cursor is the default.
    radios[1].set_on(true);

    let grid = grid_box!(
        &radios[0],
        &radios[1],
        &radios[2],
        &radios[3],
        &radios[4],
        &radios[5],
        &radios[6],
        &radios[7],
        &radios[8],
        &radios[9],
        &radios[10],
        &radios[11],
        &radios[12],
        &radios[13],
        &radios[14],
        &radios[15],
        &radios[16],
        &radios[17],
    );
    grid.set_num_div(NumDiv::Fixed(2));
    grid.fit_all_to_children();
    let page = vbox!(
        &cursors_canvas,
        hbox!(
            fill!(),
            Radio::with_child(&grid),
            fill!(),
        ),
    );
    Box::new(page)
}

fn create_file_dialog_page() -> Box<Control> {
    let type_check_box = Toggle::new();
    type_check_box.set_title("Dialog Type:");

    let open_radio = Toggle::new();
    open_radio.set_title("Open");
    let save_radio = Toggle::new();
    save_radio.set_title("Save");
    let dir_radio = Toggle::new();
    dir_radio.set_title("Directory");
    let type_radio = Radio::with_child(&vbox!(
        &open_radio,
        &save_radio,
        &dir_radio,
    ));

    let dir_check_box = Toggle::new();
    dir_check_box.set_title("Directory:");

    let dir_text_box = Text::new();

    let multiple_files_check_box = Toggle::new();
    multiple_files_check_box.set_title("Multiple Files");

    let show_dialog = Button::with_title("Show Dialog");

    let type_check_box_capt = type_check_box.clone();
    let open_radio_capt = open_radio.clone();
    let save_radio_capt = save_radio.clone();
    let dir_check_box_capt = dir_check_box.clone();
    let dir_text_box_capt = dir_text_box.clone();
    let multiple_files_check_box_capt = multiple_files_check_box.clone();
    show_dialog.action_event().add(move || {
        let dialog = FileDlg::new();
        if type_check_box_capt.is_on() {
            dialog.set_dialog_type(if open_radio_capt.is_on() {
                FileDialogType::Open
            } else if save_radio_capt.is_on() {
                FileDialogType::Save
            } else {
                FileDialogType::Dir
            })
        }
        if dir_check_box_capt.is_on() {
            dialog.set_directory(&dir_text_box_capt.value());
        }
        if multiple_files_check_box_capt.is_on() {
            dialog.set_multiple_files(true);
        }
        dialog.popup(ScreenPosition::CenterParent, ScreenPosition::CenterParent)
              .expect("couldn't show file dialog");
    });

    let grid = grid_box!(
        type_check_box, type_radio,
        dir_check_box, dir_text_box,
        multiple_files_check_box, fill!(),
        fill!(), show_dialog,
    );
    grid.set_top_level_margin_and_gap();
    grid.set_num_div(NumDiv::Fixed(2));
    grid.set_size_col(1);
    grid.fit_all_to_children();
    // I don't think the extra vbox should be necessary, but there won't be space around
    // the GridBox otherwise.
    let wrapper = vbox!(&grid);
    wrapper.set_top_level_margin_and_gap();
    Box::new(wrapper)
}

fn create_list_page() -> Box<Control> {
    let list = List::new();
    list.set_items(&["A", "B", "C"]);
    let list_label = Label::new();

    let multiple_list = List::new();
    multiple_list.set_multiple(true);
    multiple_list.set_items(&["D", "E", "F"]);
    let multiple_list_label = Label::new();

    let dropdown = List::new();
    dropdown.set_dropdown(true);
    dropdown.set_items(&["Apple", "Grape", "Orange"]);
    let dropdown_label = Label::new();

    let edit_box = List::new();
    edit_box.set_dropdown(true);
    edit_box.set_edit_box(true);
    edit_box.set_items(&["Cherry", "Peach", "Pumpkin", "Rhubarb"]);
    let edit_box_label = Label::new();

    let grid = grid_box!(
        &list,
        &multiple_list,
        &list_label,
        &multiple_list_label,
        &dropdown,
        &edit_box,
        &dropdown_label,
        &edit_box_label,
    );
    grid.set_top_level_margin_and_gap();
    grid.set_num_div(NumDiv::Fixed(2));
    grid.fit_all_to_children();

    let list_label_capt = list_label.clone();
    let grid_capt = grid.clone();
    list.action_event().add(move |args: &ListActionArgs| {
        if !args.selected {
            return;
        }
        list_label_capt.set_title(&format!("Selected {}", args.item_index));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    let multiple_list_capt = multiple_list.clone();
    let grid_capt = grid.clone();
    multiple_list.action_event().add(move |_: &ListActionArgs| {
        let mut s = String::with_capacity(32);
        for (i, index) in multiple_list_capt.value_multiple().into_iter().enumerate() {
            if i > 0 {
                s += ", ";
            }
            s += &*index.to_string();
        }
        multiple_list_label.set_title(&format!("Selected {}", &s));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    let dropdown_capt = dropdown.clone();
    let grid_capt = grid.clone();
    dropdown.action_event().add(move |_: &ListActionArgs| {
        use std::borrow::Cow;
        let s = dropdown_capt.value_single().map(|i| Cow::Owned(dropdown_capt.item(i))).unwrap_or("No".into());
        dropdown_label.set_title(&format!("{} Juice", &s));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    let grid_capt = grid.clone();
    edit_box.action_event().add(move |args: &ListActionArgs| {
        edit_box_label.set_title(&format!("{} Pie", &args.text));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    // I don't think the extra vbox should be necessary, but there won't be space around
    // the GridBox otherwise.
    let wrapper = vbox!(&grid);
    wrapper.set_top_level_margin_and_gap();
    Box::new(wrapper)
}

fn main() {

    let dialog = Dialog::new();

    let tabs = Tabs::new();

    tabs.append_tabs(&[
        TabInfo::new(&*create_cursors_page()).title("Cursors"),
        TabInfo::new(&*create_file_dialog_page()).title("File Dialog"),
        TabInfo::new(&*create_list_page()).title("List"),
    ]);

    dialog.append(&tabs).expect("failed to build the window");
    dialog.set_title("Showcase");

    dialog.show_xy(ScreenPosition::Center, ScreenPosition::Center)
          .expect("failed to show the window");
    main_loop();
}
<commit_msg>Set the minimum size of the cursor canvas so it isn't tiny<commit_after>/* Copyright 2016 Jordan Miner
 *
 * Licensed under the MIT license <LICENSE or
 * http://opensource.org/licenses/MIT>. This file may not be copied,
 * modified, or distributed except according to those terms.
 */

#[macro_use]
extern crate clear_coat;
extern crate iup_sys;
extern crate smallvec;

use std::rc::Rc;
use iup_sys::*;
use smallvec::SmallVec;

use clear_coat::*;
use clear_coat::common_attrs_cbs::*;

struct CursorsCanvas {
    canvas: Canvas,
}

impl CursorsCanvas {
    pub fn new() -> Self {
        CursorsCanvas {
            canvas: Canvas::new(),
        }
    }
}

impl CursorAttribute for CursorsCanvas {}

unsafe impl Control for CursorsCanvas {
    fn handle(&self) -> *mut Ihandle {
        self.canvas.handle()
    }
}

fn create_cursors_page() -> Box<Control> {
    let cursors_canvas = Rc::new(CursorsCanvas::new());
    cursors_canvas.canvas.set_min_size(300, 200);

    let radios_info = [
        ("None", Cursor::None),
        ("Arrow", Cursor::Arrow),
        ("Busy", Cursor::Busy),
        ("Cross", Cursor::Cross),
        ("Hand", Cursor::Hand),
        ("Help", Cursor::Help),
        ("Move", Cursor::Move),
        ("ResizeN", Cursor::ResizeN),
        ("ResizeS", Cursor::ResizeS),
        ("ResizeNS", Cursor::ResizeNS),
        ("ResizeW", Cursor::ResizeW),
        ("ResizeE", Cursor::ResizeE),
        ("ResizeWE", Cursor::ResizeWE),
        ("ResizeNE", Cursor::ResizeNE),
        ("ResizeSW", Cursor::ResizeSW),
        ("ResizeNW", Cursor::ResizeNW),
        ("ResizeSE", Cursor::ResizeSE),
        ("Text", Cursor::Text),
    ];

    let mut radios = SmallVec::<[Toggle; 32]>::new();
    for &(text, cur) in radios_info.iter() {
        let toggle = Toggle::new();
        toggle.set_title(text);
        let cursors_canvas2 = cursors_canvas.clone();
        toggle.action_event().add(move |checked| {
            if checked { cursors_canvas2.set_cursor(cur); }
        });
        radios.push(toggle);
    }
    // The arrow cursor is the default.
    radios[1].set_on(true);

    let grid = grid_box!(
        &radios[0],
        &radios[1],
        &radios[2],
        &radios[3],
        &radios[4],
        &radios[5],
        &radios[6],
        &radios[7],
        &radios[8],
        &radios[9],
        &radios[10],
        &radios[11],
        &radios[12],
        &radios[13],
        &radios[14],
        &radios[15],
        &radios[16],
        &radios[17],
    );
    grid.set_num_div(NumDiv::Fixed(2));
    grid.fit_all_to_children();
    let page = vbox!(
        &cursors_canvas,
        hbox!(
            fill!(),
            Radio::with_child(&grid),
            fill!(),
        ),
    );
    Box::new(page)
}

fn create_file_dialog_page() -> Box<Control> {
    let type_check_box = Toggle::new();
    type_check_box.set_title("Dialog Type:");

    let open_radio = Toggle::new();
    open_radio.set_title("Open");
    let save_radio = Toggle::new();
    save_radio.set_title("Save");
    let dir_radio = Toggle::new();
    dir_radio.set_title("Directory");
    let type_radio = Radio::with_child(&vbox!(
        &open_radio,
        &save_radio,
        &dir_radio,
    ));

    let dir_check_box = Toggle::new();
    dir_check_box.set_title("Directory:");

    let dir_text_box = Text::new();

    let multiple_files_check_box = Toggle::new();
    multiple_files_check_box.set_title("Multiple Files");

    let show_dialog = Button::with_title("Show Dialog");

    let type_check_box_capt = type_check_box.clone();
    let open_radio_capt = open_radio.clone();
    let save_radio_capt = save_radio.clone();
    let dir_check_box_capt = dir_check_box.clone();
    let dir_text_box_capt = dir_text_box.clone();
    let multiple_files_check_box_capt = multiple_files_check_box.clone();
    show_dialog.action_event().add(move || {
        let dialog = FileDlg::new();
        if type_check_box_capt.is_on() {
            dialog.set_dialog_type(if open_radio_capt.is_on() {
                FileDialogType::Open
            } else if save_radio_capt.is_on() {
                FileDialogType::Save
            } else {
                FileDialogType::Dir
            })
        }
        if dir_check_box_capt.is_on() {
            dialog.set_directory(&dir_text_box_capt.value());
        }
        if multiple_files_check_box_capt.is_on() {
            dialog.set_multiple_files(true);
        }
        dialog.popup(ScreenPosition::CenterParent, ScreenPosition::CenterParent)
              .expect("couldn't show file dialog");
    });

    let grid = grid_box!(
        type_check_box, type_radio,
        dir_check_box, dir_text_box,
        multiple_files_check_box, fill!(),
        fill!(), show_dialog,
    );
    grid.set_top_level_margin_and_gap();
    grid.set_num_div(NumDiv::Fixed(2));
    grid.set_size_col(1);
    grid.fit_all_to_children();
    // I don't think the extra vbox should be necessary, but there won't be space around
    // the GridBox otherwise.
    let wrapper = vbox!(&grid);
    wrapper.set_top_level_margin_and_gap();
    Box::new(wrapper)
}

fn create_list_page() -> Box<Control> {
    let list = List::new();
    list.set_items(&["A", "B", "C"]);
    let list_label = Label::new();

    let multiple_list = List::new();
    multiple_list.set_multiple(true);
    multiple_list.set_items(&["D", "E", "F"]);
    let multiple_list_label = Label::new();

    let dropdown = List::new();
    dropdown.set_dropdown(true);
    dropdown.set_items(&["Apple", "Grape", "Orange"]);
    let dropdown_label = Label::new();

    let edit_box = List::new();
    edit_box.set_dropdown(true);
    edit_box.set_edit_box(true);
    edit_box.set_items(&["Cherry", "Peach", "Pumpkin", "Rhubarb"]);
    let edit_box_label = Label::new();

    let grid = grid_box!(
        &list,
        &multiple_list,
        &list_label,
        &multiple_list_label,
        &dropdown,
        &edit_box,
        &dropdown_label,
        &edit_box_label,
    );
    grid.set_top_level_margin_and_gap();
    grid.set_num_div(NumDiv::Fixed(2));
    grid.fit_all_to_children();

    let list_label_capt = list_label.clone();
    let grid_capt = grid.clone();
    list.action_event().add(move |args: &ListActionArgs| {
        if !args.selected {
            return;
        }
        list_label_capt.set_title(&format!("Selected {}", args.item_index));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    let multiple_list_capt = multiple_list.clone();
    let grid_capt = grid.clone();
    multiple_list.action_event().add(move |_: &ListActionArgs| {
        let mut s = String::with_capacity(32);
        for (i, index) in multiple_list_capt.value_multiple().into_iter().enumerate() {
            if i > 0 {
                s += ", ";
            }
            s += &*index.to_string();
        }
        multiple_list_label.set_title(&format!("Selected {}", &s));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    let dropdown_capt = dropdown.clone();
    let grid_capt = grid.clone();
    dropdown.action_event().add(move |_: &ListActionArgs| {
        use std::borrow::Cow;
        let s = dropdown_capt.value_single().map(|i| Cow::Owned(dropdown_capt.item(i))).unwrap_or("No".into());
        dropdown_label.set_title(&format!("{} Juice", &s));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    let grid_capt = grid.clone();
    edit_box.action_event().add(move |args: &ListActionArgs| {
        edit_box_label.set_title(&format!("{} Pie", &args.text));
        grid_capt.refresh_children();
        grid_capt.fit_all_to_children();
    });

    // I don't think the extra vbox should be necessary, but there won't be space around
    // the GridBox otherwise.
    let wrapper = vbox!(&grid);
    wrapper.set_top_level_margin_and_gap();
    Box::new(wrapper)
}

fn main() {

    let dialog = Dialog::new();

    let tabs = Tabs::new();

    tabs.append_tabs(&[
        TabInfo::new(&*create_cursors_page()).title("Cursors"),
        TabInfo::new(&*create_file_dialog_page()).title("File Dialog"),
        TabInfo::new(&*create_list_page()).title("List"),
    ]);

    dialog.append(&tabs).expect("failed to build the window");
    dialog.set_title("Showcase");

    dialog.show_xy(ScreenPosition::Center, ScreenPosition::Center)
          .expect("failed to show the window");
    main_loop();
}
<|endoftext|>


<commit_before>extern crate gluon;

use gluon::{new_vm, Compiler};

fn main() {
    let vm = new_vm();

    let _ = Compiler::new().run_expr::<&str>(&vm, "", r#" "test" "#);
    //~^ the trait bound `for<'value> &str: gluon::gluon_vm::api::Getable<'_, 'value>` is not satisfied
}
<commit_msg>Fix compile test from updated nightly<commit_after>extern crate gluon;

use gluon::{new_vm, Compiler};

fn main() {
    let vm = new_vm();

    let _ = Compiler::new().run_expr::<&str>(&vm, "", r#" "test" "#);
    //~^ mismatched types [E0308]
}
<|endoftext|>


<commit_before>use crate::peer::DisconnectReason;
use arrayvec::ArrayString;
use async_trait::async_trait;
use auto_impl::auto_impl;
use bytes::Bytes;
use derive_more::Display;
pub use ethereum_types::H512 as PeerId;
use rlp::{DecoderError, Rlp, RlpStream};
use std::{collections::BTreeSet, fmt::Debug, net::SocketAddr, str::FromStr};

/// Record that specifies information necessary to connect to RLPx node
#[derive(Clone, Copy, Debug)]
pub struct NodeRecord {
    /// Node ID.
    pub id: PeerId,
    /// Address of RLPx TCP server.
    pub addr: SocketAddr,
}

impl FromStr for NodeRecord {
    type Err = Box<dyn std::error::Error + Send + Sync>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        const PREFIX: &str = "enode://";

        let (prefix, data) = s.split_at(PREFIX.len());
        if prefix != PREFIX {
            return Err("Not an enode".into());
        }

        let mut parts = data.split('@');
        let id = parts
            .next()
            .ok_or_else(|| "Failed to read remote ID")?
            .parse()?;
        let addr = parts
            .next()
            .ok_or_else(|| "Failed to read address")?
            .parse()?;

        Ok(Self { id, addr })
    }
}

#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CapabilityName(pub ArrayString<[u8; 4]>);

impl rlp::Encodable for CapabilityName {
    fn rlp_append(&self, s: &mut RlpStream) {
        self.0.as_bytes().rlp_append(s);
    }
}

impl rlp::Decodable for CapabilityName {
    fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
        Ok(Self(
            ArrayString::from(
                std::str::from_utf8(rlp.data()?)
                    .map_err(|_| DecoderError::Custom("should be a UTF-8 string"))?,
            )
            .map_err(|_| DecoderError::RlpIsTooBig)?,
        ))
    }
}

pub type CapabilityLength = usize;
pub type CapabilityVersion = usize;

#[derive(Clone, Debug, Copy, PartialEq, Eq)]
/// Capability information
pub struct CapabilityInfo {
    pub name: CapabilityName,
    pub version: CapabilityVersion,
    pub length: CapabilityLength,
}

impl CapabilityInfo {
    pub fn new(CapabilityId { name, version }: CapabilityId, length: CapabilityLength) -> Self {
        Self {
            name,
            version,
            length,
        }
    }
}

#[derive(Clone, Debug, Display, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[display(fmt = "{}/{}", name, version)]
pub struct CapabilityId {
    pub name: CapabilityName,
    pub version: CapabilityVersion,
}

impl From<CapabilityInfo> for CapabilityId {
    fn from(CapabilityInfo { name, version, .. }: CapabilityInfo) -> Self {
        Self { name, version }
    }
}

#[derive(Clone, Debug)]
pub enum InboundEvent {
    Disconnect {
        reason: Option<DisconnectReason>,
    },
    Message {
        capability_name: CapabilityName,
        message: Message,
    },
}

#[derive(Clone, Debug)]
pub enum OutboundEvent {
    Disconnect {
        reason: DisconnectReason,
    },
    Message {
        capability_name: CapabilityName,
        message: Message,
    },
}

#[async_trait]
#[auto_impl(&, Box, Arc)]
pub trait CapabilityServer: Send + Sync + 'static {
    /// Should be used to set up relevant state for the peer.
    fn on_peer_connect(&self, peer: PeerId, caps: BTreeSet<CapabilityId>);
    /// Called on the next event for peer.
    async fn on_peer_event(&self, peer: PeerId, event: InboundEvent);
    /// Get the next event for peer.
    async fn next(&self, peer: PeerId) -> OutboundEvent;
}

#[async_trait]
impl CapabilityServer for () {
    fn on_peer_connect(&self, _: PeerId, _: BTreeSet<CapabilityId>) {}

    async fn on_peer_event(&self, _: PeerId, _: InboundEvent) {}

    async fn next(&self, _: PeerId) -> OutboundEvent {
        futures::future::pending().await
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Message {
    pub id: usize,
    pub data: Bytes,
}
<commit_msg>impl Display for InboundEvent<commit_after>use crate::peer::DisconnectReason;
use arrayvec::ArrayString;
use async_trait::async_trait;
use auto_impl::auto_impl;
use bytes::Bytes;
use derive_more::Display;
pub use ethereum_types::H512 as PeerId;
use rlp::{DecoderError, Rlp, RlpStream};
use std::{collections::BTreeSet, fmt::Debug, net::SocketAddr, str::FromStr};

/// Record that specifies information necessary to connect to RLPx node
#[derive(Clone, Copy, Debug)]
pub struct NodeRecord {
    /// Node ID.
    pub id: PeerId,
    /// Address of RLPx TCP server.
    pub addr: SocketAddr,
}

impl FromStr for NodeRecord {
    type Err = Box<dyn std::error::Error + Send + Sync>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        const PREFIX: &str = "enode://";

        let (prefix, data) = s.split_at(PREFIX.len());
        if prefix != PREFIX {
            return Err("Not an enode".into());
        }

        let mut parts = data.split('@');
        let id = parts
            .next()
            .ok_or_else(|| "Failed to read remote ID")?
            .parse()?;
        let addr = parts
            .next()
            .ok_or_else(|| "Failed to read address")?
            .parse()?;

        Ok(Self { id, addr })
    }
}

#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CapabilityName(pub ArrayString<[u8; 4]>);

impl rlp::Encodable for CapabilityName {
    fn rlp_append(&self, s: &mut RlpStream) {
        self.0.as_bytes().rlp_append(s);
    }
}

impl rlp::Decodable for CapabilityName {
    fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
        Ok(Self(
            ArrayString::from(
                std::str::from_utf8(rlp.data()?)
                    .map_err(|_| DecoderError::Custom("should be a UTF-8 string"))?,
            )
            .map_err(|_| DecoderError::RlpIsTooBig)?,
        ))
    }
}

pub type CapabilityLength = usize;
pub type CapabilityVersion = usize;

#[derive(Clone, Debug, Copy, PartialEq, Eq)]
/// Capability information
pub struct CapabilityInfo {
    pub name: CapabilityName,
    pub version: CapabilityVersion,
    pub length: CapabilityLength,
}

impl CapabilityInfo {
    pub fn new(CapabilityId { name, version }: CapabilityId, length: CapabilityLength) -> Self {
        Self {
            name,
            version,
            length,
        }
    }
}

#[derive(Clone, Debug, Display, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[display(fmt = "{}/{}", name, version)]
pub struct CapabilityId {
    pub name: CapabilityName,
    pub version: CapabilityVersion,
}

impl From<CapabilityInfo> for CapabilityId {
    fn from(CapabilityInfo { name, version, .. }: CapabilityInfo) -> Self {
        Self { name, version }
    }
}

#[derive(Clone, Debug, Display)]
pub enum InboundEvent {
    #[display(
        fmt = "disconnect/{}",
        "reason.map(|r| r.to_string()).unwrap_or_else(|| \"(no reason)\".to_string())"
    )]
    Disconnect { reason: Option<DisconnectReason> },
    #[display(fmt = "message/{}/{}", capability_name, "message.id.to_string()")]
    Message {
        capability_name: CapabilityName,
        message: Message,
    },
}

#[derive(Clone, Debug)]
pub enum OutboundEvent {
    Disconnect {
        reason: DisconnectReason,
    },
    Message {
        capability_name: CapabilityName,
        message: Message,
    },
}

#[async_trait]
#[auto_impl(&, Box, Arc)]
pub trait CapabilityServer: Send + Sync + 'static {
    /// Should be used to set up relevant state for the peer.
    fn on_peer_connect(&self, peer: PeerId, caps: BTreeSet<CapabilityId>);
    /// Called on the next event for peer.
    async fn on_peer_event(&self, peer: PeerId, event: InboundEvent);
    /// Get the next event for peer.
    async fn next(&self, peer: PeerId) -> OutboundEvent;
}

#[async_trait]
impl CapabilityServer for () {
    fn on_peer_connect(&self, _: PeerId, _: BTreeSet<CapabilityId>) {}

    async fn on_peer_event(&self, _: PeerId, _: InboundEvent) {}

    async fn next(&self, _: PeerId) -> OutboundEvent {
        futures::future::pending().await
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Message {
    pub id: usize,
    pub data: Bytes,
}
<|endoftext|>


<commit_before>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use types::gpointer;
use wrap;
use wrap::Wrapper;

use std::marker;
use std::mem;
use std::ops::{Deref, DerefMut};

pub type RefFunc = unsafe extern "C" fn(gpointer) -> gpointer;
pub type UnrefFunc = unsafe extern "C" fn(gpointer);
pub type RefcountFuncs = (*const RefFunc, *const UnrefFunc);

pub trait Refcount {
    fn refcount_funcs(&self) -> &'static RefcountFuncs;
}

pub struct Ref<T: Refcount> {
    plumbing: RefImpl,
    no_send: marker::NoSend,
    no_sync: marker::NoSync
}

pub struct SyncRef<T: Refcount + Send + Sync> {
    plumbing: RefImpl
}

impl<T> Ref<T> where T: Refcount {

    pub fn new(source: &mut T) -> Ref<T> {
        new_ref(source)
    }
}

impl<T> Ref<T> where T: Refcount + Wrapper {

    pub unsafe fn from_raw(ptr: *mut <T as Wrapper>::Raw) -> Ref<T> {
        Ref::new(wrap::from_raw_mut(ptr, &ptr))
    }
}

impl<T> SyncRef<T> where T: Refcount + Send + Sync {

    pub fn new(source: &mut T) -> SyncRef<T> {
        new_sync_ref(source)
    }
}

impl<T> SyncRef<T> where T: Refcount + Wrapper + Send + Sync {

    pub unsafe fn from_raw(ptr: *mut <T as Wrapper>::Raw) -> SyncRef<T> {
        SyncRef::new(wrap::from_raw_mut(ptr, &ptr))
    }
}

struct RefImpl {
    ptr: gpointer
}

impl RefImpl {

    unsafe fn impl_drop(&mut self, (_, dec_ref): RefcountFuncs) {
        (*dec_ref)(self.ptr);
    }

    unsafe fn impl_clone_from(&mut self, source: &RefImpl,
                              (inc_ref, dec_ref): RefcountFuncs)
    {
        if self.ptr == source.ptr {
            return;
        }
        (*inc_ref)(source.ptr);
        (*dec_ref)(self.ptr);
        self.ptr = source.ptr;
    }
}

unsafe fn new_ref_impl(p: gpointer, (inc_ref, _): RefcountFuncs) -> RefImpl {
    (*inc_ref)(p);
    RefImpl { ptr: p }
}

fn new_ref<T>(source: &T) -> Ref<T>
    where T: Refcount
{
    let p = source as *const T as *mut T as gpointer;
    let funcs = source.refcount_funcs();
    Ref {
        plumbing: unsafe { new_ref_impl(p, *funcs) },
        no_send: marker::NoSend,
        no_sync: marker::NoSync
    }
}

fn new_sync_ref<T>(source: &T) -> SyncRef<T>
    where T: Refcount + Send + Sync
{
    let p = source as *const T as *mut T as gpointer;
    let funcs = source.refcount_funcs();
    SyncRef {
        plumbing: unsafe { new_ref_impl(p, *funcs) }
    }
}

#[unsafe_destructor]
impl<T> Drop for Ref<T> where T: Refcount {
    fn drop(&mut self) {
        let funcs = self.refcount_funcs();
        unsafe {
            self.plumbing.impl_drop(*funcs);
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for SyncRef<T> where T: Refcount + Send + Sync {
    fn drop(&mut self) {
        let funcs = self.refcount_funcs();
        unsafe {
            self.plumbing.impl_drop(*funcs);
        }
    }
}

impl<T: Refcount> Clone for Ref<T> {

    fn clone(&self) -> Ref<T> {
        new_ref(self.deref())
    }

    fn clone_from(&mut self, source: &Ref<T>) {
        let funcs = self.refcount_funcs();
        unsafe {
            self.plumbing.impl_clone_from(&source.plumbing, *funcs);
        }
    }
}

impl<T: Refcount + Send + Sync> Clone for SyncRef<T> {

    fn clone(&self) -> SyncRef<T> {
        new_sync_ref(self.deref())
    }

    fn clone_from(&mut self, source: &SyncRef<T>) {
        let funcs = self.refcount_funcs();
        unsafe {
            self.plumbing.impl_clone_from(&source.plumbing, *funcs);
        }
    }
}

unsafe impl<T> Send for SyncRef<T> where T: Refcount + Send + Sync { }

impl<T> Deref for Ref<T> where T: Refcount {

    type Target = T;

    fn deref(&self) -> &T {
        let p = self.plumbing.ptr as *const T;
        unsafe { mem::copy_lifetime(self, &*p) }
    }
}

impl<T> Deref for SyncRef<T> where T: Refcount + Send + Sync {

    type Target = T;

    fn deref(&self) -> &T {
        let p = self.plumbing.ptr as *const T;
        unsafe { mem::copy_lifetime(self, &*p) }
    }
}

impl<T> DerefMut for Ref<T> where T: Refcount {

    fn deref_mut(&mut self) -> &mut T {
        let p = self.plumbing.ptr as *mut T;
        unsafe { mem::copy_mut_lifetime(self, &mut *p) }
    }
}

impl<T> DerefMut for SyncRef<T> where T: Refcount + Send + Sync {

    fn deref_mut(&mut self) -> &mut T {
        let p = self.plumbing.ptr as *mut T;
        unsafe { mem::copy_mut_lifetime(self, &mut *p) }
    }
}
<commit_msg>refcount: Opt into Sync for SyncRef<commit_after>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use types::gpointer;
use wrap;
use wrap::Wrapper;

use std::marker;
use std::mem;
use std::ops::{Deref, DerefMut};

pub type RefFunc = unsafe extern "C" fn(gpointer) -> gpointer;
pub type UnrefFunc = unsafe extern "C" fn(gpointer);
pub type RefcountFuncs = (*const RefFunc, *const UnrefFunc);

pub trait Refcount {
    fn refcount_funcs(&self) -> &'static RefcountFuncs;
}

pub struct Ref<T: Refcount> {
    plumbing: RefImpl,
    no_send: marker::NoSend,
    no_sync: marker::NoSync
}

pub struct SyncRef<T: Refcount + Send + Sync> {
    plumbing: RefImpl
}

unsafe impl<T> Send for SyncRef<T> where T: Refcount + Send + Sync { }
unsafe impl<T> Sync for SyncRef<T> where T: Refcount + Send + Sync { }

impl<T> Ref<T> where T: Refcount {

    pub fn new(source: &mut T) -> Ref<T> {
        new_ref(source)
    }
}

impl<T> Ref<T> where T: Refcount + Wrapper {

    pub unsafe fn from_raw(ptr: *mut <T as Wrapper>::Raw) -> Ref<T> {
        Ref::new(wrap::from_raw_mut(ptr, &ptr))
    }
}

impl<T> SyncRef<T> where T: Refcount + Send + Sync {

    pub fn new(source: &mut T) -> SyncRef<T> {
        new_sync_ref(source)
    }
}

impl<T> SyncRef<T> where T: Refcount + Wrapper + Send + Sync {

    pub unsafe fn from_raw(ptr: *mut <T as Wrapper>::Raw) -> SyncRef<T> {
        SyncRef::new(wrap::from_raw_mut(ptr, &ptr))
    }
}

struct RefImpl {
    ptr: gpointer
}

impl RefImpl {

    unsafe fn impl_drop(&mut self, (_, dec_ref): RefcountFuncs) {
        (*dec_ref)(self.ptr);
    }

    unsafe fn impl_clone_from(&mut self, source: &RefImpl,
                              (inc_ref, dec_ref): RefcountFuncs)
    {
        if self.ptr == source.ptr {
            return;
        }
        (*inc_ref)(source.ptr);
        (*dec_ref)(self.ptr);
        self.ptr = source.ptr;
    }
}

unsafe fn new_ref_impl(p: gpointer, (inc_ref, _): RefcountFuncs) -> RefImpl {
    (*inc_ref)(p);
    RefImpl { ptr: p }
}

fn new_ref<T>(source: &T) -> Ref<T>
    where T: Refcount
{
    let p = source as *const T as *mut T as gpointer;
    let funcs = source.refcount_funcs();
    Ref {
        plumbing: unsafe { new_ref_impl(p, *funcs) },
        no_send: marker::NoSend,
        no_sync: marker::NoSync
    }
}

fn new_sync_ref<T>(source: &T) -> SyncRef<T>
    where T: Refcount + Send + Sync
{
    let p = source as *const T as *mut T as gpointer;
    let funcs = source.refcount_funcs();
    SyncRef {
        plumbing: unsafe { new_ref_impl(p, *funcs) }
    }
}

#[unsafe_destructor]
impl<T> Drop for Ref<T> where T: Refcount {
    fn drop(&mut self) {
        let funcs = self.refcount_funcs();
        unsafe {
            self.plumbing.impl_drop(*funcs);
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for SyncRef<T> where T: Refcount + Send + Sync {
    fn drop(&mut self) {
        let funcs = self.refcount_funcs();
        unsafe {
            self.plumbing.impl_drop(*funcs);
        }
    }
}

impl<T: Refcount> Clone for Ref<T> {

    fn clone(&self) -> Ref<T> {
        new_ref(self.deref())
    }

    fn clone_from(&mut self, source: &Ref<T>) {
        let funcs = self.refcount_funcs();
        unsafe {
            self.plumbing.impl_clone_from(&source.plumbing, *funcs);
        }
    }
}

impl<T: Refcount + Send + Sync> Clone for SyncRef<T> {

    fn clone(&self) -> SyncRef<T> {
        new_sync_ref(self.deref())
    }

    fn clone_from(&mut self, source: &SyncRef<T>) {
        let funcs = self.refcount_funcs();
        unsafe {
            self.plumbing.impl_clone_from(&source.plumbing, *funcs);
        }
    }
}

impl<T> Deref for Ref<T> where T: Refcount {

    type Target = T;

    fn deref(&self) -> &T {
        let p = self.plumbing.ptr as *const T;
        unsafe { mem::copy_lifetime(self, &*p) }
    }
}

impl<T> Deref for SyncRef<T> where T: Refcount + Send + Sync {

    type Target = T;

    fn deref(&self) -> &T {
        let p = self.plumbing.ptr as *const T;
        unsafe { mem::copy_lifetime(self, &*p) }
    }
}

impl<T> DerefMut for Ref<T> where T: Refcount {

    fn deref_mut(&mut self) -> &mut T {
        let p = self.plumbing.ptr as *mut T;
        unsafe { mem::copy_mut_lifetime(self, &mut *p) }
    }
}

impl<T> DerefMut for SyncRef<T> where T: Refcount + Send + Sync {

    fn deref_mut(&mut self) -> &mut T {
        let p = self.plumbing.ptr as *mut T;
        unsafe { mem::copy_mut_lifetime(self, &mut *p) }
    }
}
<|endoftext|>


<commit_before>extern crate nickel;
extern crate postgres;

use nickel::{ Request, Response, Middleware, Action, Continue };
use postgres::pool::{ PooledPostgresConnection, PostgresConnectionPool };

#[deriving(Clone)]
pub struct PostgresMiddleware {
    pub pool: PostgresConnectionPool
}

impl PostgresMiddleware {
    pub fn new (connect_str: &str, sslMode: postgres::SslMode, num_connections: uint) -> PostgresMiddleware {
        PostgresMiddleware {
            pool: PostgresConnectionPool::new(connect_str, sslMode, num_connections).unwrap()
        }
    }
}

impl Middleware for PostgresMiddleware {
    fn invoke (&self, req: &mut Request, _resp: &mut Response) -> Action {
        req.map.insert(self.pool.clone().get_connection());
        nickel::Continue
    }
}

pub trait PostgresRequestExtensions {
    fn db_conn(&self) -> &PooledPostgresConnection;
}

impl<'a> PostgresRequestExtensions for Request<'a> {
    fn db_conn(&self) -> &PooledPostgresConnection {
        return self.map.find::<PooledPostgresConnection>().unwrap();
    }
}
<commit_msg>=BG= Fixes #2 - update return type of middleware invoke signature Was `Action`, now is `Result<Action, NickelError>`<commit_after>extern crate nickel;
extern crate postgres;

use nickel::{ Request, Response, Middleware, Action, Continue, NickelError };
use postgres::pool::{ PooledPostgresConnection, PostgresConnectionPool };

#[deriving(Clone)]
pub struct PostgresMiddleware {
    pub pool: PostgresConnectionPool
}

impl PostgresMiddleware {
    pub fn new (connect_str: &str, sslMode: postgres::SslMode, num_connections: uint) -> PostgresMiddleware {
        PostgresMiddleware {
            pool: PostgresConnectionPool::new(connect_str, sslMode, num_connections).unwrap()
        }
    }
}

impl Middleware for PostgresMiddleware {
    fn invoke (&self, req: &mut Request, _resp: &mut Response) -> Result<Action, NickelError> {
        req.map.insert(self.pool.clone().get_connection());
        Ok(Continue)
    }
}

pub trait PostgresRequestExtensions {
    fn db_conn(&self) -> &PooledPostgresConnection;
}

impl<'a> PostgresRequestExtensions for Request<'a> {
    fn db_conn(&self) -> &PooledPostgresConnection {
        return self.map.find::<PooledPostgresConnection>().unwrap();
    }
}
<|endoftext|>


<commit_before>// FIXME: add the support of transient objects

use notify::{self, RecommendedWatcher, Watcher};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{Receiver, Sender, channel};
use std::thread;
use time::precise_time_s;

use id::Id;
use model::Model;
use object::Object;
use shader::Program;
use spline::Spline;
use texture::TextureImage;

/// Class of types that can be loaded.
pub trait Load<'a>: Sized {
  /// Arguments passed at loading.
  type Args;

  // TODO: see whether we can use something with From/Into instead, so that we can use lambdas.
  fn load<P>(path: P, cache: &mut Cache<'a>, args: Self::Args) -> Result<Self, LoadError> where P: AsRef<Path>;
}

/// Class of types that can be reloaded.
///
/// The idea is to simply recover the arguments used in `Load::load`.
pub trait Reload<'a>: Load<'a> {
  fn reload_args(&self) -> Self::Args;
}

/// Default implementation for types which are loaded without any arguments.
impl<'a, T> Reload<'a> for T where T: Load<'a, Args=()> {
  fn reload_args(&self) -> Self::Args {
    ()
  }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum LoadError {
  FileNotFound(PathBuf, String),
  ParseFailed(String),
  ConversionFailed(String)
}

type Timestamp = f64;

/// Time to await after a resource update to establish that it should be reloaded.
const UPDATE_AWAIT_TIME: Timestamp = 0.1; // 100ms

struct CacheBlock<'a, T> where T: 'a {
  data: Vec<(Rc<T>, PathBuf, (Receiver<Timestamp>, f64))>,
  ids: HashMap<String, Id<'a, T>>,
}

impl<'a, T> CacheBlock<'a, T> {
  pub fn new() -> Self {
    CacheBlock {
      data: Vec::new(),
      ids: HashMap::new(),
    }
  }
}

macro_rules! cache_struct {
  ($l:tt, $($n:ident : $t:ty),*) => {
    pub struct Cache<$l> {
      senders: Arc<Mutex<HashMap<PathBuf, Sender<Timestamp>>>>,
      $(
        $n: CacheBlock<$l, $t>
      ),*
    }

    impl<$l> Cache<$l> {
      pub fn new<P>(root:P) -> Self where P: AsRef<Path> {
        let senders: Arc<Mutex<HashMap<PathBuf, Sender<Timestamp>>>> = Arc::new(Mutex::new(HashMap::new()));

        // start watcher thread
        {
          let senders = senders.clone();
          let root = root.as_ref().to_path_buf();
          let (wsx, wrx) = channel();
          let mut watcher: RecommendedWatcher = Watcher::new(wsx).unwrap();

          let _ = thread::spawn(move || {
            let _ = watcher.watch(root);

            for event in wrx.iter() {
              match event {
                notify::Event { path: Some(path), op: Ok(notify::op::WRITE) } => {
                  if let Some(sx) = senders.lock().unwrap().get(&path) {
                    sx.send(precise_time_s()).unwrap();
                  }
                },
                _ => {}
              }
            }
          });
        }

        Cache {
          senders: senders,
          $(
            $n: CacheBlock::new()
          ),*
        }
      }
    }
  }
}

pub trait Get<'a, T> where T: 'a + Reload<'a> {
  fn get_id(&mut self, name: &str, args: T::Args) -> Option<Id<'a, T>>;
  fn get_by_id(&mut self, id: &Id<'a, T>) -> Option<Rc<T>>;
  fn get(&mut self, name: &str, args: T::Args) -> Option<Rc<T>> {
    self.get_id(name, args).and_then(move |i| self.get_by_id(&i))
  }
}

macro_rules! impl_get_id {
  ($n:ident : $t:ty, $this:ident, $name:ident, $args: ident) => {{
    let path_str = format!("data/{}/{}", stringify!($n), $name);
    let path = Path::new(&path_str);

    match $this.$n.ids.get($name).cloned() {
      id@Some(..) => {
        deb!("cache hit for {}", path_str);
        id
      },
      None => {
        deb!("cache miss for {}", path_str);

        // specific loading
        if path.exists() {
          match <$t as Load>::load(&path, $this, $args) {
            Ok(resource) => {
              let path_buf = path.to_owned();

              // create the id if we have loaded the resource
              let id: Id<$t> = ($this.$n.data.len() as u32).into();

              // create a channel to notify any update later and register the sender for the
              // given path
              let (sx, rx) = channel();
              {
                let mut senders = $this.senders.lock().unwrap();
                senders.insert(path_buf.clone(), sx);
              }

              // add the resource to the list of loaded ones
              $this.$n.data.push((Rc::new(resource), path_buf.clone(), (rx, precise_time_s())));
              // cache the resource
              $this.$n.ids.insert($name.to_owned(), id.clone());

              Some(id)
            },
            Err(e) => {
              err!("unable to load resource from {}:\n{:#?}", path_str, e);
              None
            }
          }
        } else { // path doesn’t exist
          err!("ressource at {} cannot be found", path_str);
          None
        }
      }
    }
  }}
}

macro_rules! impl_get_by_id {
  ($n:ident : $t:ty, $this:ident, $id:ident) => {{
    // synchronization
    let mut reload_args = None;

    if let Some(data) = $this.$n.data.get($id.id as usize) {
      match (data.2).0.try_recv() {
        Ok(timestamp) if timestamp - (data.2).1 >= UPDATE_AWAIT_TIME => {
          reload_args = Some((data.1.to_owned(), data.0.reload_args()));
        },
        _ => {}
      }
    } else {
      return None;
    }

    if let Some((path, args)) = reload_args {
      match <$t as Load>::load(&path, $this, args) {
        Ok(new_resource) => {
          // replace the current resource with the freshly loaded one
          deb!("reloaded resource from {:?}", path);
          $this.$n.data[$id.id as usize].0 = Rc::new(new_resource);
        },
        Err(e) => {
          warn!("reloading resource from {:?} has failed:\n{:#?}", path, e);
        }
      }
    }

    $this.$n.data.get($id.id as usize).map(|r| r.0.clone())
  }}
}

macro_rules! impl_get_no_lifetime {
  ($n:ident : $t:ty) => {
    impl<'a> Get<'a, $t> for Cache<'a> {
      fn get_id(&mut self, name: &str, args: <$t as Load<'a>>::Args) -> Option<Id<'a, $t>> {
        impl_get_id!($n: $t, self, name, args)
      }

      fn get_by_id(&mut self, id: &Id<'a, $t>) -> Option<Rc<$t>> {
        impl_get_by_id!($n: $t, self, id)
      }
    }
  }
}

cache_struct!('a,
              models: Model,
              objects: Object<'a>,
              shaders: Program,
              splines: Spline<f32>,
              textures: TextureImage);

impl_get_no_lifetime!(models: Model);
impl_get_no_lifetime!(shaders: Program);
impl_get_no_lifetime!(splines: Spline<f32>);
impl_get_no_lifetime!(textures: TextureImage);

impl<'a> Get<'a, Object<'a>> for Cache<'a> {
  fn get_id(&mut self, name: &str, args: <Object<'a> as Load<'a>>::Args) -> Option<Id<'a, Object<'a>>> {
    impl_get_id!(objects: Object<'a>, self, name, args)
  }

  fn get_by_id(&mut self, id: &Id<'a, Object<'a>>) -> Option<Rc<Object<'a>>> {
    impl_get_by_id!(objects: Object<'a>, self, id)
  }
}
<commit_msg>Prevent resource reloading saturation by unqueuing the resource channel.<commit_after>// FIXME: add the support of transient objects

use notify::{self, RecommendedWatcher, Watcher};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{Receiver, Sender, channel};
use std::thread;
use time::precise_time_s;

use id::Id;
use model::Model;
use object::Object;
use shader::Program;
use spline::Spline;
use texture::TextureImage;

/// Class of types that can be loaded.
pub trait Load<'a>: Sized {
  /// Arguments passed at loading.
  type Args;

  // TODO: see whether we can use something with From/Into instead, so that we can use lambdas.
  fn load<P>(path: P, cache: &mut Cache<'a>, args: Self::Args) -> Result<Self, LoadError> where P: AsRef<Path>;
}

/// Class of types that can be reloaded.
///
/// The idea is to simply recover the arguments used in `Load::load`.
pub trait Reload<'a>: Load<'a> {
  fn reload_args(&self) -> Self::Args;
}

/// Default implementation for types which are loaded without any arguments.
impl<'a, T> Reload<'a> for T where T: Load<'a, Args=()> {
  fn reload_args(&self) -> Self::Args {
    ()
  }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum LoadError {
  FileNotFound(PathBuf, String),
  ParseFailed(String),
  ConversionFailed(String)
}

type Timestamp = f64;

/// Time to await after a resource update to establish that it should be reloaded.
const UPDATE_AWAIT_TIME: Timestamp = 0.1; // 100ms

struct CacheBlock<'a, T> where T: 'a {
  data: Vec<(Rc<T>, PathBuf, (Receiver<Timestamp>, f64))>,
  ids: HashMap<String, Id<'a, T>>,
}

impl<'a, T> CacheBlock<'a, T> {
  pub fn new() -> Self {
    CacheBlock {
      data: Vec::new(),
      ids: HashMap::new(),
    }
  }
}

macro_rules! cache_struct {
  ($l:tt, $($n:ident : $t:ty),*) => {
    pub struct Cache<$l> {
      senders: Arc<Mutex<HashMap<PathBuf, Sender<Timestamp>>>>,
      $(
        $n: CacheBlock<$l, $t>
      ),*
    }

    impl<$l> Cache<$l> {
      pub fn new<P>(root:P) -> Self where P: AsRef<Path> {
        let senders: Arc<Mutex<HashMap<PathBuf, Sender<Timestamp>>>> = Arc::new(Mutex::new(HashMap::new()));

        // start watcher thread
        {
          let senders = senders.clone();
          let root = root.as_ref().to_path_buf();
          let (wsx, wrx) = channel();
          let mut watcher: RecommendedWatcher = Watcher::new(wsx).unwrap();

          let _ = thread::spawn(move || {
            let _ = watcher.watch(root);

            for event in wrx.iter() {
              match event {
                notify::Event { path: Some(path), op: Ok(notify::op::WRITE) } => {
                  if let Some(sx) = senders.lock().unwrap().get(&path) {
                    sx.send(precise_time_s()).unwrap();
                  }
                },
                _ => {}
              }
            }
          });
        }

        Cache {
          senders: senders,
          $(
            $n: CacheBlock::new()
          ),*
        }
      }
    }
  }
}

pub trait Get<'a, T> where T: 'a + Reload<'a> {
  fn get_id(&mut self, name: &str, args: T::Args) -> Option<Id<'a, T>>;
  fn get_by_id(&mut self, id: &Id<'a, T>) -> Option<Rc<T>>;
  fn get(&mut self, name: &str, args: T::Args) -> Option<Rc<T>> {
    self.get_id(name, args).and_then(move |i| self.get_by_id(&i))
  }
}

macro_rules! impl_get_id {
  ($n:ident : $t:ty, $this:ident, $name:ident, $args: ident) => {{
    let path_str = format!("data/{}/{}", stringify!($n), $name);
    let path = Path::new(&path_str);

    match $this.$n.ids.get($name).cloned() {
      id@Some(..) => {
        deb!("cache hit for {}", path_str);
        id
      },
      None => {
        deb!("cache miss for {}", path_str);

        // specific loading
        if path.exists() {
          match <$t as Load>::load(&path, $this, $args) {
            Ok(resource) => {
              let path_buf = path.to_owned();

              // create the id if we have loaded the resource
              let id: Id<$t> = ($this.$n.data.len() as u32).into();

              // create a channel to notify any update later and register the sender for the
              // given path
              let (sx, rx) = channel();
              {
                let mut senders = $this.senders.lock().unwrap();
                senders.insert(path_buf.clone(), sx);
              }

              // add the resource to the list of loaded ones
              $this.$n.data.push((Rc::new(resource), path_buf.clone(), (rx, precise_time_s())));
              // cache the resource
              $this.$n.ids.insert($name.to_owned(), id.clone());

              Some(id)
            },
            Err(e) => {
              err!("unable to load resource from {}:\n{:#?}", path_str, e);
              None
            }
          }
        } else { // path doesn’t exist
          err!("ressource at {} cannot be found", path_str);
          None
        }
      }
    }
  }}
}

macro_rules! impl_get_by_id {
  ($n:ident : $t:ty, $this:ident, $id:ident) => {{
    // synchronization
    let mut reload_args = None;

    if let Some(data) = $this.$n.data.get($id.id as usize) {
      // this while loop unqueue the channel to prevent any resource reloading saturation; that can
      // occur if several changes / update are required by the channel is not consumed for a long
      // period of time
      while let Ok(timestamp) = (data.2).0.try_recv() {
        // if the change is old enough, consider the resource has been updated; otherwise, keep on
        // waiting
        if timestamp - (data.2).1 >= UPDATE_AWAIT_TIME {
          reload_args = Some((data.1.to_owned(), data.0.reload_args()));
        }
      }
    } else {
      return None;
    }

    if let Some((path, args)) = reload_args {
      match <$t as Load>::load(&path, $this, args) {
        Ok(new_resource) => {
          // replace the current resource with the freshly loaded one
          deb!("reloaded resource from {:?}", path);
          $this.$n.data[$id.id as usize].0 = Rc::new(new_resource);
        },
        Err(e) => {
          warn!("reloading resource from {:?} has failed:\n{:#?}", path, e);
        }
      }
    }

    $this.$n.data.get($id.id as usize).map(|r| r.0.clone())
  }}
}

macro_rules! impl_get_no_lifetime {
  ($n:ident : $t:ty) => {
    impl<'a> Get<'a, $t> for Cache<'a> {
      fn get_id(&mut self, name: &str, args: <$t as Load<'a>>::Args) -> Option<Id<'a, $t>> {
        impl_get_id!($n: $t, self, name, args)
      }

      fn get_by_id(&mut self, id: &Id<'a, $t>) -> Option<Rc<$t>> {
        impl_get_by_id!($n: $t, self, id)
      }
    }
  }
}

cache_struct!('a,
              models: Model,
              objects: Object<'a>,
              shaders: Program,
              splines: Spline<f32>,
              textures: TextureImage);

impl_get_no_lifetime!(models: Model);
impl_get_no_lifetime!(shaders: Program);
impl_get_no_lifetime!(splines: Spline<f32>);
impl_get_no_lifetime!(textures: TextureImage);

impl<'a> Get<'a, Object<'a>> for Cache<'a> {
  fn get_id(&mut self, name: &str, args: <Object<'a> as Load<'a>>::Args) -> Option<Id<'a, Object<'a>>> {
    impl_get_id!(objects: Object<'a>, self, name, args)
  }

  fn get_by_id(&mut self, id: &Id<'a, Object<'a>>) -> Option<Rc<Object<'a>>> {
    impl_get_by_id!(objects: Object<'a>, self, id)
  }
}
<|endoftext|>