<commit_before>use configuration::Configuration;
use std::slice::SliceExt;
use std::cmp::min;
use score::Score;
use sorted_result_set::SortedResultSet;
use std::ascii::AsciiExt;

#[derive(Debug)]
pub struct Search<'s> {
    pub config: &'s Configuration<'s>,
    current: usize,
    pub query: String,
    pub selection: Option<String>,
    pub result: Vec<String>,
    choice_stack: Vec<&'s Vec<String>>,
    done: bool,
}

impl<'s> Search<'s> {
    pub fn blank(config: &'s Configuration<'s>) -> Search<'s> {
        let query = config.initial_search.clone();
        let choice_stack: Vec<&'s Vec<String>> = Vec::new();
        let mut results: Vec<String> = Vec::new();

        for choice in config.choices.iter().take(config.visible_limit) {
            results.push(choice.clone());
        }

        Search::new(config, query, choice_stack, results, 0, false)
    }

    pub fn is_done(&self) -> bool {
        self.done
    }

    pub fn done(self) -> Search<'s> {
        Search::new(self.config, self.query, self.choice_stack, self.result, self.current, true)
    }

    fn new(config: &'s Configuration<'s>, query: String, choice_stack: Vec<&'s Vec<String>>, result: Vec<String>, index: usize, done: bool) -> Search<'s> {
        let selection = Search::select(&result, index);

        Search { config: config,
                 current: index,
                 query: query,
                 selection: selection,
                 result: result,
                 choice_stack: choice_stack,
                 done: done}
    }

    fn new_for_index(self, index: usize) -> Search<'s> {
        Search::new(self.config, self.query, self.choice_stack, self.result, index, self.done)
    }

    fn new_for_query(self, new_query: String) -> Search<'s> {
        let new_result = Search::filter(new_query.as_slice(), self.config.choices, self.config.visible_limit);

        Search::new(self.config, new_query, self.choice_stack, new_result, 0, self.done)
    }

    pub fn filter(query: &str, choices: &Vec<String>, result_size: usize) -> Vec<String> {
        let mut results = SortedResultSet::new(result_size);
        let query = query.to_ascii_lowercase();

        for choice in choices.iter() {
            let lower_choice = choice.to_ascii_lowercase();

            match Score::score(&lower_choice, &query) {
                0.0     => continue,
                quality => results.push(quality, choice),
            };
        }
        results.sorted_vec()
    }

    fn select(result: &Vec<String>, index: usize) -> Option<String> {
        if result.len() > 0 {
            Some(result[index].to_string())
        } else {
            None
        }
    }

    pub fn down(self) -> Search<'s> {
        let next_index = self.next_index();
        self.new_for_index(next_index)
    }

    pub fn up(self) -> Search<'s> {
        let next_index = self.prev_index();
        self.new_for_index(next_index)
    }

    pub fn append_to_search(self, input: &str) -> Search<'s> {
        let mut new_query = self.query.clone();
        new_query.push_str(input.as_slice());

        self.new_for_query(new_query)
    }

    pub fn backspace(self) -> Search<'s> {
        let mut new_query = self.query.clone();
        new_query.pop();

        self.new_for_query(new_query)
    }

    fn next_index(&self) -> usize {
        let next_index = self.current + 1;

        if next_index >= self.actual_limit() {
            0
        } else {
            next_index
        }
    }

    fn prev_index(&self) -> usize {
        if self.current == 0 {
            self.actual_limit() - 1
        } else {
            self.current - 1
        }
    }

    fn actual_limit(&self) -> usize {
        min(self.config.visible_limit, self.result.len())
    }
}

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

    fn one_two_three() -> Vec<String> {
        vec!["one".to_string(),
             "two".to_string(),
             "three".to_string()]
    }

    #[test]
    fn it_selects_the_first_choice_by_default() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.selection, Some("one".to_string()));
    }

    #[test]
    fn it_selets_the_second_when_down_is_called() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.down().selection, Some("two".to_string()));
    }

    #[test]
    fn it_loop_around_when_reaching_end_of_list() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.down().down().down().down().selection, Some("two".to_string()));
    }

    #[test]
    fn it_loop_around_when_reaching_top_of_list() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.up().up().selection, Some("two".to_string()));
    }

    #[test]
    fn it_loop_around_when_reaching_visible_limit() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, Some(2));
        let search = Search::blank(&config);

        assert_eq!(search.down().down().down().selection, Some("two".to_string()));
    }

    #[test]
    fn it_moves_down_the_filtered_search_results() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.append_to_search("t").down().selection, Some("three".to_string()));
    }

    #[test]
    fn it_moves_down_the_filtered_search_results_twice() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.append_to_search("t").append_to_search("w").selection, Some("two".to_string()));
    }

    #[test]
    fn it_handles_not_matching_anything() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.append_to_search("x").selection, None);
    }

    #[test]
    fn up_match_nothing_after_filtering_all_out() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("x");

        assert_eq!(search.up().selection, None);
    }

    #[test]
    fn down_match_nothing_after_filtering_all_out() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("x");

        assert_eq!(search.down().selection, None);
    }

    #[test]
    fn backspaces_over_characters() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("e");

        assert_eq!(search.query, "e");
        assert_eq!(search.backspace().query, "");
    }

    #[test]
    fn resets_the_index_when_removing_char_from_search() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("e");

        assert_eq!(search.down().backspace().current, 0);
    }

    #[test]
    fn resets_the_index_when_adding_char_to_seach() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).down();

        assert_eq!(search.append_to_search("o").current, 0);
    }

    #[test]
    fn previous_results_appear_after_backspace() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("t");

        assert_eq!(search.backspace().result.len(), 3);
    }

    #[test]
    fn initial_search_is_not_done() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert!(!search.is_done());
    }

    #[test]
    fn done_search_is_done() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).done();

        assert!(search.is_done());
    }

    #[test]
    fn done_search_has_selection() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).done();

        assert_eq!(search.selection, Some("one".to_string()));
    }

    #[test]
    fn loop_around_when_reaching_bottom_of_choices() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("n").down();

        assert_eq!(search.selection, Some("one".to_string()));
    }

    #[test]
    fn loop_around_when_reaching_top_of_choices() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("n").up();

        assert_eq!(search.selection, Some("one".to_string()));
    }

    #[test]
    fn search_is_case_insensitive() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("T");

        assert_eq!(search.result.len(), 2);
    }

    #[test]
    fn uses_configs_visible_limit_as_result_size() {
        let input = input_times(30);
        let config = Configuration::from_inputs(&input, None, Some(20));
        let search = Search::blank(&config).append_to_search("T");

        assert_eq!(search.result.len(), 20);
    }

    fn input_times(n: usize) ->Vec<String> {
        let mut result: Vec<String> = Vec::new();
        for thing in one_two_three().iter().cycle().take(n) {
            result.push(thing.clone());
        }
        result
    }

    //84114 ns/iter (+/- 33515)
    #[bench]
    fn filter_speed(b: &mut Bencher) {
        let input = input_times(1000);
        let query = "t";

        b.iter(||{
            Search::filter(query, &input, 20)
        });
    }
}
<commit_msg>No need for explicit types<commit_after>use configuration::Configuration;
use std::slice::SliceExt;
use std::cmp::min;
use score::Score;
use sorted_result_set::SortedResultSet;
use std::ascii::AsciiExt;

#[derive(Debug)]
pub struct Search<'s> {
    pub config: &'s Configuration<'s>,
    current: usize,
    pub query: String,
    pub selection: Option<String>,
    pub result: Vec<String>,
    choice_stack: Vec<&'s Vec<String>>,
    done: bool,
}

impl<'s> Search<'s> {
    pub fn blank(config: &'s Configuration<'s>) -> Search<'s> {
        let query = config.initial_search.clone();
        let choice_stack = Vec::new();
        let mut results = Vec::new();

        for choice in config.choices.iter().take(config.visible_limit) {
            results.push(choice.clone());
        }

        Search::new(config, query, choice_stack, results, 0, false)
    }

    pub fn is_done(&self) -> bool {
        self.done
    }

    pub fn done(self) -> Search<'s> {
        Search::new(self.config, self.query, self.choice_stack, self.result, self.current, true)
    }

    fn new(config: &'s Configuration<'s>, query: String, choice_stack: Vec<&'s Vec<String>>, result: Vec<String>, index: usize, done: bool) -> Search<'s> {
        let selection = Search::select(&result, index);

        Search { config: config,
                 current: index,
                 query: query,
                 selection: selection,
                 result: result,
                 choice_stack: choice_stack,
                 done: done}
    }

    fn new_for_index(self, index: usize) -> Search<'s> {
        Search::new(self.config, self.query, self.choice_stack, self.result, index, self.done)
    }

    fn new_for_query(self, new_query: String) -> Search<'s> {
        let new_result = Search::filter(new_query.as_slice(), self.config.choices, self.config.visible_limit);

        Search::new(self.config, new_query, self.choice_stack, new_result, 0, self.done)
    }

    pub fn filter(query: &str, choices: &Vec<String>, result_size: usize) -> Vec<String> {
        let mut results = SortedResultSet::new(result_size);
        let query = query.to_ascii_lowercase();

        for choice in choices.iter() {
            let lower_choice = choice.to_ascii_lowercase();

            match Score::score(&lower_choice, &query) {
                0.0     => continue,
                quality => results.push(quality, choice),
            };
        }
        results.sorted_vec()
    }

    fn select(result: &Vec<String>, index: usize) -> Option<String> {
        if result.len() > 0 {
            Some(result[index].to_string())
        } else {
            None
        }
    }

    pub fn down(self) -> Search<'s> {
        let next_index = self.next_index();
        self.new_for_index(next_index)
    }

    pub fn up(self) -> Search<'s> {
        let next_index = self.prev_index();
        self.new_for_index(next_index)
    }

    pub fn append_to_search(self, input: &str) -> Search<'s> {
        let mut new_query = self.query.clone();
        new_query.push_str(input.as_slice());

        self.new_for_query(new_query)
    }

    pub fn backspace(self) -> Search<'s> {
        let mut new_query = self.query.clone();
        new_query.pop();

        self.new_for_query(new_query)
    }

    fn next_index(&self) -> usize {
        let next_index = self.current + 1;

        if next_index >= self.actual_limit() {
            0
        } else {
            next_index
        }
    }

    fn prev_index(&self) -> usize {
        if self.current == 0 {
            self.actual_limit() - 1
        } else {
            self.current - 1
        }
    }

    fn actual_limit(&self) -> usize {
        min(self.config.visible_limit, self.result.len())
    }
}

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

    fn one_two_three() -> Vec<String> {
        vec!["one".to_string(),
             "two".to_string(),
             "three".to_string()]
    }

    #[test]
    fn it_selects_the_first_choice_by_default() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.selection, Some("one".to_string()));
    }

    #[test]
    fn it_selets_the_second_when_down_is_called() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.down().selection, Some("two".to_string()));
    }

    #[test]
    fn it_loop_around_when_reaching_end_of_list() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.down().down().down().down().selection, Some("two".to_string()));
    }

    #[test]
    fn it_loop_around_when_reaching_top_of_list() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.up().up().selection, Some("two".to_string()));
    }

    #[test]
    fn it_loop_around_when_reaching_visible_limit() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, Some(2));
        let search = Search::blank(&config);

        assert_eq!(search.down().down().down().selection, Some("two".to_string()));
    }

    #[test]
    fn it_moves_down_the_filtered_search_results() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.append_to_search("t").down().selection, Some("three".to_string()));
    }

    #[test]
    fn it_moves_down_the_filtered_search_results_twice() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.append_to_search("t").append_to_search("w").selection, Some("two".to_string()));
    }

    #[test]
    fn it_handles_not_matching_anything() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert_eq!(search.append_to_search("x").selection, None);
    }

    #[test]
    fn up_match_nothing_after_filtering_all_out() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("x");

        assert_eq!(search.up().selection, None);
    }

    #[test]
    fn down_match_nothing_after_filtering_all_out() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("x");

        assert_eq!(search.down().selection, None);
    }

    #[test]
    fn backspaces_over_characters() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("e");

        assert_eq!(search.query, "e");
        assert_eq!(search.backspace().query, "");
    }

    #[test]
    fn resets_the_index_when_removing_char_from_search() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("e");

        assert_eq!(search.down().backspace().current, 0);
    }

    #[test]
    fn resets_the_index_when_adding_char_to_seach() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).down();

        assert_eq!(search.append_to_search("o").current, 0);
    }

    #[test]
    fn previous_results_appear_after_backspace() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("t");

        assert_eq!(search.backspace().result.len(), 3);
    }

    #[test]
    fn initial_search_is_not_done() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config);

        assert!(!search.is_done());
    }

    #[test]
    fn done_search_is_done() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).done();

        assert!(search.is_done());
    }

    #[test]
    fn done_search_has_selection() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).done();

        assert_eq!(search.selection, Some("one".to_string()));
    }

    #[test]
    fn loop_around_when_reaching_bottom_of_choices() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("n").down();

        assert_eq!(search.selection, Some("one".to_string()));
    }

    #[test]
    fn loop_around_when_reaching_top_of_choices() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("n").up();

        assert_eq!(search.selection, Some("one".to_string()));
    }

    #[test]
    fn search_is_case_insensitive() {
        let input = one_two_three();
        let config = Configuration::from_inputs(&input, None, None);
        let search = Search::blank(&config).append_to_search("T");

        assert_eq!(search.result.len(), 2);
    }

    #[test]
    fn uses_configs_visible_limit_as_result_size() {
        let input = input_times(30);
        let config = Configuration::from_inputs(&input, None, Some(20));
        let search = Search::blank(&config).append_to_search("T");

        assert_eq!(search.result.len(), 20);
    }

    fn input_times(n: usize) ->Vec<String> {
        let mut result: Vec<String> = Vec::new();
        for thing in one_two_three().iter().cycle().take(n) {
            result.push(thing.clone());
        }
        result
    }

    //84114 ns/iter (+/- 33515)
    #[bench]
    fn filter_speed(b: &mut Bencher) {
        let input = input_times(1000);
        let query = "t";

        b.iter(||{
            Search::filter(query, &input, 20)
        });
    }
}
<|endoftext|>


<commit_before>use rustc::lint::{Context, LintPass, LintArray};
use std::cmp::Ordering;
use syntax::ast::{Mod, Item, Item_, Lit_, PathListItem_, ViewPath_, Visibility, MetaItem_};
use syntax::codemap::Span;
use syntax::print::pprust::path_to_string;

declare_lint!(UNSORTED_DECLARATIONS, Warn,
              "Warn when the declarations of crates or modules are not in alphabetical order");

pub struct Sorter;

impl LintPass for Sorter {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNSORTED_DECLARATIONS)
    }

    fn check_mod(&mut self, cx: &Context, module: &Mod, _span: Span, _id: u32) {
        let session_codemap = cx.tcx.sess.codemap();
        let mut extern_crates = Vec::new();
        let mut uses = Vec::new();
        let mut mods = Vec::new();
        for item in &module.items {
            let item_name = format!("{}", item.ident.name.as_str());
            let item_span = item.span;
            match item.node.clone() {
                Item_::ItemExternCrate(_) if item_name != "std" => {
                    let item_attrs = get_item_attrs(&item, false);
                    extern_crates.push((item_name, item_attrs, item_span, false));
                },
                Item_::ItemMod(module) => {
                    let mod_invoked_file = session_codemap.span_to_filename(item.span);
                    let mod_declared_file = session_codemap.span_to_filename(module.inner);
                    if mod_declared_file != mod_invoked_file {      // ignores inline modules
                        let item_attrs = get_item_attrs(&item, true);
                        mods.push((item_name, item_attrs, item_span, false));
                    }
                },
                Item_::ItemUse(spanned) => {
                    let item_attrs = get_item_attrs(&item, true);
                    match spanned.node {
                        ViewPath_::ViewPathSimple(_, ref path) => {
                            uses.push((path_to_string(&path), item_attrs, item_span, false));
                        },
                        ViewPath_::ViewPathList(ref path, ref list) => {
                            let old_list = list
                                           .iter()
                                           .filter_map(|&list_item| {
                                                match list_item.node {
                                                    PathListItem_::PathListIdent { name, .. } => {
                                                        let interned = name.name.as_str();
                                                        let string = &*interned;
                                                        Some(string.to_owned())
                                                    },
                                                    _ => None,
                                                }
                                            }).collect::<Vec<String>>();
                            let mut new_list = old_list.clone();
                            new_list.sort_by(|a, b| {
                                match *a == "self" {    // `self` should be first in an use list
                                    true => Ordering::Less,
                                    false => a.cmp(b),
                                }
                            });
                            let mut warn = false;
                            for i in 0..old_list.len() {
                                if old_list[i] != new_list[i] {
                                    warn = true;
                                    break;
                                }
                            }
                            let use_list = format!("{}::{{{}}}", path_to_string(&path), new_list.connect(", "));
                            uses.push((use_list, item_attrs, path.span, warn));
                        },
                        ViewPath_::ViewPathGlob(ref path) => {
                            let path_str = path_to_string(&path);
                            // we don't have any use statements like `use std::prelude::*`
                            // since it's done only by rustc, we can safely neglect those here
                            if !path_str.starts_with("std::") {
                                uses.push((path_str, item_attrs, item_span, false));
                            }
                        },
                    }
                },
                _ => (),
            }
        }

        check_sort(&extern_crates, cx, "crate declarations", "extern crate");
        check_sort(&mods, cx, "module declarations", "mod");
        check_sort(&uses, cx, "use statements", "use");

        fn get_item_attrs(item: &Item, pub_check: bool) -> String {
            let attr_vec = item.attrs
                           .iter()
                           .filter_map(|attr| {
                                let meta_item = attr.node.value.node.clone();
                                let meta_string = get_meta_as_string(&meta_item);
                                match meta_string.starts_with("doc = ") {
                                    true => None,
                                    false => Some(format!("#[{}]", meta_string)),
                                }
                           }).collect::<Vec<String>>();
            let attr_string = attr_vec.connect("\n");
            match item.vis {
                Visibility::Public if pub_check => {
                    match attr_string.is_empty() {
                        true => "pub ".to_owned(),
                        false => attr_string + "\npub ",    // `pub` for mods and uses
                    }
                },
                _ => {
                    match attr_string.is_empty() {
                        true => attr_string,
                        false => attr_string + "\n",
                    }
                },
            }
        }

        fn get_meta_as_string(meta_item: &MetaItem_) -> String {
            match *meta_item {      // recursively collect the information from meta items into Strings
                MetaItem_::MetaWord(ref string) => format!("{}", string),
                MetaItem_::MetaList(ref string, ref meta_items) => {
                    let stuff = meta_items
                                .iter()
                                .map(|meta_item| {
                                    get_meta_as_string(&meta_item.node)
                                }).collect::<Vec<String>>();
                    format!("{}({})", string, stuff.connect(", "))
                },
                MetaItem_::MetaNameValue(ref string, ref literal) => {
                    let value = match literal.node {
                        Lit_::LitStr(ref inner_str, _style) => inner_str,
                        _ => panic!("unexpected literal found for meta item!"),
                    }; format!("{} = \"{}\"", string, value)
                },
            }
        }

        // slice of tuples with a name, related attributes, spans and whether to warn for an use list
        fn check_sort(old_list: &[(String, String, Span, bool)], cx: &Context, kind: &str, syntax: &str) {
            let length = old_list.len();
            let mut new_list = old_list
                                .iter()
                                .map(|&(ref name, ref attrs, _span, warn)| (name.clone(), attrs.clone(), warn))
                                .collect::<Vec<(String, String, bool)>>();
            new_list.sort_by(|&(ref str_a, ref attr_a, _), &(ref str_b, ref attr_b, _)| {
                match attr_b.ends_with("pub ") {
                    true => {   // a closure only to move the ordered `pub` statements to the bottom
                        let new_str_b = "~".to_owned() + &str_b;
                        match attr_a.ends_with("pub ") {
                            true => {   // since `~` is superior to almost all the ASCII chars
                                let new_str_a = "~".to_owned() + &str_a;
                                new_str_a.cmp(&new_str_b)
                            },
                            false => str_a.cmp(&new_str_b)
                        }
                    },
                    false => str_a.cmp(str_b),
                }
            });

            let mut span: Option<Span> = None;
            let message = format!("{} should be in alphabetical order!\nTry this...\n", kind);
            let mut suggested_list = Vec::new();
            suggested_list.push(message);
            for i in 0..length {
                let name = new_list[i].0.clone();
                if (old_list[i].0 != name) || new_list[i].2 {
                    let suggestion = format!("{}{} {};", new_list[i].1, syntax, name);
                    suggested_list.push(suggestion);
                    span = match span {
                        Some(old_span) => {
                            let mut sp = old_span;
                            sp.hi = old_list[i].2.hi;   // increase the span to include more lines
                            Some(sp)
                        },
                        None => Some(old_list[i].2),
                    }
                }
            }

            match span {
                Some(sp) => cx.span_lint(UNSORTED_DECLARATIONS, sp, &suggested_list.connect("\n")),
                None => (),
            }
        }
    }
}
<commit_msg>pattern matching and revised methods<commit_after>use rustc::lint::{Context, LintPass, LintArray};
use std::cmp::Ordering;
use syntax::ast::{Mod, Item, Item_, Lit_, PathListItem_, ViewPath_, Visibility, MetaItem_};
use syntax::codemap::Span;
use syntax::print::pprust::path_to_string;

declare_lint!(UNSORTED_DECLARATIONS, Warn,
              "Warn when the declarations of crates or modules are not in alphabetical order");

pub struct Sorter;

impl LintPass for Sorter {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNSORTED_DECLARATIONS)
    }

    fn check_mod(&mut self, cx: &Context, module: &Mod, _span: Span, _id: u32) {
        let session_codemap = cx.tcx.sess.codemap();
        let mut extern_crates = Vec::new();
        let mut uses = Vec::new();
        let mut mods = Vec::new();
        for item in &module.items {
            let item_name = format!("{}", item.ident.name.as_str());
            let item_span = item.span;
            match item.node.clone() {
                Item_::ItemExternCrate(_) if item_name != "std" => {
                    let item_attrs = get_item_attrs(&item, false);
                    extern_crates.push((item_name, item_attrs, item_span, false));
                },
                Item_::ItemMod(module) => {
                    let mod_invoked_file = session_codemap.span_to_filename(item.span);
                    let mod_declared_file = session_codemap.span_to_filename(module.inner);
                    if mod_declared_file != mod_invoked_file {      // ignores inline modules
                        let item_attrs = get_item_attrs(&item, true);
                        mods.push((item_name, item_attrs, item_span, false));
                    }
                },
                Item_::ItemUse(spanned) => {
                    let item_attrs = get_item_attrs(&item, true);
                    match spanned.node {
                        ViewPath_::ViewPathSimple(ref ident, ref path) => {
                            let path_str = path_to_string(&path);
                            let name = ident.name.as_str();
                            let renamed = match path_str.ends_with(&*name) {
                                true => path_str,   // for checking `use foo as bar`
                                false => format!("{} as {}", &path_str, &name),
                            };
                            uses.push((renamed, item_attrs, item_span, false));
                        },
                        ViewPath_::ViewPathList(ref path, ref list) => {
                            let old_list = list
                                           .iter()
                                           .map(|&list_item| {
                                                match list_item.node {
                                                    PathListItem_::PathListMod { .. } =>
                                                        "self".to_owned(),
                                                    PathListItem_::PathListIdent { name, .. } => {
                                                        let interned = name.name.as_str();
                                                        let string = &*interned;
                                                        string.to_owned()
                                                    },
                                                }
                                            }).collect::<Vec<String>>();
                            let mut new_list = old_list.clone();
                            new_list.sort_by(|a, b| {
                                match (&**a, &**b) {    // `self` should be first in an use list
                                    ("self", _) => Ordering::Less,
                                    (_, "self") => Ordering::Greater,
                                    _ => a.cmp(b),
                                }
                            });
                            let mut warn = false;
                            for i in 0..old_list.len() {
                                if old_list[i] != new_list[i] {
                                    warn = true;
                                    break;
                                }
                            }
                            let use_list = format!("{}::{{{}}}", path_to_string(&path), new_list.connect(", "));
                            uses.push((use_list, item_attrs, path.span, warn));
                        },
                        ViewPath_::ViewPathGlob(ref path) => {
                            let path_str = path_to_string(&path) + "::*";
                            // we don't have any use statements like `use std::prelude::*`
                            // since it's done only by rustc, we can safely neglect those here
                            if !path_str.starts_with("std::") {
                                uses.push((path_str, item_attrs, item_span, false));
                            }
                        },
                    }
                },
                _ => (),
            }
        }

        check_sort(&extern_crates, cx, "crate declarations", "extern crate");
        check_sort(&mods, cx, "module declarations (ignoring the inline modules)", "mod");
        check_sort(&uses, cx, "use statements", "use");

        // for collecting, formatting & filtering the meta items, and checking the visibility
        fn get_item_attrs(item: &Item, pub_check: bool) -> String {
            let attr_vec = item.attrs
                           .iter()
                           .filter_map(|attr| {
                                let meta_item = attr.node.value.node.clone();
                                let meta_string = get_meta_as_string(&meta_item);
                                match meta_string.starts_with("doc = ") {
                                    true => None,
                                    false => Some(format!("#[{}]", meta_string)),
                                }
                           }).collect::<Vec<String>>();
            let attr_string = attr_vec.connect("\n");
            match item.vis {
                Visibility::Public if pub_check => {
                    match attr_string.is_empty() {
                        true => "pub ".to_owned(),
                        false => attr_string + "\npub ",    // `pub` for mods and uses
                    }
                },
                _ => {
                    match attr_string.is_empty() {
                        true => attr_string,
                        false => attr_string + "\n",
                    }
                },
            }
        }

        // recursively collect the information from meta items into Strings
        fn get_meta_as_string(meta_item: &MetaItem_) -> String {
            match *meta_item {
                MetaItem_::MetaWord(ref string) => format!("{}", string),
                MetaItem_::MetaList(ref string, ref meta_items) => {
                    let stuff = meta_items
                                .iter()
                                .map(|meta_item| {
                                    get_meta_as_string(&meta_item.node)
                                }).collect::<Vec<String>>();
                    format!("{}({})", string, stuff.connect(", "))
                },
                MetaItem_::MetaNameValue(ref string, ref literal) => {
                    let value = match literal.node {
                        Lit_::LitStr(ref inner_str, _style) => inner_str,
                        _ => panic!("unexpected literal found for meta item!"),
                    }; format!("{} = \"{}\"", string, value)
                },
            }
        }

        // checks the sorting of all the declarations and raises warnings whenever necessary
        // takes a slice of tuples with a name, related attributes, spans and whether to warn for an unordered use list
        fn check_sort(old_list: &[(String, String, Span, bool)], cx: &Context, kind: &str, syntax: &str) {
            let length = old_list.len();
            let mut new_list = old_list
                                .iter()
                                .map(|&(ref name, ref attrs, _span, warn)| (name.clone(), attrs.clone(), warn))
                                .collect::<Vec<(String, String, bool)>>();
            new_list.sort_by(|&(ref str_a, ref attr_a, _), &(ref str_b, ref attr_b, _)| {
                // a closure only to move the ordered `pub` statements to the bottom
                let new_str_a = "~".to_owned() + &str_a;    // since `~` is superior to almost all the ASCII chars
                let new_str_b = "~".to_owned() + &str_b;
                match (attr_a.ends_with("pub "), attr_b.ends_with("pub ")) {
                    (true, true) => new_str_a.cmp(&new_str_b),
                    (true, false) => new_str_a.cmp(str_b),
                    (false, true) => str_a.cmp(&new_str_b),
                    (false, false) => str_a.cmp(str_b),
                }
            });

            let mut index = 0;
            let mut span: Option<Span> = None;
            for i in 0..length {
                if (old_list[i].0 != new_list[i].0) || new_list[i].2 {
                    span = Some(old_list[i].2);
                    index = i;      // only to find the index of the first unsorted declaration
                    break;
                }
            }

            match span {
                Some(span_start) => {   // print all the declarations proceeding the first unsorted one
                    let suggestion_list = (index..length)
                                          .map(|i| {
                                              if i == length - 1 {  // increase the span to include more lines
                                                  let mut sp = span_start;
                                                  sp.hi = old_list[i].2.hi;
                                                  span = Some(sp);
                                              } format!("{}{} {};", new_list[i].1, syntax, new_list[i].0)
                                          }).collect::<Vec<String>>();
                    let suggestion = format!("{} should be in alphabetical order!\nTry this...\n\n{}\n\n",
                                            kind, suggestion_list.connect("\n"));
                    // unwrapping the value here, because it's certain there's something in `span`
                    cx.span_lint(UNSORTED_DECLARATIONS, span.unwrap(), &suggestion);
                },
                None => (),
            }
        }
    }
}
<|endoftext|>


<commit_before>//! All keys in leveldb are compared by their binary value unless
//! defined otherwise.
//!
//! Comparators allow to override this comparison.
//! The ordering of keys introduced by the compartor influences iteration order.
//! Databases written with one Comparator cannot be opened with another.
use leveldb_sys::*;
use libc::{size_t, c_void, c_char};
use libc;
use std::mem;
use std::slice;
use std::cmp::Ordering;
use database::key::Key;
use database::key::from_u8;
use std::marker::PhantomData;

/// A comparator has two important functions:
///
/// * the name function returns a fixed name to detect errors when
///   opening databases with a different name
/// * The comparison implementation
pub trait Comparator {
    /// The type that the comparator compares.
    type K: Key;

    /// Return the name of the Comparator
    fn name(&self) -> *const c_char;
    /// compare two keys. This must implement a total ordering.
    fn compare(&self, a: &Self::K, b: &Self::K) -> Ordering;
    /// whether the comparator is the `DefaultComparator`
    fn null() -> bool {
        false
    }
}

/// OrdComparator is a comparator comparing Keys that implement `Ord`
pub struct OrdComparator<K> {
    name: String,
    marker: PhantomData<K>,
}

impl<K> OrdComparator<K> {
    /// Create a new OrdComparator
    pub fn new(name: &str) -> OrdComparator<K> {
        OrdComparator {
            marker: PhantomData,
            name: name.to_string(),
        }
    }
}
/// DefaultComparator is the a stand in for "no comparator set"
#[derive(Copy,Clone)]
pub struct DefaultComparator;

extern "C" fn name<K: Key, T: Comparator>(state: *mut libc::c_void) -> *const c_char {
    let x: &T = unsafe { &*(state as *mut T) };
    x.name()
}

extern "C" fn compare<K: Key, T: Comparator>(state: *mut libc::c_void,
                                             a: *const i8,
                                             a_len: size_t,
                                             b: *const i8,
                                             b_len: size_t)
                                             -> i32 {
    unsafe {
        let a_slice = slice::from_raw_parts::<u8>(a as *const u8, a_len as usize);
        let b_slice = slice::from_raw_parts::<u8>(b as *const u8, b_len as usize);
        let x: &T = &*(state as *mut T);
        let a_key = from_u8::<<T as Comparator>::K>(a_slice);
        let b_key = from_u8::<<T as Comparator>::K>(b_slice);
        match x.compare(&a_key, &b_key) {
            Ordering::Less => -1,
            Ordering::Equal => 0,
            Ordering::Greater => 1,
        }
    }
}

extern "C" fn destructor<T>(state: *mut libc::c_void) {
    let _x: Box<T> = unsafe { mem::transmute(state) };
     // let the Box fall out of scope and run the T's destructor
}

#[allow(missing_docs)]
pub fn create_comparator<K: Key, T: Comparator<K = K>>(x: Box<T>) -> *mut leveldb_comparator_t {
    unsafe {
        leveldb_comparator_create(mem::transmute(x),
                                  destructor::<T>,
                                  compare::<K, T>,
                                  name::<K, T>)
    }
}

impl<K: Key + Ord> Comparator for OrdComparator<K> {
  type K = K;

    fn name(&self) -> *const c_char {
        let slice: &str = self.name.as_ref();
        slice.as_ptr() as *const c_char
    }

    fn compare(&self, a: &K, b: &K) -> Ordering {
        a.cmp(b)
    }
}

impl Comparator for DefaultComparator {
  type K = i32;

    fn name(&self) -> *const c_char {
        "default_comparator".as_ptr() as *const c_char
    }

    fn compare(&self, _a: &i32, _b: &i32) -> Ordering {
        Ordering::Equal
    }

    fn null() -> bool {
        true
    }
}
<commit_msg>Rework comparator<commit_after>//! All keys in leveldb are compared by their binary value unless
//! defined otherwise.
//!
//! Comparators allow to override this comparison.
//! The ordering of keys introduced by the compartor influences iteration order.
//! Databases written with one Comparator cannot be opened with another.
use leveldb_sys::*;
use libc::{size_t, c_void, c_char};
use libc;
use std::mem;
use std::slice;
use std::cmp::Ordering;
use database::key::Key;
use database::key::from_u8;
use std::marker::PhantomData;

/// A comparator has two important functions:
///
/// * the name function returns a fixed name to detect errors when
///   opening databases with a different name
/// * The comparison implementation
pub trait Comparator {
    /// The type that the comparator compares.
    type K: Key;

    /// Return the name of the Comparator
    fn name(&self) -> *const c_char;
    /// compare two keys. This must implement a total ordering.
    fn compare(&self, a: &Self::K, b: &Self::K) -> Ordering;
    /// whether the comparator is the `DefaultComparator`
    fn null() -> bool {
        false
    }
}

/// OrdComparator is a comparator comparing Keys that implement `Ord`
pub struct OrdComparator<K: Key + Ord> {
    name: String,
    marker: PhantomData<K>,
}

impl<K: Key + Ord> OrdComparator<K> {
    /// Create a new OrdComparator
    pub fn new(name: &str) -> OrdComparator<K> {
        OrdComparator {
            marker: PhantomData,
            name: name.to_string(),
        }
    }
}

/// DefaultComparator is the a stand in for "no comparator set"
#[derive(Copy,Clone)]
pub struct DefaultComparator;

trait InternalComparator<C: Comparator> {

    extern "C" fn name(state: *mut c_void) -> *const c_char {
        let x: &C = unsafe { &*(state as *mut C) };
        x.name()
    }

    extern "C" fn compare(state: *mut c_void,
                          a: *const i8,
                          a_len: size_t,
                          b: *const i8,
                          b_len: size_t)
                          -> i32 {
        unsafe {
            let a_slice = slice::from_raw_parts::<u8>(a as *const u8, a_len as usize);
            let b_slice = slice::from_raw_parts::<u8>(b as *const u8, b_len as usize);
            let x: &C = &*(state as *mut C);
            let a_key = from_u8::<<C as Comparator>::K>(a_slice);
            let b_key = from_u8::<<C as Comparator>::K>(b_slice);
            match x.compare(&a_key, &b_key) {
                Ordering::Less => -1,
                Ordering::Equal => 0,
                Ordering::Greater => 1,
            }
        }
    }

    extern "C" fn destructor(state: *mut c_void) {
        let _x: Box<C> = unsafe { mem::transmute(state) };
         // let the Box fall out of scope and run the T's destructor
    }
}

impl<C: Comparator> InternalComparator<C> for C {}

#[allow(missing_docs)]
pub fn create_comparator<K: Key, T: Comparator<K = K>>(x: Box<T>) -> *mut leveldb_comparator_t {
    unsafe {
        leveldb_comparator_create(mem::transmute(x),
                                  <T as InternalComparator<T>>::destructor,
                                  <T as InternalComparator<T>>::compare,
                                  <T as InternalComparator<T>>::name)
    }
}

impl<K: Key + Ord> Comparator for OrdComparator<K> {
  type K = K;

    fn name(&self) -> *const c_char {
        let slice: &str = self.name.as_ref();
        slice.as_ptr() as *const c_char
    }

    fn compare(&self, a: &K, b: &K) -> Ordering {
        a.cmp(b)
    }
}

impl Comparator for DefaultComparator {
  type K = i32;

    fn name(&self) -> *const c_char {
        "default_comparator".as_ptr() as *const c_char
    }

    fn compare(&self, _a: &i32, _b: &i32) -> Ordering {
        Ordering::Equal
    }

    fn null() -> bool {
        true
    }
}
<|endoftext|>


<commit_before>
use std::rc::Rc;
use std::collections::HashMap;

use uuid::Uuid;

use graphics::*;
use graphics::internal::{
    Rectangle,
    Vec2d,
};
use graphics::vecmath::Scalar;

/// A sprite is a texture with some properties.
pub struct Sprite<I: ImageSize> {
    id: Uuid,

    visible: bool,

    anchor: Vec2d,

    position: Vec2d,
    rotation: Scalar,
    scale: Vec2d,

    flip_x: bool,
    flip_y: bool,

    opacity: f32,

    children: Vec<Sprite<I>>,
    children_index: HashMap<Uuid, uint>,

    texture: Rc<I>,
}

impl<I: ImageSize> Sprite<I> {
    /// Crate sprite from a texture
    pub fn from_texture(texture: Rc<I>) -> Sprite<I> {
        Sprite {
            id: Uuid::new_v4(),

            visible: true,

            anchor: [0.5, 0.5],

            position: [0.0, 0.0],
            rotation: 0.0,
            scale: [1.0, 1.0],

            flip_x: false,
            flip_y: false,

            opacity: 1.0,

            texture: texture,

            children: Vec::new(),
            children_index: HashMap::new(),
        }
    }

    /// Get the sprite's id
    #[inline(always)]
    pub fn id(&self) -> Uuid {
        self.id
    }

    /// Whether or not the sprite is visible
    pub fn visible(&self) -> bool {
        self.visible
    }

    /// Set the sprite's visibility
    pub fn set_visible(&mut self, visible: bool) {
        self.visible = visible;
    }

    /// Get the sprite's anchor point
    ///
    /// The value is normalized. Default value is [0.5, 0.5] (the center of texture)
    #[inline(always)]
    pub fn anchor(&self) -> (Scalar, Scalar) {
        (self.anchor[0], self.anchor[1])
    }

    /// Set the sprite's anchor point
    #[inline(always)]
    pub fn set_anchor(&mut self, x: Scalar, y: Scalar) {
        self.anchor = [x, y];
    }

    /// Get the sprite's position
    #[inline(always)]
    pub fn position(&self) -> (Scalar, Scalar) {
        (self.position[0], self.position[1])
    }

    /// Set the sprite's position
    #[inline(always)]
    pub fn set_position(&mut self, x: Scalar, y: Scalar) {
        self.position = [x, y];
    }

    /// Get the sprite's rotation (in degree)
    #[inline(always)]
    pub fn rotation(&self) -> Scalar {
        self.rotation
    }

    /// Set the sprite's rotation (in degree)
    #[inline(always)]
    pub fn set_rotation(&mut self, deg: Scalar) {
        self.rotation = deg;
    }

    /// Get the sprite's scale
    #[inline(always)]
    pub fn scale(&self) -> (Scalar, Scalar) {
        (self.scale[0], self.scale[1])
    }

    /// Set the sprite's scale
    #[inline(always)]
    pub fn set_scale(&mut self, sx: Scalar, sy: Scalar) {
        self.scale = [sx, sy];
    }

    /// Whether or not the sprite is flipped horizontally.
    ///
    /// It only flips the texture of the sprite,
    /// and not the texture of the sprite’s children.
    ///
    /// Also, flipping the texture doesn’t alter the `anchor`.
    ///
    /// If you want to flip the `anchor` too,
    /// and/or to flip the children too use: sprite.scale.x *= -1;
    #[inline(always)]
    pub fn flip_x(&self) -> bool {
        self.flip_x
    }

    /// Flip the sprite
    #[inline(always)]
    pub fn set_flip_x(&mut self, flip_x: bool) {
        self.flip_x = flip_x;
    }

    /// Whether or not the sprite is flipped vertically.
    ///
    /// It only flips the texture of the sprite,
    /// and not the texture of the sprite’s children.
    ///
    /// Also, flipping the texture doesn’t alter the `anchor`.
    ///
    /// If you want to flip the `anchor` too,
    /// and/or to flip the children too use: sprite.scale.y *= -1;
    #[inline(always)]
    pub fn flip_y(&self) -> bool {
        self.flip_y
    }

    /// Flip the sprite
    #[inline(always)]
    pub fn set_flip_y(&mut self, flip_y: bool) {
        self.flip_y = flip_y;
    }

    /// Get the sprite's opacity
    #[inline(always)]
    pub fn opacity(&self) -> f32 {
        self.opacity
    }

    /// Set the sprite's opacity
    #[inline(always)]
    pub fn set_opacity(&mut self, opacity: f32) {
        self.opacity = opacity;
    }

    /// Get the sprite's texture
    #[inline(always)]
    pub fn texture(&self) -> &Rc<I> {
        &self.texture
    }

    /// Set the sprite's texture
    #[inline(always)]
    pub fn set_texture(&mut self, texture: Rc<I>) {
        self.texture = texture;
    }

    /// Add a sprite as the child of this sprite, return the added sprite's id.
    pub fn add_child(&mut self, sprite: Sprite<I>) -> Uuid {
        let id = sprite.id();
        self.children.push(sprite);
        self.children_index.insert(id, self.children.len() - 1);
        id
    }

    /// Remove the child by `id` from this sprite's children or grandchild
    pub fn remove_child(&mut self, id: Uuid) -> Option<Sprite<I>> {
        match self.children_index.remove(&id) {
            Some(i) => {
                let removed = self.children.remove(i).unwrap();
                // Removing a element of vector will alter the index,
                // update the mapping from uuid to index.
                for index in range(i, self.children.len()) {
                    let uuid = self.children[index].id();
                    self.children_index.insert(uuid, index);
                }
                Some(removed)
            },
            None => {
                for child in self.children.iter_mut() {
                    match child.remove_child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }

    /// Find the child by `id` from this sprite's children or grandchild
    pub fn child(&self, id: Uuid) -> Option<&Sprite<I>> {
        match self.children_index.get(&id) {
            Some(i) => { Some(&self.children[*i]) },
            None => {
                for child in self.children.iter() {
                    match child.child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }

    /// Find the child by `id` from this sprite's children or grandchild, mutability
    pub fn child_mut(&mut self, id: Uuid) -> Option<&mut Sprite<I>> {
        match self.children_index.get(&id) {
            Some(i) => { Some(&mut self.children[*i]) },
            None => {
                for child in self.children.iter_mut() {
                    match child.child_mut(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }

    /// Get the sprite's children
    #[inline(always)]
    pub fn children(&self) -> &Vec<Sprite<I>> {
        &self.children
    }

    /// Draw this sprite and its children
    pub fn draw<B: BackEnd<I>>(&self, c: &Context, b: &mut B) {
        if !self.visible {
            return;
        }

        let (w, h) = self.texture.get_size();
        let w = w as f64;
        let h = h as f64;
        let anchor = [self.anchor[0] * w, self.anchor[1] * h];

        let transformed = c.trans(self.position[0], self.position[1])
                           .rot_deg(self.rotation)
                           .scale(self.scale[0], self.scale[1]);

        let mut model = transformed.rect(-anchor[0],
                                         -anchor[1],
                                          w,
                                          h);

        if self.flip_x {
            model = model.trans(w - 2.0 * anchor[0], 0.0).flip_h();
        }

        if self.flip_y {
            model = model.trans(0.0, h - 2.0 * anchor[1]).flip_v();
        }

        // for debug: bounding_box
        //model.rgb(1.0, 0.0, 0.0).draw(b);

        model.rgba(1.0, 1.0, 1.0, self.opacity).image(&*self.texture).draw(b);

        // for debug: anchor point
        //c.trans(self.position[0], self.position[1]).rect(-5.0, -5.0, 10.0, 10.0).rgb(0.0, 0.0, 1.0).draw(b);

        for child in self.children.iter() {
            child.draw(&transformed, b);
        }
    }

    /// Get the sprite's bounding box
    pub fn bounding_box(&self) -> Rectangle {
        let (w, h) = self.texture.get_size();
        let w = w as f64 * self.scale[0];
        let h = h as f64 * self.scale[1];

        [
            self.position[0] - self.anchor[0] * w,
            self.position[1] - self.anchor[1] * h,
            w,
            h
        ]
    }
}

<commit_msg>Upgraded to latest piston-graphics<commit_after>
use std::rc::Rc;
use std::collections::HashMap;

use uuid::Uuid;

use graphics::{ Context, BackEnd, ImageSize };
use graphics::internal::{
    Rectangle,
    Vec2d,
};
use graphics::vecmath::Scalar;

/// A sprite is a texture with some properties.
pub struct Sprite<I: ImageSize> {
    id: Uuid,

    visible: bool,

    anchor: Vec2d,

    position: Vec2d,
    rotation: Scalar,
    scale: Vec2d,

    flip_x: bool,
    flip_y: bool,

    opacity: f32,

    children: Vec<Sprite<I>>,
    children_index: HashMap<Uuid, uint>,

    texture: Rc<I>,
}

impl<I: ImageSize> Sprite<I> {
    /// Crate sprite from a texture
    pub fn from_texture(texture: Rc<I>) -> Sprite<I> {
        Sprite {
            id: Uuid::new_v4(),

            visible: true,

            anchor: [0.5, 0.5],

            position: [0.0, 0.0],
            rotation: 0.0,
            scale: [1.0, 1.0],

            flip_x: false,
            flip_y: false,

            opacity: 1.0,

            texture: texture,

            children: Vec::new(),
            children_index: HashMap::new(),
        }
    }

    /// Get the sprite's id
    #[inline(always)]
    pub fn id(&self) -> Uuid {
        self.id
    }

    /// Whether or not the sprite is visible
    pub fn visible(&self) -> bool {
        self.visible
    }

    /// Set the sprite's visibility
    pub fn set_visible(&mut self, visible: bool) {
        self.visible = visible;
    }

    /// Get the sprite's anchor point
    ///
    /// The value is normalized. Default value is [0.5, 0.5] (the center of texture)
    #[inline(always)]
    pub fn anchor(&self) -> (Scalar, Scalar) {
        (self.anchor[0], self.anchor[1])
    }

    /// Set the sprite's anchor point
    #[inline(always)]
    pub fn set_anchor(&mut self, x: Scalar, y: Scalar) {
        self.anchor = [x, y];
    }

    /// Get the sprite's position
    #[inline(always)]
    pub fn position(&self) -> (Scalar, Scalar) {
        (self.position[0], self.position[1])
    }

    /// Set the sprite's position
    #[inline(always)]
    pub fn set_position(&mut self, x: Scalar, y: Scalar) {
        self.position = [x, y];
    }

    /// Get the sprite's rotation (in degree)
    #[inline(always)]
    pub fn rotation(&self) -> Scalar {
        self.rotation
    }

    /// Set the sprite's rotation (in degree)
    #[inline(always)]
    pub fn set_rotation(&mut self, deg: Scalar) {
        self.rotation = deg;
    }

    /// Get the sprite's scale
    #[inline(always)]
    pub fn scale(&self) -> (Scalar, Scalar) {
        (self.scale[0], self.scale[1])
    }

    /// Set the sprite's scale
    #[inline(always)]
    pub fn set_scale(&mut self, sx: Scalar, sy: Scalar) {
        self.scale = [sx, sy];
    }

    /// Whether or not the sprite is flipped horizontally.
    ///
    /// It only flips the texture of the sprite,
    /// and not the texture of the sprite’s children.
    ///
    /// Also, flipping the texture doesn’t alter the `anchor`.
    ///
    /// If you want to flip the `anchor` too,
    /// and/or to flip the children too use: sprite.scale.x *= -1;
    #[inline(always)]
    pub fn flip_x(&self) -> bool {
        self.flip_x
    }

    /// Flip the sprite
    #[inline(always)]
    pub fn set_flip_x(&mut self, flip_x: bool) {
        self.flip_x = flip_x;
    }

    /// Whether or not the sprite is flipped vertically.
    ///
    /// It only flips the texture of the sprite,
    /// and not the texture of the sprite’s children.
    ///
    /// Also, flipping the texture doesn’t alter the `anchor`.
    ///
    /// If you want to flip the `anchor` too,
    /// and/or to flip the children too use: sprite.scale.y *= -1;
    #[inline(always)]
    pub fn flip_y(&self) -> bool {
        self.flip_y
    }

    /// Flip the sprite
    #[inline(always)]
    pub fn set_flip_y(&mut self, flip_y: bool) {
        self.flip_y = flip_y;
    }

    /// Get the sprite's opacity
    #[inline(always)]
    pub fn opacity(&self) -> f32 {
        self.opacity
    }

    /// Set the sprite's opacity
    #[inline(always)]
    pub fn set_opacity(&mut self, opacity: f32) {
        self.opacity = opacity;
    }

    /// Get the sprite's texture
    #[inline(always)]
    pub fn texture(&self) -> &Rc<I> {
        &self.texture
    }

    /// Set the sprite's texture
    #[inline(always)]
    pub fn set_texture(&mut self, texture: Rc<I>) {
        self.texture = texture;
    }

    /// Add a sprite as the child of this sprite, return the added sprite's id.
    pub fn add_child(&mut self, sprite: Sprite<I>) -> Uuid {
        let id = sprite.id();
        self.children.push(sprite);
        self.children_index.insert(id, self.children.len() - 1);
        id
    }

    /// Remove the child by `id` from this sprite's children or grandchild
    pub fn remove_child(&mut self, id: Uuid) -> Option<Sprite<I>> {
        match self.children_index.remove(&id) {
            Some(i) => {
                let removed = self.children.remove(i).unwrap();
                // Removing a element of vector will alter the index,
                // update the mapping from uuid to index.
                for index in range(i, self.children.len()) {
                    let uuid = self.children[index].id();
                    self.children_index.insert(uuid, index);
                }
                Some(removed)
            },
            None => {
                for child in self.children.iter_mut() {
                    match child.remove_child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }

    /// Find the child by `id` from this sprite's children or grandchild
    pub fn child(&self, id: Uuid) -> Option<&Sprite<I>> {
        match self.children_index.get(&id) {
            Some(i) => { Some(&self.children[*i]) },
            None => {
                for child in self.children.iter() {
                    match child.child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }

    /// Find the child by `id` from this sprite's children or grandchild, mutability
    pub fn child_mut(&mut self, id: Uuid) -> Option<&mut Sprite<I>> {
        match self.children_index.get(&id) {
            Some(i) => { Some(&mut self.children[*i]) },
            None => {
                for child in self.children.iter_mut() {
                    match child.child_mut(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }

    /// Get the sprite's children
    #[inline(always)]
    pub fn children(&self) -> &Vec<Sprite<I>> {
        &self.children
    }

    /// Draw this sprite and its children
    pub fn draw<B: BackEnd<I>>(&self, c: &Context, b: &mut B) {
        use graphics::*;

        if !self.visible {
            return;
        }

        let (w, h) = self.texture.get_size();
        let w = w as f64;
        let h = h as f64;
        let anchor = [self.anchor[0] * w, self.anchor[1] * h];

        let transformed = c.trans(self.position[0], self.position[1])
                           .rot_deg(self.rotation)
                           .scale(self.scale[0], self.scale[1]);

        let mut model = transformed.rect(-anchor[0],
                                         -anchor[1],
                                          w,
                                          h);

        if self.flip_x {
            model = model.trans(w - 2.0 * anchor[0], 0.0).flip_h();
        }

        if self.flip_y {
            model = model.trans(0.0, h - 2.0 * anchor[1]).flip_v();
        }

        // for debug: bounding_box
        //model.rgb(1.0, 0.0, 0.0).draw(b);

        model.rgba(1.0, 1.0, 1.0, self.opacity).image(&*self.texture).draw(b);

        // for debug: anchor point
        //c.trans(self.position[0], self.position[1]).rect(-5.0, -5.0, 10.0, 10.0).rgb(0.0, 0.0, 1.0).draw(b);

        for child in self.children.iter() {
            child.draw(&transformed, b);
        }
    }

    /// Get the sprite's bounding box
    pub fn bounding_box(&self) -> Rectangle {
        let (w, h) = self.texture.get_size();
        let w = w as f64 * self.scale[0];
        let h = h as f64 * self.scale[1];

        [
            self.position[0] - self.anchor[0] * w,
            self.position[1] - self.anchor[1] * h,
            w,
            h
        ]
    }
}

<|endoftext|>


<commit_before>use metadata;

use metadata::{StreamInfo, metadata_parser};
use frame::{frame_parser, Frame};

pub struct Stream {
  pub info: StreamInfo,
  pub metadata: Vec<metadata::Metadata>,
  pub frames: Vec<Frame>,
}

named!(pub stream <&[u8], Stream>,
  chain!(
    blocks: metadata_parser ~
    frames: many1!(apply!(frame_parser, &blocks.0)),
    move|| {
      Stream {
        info: blocks.0,
        metadata: blocks.1,
        frames: frames,
      }
    }
  )
);
<commit_msg>Re-export Metadata struct<commit_after>use metadata::{Metadata, StreamInfo, metadata_parser};
use frame::{frame_parser, Frame};

pub struct Stream {
  pub info: StreamInfo,
  pub metadata: Vec<Metadata>,
  pub frames: Vec<Frame>,
}

named!(pub stream <&[u8], Stream>,
  chain!(
    blocks: metadata_parser ~
    frames: many1!(apply!(frame_parser, &blocks.0)),
    move|| {
      Stream {
        info: blocks.0,
        metadata: blocks.1,
        frames: frames,
      }
    }
  )
);
<|endoftext|>


<commit_before>use nom;
use nom::{Err, IResult};

use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo, metadata_parser};
use frame::{frame_parser, Frame};
use utility::{ErrorKind, ByteStream, ReadStream, StreamProducer};

use std::io;
use std::usize;
use std::fs::File;

enum ParserState {
  Marker,
  Metadata,
  Frame,
}

/// FLAC stream that decodes and hold file information.
pub struct Stream {
  info: StreamInfo,
  metadata: Vec<Metadata>,
  frames: Vec<Frame>,
  state: ParserState,
  output: Vec<i32>,
  frame_index: usize,
}

impl Stream {
  /// Constructor for the default state of a FLAC stream.
  ///
  /// This doesn't actually decode anything, it just hold the default values
  /// of each field.
  pub fn new() -> Stream {
    Stream {
      info: StreamInfo::new(),
      metadata: Vec::new(),
      frames: Vec::new(),
      state: ParserState::Marker,
      output: Vec::new(),
      frame_index: 0,
    }
  }

  /// Returns information for the current stream.
  pub fn info(&self) -> StreamInfo {
    self.info
  }

  /// Returns a slice of `Metadata`
  ///
  /// This slice excludes `StreamInfo`, which is located in `Stream::info`.
  /// Everything else is related to metadata for the FLAC stream is in the
  /// slice.
  pub fn metadata(&self) -> &[Metadata] {
    &self.metadata
  }

  /// Constructs a decoder with the given file name.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::NotFound` is returned when the given filename isn't found.
  /// * `ErrorKind::InvalidData` is returned when the data within the file
  ///   isn't valid FLAC data.
  pub fn from_file(filename: &str) -> io::Result<Stream> {
    File::open(filename).and_then(|file| {
      let mut producer = ReadStream::new(file);
      let error_str    = format!("parser: couldn't parse the given file {}",
                                 filename);

      Stream::from_stream_producer(&mut producer, &error_str)
    })
  }

  /// Constructs a decoder with the given buffer.
  ///
  /// This constructor assumes that an entire FLAC file is in the buffer.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::InvalidData` is returned when the data within the buffer
  ///   isn't valid FLAC data.
  pub fn from_buffer(buffer: &[u8]) -> io::Result<Stream> {
    let mut producer = ByteStream::new(buffer);
    let error_str    = "parser: couldn't parse the buffer";

    Stream::from_stream_producer(&mut producer, error_str)
  }

  fn from_stream_producer<P>(producer: &mut P, error_str: &str)
                             -> io::Result<Stream>
   where P: StreamProducer {
    let mut is_error = false;
    let mut stream   = Stream {
      info: StreamInfo::new(),
      metadata: Vec::new(),
      frames: Vec::new(),
      state: ParserState::Marker,
      output: Vec::new(),
      frame_index: 0,
    };

    loop {
      match stream.handle(producer) {
        Ok(_)                      => break,
        Err(ErrorKind::EndOfInput) => break,
        Err(ErrorKind::Continue)   => continue,
        Err(_)                     => {
          is_error = true;

          break;
        }
      }
    }

    if !is_error {
      let channels    = stream.info.channels as usize;
      let block_size  = stream.info.max_block_size as usize;
      let output_size = block_size * channels;

      stream.output.reserve_exact(output_size);

      unsafe { stream.output.set_len(output_size) }

      Ok(stream)
    } else {
      Err(io::Error::new(io::ErrorKind::InvalidData, error_str))
    }
  }

  /// Returns an iterator over the decoded samples.
  pub fn iter(&mut self) -> Iter {
    let samples_left = self.info.total_samples;

    Iter {
      stream: self,
      channel: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
    }
  }

  fn next_frame<'a>(&'a mut self) -> Option<&'a [i32]> {
    if self.frames.is_empty() || self.frame_index >= self.frames.len() {
      None
    } else {
      let frame       = &self.frames[self.frame_index];
      let channels    = frame.header.channels as usize;
      let block_size  = frame.header.block_size as usize;
      let mut channel = 0;

      for subframe in &frame.subframes[0..channels] {
        let start  = channel * block_size;
        let end    = (channel + 1) * block_size;
        let output = &mut self.output[start..end];

        subframe::decode(&subframe, output);

        channel += 1;
      }

      frame::decode(frame.header.channel_assignment, &mut self.output);

      self.frame_index += 1;

      Some(&self.output[0..(block_size * channels)])
    }
  }

  fn handle_marker<'a>(&mut self, input: &'a [u8]) -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(0);

    match tag!(input, "fLaC") {
      IResult::Done(i, _)    => {
        self.state = ParserState::Metadata;

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle_metadata<'a>(&mut self, input: &'a [u8])
                         -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(1);

    match metadata_parser(input) {
      IResult::Done(i, block) => {
        let is_last = block.is_last;

        if let metadata::Data::StreamInfo(info) = block.data {
          self.info = info;
        } else {
          self.metadata.push(block);
        }

        if is_last {
          self.state = ParserState::Frame;
        }

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle_frame<'a>(&mut self, input: &'a [u8]) -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(2);

    match frame_parser(input, &self.info) {
      IResult::Done(i, frame) => {
        self.frames.push(frame);

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle<S: StreamProducer>(&mut self, stream: &mut S)
                               -> Result<(), ErrorKind> {
    stream.parse(|input| {
      match self.state {
        ParserState::Marker   => self.handle_marker(input),
        ParserState::Metadata => self.handle_metadata(input),
        ParserState::Frame    => self.handle_frame(input),
      }
    })
  }
}

/// An iterator over a reference of the decoded FLAC stream.
pub struct Iter<'a> {
  stream: &'a mut Stream,
  channel: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
}

impl<'a> Iterator for Iter<'a> {
  type Item = i32;

  fn next(&mut self) -> Option<Self::Item> {
    if self.sample_index == self.block_size {
      let frame_index = self.stream.frame_index;

      if self.stream.next_frame().is_none() {
        return None;
      } else {
        let frame = &self.stream.frames[frame_index];

        self.sample_index = 0;
        self.block_size   = frame.header.block_size as usize;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = self.stream.output[index];

    self.channel += 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
      self.samples_left -= 1;
    }

    Some(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a chance that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}

impl<'a> IntoIterator for &'a mut Stream {
  type Item     = i32;
  type IntoIter = Iter<'a>;

  fn into_iter(self) -> Self::IntoIter {
    self.iter()
  }
}
<commit_msg>Add parser function for handling only metadata<commit_after>use nom;
use nom::{Err, IResult};

use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo, metadata_parser};
use frame::{frame_parser, Frame};
use utility::{ErrorKind, ByteStream, ReadStream, StreamProducer};

use std::io;
use std::usize;
use std::fs::File;

enum ParserState {
  Marker,
  Metadata,
  Frame,
}

/// FLAC stream that decodes and hold file information.
pub struct Stream {
  info: StreamInfo,
  metadata: Vec<Metadata>,
  frames: Vec<Frame>,
  state: ParserState,
  output: Vec<i32>,
  frame_index: usize,
}

fn parser<'a>(input: &'a [u8], is_start: &mut bool)
              -> IResult<&'a [u8], Metadata> {
  let mut slice = input;

  if *is_start {
    let (i, _) = try_parse!(slice, tag!("fLaC"));

    slice     = i;
    *is_start = false;
  }

  metadata_parser(slice)
}

impl Stream {
  /// Constructor for the default state of a FLAC stream.
  ///
  /// This doesn't actually decode anything, it just hold the default values
  /// of each field.
  pub fn new() -> Stream {
    Stream {
      info: StreamInfo::new(),
      metadata: Vec::new(),
      frames: Vec::new(),
      state: ParserState::Marker,
      output: Vec::new(),
      frame_index: 0,
    }
  }

  /// Returns information for the current stream.
  pub fn info(&self) -> StreamInfo {
    self.info
  }

  /// Returns a slice of `Metadata`
  ///
  /// This slice excludes `StreamInfo`, which is located in `Stream::info`.
  /// Everything else is related to metadata for the FLAC stream is in the
  /// slice.
  pub fn metadata(&self) -> &[Metadata] {
    &self.metadata
  }

  /// Constructs a decoder with the given file name.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::NotFound` is returned when the given filename isn't found.
  /// * `ErrorKind::InvalidData` is returned when the data within the file
  ///   isn't valid FLAC data.
  pub fn from_file(filename: &str) -> io::Result<Stream> {
    File::open(filename).and_then(|file| {
      let mut producer = ReadStream::new(file);
      let error_str    = format!("parser: couldn't parse the given file {}",
                                 filename);

      Stream::from_stream_producer(&mut producer, &error_str)
    })
  }

  /// Constructs a decoder with the given buffer.
  ///
  /// This constructor assumes that an entire FLAC file is in the buffer.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::InvalidData` is returned when the data within the buffer
  ///   isn't valid FLAC data.
  pub fn from_buffer(buffer: &[u8]) -> io::Result<Stream> {
    let mut producer = ByteStream::new(buffer);
    let error_str    = "parser: couldn't parse the buffer";

    Stream::from_stream_producer(&mut producer, error_str)
  }

  fn from_stream_producer<P>(producer: &mut P, error_str: &str)
                             -> io::Result<Stream>
   where P: StreamProducer {
    let mut is_error = false;
    let mut stream   = Stream {
      info: StreamInfo::new(),
      metadata: Vec::new(),
      frames: Vec::new(),
      state: ParserState::Marker,
      output: Vec::new(),
      frame_index: 0,
    };

    loop {
      match stream.handle(producer) {
        Ok(_)                      => break,
        Err(ErrorKind::EndOfInput) => break,
        Err(ErrorKind::Continue)   => continue,
        Err(_)                     => {
          is_error = true;

          break;
        }
      }
    }

    if !is_error {
      let channels    = stream.info.channels as usize;
      let block_size  = stream.info.max_block_size as usize;
      let output_size = block_size * channels;

      stream.output.reserve_exact(output_size);

      unsafe { stream.output.set_len(output_size) }

      Ok(stream)
    } else {
      Err(io::Error::new(io::ErrorKind::InvalidData, error_str))
    }
  }

  /// Returns an iterator over the decoded samples.
  pub fn iter(&mut self) -> Iter {
    let samples_left = self.info.total_samples;

    Iter {
      stream: self,
      channel: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
    }
  }

  fn next_frame<'a>(&'a mut self) -> Option<&'a [i32]> {
    if self.frames.is_empty() || self.frame_index >= self.frames.len() {
      None
    } else {
      let frame       = &self.frames[self.frame_index];
      let channels    = frame.header.channels as usize;
      let block_size  = frame.header.block_size as usize;
      let mut channel = 0;

      for subframe in &frame.subframes[0..channels] {
        let start  = channel * block_size;
        let end    = (channel + 1) * block_size;
        let output = &mut self.output[start..end];

        subframe::decode(&subframe, output);

        channel += 1;
      }

      frame::decode(frame.header.channel_assignment, &mut self.output);

      self.frame_index += 1;

      Some(&self.output[0..(block_size * channels)])
    }
  }

  fn handle_marker<'a>(&mut self, input: &'a [u8]) -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(0);

    match tag!(input, "fLaC") {
      IResult::Done(i, _)    => {
        self.state = ParserState::Metadata;

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle_metadata<'a>(&mut self, input: &'a [u8])
                         -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(1);

    match metadata_parser(input) {
      IResult::Done(i, block) => {
        let is_last = block.is_last;

        if let metadata::Data::StreamInfo(info) = block.data {
          self.info = info;
        } else {
          self.metadata.push(block);
        }

        if is_last {
          self.state = ParserState::Frame;
        }

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle_frame<'a>(&mut self, input: &'a [u8]) -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(2);

    match frame_parser(input, &self.info) {
      IResult::Done(i, frame) => {
        self.frames.push(frame);

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle<S: StreamProducer>(&mut self, stream: &mut S)
                               -> Result<(), ErrorKind> {
    stream.parse(|input| {
      match self.state {
        ParserState::Marker   => self.handle_marker(input),
        ParserState::Metadata => self.handle_metadata(input),
        ParserState::Frame    => self.handle_frame(input),
      }
    })
  }
}

/// An iterator over a reference of the decoded FLAC stream.
pub struct Iter<'a> {
  stream: &'a mut Stream,
  channel: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
}

impl<'a> Iterator for Iter<'a> {
  type Item = i32;

  fn next(&mut self) -> Option<Self::Item> {
    if self.sample_index == self.block_size {
      let frame_index = self.stream.frame_index;

      if self.stream.next_frame().is_none() {
        return None;
      } else {
        let frame = &self.stream.frames[frame_index];

        self.sample_index = 0;
        self.block_size   = frame.header.block_size as usize;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = self.stream.output[index];

    self.channel += 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
      self.samples_left -= 1;
    }

    Some(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a chance that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}

impl<'a> IntoIterator for &'a mut Stream {
  type Item     = i32;
  type IntoIter = Iter<'a>;

  fn into_iter(self) -> Self::IntoIter {
    self.iter()
  }
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>Example of iterator usage in for-loop<commit_after>fn main() {
    let some_vec = vec![1, 2, 3];
    let some_vec_iter = some_vec.iter();

    for val in some_vec_iter {
        println!("Value: {}", val);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Commands that the GPU will execute (includes draw commands).
//!
//! With Vulkan, before the GPU can do anything you must create a `CommandBuffer`. A command buffer
//! is a list of commands that will executed by the GPU. Once a command buffer is created, you can
//! execute it. A command buffer must be created even for the most simple tasks.
//!
//! # Pools
//!
//! Command buffers are allocated from pools. You must first create a command buffer pool which
//! you will create command buffers from.
//!
//! A pool is linked to a queue family. Command buffers that are created from a certain pool can
//! only be submitted to queues that belong to that specific family.
//!
//! # Primary and secondary command buffers.
//!
//! There are three types of command buffers:
//!
//! - **Primary command buffers**. They can contain any command. They are the only type of command
//!   buffer that can be submitted to a queue.
//! - **Secondary "graphics" command buffers**. They contain draw and clear commands. They can be
//!   called from a primary command buffer once a framebuffer has been selected.
//! - **Secondary "compute" command buffers**. They can contain non-draw and non-clear commands
//!   (eg. copying between buffers) and can be called from a primary command buffer outside of a
//!   render pass.
//!
//! Note that secondary command buffers cannot call other command buffers.
//!

// Implementation note.
// There are various restrictions about which command can be used at which moment. Therefore the
// API has several different command buffer wrappers, but they all use the same internal
// struct. The restrictions are enforced only in the public types.

pub use self::inner::Submission;
pub use self::outer::submit;
pub use self::outer::DynamicState;
pub use self::outer::PrimaryCommandBufferBuilder;
pub use self::outer::PrimaryCommandBufferBuilderInlineDraw;
pub use self::outer::PrimaryCommandBufferBuilderSecondaryDraw;
pub use self::outer::PrimaryCommandBuffer;
pub use self::outer::SecondaryGraphicsCommandBufferBuilder;
pub use self::outer::SecondaryGraphicsCommandBuffer;
pub use self::outer::SecondaryComputeCommandBufferBuilder;
pub use self::outer::SecondaryComputeCommandBuffer;
pub use self::pool::CommandBufferPool;

mod inner;
mod outer;
mod pool;
<commit_msg>Add DrawIndirectCommand and DrawIndexedIndirectCommand<commit_after>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Commands that the GPU will execute (includes draw commands).
//!
//! With Vulkan, before the GPU can do anything you must create a `CommandBuffer`. A command buffer
//! is a list of commands that will executed by the GPU. Once a command buffer is created, you can
//! execute it. A command buffer must be created even for the most simple tasks.
//!
//! # Pools
//!
//! Command buffers are allocated from pools. You must first create a command buffer pool which
//! you will create command buffers from.
//!
//! A pool is linked to a queue family. Command buffers that are created from a certain pool can
//! only be submitted to queues that belong to that specific family.
//!
//! # Primary and secondary command buffers.
//!
//! There are three types of command buffers:
//!
//! - **Primary command buffers**. They can contain any command. They are the only type of command
//!   buffer that can be submitted to a queue.
//! - **Secondary "graphics" command buffers**. They contain draw and clear commands. They can be
//!   called from a primary command buffer once a framebuffer has been selected.
//! - **Secondary "compute" command buffers**. They can contain non-draw and non-clear commands
//!   (eg. copying between buffers) and can be called from a primary command buffer outside of a
//!   render pass.
//!
//! Note that secondary command buffers cannot call other command buffers.
//!

// Implementation note.
// There are various restrictions about which command can be used at which moment. Therefore the
// API has several different command buffer wrappers, but they all use the same internal
// struct. The restrictions are enforced only in the public types.

pub use self::inner::Submission;
pub use self::outer::submit;
pub use self::outer::DynamicState;
pub use self::outer::PrimaryCommandBufferBuilder;
pub use self::outer::PrimaryCommandBufferBuilderInlineDraw;
pub use self::outer::PrimaryCommandBufferBuilderSecondaryDraw;
pub use self::outer::PrimaryCommandBuffer;
pub use self::outer::SecondaryGraphicsCommandBufferBuilder;
pub use self::outer::SecondaryGraphicsCommandBuffer;
pub use self::outer::SecondaryComputeCommandBufferBuilder;
pub use self::outer::SecondaryComputeCommandBuffer;
pub use self::pool::CommandBufferPool;

#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct DrawIndirectCommand {
    pub vertex_count: u32,
    pub instance_count: u32,
    pub first_vertex: u32,
    pub first_instance: u32,
}

#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct DrawIndexedIndirectCommand {
    pub index_count: u32,
    pub instance_count: u32,
    pub first_index: u32,
    pub vertex_offset: u32,
    pub first_instance: u32,
}

mod inner;
mod outer;
mod pool;
<|endoftext|>


<commit_before>extern crate dbus;
use self::dbus::Message;

#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub struct DBusTarget {
    pub interface: String,
    pub object: String,
    pub method: String,
}

pub fn make_target(interface: String, object: String, method: String) -> DBusTarget {
    DBusTarget {
        interface: interface,
        object: object,
        method: method,
    }
}

pub fn extract_target(m: &Message) -> Option<DBusTarget> {
    let (_, opt_interface, opt_object, opt_method) = m.headers();

    opt_interface.and_then(|interface| {
        opt_object.and_then(|object| {
            opt_method.map(|method| {
                make_target(interface, object, method)
            })
        })
    })
}
<commit_msg>target: simplify target generator<commit_after>extern crate dbus;
use self::dbus::Message;

#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub struct DBusTarget {
    pub interface: String,
    pub object: String,
    pub method: String,
}

pub fn make_target<I: ToString, O: ToString, M: ToString>(interface: I, object: O, method: M) -> DBusTarget {
    DBusTarget {
        interface: interface.to_string(),
        object: object.to_string(),
        method: method.to_string(),
    }
}

pub fn extract_target(m: &Message) -> Option<DBusTarget> {
    let (_, opt_interface, opt_object, opt_method) = m.headers();

    opt_interface.and_then(|interface| {
        opt_object.and_then(|object| {
            opt_method.map(|method| {
                make_target(interface, object, method)
            })
        })
    })
}
<|endoftext|>