<commit_before>use std::sync::Arc;

use arrayvec::ArrayVec;
use relative_path::RelativePathBuf;
use ra_db::{FileId, SourceRoot, CrateId};
use ra_syntax::{
    SyntaxNode, TreeArc,
    algo::generate,
    ast::{self, AstNode, NameOwner},
};
use ra_arena::{Arena, RawId, impl_arena_id};
use test_utils::tested_by;

use crate::{
    Name, AsName, HirDatabase, SourceItemId, HirFileId, Problem, SourceFileItems, ModuleSource,
    ids::SourceFileItemId,
};

impl ModuleSource {
    pub(crate) fn new(
        db: &impl HirDatabase,
        file_id: HirFileId,
        decl_id: Option<SourceFileItemId>,
    ) -> ModuleSource {
        match decl_id {
            Some(item_id) => {
                let module = db.file_item(SourceItemId { file_id, item_id });
                let module = ast::Module::cast(&*module).unwrap();
                assert!(module.item_list().is_some(), "expected inline module");
                ModuleSource::Module(module.to_owned())
            }
            None => {
                let source_file = db.hir_parse(file_id);
                ModuleSource::SourceFile(source_file)
            }
        }
    }
}

#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub struct Submodule {
    name: Name,
    is_declaration: bool,
    decl_id: SourceFileItemId,
}

impl Submodule {
    pub(crate) fn submodules_query(
        db: &impl HirDatabase,
        file_id: HirFileId,
        decl_id: Option<SourceFileItemId>,
    ) -> Arc<Vec<Submodule>> {
        db.check_canceled();
        let file_items = db.file_items(file_id);
        let module_source = ModuleSource::new(db, file_id, decl_id);
        let submodules = match module_source {
            ModuleSource::SourceFile(source_file) => {
                collect_submodules(file_id, &file_items, &*source_file)
            }
            ModuleSource::Module(module) => {
                collect_submodules(file_id, &file_items, module.item_list().unwrap())
            }
        };

        return Arc::new(submodules);

        fn collect_submodules(
            file_id: HirFileId,
            file_items: &SourceFileItems,
            root: &impl ast::ModuleItemOwner,
        ) -> Vec<Submodule> {
            root.items()
                .filter_map(|item| match item.kind() {
                    ast::ModuleItemKind::Module(m) => Some(m),
                    _ => None,
                })
                .filter_map(|module| {
                    let name = module.name()?.as_name();
                    if !module.has_semi() && module.item_list().is_none() {
                        tested_by!(name_res_works_for_broken_modules);
                        return None;
                    }
                    let sub = Submodule {
                        name,
                        is_declaration: module.has_semi(),
                        decl_id: file_items.id_of(file_id, module.syntax()),
                    };
                    Some(sub)
                })
                .collect()
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ModuleId(RawId);
impl_arena_id!(ModuleId);

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LinkId(RawId);
impl_arena_id!(LinkId);

/// Physically, rust source is organized as a set of files, but logically it is
/// organized as a tree of modules. Usually, a single file corresponds to a
/// single module, but it is not neccessarily always the case.
///
/// `ModuleTree` encapsulates the logic of transitioning from the fuzzy world of files
/// (which can have multiple parents) to the precise world of modules (which
/// always have one parent).
#[derive(Default, Debug, PartialEq, Eq)]
pub struct ModuleTree {
    mods: Arena<ModuleId, ModuleData>,
    links: Arena<LinkId, LinkData>,
}

#[derive(Debug, PartialEq, Eq, Hash)]
pub struct ModuleData {
    file_id: HirFileId,
    /// Points to `ast::Module`, `None` for the whole file.
    decl_id: Option<SourceFileItemId>,
    parent: Option<LinkId>,
    children: Vec<LinkId>,
}

#[derive(Hash, Debug, PartialEq, Eq)]
struct LinkData {
    source: SourceItemId,
    owner: ModuleId,
    name: Name,
    points_to: Vec<ModuleId>,
    problem: Option<Problem>,
}

impl ModuleTree {
    pub(crate) fn module_tree_query(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ModuleTree> {
        db.check_canceled();
        let mut res = ModuleTree::default();
        res.init_crate(db, crate_id);
        Arc::new(res)
    }

    pub(crate) fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a {
        self.mods.iter().map(|(id, _)| id)
    }

    pub(crate) fn find_module_by_source(
        &self,
        file_id: HirFileId,
        decl_id: Option<SourceFileItemId>,
    ) -> Option<ModuleId> {
        let (res, _) = self
            .mods
            .iter()
            .find(|(_, m)| (m.file_id, m.decl_id) == (file_id, decl_id))?;
        Some(res)
    }

    fn init_crate(&mut self, db: &impl HirDatabase, crate_id: CrateId) {
        let crate_graph = db.crate_graph();
        let file_id = crate_graph.crate_root(crate_id);
        let source_root_id = db.file_source_root(file_id);

        let source_root = db.source_root(source_root_id);
        self.init_subtree(db, &source_root, None, file_id.into(), None);
    }

    fn init_subtree(
        &mut self,
        db: &impl HirDatabase,
        source_root: &SourceRoot,
        parent: Option<LinkId>,
        file_id: HirFileId,
        decl_id: Option<SourceFileItemId>,
    ) -> ModuleId {
        let id = self.alloc_mod(ModuleData {
            file_id,
            decl_id,
            parent,
            children: Vec::new(),
        });
        for sub in db.submodules(file_id, decl_id).iter() {
            let link = self.alloc_link(LinkData {
                source: SourceItemId {
                    file_id,
                    item_id: sub.decl_id,
                },
                name: sub.name.clone(),
                owner: id,
                points_to: Vec::new(),
                problem: None,
            });

            let (points_to, problem) = if sub.is_declaration {
                let (points_to, problem) = resolve_submodule(db, file_id, &sub.name);
                let points_to = points_to
                    .into_iter()
                    .map(|file_id| {
                        self.init_subtree(db, source_root, Some(link), file_id.into(), None)
                    })
                    .collect::<Vec<_>>();
                (points_to, problem)
            } else {
                let points_to =
                    self.init_subtree(db, source_root, Some(link), file_id, Some(sub.decl_id));
                (vec![points_to], None)
            };

            self.links[link].points_to = points_to;
            self.links[link].problem = problem;
        }
        id
    }

    fn alloc_mod(&mut self, data: ModuleData) -> ModuleId {
        self.mods.alloc(data)
    }

    fn alloc_link(&mut self, data: LinkData) -> LinkId {
        let owner = data.owner;
        let id = self.links.alloc(data);
        self.mods[owner].children.push(id);
        id
    }
}

impl ModuleId {
    pub(crate) fn file_id(self, tree: &ModuleTree) -> HirFileId {
        tree.mods[self].file_id
    }
    pub(crate) fn decl_id(self, tree: &ModuleTree) -> Option<SourceFileItemId> {
        tree.mods[self].decl_id
    }
    pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> {
        tree.mods[self].parent
    }
    pub(crate) fn parent(self, tree: &ModuleTree) -> Option<ModuleId> {
        let link = self.parent_link(tree)?;
        Some(tree.links[link].owner)
    }
    pub(crate) fn crate_root(self, tree: &ModuleTree) -> ModuleId {
        generate(Some(self), move |it| it.parent(tree))
            .last()
            .unwrap()
    }
    pub(crate) fn child(self, tree: &ModuleTree, name: &Name) -> Option<ModuleId> {
        let link = tree.mods[self]
            .children
            .iter()
            .map(|&it| &tree.links[it])
            .find(|it| it.name == *name)?;
        Some(*link.points_to.first()?)
    }
    pub(crate) fn children<'a>(
        self,
        tree: &'a ModuleTree,
    ) -> impl Iterator<Item = (Name, ModuleId)> + 'a {
        tree.mods[self].children.iter().filter_map(move |&it| {
            let link = &tree.links[it];
            let module = *link.points_to.first()?;
            Some((link.name.clone(), module))
        })
    }
    pub(crate) fn problems(
        self,
        tree: &ModuleTree,
        db: &impl HirDatabase,
    ) -> Vec<(TreeArc<SyntaxNode>, Problem)> {
        tree.mods[self]
            .children
            .iter()
            .filter_map(|&link| {
                let p = tree.links[link].problem.clone()?;
                let s = link.source(tree, db);
                let s = s.name().unwrap().syntax().to_owned();
                Some((s, p))
            })
            .collect()
    }
}

impl LinkId {
    pub(crate) fn owner(self, tree: &ModuleTree) -> ModuleId {
        tree.links[self].owner
    }
    pub(crate) fn name(self, tree: &ModuleTree) -> &Name {
        &tree.links[self].name
    }
    pub(crate) fn source(self, tree: &ModuleTree, db: &impl HirDatabase) -> TreeArc<ast::Module> {
        let syntax_node = db.file_item(tree.links[self].source);
        ast::Module::cast(&syntax_node).unwrap().to_owned()
    }
}

fn resolve_submodule(
    db: &impl HirDatabase,
    file_id: HirFileId,
    name: &Name,
) -> (Vec<FileId>, Option<Problem>) {
    // FIXME: handle submodules of inline modules properly
    let file_id = file_id.original_file(db);
    let source_root_id = db.file_source_root(file_id);
    let path = db.file_relative_path(file_id);
    let root = RelativePathBuf::default();
    let dir_path = path.parent().unwrap_or(&root);
    let mod_name = path.file_stem().unwrap_or("unknown");
    let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main";

    let file_mod = dir_path.join(format!("{}.rs", name));
    let dir_mod = dir_path.join(format!("{}/mod.rs", name));
    let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name));
    let mut candidates = ArrayVec::<[_; 2]>::new();
    if is_dir_owner {
        candidates.push(file_mod.clone());
        candidates.push(dir_mod);
    } else {
        candidates.push(file_dir_mod.clone());
    };
    let sr = db.source_root(source_root_id);
    let points_to = candidates
        .into_iter()
        .filter_map(|path| sr.files.get(&path))
        .map(|&it| it)
        .collect::<Vec<_>>();
    let problem = if points_to.is_empty() {
        Some(Problem::UnresolvedModule {
            candidate: if is_dir_owner { file_mod } else { file_dir_mod },
        })
    } else {
        None
    };
    (points_to, problem)
}
<commit_msg>fix #668<commit_after>use std::sync::Arc;

use arrayvec::ArrayVec;
use relative_path::RelativePathBuf;
use ra_db::{FileId, SourceRoot, CrateId};
use ra_syntax::{
    SyntaxNode, TreeArc,
    algo::generate,
    ast::{self, AstNode, NameOwner},
};
use ra_arena::{Arena, RawId, impl_arena_id};
use test_utils::tested_by;

use crate::{
    Name, AsName, HirDatabase, SourceItemId, HirFileId, Problem, SourceFileItems, ModuleSource,
    ids::SourceFileItemId,
};

impl ModuleSource {
    pub(crate) fn new(
        db: &impl HirDatabase,
        file_id: HirFileId,
        decl_id: Option<SourceFileItemId>,
    ) -> ModuleSource {
        match decl_id {
            Some(item_id) => {
                let module = db.file_item(SourceItemId { file_id, item_id });
                let module = ast::Module::cast(&*module).unwrap();
                assert!(module.item_list().is_some(), "expected inline module");
                ModuleSource::Module(module.to_owned())
            }
            None => {
                let source_file = db.hir_parse(file_id);
                ModuleSource::SourceFile(source_file)
            }
        }
    }
}

#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub struct Submodule {
    name: Name,
    is_declaration: bool,
    decl_id: SourceFileItemId,
}

impl Submodule {
    pub(crate) fn submodules_query(
        db: &impl HirDatabase,
        file_id: HirFileId,
        decl_id: Option<SourceFileItemId>,
    ) -> Arc<Vec<Submodule>> {
        db.check_canceled();
        let file_items = db.file_items(file_id);
        let module_source = ModuleSource::new(db, file_id, decl_id);
        let submodules = match module_source {
            ModuleSource::SourceFile(source_file) => {
                collect_submodules(file_id, &file_items, &*source_file)
            }
            ModuleSource::Module(module) => {
                collect_submodules(file_id, &file_items, module.item_list().unwrap())
            }
        };

        return Arc::new(submodules);

        fn collect_submodules(
            file_id: HirFileId,
            file_items: &SourceFileItems,
            root: &impl ast::ModuleItemOwner,
        ) -> Vec<Submodule> {
            root.items()
                .filter_map(|item| match item.kind() {
                    ast::ModuleItemKind::Module(m) => Some(m),
                    _ => None,
                })
                .filter_map(|module| {
                    let name = module.name()?.as_name();
                    if !module.has_semi() && module.item_list().is_none() {
                        tested_by!(name_res_works_for_broken_modules);
                        return None;
                    }
                    let sub = Submodule {
                        name,
                        is_declaration: module.has_semi(),
                        decl_id: file_items.id_of(file_id, module.syntax()),
                    };
                    Some(sub)
                })
                .collect()
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ModuleId(RawId);
impl_arena_id!(ModuleId);

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LinkId(RawId);
impl_arena_id!(LinkId);

/// Physically, rust source is organized as a set of files, but logically it is
/// organized as a tree of modules. Usually, a single file corresponds to a
/// single module, but it is not neccessarily always the case.
///
/// `ModuleTree` encapsulates the logic of transitioning from the fuzzy world of files
/// (which can have multiple parents) to the precise world of modules (which
/// always have one parent).
#[derive(Default, Debug, PartialEq, Eq)]
pub struct ModuleTree {
    mods: Arena<ModuleId, ModuleData>,
    links: Arena<LinkId, LinkData>,
}

#[derive(Debug, PartialEq, Eq, Hash)]
pub struct ModuleData {
    file_id: HirFileId,
    /// Points to `ast::Module`, `None` for the whole file.
    decl_id: Option<SourceFileItemId>,
    parent: Option<LinkId>,
    children: Vec<LinkId>,
}

#[derive(Hash, Debug, PartialEq, Eq)]
struct LinkData {
    source: SourceItemId,
    owner: ModuleId,
    name: Name,
    points_to: Vec<ModuleId>,
    problem: Option<Problem>,
}

impl ModuleTree {
    pub(crate) fn module_tree_query(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ModuleTree> {
        db.check_canceled();
        let mut res = ModuleTree::default();
        res.init_crate(db, crate_id);
        Arc::new(res)
    }

    pub(crate) fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a {
        self.mods.iter().map(|(id, _)| id)
    }

    pub(crate) fn find_module_by_source(
        &self,
        file_id: HirFileId,
        decl_id: Option<SourceFileItemId>,
    ) -> Option<ModuleId> {
        let (res, _) = self
            .mods
            .iter()
            .find(|(_, m)| (m.file_id, m.decl_id) == (file_id, decl_id))?;
        Some(res)
    }

    fn init_crate(&mut self, db: &impl HirDatabase, crate_id: CrateId) {
        let crate_graph = db.crate_graph();
        let file_id = crate_graph.crate_root(crate_id);
        let source_root_id = db.file_source_root(file_id);

        let source_root = db.source_root(source_root_id);
        self.init_subtree(db, &source_root, None, file_id.into(), None);
    }

    fn init_subtree(
        &mut self,
        db: &impl HirDatabase,
        source_root: &SourceRoot,
        parent: Option<LinkId>,
        file_id: HirFileId,
        decl_id: Option<SourceFileItemId>,
    ) -> ModuleId {
        let is_root = parent.is_none();
        let id = self.alloc_mod(ModuleData {
            file_id,
            decl_id,
            parent,
            children: Vec::new(),
        });
        for sub in db.submodules(file_id, decl_id).iter() {
            let link = self.alloc_link(LinkData {
                source: SourceItemId {
                    file_id,
                    item_id: sub.decl_id,
                },
                name: sub.name.clone(),
                owner: id,
                points_to: Vec::new(),
                problem: None,
            });

            let (points_to, problem) = if sub.is_declaration {
                let (points_to, problem) = resolve_submodule(db, file_id, &sub.name);
                let points_to = points_to
                    .into_iter()
                    .map(|file_id| {
                        self.init_subtree(db, source_root, Some(link), file_id.into(), None)
                    })
                    .collect::<Vec<_>>();
                (points_to, problem)
            } else {
                let points_to =
                    self.init_subtree(db, source_root, Some(link), file_id, Some(sub.decl_id));
                (vec![points_to], None)
            };

            self.links[link].points_to = points_to;
            self.links[link].problem = problem;
        }
        id
    }

    fn alloc_mod(&mut self, data: ModuleData) -> ModuleId {
        self.mods.alloc(data)
    }

    fn alloc_link(&mut self, data: LinkData) -> LinkId {
        let owner = data.owner;
        let id = self.links.alloc(data);
        self.mods[owner].children.push(id);
        id
    }
}

impl ModuleId {
    pub(crate) fn file_id(self, tree: &ModuleTree) -> HirFileId {
        tree.mods[self].file_id
    }
    pub(crate) fn decl_id(self, tree: &ModuleTree) -> Option<SourceFileItemId> {
        tree.mods[self].decl_id
    }
    pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> {
        tree.mods[self].parent
    }
    pub(crate) fn parent(self, tree: &ModuleTree) -> Option<ModuleId> {
        let link = self.parent_link(tree)?;
        Some(tree.links[link].owner)
    }
    pub(crate) fn crate_root(self, tree: &ModuleTree) -> ModuleId {
        generate(Some(self), move |it| it.parent(tree))
            .last()
            .unwrap()
    }
    pub(crate) fn child(self, tree: &ModuleTree, name: &Name) -> Option<ModuleId> {
        let link = tree.mods[self]
            .children
            .iter()
            .map(|&it| &tree.links[it])
            .find(|it| it.name == *name)?;
        Some(*link.points_to.first()?)
    }
    pub(crate) fn children<'a>(
        self,
        tree: &'a ModuleTree,
    ) -> impl Iterator<Item = (Name, ModuleId)> + 'a {
        tree.mods[self].children.iter().filter_map(move |&it| {
            let link = &tree.links[it];
            let module = *link.points_to.first()?;
            Some((link.name.clone(), module))
        })
    }
    pub(crate) fn problems(
        self,
        tree: &ModuleTree,
        db: &impl HirDatabase,
    ) -> Vec<(TreeArc<SyntaxNode>, Problem)> {
        tree.mods[self]
            .children
            .iter()
            .filter_map(|&link| {
                let p = tree.links[link].problem.clone()?;
                let s = link.source(tree, db);
                let s = s.name().unwrap().syntax().to_owned();
                Some((s, p))
            })
            .collect()
    }
}

impl LinkId {
    pub(crate) fn owner(self, tree: &ModuleTree) -> ModuleId {
        tree.links[self].owner
    }
    pub(crate) fn name(self, tree: &ModuleTree) -> &Name {
        &tree.links[self].name
    }
    pub(crate) fn source(self, tree: &ModuleTree, db: &impl HirDatabase) -> TreeArc<ast::Module> {
        let syntax_node = db.file_item(tree.links[self].source);
        ast::Module::cast(&syntax_node).unwrap().to_owned()
    }
}

fn resolve_submodule(
    db: &impl HirDatabase,
    file_id: HirFileId,
    name: &Name,
    is_root: bool,
) -> (Vec<FileId>, Option<Problem>) {
    // FIXME: handle submodules of inline modules properly
    let file_id = file_id.original_file(db);
    let source_root_id = db.file_source_root(file_id);
    let path = db.file_relative_path(file_id);
    let root = RelativePathBuf::default();
    let dir_path = path.parent().unwrap_or(&root);
    let mod_name = path.file_stem().unwrap_or("unknown");
    let is_dir_owner = is_root || mod_name == "mod";

    let file_mod = dir_path.join(format!("{}.rs", name));
    let dir_mod = dir_path.join(format!("{}/mod.rs", name));
    let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name));
    let mut candidates = ArrayVec::<[_; 2]>::new();
    if is_dir_owner {
        candidates.push(file_mod.clone());
        candidates.push(dir_mod);
    } else {
        candidates.push(file_dir_mod.clone());
    };
    let sr = db.source_root(source_root_id);
    let points_to = candidates
        .into_iter()
        .filter_map(|path| sr.files.get(&path))
        .map(|&it| it)
        .collect::<Vec<_>>();
    let problem = if points_to.is_empty() {
        Some(Problem::UnresolvedModule {
            candidate: if is_dir_owner { file_mod } else { file_dir_mod },
        })
    } else {
        None
    };
    (points_to, problem)
}
<|endoftext|>


<commit_before>use rusqlite::Connection;
#[derive(Debug)]
pub struct Provider {
    id: i32,
    name: String,
}

pub fn table_create_provider(conn: &Connection) -> &Connection {
    conn.execute("CREATE TABLE PROVIDER (
                  id              INTEGER PRIMARY KEY ASC,
                  name            TEXT NOT NULL UNIQUE
                  )", &[]).unwrap();
    return conn;
}

pub fn insert_provider(conn: &Connection, name: String) {

    let me = Provider {
        id: 0,
        name: name,
    };
    let provider_instance = conn.execute("INSERT INTO PROVIDER (name)
                  VALUES (?1)",
                 &[&me.name]);
    if provider_instance.is_err() {
        return;
    }
    provider_instance.unwrap();

}

pub fn list_provider(conn: &Connection)-> Vec<Provider> {
    let mut stmt = conn.prepare("SELECT id, name  FROM PROVIDER").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        Provider {
            id: row.get(0),
            name: row.get(1),
        }
    });
    let mut items = Vec::<Provider>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn provider_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, name FROM PROVIDER").unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        Provider {
            id: row.get(0),
            name: row.get(1)
        }
    }).unwrap();

    for person in person_iter {
        println!("Found provider {:?}", person.unwrap());
    }
}
<commit_msg>Add pk_provider_by_name<commit_after>use rusqlite::Connection;
#[derive(Debug)]
pub struct Provider {
    id: i32,
    name: String,
}

pub fn table_create_provider(conn: &Connection) -> &Connection {
    conn.execute("CREATE TABLE PROVIDER (
                  id              INTEGER PRIMARY KEY ASC,
                  name            TEXT NOT NULL UNIQUE
                  )", &[]).unwrap();
    return conn;
}

pub fn insert_provider(conn: &Connection,  name: &String) -> Result<i32, &'static str> {
    let bill = name.clone();
    let me = Provider {
        id: 0,
        name: bill,
    };
    let provider_instance = conn.execute("INSERT INTO PROVIDER (name)
                  VALUES (?1)",
                 &[&me.name]);
    if provider_instance.is_err() {
        return Err("Insert failed");
    }
    provider_instance.unwrap();
    return Ok(0);
}

pub fn list_provider(conn: &Connection)-> Vec<Provider> {
    let mut stmt = conn.prepare("SELECT id, name  FROM PROVIDER").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        Provider {
            id: row.get(0),
            name: row.get(1),
        }
    });
    let mut items = Vec::<Provider>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn provider_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, name FROM PROVIDER").unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        Provider {
            id: row.get(0),
            name: row.get(1)
        }
    }).unwrap();

    for person in person_iter {
        println!("Found provider {:?}", person.unwrap());
    }
}

pub fn pk_provider_by_name(conn: &Connection, name: &String, pk: &mut i32) -> Result<i32, &'static str>{
    let bill = name.clone();
    let mut stmt = conn.prepare("SELECT id, name  FROM PROVIDER WHERE name = ?1").unwrap();
    let provider_iter = stmt.query_map(&[&bill], |row| {
        Provider {
            id: row.get(0),
            name: row.get(1),
        }
    }).unwrap();
    let mut found = 0;
    let mut items = Vec::<Provider>::new();
    for person in provider_iter {
        let bill= person.unwrap();
        *pk = bill.id;
        found = bill.id;
    }
    if found != 0 {
        return Ok(found);
    }
    return Err("None found");
}
<|endoftext|>


<commit_before>use types::*;

#[derive(Debug, Clone, PartialEq, PartialOrd, Deserialize)]
pub struct ResponseParameters {
    pub migrate_to_chat_id: Option<Integer>,
    pub retry_after: Option<Integer>,
}
<commit_msg>feat: add Response<T> type<commit_after>use serde::de::{Deserialize, Deserializer, Error};

use types::*;

#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum Response<T> {
    Success {
        result: T,
    },
    Error {
        description: String,
        parameters: Option<ResponseParameters>,
    },
}

impl<T: Deserialize> Deserialize for Response<T> {
    fn deserialize<D>(deserializer: D) -> Result<Response<T>, D::Error> where D: Deserializer {
        let raw: RawResponse<T> = Deserialize::deserialize(deserializer)?;
        match (raw.ok, raw.description, raw.result) {
            (false, Some(description), None) => {
                Ok(Response::Error {
                    description: description,
                    parameters: raw.parameters,
                })
            },
            (true, None, Some(result)) => {
                Ok(Response::Success {
                    result: result,
                })
            }
            _ => Err(D::Error::custom("ambiguous response")),
        }
    }
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Deserialize)]
pub struct RawResponse<T> {
    ok: bool,
    description: Option<String>,
    result: Option<T>,
    parameters: Option<ResponseParameters>,
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Deserialize)]
pub struct ResponseParameters {
    pub migrate_to_chat_id: Option<Integer>,
    pub retry_after: Option<Integer>,
}
<|endoftext|>


<commit_before>use std::ops::{Index, IndexMut};

/// Delay-line whose maximum size is fixed
/// The advantage of using a static versus dynamic array is that its elements
/// can be laid out in a predicatable location in memeory. This can improve
/// access speeds if many delay-lines are used within another object, like a
/// reverb
pub struct DelayLine<B> {
    pos: usize,
    buffer: B,
}

impl<B> DelayLine<B> where  B: Buffer {

    /// Default constructor for a delay line
    pub fn new() -> DelayLine<B> {
        DelayLine {
            pos: 0,
            buffer: B::zeroed(),
        }
    }

    /// Get size of delay-line
    pub fn size(&self) -> usize {
        self.buffer.len()
    }

    /// Get element at back
    pub fn back(&self) -> f32 {
        let idx = self.index_back();
        *self.buffer.index(idx)
    }

    /// Get index of back element.
    pub fn index_back(&self) -> usize {
        let i = self.pos + 1;
        if i < self.size() { i } else { 0 }
    }

    /// Read value at delay i
    pub fn read(&self, i: i32) -> &f32 {
        let mut idx = self.pos as i32 - i;
        if idx < 0 { idx += self.size() as i32; }
        &self.buffer.index(idx as usize)
    }

    /// Write value to delay
    pub fn write(&mut self, value: f32) {
        *self.buffer.index_mut(self.pos) = value;
        self.pos += 1;
        if self.pos >= self.size() { self.pos = 0; }
    }

    /// Write new value and return oldest value
    pub fn get_write_and_step(&mut self, value: f32) -> f32 {
        let r = *self.buffer.index(self.pos);
        self.write(value);
        r
    }

    /// Comb filter input using a delay time equal to the maximum size of the delay-line
    pub fn comb(&mut self, value: f32, feed_fwd: f32, feed_bck: f32) -> f32 {
        let d = *self.buffer.index(self.pos);
        let r = value + d*feed_bck;
        self.write(r);
        d + r*feed_fwd
    }

    /// Allpass filter input using a delay time equal to the maximum size of the delay-line
    pub fn allpass(&mut self, value: f32, feed_fwd: f32) -> f32 {
        self.comb(value, feed_fwd, -feed_fwd)
    }
}

impl<B> Clone for DelayLine<B> where B: Buffer {
    fn clone(&self) -> Self {
        DelayLine {
            pos: self.pos,
            buffer: Buffer::clone(&self.buffer),
        }
    }
}

impl<B> ::std::fmt::Debug for DelayLine<B> where B: Buffer {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
        write!(f, "pos: {:?}, buffer: [f32; {:?}]", self.pos, self.buffer.len())
    }
}

/// Some buffer of Float values that is compatible with the delay-line
pub trait Buffer {
    fn zeroed() -> Self;
    fn clone(&self) -> Self;
    fn len(&self) -> usize;
    fn index(&self, idx: usize) -> &f32;
    fn index_mut(&mut self, idx: usize) -> &mut f32;
}
<commit_msg>Fix unused import warnings introduced in recent rustc update<commit_after>/// Delay-line whose maximum size is fixed
/// The advantage of using a static versus dynamic array is that its elements
/// can be laid out in a predicatable location in memeory. This can improve
/// access speeds if many delay-lines are used within another object, like a
/// reverb
pub struct DelayLine<B> {
    pos: usize,
    buffer: B,
}

impl<B> DelayLine<B> where  B: Buffer {

    /// Default constructor for a delay line
    pub fn new() -> DelayLine<B> {
        DelayLine {
            pos: 0,
            buffer: B::zeroed(),
        }
    }

    /// Get size of delay-line
    pub fn size(&self) -> usize {
        self.buffer.len()
    }

    /// Get element at back
    pub fn back(&self) -> f32 {
        let idx = self.index_back();
        *self.buffer.index(idx)
    }

    /// Get index of back element.
    pub fn index_back(&self) -> usize {
        let i = self.pos + 1;
        if i < self.size() { i } else { 0 }
    }

    /// Read value at delay i
    pub fn read(&self, i: i32) -> &f32 {
        let mut idx = self.pos as i32 - i;
        if idx < 0 { idx += self.size() as i32; }
        &self.buffer.index(idx as usize)
    }

    /// Write value to delay
    pub fn write(&mut self, value: f32) {
        *self.buffer.index_mut(self.pos) = value;
        self.pos += 1;
        if self.pos >= self.size() { self.pos = 0; }
    }

    /// Write new value and return oldest value
    pub fn get_write_and_step(&mut self, value: f32) -> f32 {
        let r = *self.buffer.index(self.pos);
        self.write(value);
        r
    }

    /// Comb filter input using a delay time equal to the maximum size of the delay-line
    pub fn comb(&mut self, value: f32, feed_fwd: f32, feed_bck: f32) -> f32 {
        let d = *self.buffer.index(self.pos);
        let r = value + d*feed_bck;
        self.write(r);
        d + r*feed_fwd
    }

    /// Allpass filter input using a delay time equal to the maximum size of the delay-line
    pub fn allpass(&mut self, value: f32, feed_fwd: f32) -> f32 {
        self.comb(value, feed_fwd, -feed_fwd)
    }
}

impl<B> Clone for DelayLine<B> where B: Buffer {
    fn clone(&self) -> Self {
        DelayLine {
            pos: self.pos,
            buffer: Buffer::clone(&self.buffer),
        }
    }
}

impl<B> ::std::fmt::Debug for DelayLine<B> where B: Buffer {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
        write!(f, "pos: {:?}, buffer: [f32; {:?}]", self.pos, self.buffer.len())
    }
}

/// Some buffer of Float values that is compatible with the delay-line
pub trait Buffer {
    fn zeroed() -> Self;
    fn clone(&self) -> Self;
    fn len(&self) -> usize;
    fn index(&self, idx: usize) -> &f32;
    fn index_mut(&mut self, idx: usize) -> &mut f32;
}
<|endoftext|>


<commit_before>//! Module for working with derivatives.
//!
//! This module has functions for estimating and evaluating
//! derivatives of functions with one or more variables.

pub use super::func::*;

/// The value used for `h` in derivative estimates.
///
/// This value is chosen so as to offer the best accuracy,
/// it is a compromise between the increase in accuracy caused
/// by having an `h` closer to zero, and the decrease decrease
/// in accuracy caused by floating point imprecision with very
/// small values.
pub const EPSILON: f64 = 10.0e-7;

/// Return a `Function` estimating the `n`th derivative of `f`.
///
/// This function will return a `Function` that estimates the
/// `n`th derivative of `f` using the limit definition of the
/// derivative:
///
/// ```text
///                     f(x + h) - f(x)
/// f'(x) = lim         ---------------
///         h -> 0             h
/// ```
///
/// Where `h` is equal to `EPSILON`. See the documentation for
/// `EPSILON` for more information.
///
/// This function will use recursion to provide derivatives for `n > 1`.
///
/// It is important to note that the inaccuracy of the derivative
/// estimates compound each other, the higher `n` is, the less precise
/// the resulting function will be!
///
/// If `n = 0`, then a `clone()` of `f` is returned.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let first_deriv = nth_derivative(1, &f);
/// let second_deriv = nth_derivative(2, &f);
///
/// println!("f(5)   = {}", f(5.0));
/// println!("f'(5)  = {}", first_deriv(5.0));
/// println!("f''(5) = {}", second_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f'(5)  = 10.00000100148668
/// f''(5) = 2.000177801164682
/// ```
pub fn nth_derivative(n: u64, f: &Function) -> Function {

    let f_copy = f.clone();
    let deriv: Function = func!(
        move |x: f64| {
            (f_copy(x + EPSILON) - f_copy(x)) / EPSILON
    });

    match n {
        0 => f.clone(),
        1 => deriv,
        _ => nth_derivative(n - 1, & deriv),
    }
}

/// Return a function estimating the first derivative of `f`.
///
/// This is a helper function and is equivalent to calling
/// `nth_derivative(1, f)`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let first_deriv = derivative(&f);
///
/// println!("f(5)  = {}", f(5.0));
/// println!("f'(5) = {}", first_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f'(5)  = 10.00000100148668
/// ```
pub fn derivative(f: &Function) -> Function {
    nth_derivative(1, &f)
}

/// Return a function estimating the second derivative of `f`.
///
/// This is a helper function and is equivalent to calling
/// `nth_derivative(2, f)`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let second_deriv = nth_derivative(2, &f);
///
/// println!("f(5)   = {}", f(5.0));
/// println!("f''(5) = {}", second_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f''(5) = 2.000177801164682
/// ```
pub fn second_derivative(f: &Function) -> Function {
    nth_derivative(2, &f)
}

/// Estimate the value of the derivative of `f` at `x`
///
/// This is a helper function that calls `derivative` and
/// then calls the resulting function with `x`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| (x + 4.0) * (x + 4.0)];
/// println!("f'(-4.0) = {}", slope_at(&f, -4.0));
/// # }
///
/// ```
/// Outputs:
///
/// ```text
/// f'(-4.0) = 0.000001000000000279556
/// ```
pub fn slope_at(f: &Function, x: f64) -> f64 {
    derivative(f)(x)
}

/// Estimate the value of the second derivative of `f` at `x`
///
/// This is a helper function that calls `second_derivative` and
/// then calls the resulting function with `x`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| (x + 4.0) * (x + 4.0)];
/// println!("f''(-4.0) = {}", concavity_at(&f, -4.0));
/// # }
///
/// ```
/// Outputs:
///
/// ```text
/// f''(-4.0) = 2.0000000005591114
/// ```
pub fn concavity_at(f: &Function, x: f64) -> f64 {
    second_derivative(f)(x)
}

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

#[test]
    fn t_nth_derivative() {
        macro_rules! assert_fp { // todo -- make a real macro for this
            ($a:expr, $b:expr) => (assert_eq!($a.round() as i64, $b));
        }

        let f = func!(|x: f64| x * x * x + 5.0);
        let f_deriv = derivative(&f);
        let f_s_deriv = second_derivative(&f);

        assert_fp!(f(0.0), 5);
        assert_fp!(f(4.0), 69);
        assert_fp!(f(-2.0), -3);

        assert_fp!(f_deriv(0.0), 0);
        assert_fp!(f_deriv(4.0), 48);
        assert_fp!(f_deriv(-2.0), 12);

        assert_fp!(f_s_deriv(0.0), 0);
        assert_fp!(f_s_deriv(4.0), 24);
        assert_fp!(f_s_deriv(-2.0), -12);

    }

#[test]
    fn t_helpers() {
        let f = func!(|x: f64| x * x);
        let f_deriv = derivative(&f);
        let f_s_deriv = second_derivative(&f);
        let f_deriv_2 = nth_derivative(1, &f);
        let f_s_deriv_2 = nth_derivative(2, &f);

        assert_eq!(f_deriv(0.0), f_deriv_2(0.0));
        assert_eq!(f_deriv(10.4), f_deriv_2(10.4));
        assert_eq!(f_deriv(56.8), f_deriv_2(56.8));

        assert_eq!(f_s_deriv(0.0), f_s_deriv_2(0.0));
        assert_eq!(f_s_deriv(10.4), f_s_deriv_2(10.4));
        assert_eq!(f_s_deriv(56.8), f_s_deriv_2(56.8));

        assert_eq!(f_deriv(0.0), slope_at(&f, 0.0));
        assert_eq!(f_deriv(10.4), slope_at(&f, 10.4));
        assert_eq!(f_deriv(56.8), slope_at(&f, 56.8));

        assert_eq!(f_s_deriv(0.0), concavity_at(&f, 0.0));
        assert_eq!(f_s_deriv(10.4), concavity_at(&f, 10.4));
        assert_eq!(f_s_deriv(56.8), concavity_at(&f, 56.8));
    }
}
<commit_msg>add a large variety of test data<commit_after>//! Module for working with derivatives.
//!
//! This module has functions for estimating and evaluating
//! derivatives of functions with one or more variables.

pub use super::func::*;

/// The value used for `h` in derivative estimates.
///
/// This value is chosen so as to offer the best accuracy,
/// it is a compromise between the increase in accuracy caused
/// by having an `h` closer to zero, and the decrease decrease
/// in accuracy caused by floating point imprecision with very
/// small values.
pub const EPSILON: f64 = 10.0e-7;

/// Return a `Function` estimating the `n`th derivative of `f`.
///
/// This function will return a `Function` that estimates the
/// `n`th derivative of `f` using the limit definition of the
/// derivative:
///
/// ```text
///                     f(x + h) - f(x)
/// f'(x) = lim         ---------------
///         h -> 0             h
/// ```
///
/// Where `h` is equal to `EPSILON`. See the documentation for
/// `EPSILON` for more information.
///
/// This function will use recursion to provide derivatives for `n > 1`.
///
/// It is important to note that the inaccuracy of the derivative
/// estimates compound each other, the higher `n` is, the less precise
/// the resulting function will be!
///
/// If `n = 0`, then a `clone()` of `f` is returned.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let first_deriv = nth_derivative(1, &f);
/// let second_deriv = nth_derivative(2, &f);
///
/// println!("f(5)   = {}", f(5.0));
/// println!("f'(5)  = {}", first_deriv(5.0));
/// println!("f''(5) = {}", second_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f'(5)  = 10.00000100148668
/// f''(5) = 2.000177801164682
/// ```
pub fn nth_derivative(n: u64, f: &Function) -> Function {

    let f_copy = f.clone();
    let deriv: Function = func!(
        move |x: f64| {
            (f_copy(x + EPSILON) - f_copy(x)) / EPSILON
    });

    match n {
        0 => f.clone(),
        1 => deriv,
        _ => nth_derivative(n - 1, & deriv),
    }
}

/// Return a function estimating the first derivative of `f`.
///
/// This is a helper function and is equivalent to calling
/// `nth_derivative(1, f)`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let first_deriv = derivative(&f);
///
/// println!("f(5)  = {}", f(5.0));
/// println!("f'(5) = {}", first_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f'(5)  = 10.00000100148668
/// ```
pub fn derivative(f: &Function) -> Function {
    nth_derivative(1, &f)
}

/// Return a function estimating the second derivative of `f`.
///
/// This is a helper function and is equivalent to calling
/// `nth_derivative(2, f)`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let second_deriv = nth_derivative(2, &f);
///
/// println!("f(5)   = {}", f(5.0));
/// println!("f''(5) = {}", second_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f''(5) = 2.000177801164682
/// ```
pub fn second_derivative(f: &Function) -> Function {
    nth_derivative(2, &f)
}

/// Estimate the value of the derivative of `f` at `x`
///
/// This is a helper function that calls `derivative` and
/// then calls the resulting function with `x`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| (x + 4.0) * (x + 4.0)];
/// println!("f'(-4.0) = {}", slope_at(&f, -4.0));
/// # }
///
/// ```
/// Outputs:
///
/// ```text
/// f'(-4.0) = 0.000001000000000279556
/// ```
pub fn slope_at(f: &Function, x: f64) -> f64 {
    derivative(f)(x)
}

/// Estimate the value of the second derivative of `f` at `x`
///
/// This is a helper function that calls `second_derivative` and
/// then calls the resulting function with `x`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| (x + 4.0) * (x + 4.0)];
/// println!("f''(-4.0) = {}", concavity_at(&f, -4.0));
/// # }
///
/// ```
/// Outputs:
///
/// ```text
/// f''(-4.0) = 2.0000000005591114
/// ```
pub fn concavity_at(f: &Function, x: f64) -> f64 {
    second_derivative(f)(x)
}

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

#[test]
    fn t_nth_derivative() {
        macro_rules! assert_fp { // todo -- make a real macro for this
            ($a:expr, $b:expr) => (assert_eq!($a.round() as i64, $b));
        }

        let f = func!(|x: f64| x * x * x + 5.0);
        let f_deriv = derivative(&f);
        let f_s_deriv = second_derivative(&f);

        assert_fp!(f(0.0), 5);
        assert_fp!(f(4.0), 69);
        assert_fp!(f(-2.0), -3);

        assert_fp!(f_deriv(0.0), 0);
        assert_fp!(f_deriv(4.0), 48);
        assert_fp!(f_deriv(-2.0), 12);

        assert_fp!(f_s_deriv(0.0), 0);
        assert_fp!(f_s_deriv(4.0), 24);
        assert_fp!(f_s_deriv(-2.0), -12);

    }

#[test]
    fn t_helpers() {
        let f = func!(|x: f64| x * x);
        let f_deriv = derivative(&f);
        let f_s_deriv = second_derivative(&f);
        let f_deriv_2 = nth_derivative(1, &f);
        let f_s_deriv_2 = nth_derivative(2, &f);

        assert_eq!(f_deriv(0.0), f_deriv_2(0.0));
        assert_eq!(f_deriv(10.4), f_deriv_2(10.4));
        assert_eq!(f_deriv(56.8), f_deriv_2(56.8));

        assert_eq!(f_s_deriv(0.0), f_s_deriv_2(0.0));
        assert_eq!(f_s_deriv(40.4), f_s_deriv_2(40.4));
        assert_eq!(f_s_deriv(12.3), f_s_deriv_2(12.3));

        assert_eq!(f_deriv(0.0), slope_at(&f, 0.0));
        assert_eq!(f_deriv(10.4), slope_at(&f, 10.4));
        assert_eq!(f_deriv(56.8), slope_at(&f, 56.8));

        assert_eq!(f_s_deriv(0.0), concavity_at(&f, 0.0));
        assert_eq!(f_s_deriv(40.4), concavity_at(&f, 40.4));
        assert_eq!(f_s_deriv(12.3), concavity_at(&f, 12.3));
    }
}
<|endoftext|>


<commit_before>// For example, the Rust programming language is statically typed, but uses
// type inference to reduce the amount of types that have to be specified by
// the programmer.
//
// $ rustc 07-type-inference.rs

fn main() {
    let x = 1;
    let x = "Hello Joe".to_owned();

    // The following line results in a compilation error (types are checked
    // during compilation because Rust is statically typed):
    //
    // error: mismatched types (expected &str, found integral variable)
    println!("{}", x + 2);
}
<commit_msg>2020-03-02: Update the error message for 07-type-inference.rs.<commit_after>// For example, the Rust programming language is statically typed, but uses
// type inference to reduce the amount of types that have to be specified by
// the programmer.
//
// $ rustc 07-type-inference.rs

fn main() {
    let x = 1;
    let x = "Hello Joe".to_owned();

    // The following line results in a compilation error (types are checked
    // during compilation because Rust is statically typed):
    //
    // error: mismatched types (expected &str, found integer)
    println!("{}", x + 2);
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, All Contributors (see CONTRIBUTORS file)
//
// 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/.
#![feature(slice_patterns, advanced_slice_patterns)]
#![cfg_attr(test, feature(test))]

extern crate mio;
extern crate memmap;
extern crate byteorder;
extern crate rand;
extern crate num_cpus;
#[macro_use]
extern crate log;
extern crate log4rs;
extern crate slab;
extern crate num_bigint;
extern crate num_traits;
extern crate lmdb_zero as lmdb;
#[macro_use]
extern crate lazy_static;
extern crate config;
#[macro_use]
extern crate clap;
extern crate uuid;

extern crate pumpkinscript;
extern crate pumpkindb_engine;

mod connection;
mod server;

use std::fs;
use std::fs::OpenOptions;
use std::path::PathBuf;
use std::thread;
use std::sync::Arc;

use memmap::{Mmap, Protection};
use mio::*;
use mio::tcp::*;
use clap::{App, Arg};

use pumpkindb_engine::{script, storage, timestamp};
use pumpkindb_engine::script::dispatcher;
use pumpkindb_engine::messaging;

lazy_static! {
 static ref ENVIRONMENT: lmdb::Environment = {
    let _ = config::set_default("storage.path", "pumpkin.db");
    let storage_path = config::get_str("storage.path").unwrap().into_owned();
    fs::create_dir_all(storage_path.as_str()).expect("can't create directory");
    let map_size = config::get_int("storage.mapsize");
    let maxreaders = config::get_int("storage.maxreaders").and_then(|v| Some(v as u32));
    if let Some(max) = maxreaders {
       if max < 1 {
          error!("storage.maxreaders can't be less than 1");
          ::std::process::exit(1);
       }
    }
    storage::create_environment(storage_path, map_size, maxreaders)
 };
}

use mio::channel as mio_chan;

pub fn run(port: i64,
           senders: Vec<script::Sender<script::RequestMessage>>,
           relay_sender: mio_chan::Sender<server::RelayedPublishedMessage>,
           relay_receiver: mio_chan::Receiver<server::RelayedPublishedMessage>) {
    let addr = format!("0.0.0.0:{}", port).parse().unwrap();

    info!("Listening on {}", addr);

    let sock = TcpListener::bind(&addr).expect("Failed to bind address");

    let mut poll = Poll::new().expect("Failed to initialize polling");

    let mut server = server::Server::new(sock, relay_sender, relay_receiver, senders);
    server.run(&mut poll).expect("Failed to run server");

}

/// Accepts storage path, filename and length and prepares the file. It is important that the length
/// is the total length of the memory mapped file, otherwise the application _will segfault_ when
/// trying to read those sections later. There is no way to handle that.
/// The mmap file is structured as such now:
/// Byte Range         Used for
/// [0..20]            Last known HTC timestamp
fn prepare_mmap(storage_path: &str, filename: &str, length: u64) -> Mmap {
    let mut scratchpad_pathbuf = PathBuf::from(storage_path);
    scratchpad_pathbuf.push(filename);
    scratchpad_pathbuf.set_extension("dat");
    let scratchpad_path = scratchpad_pathbuf.as_path();
    let scratchpad_file = OpenOptions::new()
        .create(true)
        .write(true)
        .open(scratchpad_path)
        .expect("Could not open or create scratchpad");
    let _ = scratchpad_file.set_len(length);
    Mmap::open_path(scratchpad_path, Protection::ReadWrite).expect("Could not open scratchpad")
}

fn main() {
    let args = App::new("PumpkinDB Server")
        .version(crate_version!())
        .about("Event Sourcing Database Engine http://pumpkindb.org")
        .author("PumpkinDB Contributors")
        .setting(clap::AppSettings::ColoredHelp)
        .arg(Arg::with_name("config")
            .help("Configuration file")
            .required(false)
            .long("config")
            .short("c")
            .default_value("pumpkindb.toml")
            .takes_value(true))
        .get_matches();
    let _ = config::merge(config::Environment::new("pumpkindb"));
    let _ = config::merge(config::File::new(args.value_of("config").unwrap(),
                                            config::FileFormat::Toml));
    let _ = config::set_default("server.port", 9981);
    let _ = config::set_default("storage.path", "pumpkin.db");
    let storage_path = config::get_str("storage.path").unwrap().into_owned();
    fs::create_dir_all(storage_path.as_str()).expect("can't create directory");

    // Initialize Mmap
    let scratchpad = prepare_mmap(storage_path.as_str(), "scratchpad", 20);
    let mut hlc_state = scratchpad.into_view_sync();
    hlc_state.restrict(0, 20).expect("Could not prepare HLC state");

    // Initialize logging
    let log_config = config::get_str("logging.config");
    let mut log_configured = false;
    if log_config.is_some() {
        let log_file_path = log_config.unwrap().into_owned();
        if fs::metadata(&log_file_path).is_ok() {
            log4rs::init_file(&log_file_path, Default::default()).unwrap();
            log_configured = true;
        } else {
            println!("{} not found", &log_file_path);
        }
    }

    if !log_configured {
        let appender = log4rs::config::Appender::builder()
            .build("console",
                   Box::new(log4rs::append::console::ConsoleAppender::builder().build()));
        let root =
            log4rs::config::Root::builder().appender("console").build(log::LogLevelFilter::Info);
        let _ = log4rs::init_config(log4rs::config::Config::builder()
            .appender(appender)
            .build(root)
            .unwrap());
        warn!("No logging configuration specified, switching to console logging");
    }

    info!("Starting up");

    let mut senders = Vec::new();

    let (relay_sender, relay_receiver) = mio_chan::channel();
    let mut client_messaging = pumpkindb_engine::messaging::Simple::new();
    let publisher_accessor = client_messaging.accessor();
    let subscriber_accessor = client_messaging.accessor();
    let _ = thread::spawn(move || client_messaging.run());
    let storage = Arc::new(storage::Storage::new(&ENVIRONMENT));
    let timestamp = Arc::new(timestamp::Timestamp::new(Some(hlc_state)));

    let cpus = num_cpus::get();
    info!("Starting {} schedulers", cpus);
    for i in 0..cpus {
        debug!("Starting scheduler on core {}.", i);
        let (sender, receiver) = script::Scheduler::<dispatcher::StandardDispatcher<
            messaging::SimpleAccessor, messaging::SimpleAccessor>>::create_sender();
        let storage_clone = storage.clone();
        let timestamp_clone = timestamp.clone();

        let publisher_accessor1 = publisher_accessor.clone();
        let subscriber_accessor1 = subscriber_accessor.clone();

        thread::spawn(move || {
            let mut scheduler =
                script::Scheduler::new(
                    dispatcher::StandardDispatcher::new(&storage_clone,
                                                        publisher_accessor1, subscriber_accessor1,
                                                        timestamp_clone),
                    receiver);
            scheduler.run()
        });
        senders.push(sender)
    }

    run(config::get_int("server.port").unwrap(),
                senders, relay_sender, relay_receiver);

}
<commit_msg>Problem: unused `test` feature in pumpkindb_server<commit_after>// Copyright (c) 2017, All Contributors (see CONTRIBUTORS file)
//
// 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/.
#![feature(slice_patterns, advanced_slice_patterns)]

extern crate mio;
extern crate memmap;
extern crate byteorder;
extern crate rand;
extern crate num_cpus;
#[macro_use]
extern crate log;
extern crate log4rs;
extern crate slab;
extern crate num_bigint;
extern crate num_traits;
extern crate lmdb_zero as lmdb;
#[macro_use]
extern crate lazy_static;
extern crate config;
#[macro_use]
extern crate clap;
extern crate uuid;

extern crate pumpkinscript;
extern crate pumpkindb_engine;

mod connection;
mod server;

use std::fs;
use std::fs::OpenOptions;
use std::path::PathBuf;
use std::thread;
use std::sync::Arc;

use memmap::{Mmap, Protection};
use mio::*;
use mio::tcp::*;
use clap::{App, Arg};

use pumpkindb_engine::{script, storage, timestamp};
use pumpkindb_engine::script::dispatcher;
use pumpkindb_engine::messaging;

lazy_static! {
 static ref ENVIRONMENT: lmdb::Environment = {
    let _ = config::set_default("storage.path", "pumpkin.db");
    let storage_path = config::get_str("storage.path").unwrap().into_owned();
    fs::create_dir_all(storage_path.as_str()).expect("can't create directory");
    let map_size = config::get_int("storage.mapsize");
    let maxreaders = config::get_int("storage.maxreaders").and_then(|v| Some(v as u32));
    if let Some(max) = maxreaders {
       if max < 1 {
          error!("storage.maxreaders can't be less than 1");
          ::std::process::exit(1);
       }
    }
    storage::create_environment(storage_path, map_size, maxreaders)
 };
}

use mio::channel as mio_chan;

pub fn run(port: i64,
           senders: Vec<script::Sender<script::RequestMessage>>,
           relay_sender: mio_chan::Sender<server::RelayedPublishedMessage>,
           relay_receiver: mio_chan::Receiver<server::RelayedPublishedMessage>) {
    let addr = format!("0.0.0.0:{}", port).parse().unwrap();

    info!("Listening on {}", addr);

    let sock = TcpListener::bind(&addr).expect("Failed to bind address");

    let mut poll = Poll::new().expect("Failed to initialize polling");

    let mut server = server::Server::new(sock, relay_sender, relay_receiver, senders);
    server.run(&mut poll).expect("Failed to run server");

}

/// Accepts storage path, filename and length and prepares the file. It is important that the length
/// is the total length of the memory mapped file, otherwise the application _will segfault_ when
/// trying to read those sections later. There is no way to handle that.
/// The mmap file is structured as such now:
/// Byte Range         Used for
/// [0..20]            Last known HTC timestamp
fn prepare_mmap(storage_path: &str, filename: &str, length: u64) -> Mmap {
    let mut scratchpad_pathbuf = PathBuf::from(storage_path);
    scratchpad_pathbuf.push(filename);
    scratchpad_pathbuf.set_extension("dat");
    let scratchpad_path = scratchpad_pathbuf.as_path();
    let scratchpad_file = OpenOptions::new()
        .create(true)
        .write(true)
        .open(scratchpad_path)
        .expect("Could not open or create scratchpad");
    let _ = scratchpad_file.set_len(length);
    Mmap::open_path(scratchpad_path, Protection::ReadWrite).expect("Could not open scratchpad")
}

fn main() {
    let args = App::new("PumpkinDB Server")
        .version(crate_version!())
        .about("Event Sourcing Database Engine http://pumpkindb.org")
        .author("PumpkinDB Contributors")
        .setting(clap::AppSettings::ColoredHelp)
        .arg(Arg::with_name("config")
            .help("Configuration file")
            .required(false)
            .long("config")
            .short("c")
            .default_value("pumpkindb.toml")
            .takes_value(true))
        .get_matches();
    let _ = config::merge(config::Environment::new("pumpkindb"));
    let _ = config::merge(config::File::new(args.value_of("config").unwrap(),
                                            config::FileFormat::Toml));
    let _ = config::set_default("server.port", 9981);
    let _ = config::set_default("storage.path", "pumpkin.db");
    let storage_path = config::get_str("storage.path").unwrap().into_owned();
    fs::create_dir_all(storage_path.as_str()).expect("can't create directory");

    // Initialize Mmap
    let scratchpad = prepare_mmap(storage_path.as_str(), "scratchpad", 20);
    let mut hlc_state = scratchpad.into_view_sync();
    hlc_state.restrict(0, 20).expect("Could not prepare HLC state");

    // Initialize logging
    let log_config = config::get_str("logging.config");
    let mut log_configured = false;
    if log_config.is_some() {
        let log_file_path = log_config.unwrap().into_owned();
        if fs::metadata(&log_file_path).is_ok() {
            log4rs::init_file(&log_file_path, Default::default()).unwrap();
            log_configured = true;
        } else {
            println!("{} not found", &log_file_path);
        }
    }

    if !log_configured {
        let appender = log4rs::config::Appender::builder()
            .build("console",
                   Box::new(log4rs::append::console::ConsoleAppender::builder().build()));
        let root =
            log4rs::config::Root::builder().appender("console").build(log::LogLevelFilter::Info);
        let _ = log4rs::init_config(log4rs::config::Config::builder()
            .appender(appender)
            .build(root)
            .unwrap());
        warn!("No logging configuration specified, switching to console logging");
    }

    info!("Starting up");

    let mut senders = Vec::new();

    let (relay_sender, relay_receiver) = mio_chan::channel();
    let mut client_messaging = pumpkindb_engine::messaging::Simple::new();
    let publisher_accessor = client_messaging.accessor();
    let subscriber_accessor = client_messaging.accessor();
    let _ = thread::spawn(move || client_messaging.run());
    let storage = Arc::new(storage::Storage::new(&ENVIRONMENT));
    let timestamp = Arc::new(timestamp::Timestamp::new(Some(hlc_state)));

    let cpus = num_cpus::get();
    info!("Starting {} schedulers", cpus);
    for i in 0..cpus {
        debug!("Starting scheduler on core {}.", i);
        let (sender, receiver) = script::Scheduler::<dispatcher::StandardDispatcher<
            messaging::SimpleAccessor, messaging::SimpleAccessor>>::create_sender();
        let storage_clone = storage.clone();
        let timestamp_clone = timestamp.clone();

        let publisher_accessor1 = publisher_accessor.clone();
        let subscriber_accessor1 = subscriber_accessor.clone();

        thread::spawn(move || {
            let mut scheduler =
                script::Scheduler::new(
                    dispatcher::StandardDispatcher::new(&storage_clone,
                                                        publisher_accessor1, subscriber_accessor1,
                                                        timestamp_clone),
                    receiver);
            scheduler.run()
        });
        senders.push(sender)
    }

    run(config::get_int("server.port").unwrap(),
                senders, relay_sender, relay_receiver);

}
<|endoftext|>


<commit_before>use controls::{Button, Control, Label, Root, Sizer, Slider};
use failure::err_msg;
use failure::Error as FError;
use std::convert::TryInto;

pub struct Gui {
  pub title: String,
  pub root_control: Option<Box<dyn Control>>,
  sizerstack: Vec<Vec<i32>>,
}

impl Gui {
  pub fn new_gui(title: String) -> Gui {
    Gui {
      title: title
    , root_control: None
    , sizerstack: Vec::new()}
  }
  // one way function!
  pub fn to_root(self) -> Result<Root, FError> {
    match self.root_control {
      Some(rc) => {
        if self.sizerstack.is_empty() {
          Ok(Root {
            title: self.title.clone(),
            root_control: rc,
          })
        } else {
          Err(err_msg("there are still incomplete sizers!"))
        }
      }
      None => Err(err_msg("no controls in the gui yet!")),
    }
  }

  pub fn next_id(&self) -> Result<Vec<i32>, FError> {
    match &self.root_control {
      Some(rc) => match self.sizerstack.last() {
        Some(id) => match get_control(id, &**rc) {
          Some(c) => match c.sub_controls() {
            Some(sc) => {
              let mut nid = id.clone();
              nid.push(sc.len().try_into().unwrap());
              Ok(nid)
            }
            None => Err(err_msg(format!("element is not a sizer: {:?}", id))),
          },
          None => Err(err_msg(format!("element not found: {:?}", id))),
        },
        None => Err(err_msg(
          "no active sizer and gui is not empty; can't assign a control id!",
        )),
      },
      None => Ok(Vec::new()),
    }
  }

  pub fn add_control(&mut self, control: Box<dyn Control>) -> Result<&Gui, FError> {
    match &mut self.root_control {
      None => {
        // root level controls have an empty id - since there's only one control.
        self.root_control = Some(control);
        Ok(self)
      }

      Some(rootcontrol) =>
      // there's already a root control.  is there a sizer in the stack?
      {
        match self.sizerstack.last() {
          None => Err(err_msg("no active sizer, can't add new element!")),
          Some(id) => {
            match get_control_mut(id, &mut **rootcontrol) {
              Some(c) => c.add_control(control),
              None => (),
            }
            Ok(self)
          }
        }
      }
    }
  }

  pub fn add_button(&mut self, name: String, label: Option<String>) -> Result<&Gui, FError> {
    let newbutton = Box::new(Button {
      control_id: self.next_id()?,
      name: String::from(name),
      label: label,
      pressed: false,
    });
    self.add_control(newbutton)
  }

  pub fn add_slider(&mut self, name: String, label: Option<String>) -> Result<&Gui, FError> {
    let newslider = Box::new(Slider {
      control_id: self.next_id()?,
      name: String::from(name),
      label: label,
      location: 0.5,
      pressed: false,
    });
    self.add_control(newslider)
  }

  pub fn add_label(&mut self, name: String, label: String) -> Result<&Gui, FError> {
    let newlabel = Box::new(Label {
      control_id: self.next_id()?,
      name: name,
      label: label,
    });
    self.add_control(newlabel)
  }

  pub fn add_sizer(&mut self) -> Result<&Gui, FError> {
    let newsizer = Box::new(Sizer {
      control_id: self.next_id()?,
      controls: Vec::new(),
    });
    self.add_control(newsizer)
  }

  pub fn end_sizer(&mut self) -> Result<&Gui, FError> {
    if self.sizerstack.is_empty() {
      Err(err_msg(
        "mismatched end_sizer() call; sizer stack is empty!",
      ))
    } else {
      self.sizerstack.pop();
      Ok(self)
    }
  }
}

fn get_control<'a>(id: &Vec<i32>, control: &'a dyn Control) -> Option<&'a dyn Control> {
  // iterate through all controls, looking for our id.
  if *id == *control.control_id() {
    Some(control)
  } else {
    match control.sub_controls() {
      Some(cs) => {
        let mut ret = None;
        for c in cs.iter() {
          match get_control(id, &**c) {
            Some(cr) => ret = Some(cr),
            None => (),
          };
        }
        ret
      }
      None => None,
    }
  }
}

fn get_control_mut<'a>(id: &Vec<i32>, control: &'a mut dyn Control) -> Option<&'a mut dyn Control> {
  // iterate through all controls, looking for our id.
  if *id == *control.control_id() {
    Some(control)
  } else {
    match control.mut_sub_controls() {
      Some(cs) => {
        let mut ret = None;
        for c in cs.iter_mut() {
          match get_control_mut(id, &mut **c) {
            Some(cr) => ret = Some(cr),
            None => (),
          };
        }
        ret
      }
      None => None,
    }
  }
}
<commit_msg>fix the mut dealio<commit_after>use controls::{Button, Control, Label, Root, Sizer, Slider};
use failure::err_msg;
use failure::Error as FError;
use std::convert::TryInto;

pub struct Gui {
  pub title: String,
  pub root_control: Option<Box<dyn Control>>,
  sizerstack: Vec<Vec<i32>>,
}

impl Gui {
  pub fn new_gui(title: String) -> Gui {
    Gui {
      title: title
    , root_control: None
    , sizerstack: Vec::new()}
  }
  // one way function!
  pub fn to_root(self) -> Result<Root, FError> {
    match self.root_control {
      Some(rc) => {
        if self.sizerstack.is_empty() {
          Ok(Root {
            title: self.title.clone(),
            root_control: rc,
          })
        } else {
          Err(err_msg("there are still incomplete sizers!"))
        }
      }
      None => Err(err_msg("no controls in the gui yet!")),
    }
  }

  pub fn next_id(&self) -> Result<Vec<i32>, FError> {
    match &self.root_control {
      Some(rc) => match self.sizerstack.last() {
        Some(id) => match get_control(id, &**rc) {
          Some(c) => match c.sub_controls() {
            Some(sc) => {
              let mut nid = id.clone();
              nid.push(sc.len().try_into().unwrap());
              Ok(nid)
            }
            None => Err(err_msg(format!("element is not a sizer: {:?}", id))),
          },
          None => Err(err_msg(format!("element not found: {:?}", id))),
        },
        None => Err(err_msg(
          "no active sizer and gui is not empty; can't assign a control id!",
        )),
      },
      None => Ok(Vec::new()),
    }
  }

  pub fn add_control(&mut self, control: Box<dyn Control>) -> Result<&mut Gui, FError> {
    match &mut self.root_control {
      None => {
        // root level controls have an empty id - since there's only one control.
        self.root_control = Some(control);
        Ok(self)
      }

      Some(rootcontrol) =>
      // there's already a root control.  is there a sizer in the stack?
      {
        match self.sizerstack.last() {
          None => Err(err_msg("no active sizer, can't add new element!")),
          Some(id) => {
            match get_control_mut(id, &mut **rootcontrol) {
              Some(c) => c.add_control(control),
              None => (),
            }
            Ok(self)
          }
        }
      }
    }
  }

  pub fn add_button(&mut self, name: String, label: Option<String>) -> Result<&mut Gui, FError> {
    let newbutton = Box::new(Button {
      control_id: self.next_id()?,
      name: String::from(name),
      label: label,
      pressed: false,
    });
    self.add_control(newbutton)
  }

  pub fn add_slider(&mut self, name: String, label: Option<String>) -> Result<&mut Gui, FError> {
    let newslider = Box::new(Slider {
      control_id: self.next_id()?,
      name: String::from(name),
      label: label,
      location: 0.5,
      pressed: false,
    });
    self.add_control(newslider)
  }

  pub fn add_label(&mut self, name: String, label: String) -> Result<&mut Gui, FError> {
    let newlabel = Box::new(Label {
      control_id: self.next_id()?,
      name: name,
      label: label,
    });
    self.add_control(newlabel)
  }

  pub fn add_sizer(&mut self) -> Result<&mut Gui, FError> {
    let newsizer = Box::new(Sizer {
      control_id: self.next_id()?,
      controls: Vec::new(),
    });
    self.add_control(newsizer)
  }

  pub fn end_sizer(&mut self) -> Result<&mut Gui, FError> {
    if self.sizerstack.is_empty() {
      Err(err_msg(
        "mismatched end_sizer() call; sizer stack is empty!",
      ))
    } else {
      self.sizerstack.pop();
      Ok(self)
    }
  }
}

fn get_control<'a>(id: &Vec<i32>, control: &'a dyn Control) -> Option<&'a dyn Control> {
  // iterate through all controls, looking for our id.
  if *id == *control.control_id() {
    Some(control)
  } else {
    match control.sub_controls() {
      Some(cs) => {
        let mut ret = None;
        for c in cs.iter() {
          match get_control(id, &**c) {
            Some(cr) => ret = Some(cr),
            None => (),
          };
        }
        ret
      }
      None => None,
    }
  }
}

fn get_control_mut<'a>(id: &Vec<i32>, control: &'a mut dyn Control) -> Option<&'a mut dyn Control> {
  // iterate through all controls, looking for our id.
  if *id == *control.control_id() {
    Some(control)
  } else {
    match control.mut_sub_controls() {
      Some(cs) => {
        let mut ret = None;
        for c in cs.iter_mut() {
          match get_control_mut(id, &mut **c) {
            Some(cr) => ret = Some(cr),
            None => (),
          };
        }
        ret
      }
      None => None,
    }
  }
}
<|endoftext|>


<commit_before>iface iterable<A> {
    fn iter(blk: fn(A));
}

impl<A> of iterable<A> for fn@(fn(A)) {
    fn iter(blk: fn(A)) {
        self(blk);
    }
}

// accomodate the fact that int/uint are passed by value by default:
impl of iterable<int> for fn@(fn(int)) {
    fn iter(blk: fn(&&int)) {
        self {|i| blk(i)}
    }
}

impl of iterable<uint> for fn@(fn(uint)) {
    fn iter(blk: fn(&&uint)) {
        self {|i| blk(i)}
    }
}

impl<A> of iterable<A> for [A] {
    fn iter(blk: fn(A)) {
        vec::iter(self, blk)
    }
}

impl<A> of iterable<A> for option<A> {
    fn iter(blk: fn(A)) {
        option::may(self, blk)
    }
}

fn enumerate<A,IA:iterable<A>>(self: IA, blk: fn(uint, A)) {
    let i = 0u;
    self.iter {|a|
        blk(i, a);
        i += 1u;
    }
}

// Here: we have to use fn@ for predicates and map functions, because
// we will be binding them up into a closure.  Disappointing.  A true
// region type system might be able to do better than this.

fn filter<A,IA:iterable<A>>(self: IA, prd: fn@(A) -> bool, blk: fn(A)) {
    self.iter {|a|
        if prd(a) { blk(a) }
    }
}

fn map<A,B,IA:iterable<A>>(self: IA, cnv: fn@(A) -> B, blk: fn(B)) {
    self.iter {|a|
        let b = cnv(a);
        blk(b);
    }
}

fn flat_map<A,B,IA:iterable<A>,IB:iterable<B>>(
    self: IA, cnv: fn@(A) -> IB, blk: fn(B)) {
    self.iter {|a|
        cnv(a).iter(blk)
    }
}

fn foldl<A,B,IA:iterable<A>>(self: IA, +b0: B, blk: fn(-B, A) -> B) -> B {
    let b <- b0;
    self.iter {|a|
        b = blk(b, a);
    }
    ret b;
}

fn foldr<A:copy,B,IA:iterable<A>>(
    self: IA, +b0: B, blk: fn(A, -B) -> B) -> B {

    let b <- b0;
    reversed(self) {|a|
        b = blk(a, b);
    }
    ret b;
}

fn to_list<A:copy,IA:iterable<A>>(self: IA) -> [A] {
    foldl::<A,[A],IA>(self, [], {|r, a| r + [a]})
}

// FIXME: This could be made more efficient with an riterable interface
fn reversed<A:copy,IA:iterable<A>>(self: IA, blk: fn(A)) {
    vec::riter(to_list(self), blk)
}

fn count<A,IA:iterable<A>>(self: IA, x: A) -> uint {
    foldl(self, 0u) {|count, value|
        if value == x {
            count + 1u
        } else {
            count
        }
    }
}

fn repeat(times: uint, blk: fn()) {
    let i = 0u;
    while i < times {
        blk();
        i += 1u;
    }
}

fn min<A:copy,IA:iterable<A>>(self: IA) -> A {
    alt foldl::<A,option<A>,IA>(self, none) {|a, b|
        alt a {
          some(a_) if a_ < b {
            // FIXME: Not sure if this is successfully optimized to a move
            a
          }
          _ { some(b) }
        }
    } {
        some(val) { val }
        none { fail "min called on empty iterator" }
    }
}

fn max<A:copy,IA:iterable<A>>(self: IA) -> A {
    alt foldl::<A,option<A>,IA>(self, none) {|a, b|
        alt a {
          some(a_) if a_ > b {
            // FIXME: Not sure if this is successfully optimized to a move
            a
          }
          _ { some(b) }
        }
    } {
        some(val) { val }
        none { fail "max called on empty iterator" }
    }
}

#[test]
fn test_enumerate() {
    enumerate(["0", "1", "2"]) {|i,j|
        assert #fmt["%u",i] == j;
    }
}

#[test]
fn test_map_and_to_list() {
    let a = bind vec::iter([0, 1, 2], _);
    let b = bind map(a, {|i| i*2}, _);
    let c = to_list(b);
    assert c == [0, 2, 4];
}

#[test]
fn test_map_directly_on_vec() {
    let b = bind map([0, 1, 2], {|i| i*2}, _);
    let c = to_list(b);
    assert c == [0, 2, 4];
}

#[test]
fn test_filter_on_int_range() {
    fn is_even(&&i: int) -> bool {
        ret (i % 2) == 0;
    }

    let l = to_list(bind filter(bind int::range(0, 10, _), is_even, _));
    assert l == [0, 2, 4, 6, 8];
}

#[test]
fn test_filter_on_uint_range() {
    fn is_even(&&i: uint) -> bool {
        ret (i % 2u) == 0u;
    }

    let l = to_list(bind filter(bind uint::range(0u, 10u, _), is_even, _));
    assert l == [0u, 2u, 4u, 6u, 8u];
}

#[test]
fn test_flat_map_with_option() {
    fn if_even(&&i: int) -> option<int> {
        if (i % 2) == 0 { some(i) }
        else { none }
    }

    let a = bind vec::iter([0, 1, 2], _);
    let b = bind flat_map(a, if_even, _);
    let c = to_list(b);
    assert c == [0, 2];
}

#[test]
fn test_flat_map_with_list() {
    fn repeat(&&i: int) -> [int] {
        let r = [];
        int::range(0, i) {|_j| r += [i]; }
        r
    }

    let a = bind vec::iter([0, 1, 2, 3], _);
    let b = bind flat_map(a, repeat, _);
    let c = to_list(b);
    #debug["c = %?", c];
    assert c == [1, 2, 2, 3, 3, 3];
}

#[test]
fn test_repeat() {
    let c = [],
        i = 0u;
    repeat(5u) {||
        c += [(i * i)];
        i += 1u;
    };
    #debug["c = %?", c];
    assert c == [0u, 1u, 4u, 9u, 16u];
}

#[test]
fn test_min() {
    assert min([5, 4, 1, 2, 3]) == 1;
}

#[test]
#[should_fail]
#[ignore(cfg(target_os = "win32"))]
fn test_min_empty() {
    min::<int, [int]>([]);
}

#[test]
fn test_max() {
    assert max([1, 2, 4, 2, 3]) == 4;
}

#[test]
#[should_fail]
#[ignore(cfg(target_os = "win32"))]
fn test_max_empty() {
    max::<int, [int]>([]);
}

#[test]
fn test_reversed() {
    assert to_list(bind reversed([1, 2, 3], _)) == [3, 2, 1];
}

#[test]
fn test_count() {
    assert count([1, 2, 1, 2, 1], 1) == 3u;
}

#[test]
fn test_foldr() {
    fn sub(&&a: int, -b: int) -> int {
        a - b
    }
    let sum = foldr([1, 2, 3, 4], 0, sub);
    assert sum == -2;
}<commit_msg>core: Add iterable implementation for strings<commit_after>iface iterable<A> {
    fn iter(blk: fn(A));
}

impl<A> of iterable<A> for fn@(fn(A)) {
    fn iter(blk: fn(A)) {
        self(blk);
    }
}

// accomodate the fact that int/uint are passed by value by default:
impl of iterable<int> for fn@(fn(int)) {
    fn iter(blk: fn(&&int)) {
        self {|i| blk(i)}
    }
}

impl of iterable<uint> for fn@(fn(uint)) {
    fn iter(blk: fn(&&uint)) {
        self {|i| blk(i)}
    }
}

impl<A> of iterable<A> for [A] {
    fn iter(blk: fn(A)) {
        vec::iter(self, blk)
    }
}

impl<A> of iterable<A> for option<A> {
    fn iter(blk: fn(A)) {
        option::may(self, blk)
    }
}

impl of iterable<char> for str {
    fn iter(blk: fn(&&char)) {
        str::chars_iter(self) { |ch| blk(ch) }
    }
}

fn enumerate<A,IA:iterable<A>>(self: IA, blk: fn(uint, A)) {
    let i = 0u;
    self.iter {|a|
        blk(i, a);
        i += 1u;
    }
}

// Here: we have to use fn@ for predicates and map functions, because
// we will be binding them up into a closure.  Disappointing.  A true
// region type system might be able to do better than this.

fn filter<A,IA:iterable<A>>(self: IA, prd: fn@(A) -> bool, blk: fn(A)) {
    self.iter {|a|
        if prd(a) { blk(a) }
    }
}

fn map<A,B,IA:iterable<A>>(self: IA, cnv: fn@(A) -> B, blk: fn(B)) {
    self.iter {|a|
        let b = cnv(a);
        blk(b);
    }
}

fn flat_map<A,B,IA:iterable<A>,IB:iterable<B>>(
    self: IA, cnv: fn@(A) -> IB, blk: fn(B)) {
    self.iter {|a|
        cnv(a).iter(blk)
    }
}

fn foldl<A,B,IA:iterable<A>>(self: IA, +b0: B, blk: fn(-B, A) -> B) -> B {
    let b <- b0;
    self.iter {|a|
        b = blk(b, a);
    }
    ret b;
}

fn foldr<A:copy,B,IA:iterable<A>>(
    self: IA, +b0: B, blk: fn(A, -B) -> B) -> B {

    let b <- b0;
    reversed(self) {|a|
        b = blk(a, b);
    }
    ret b;
}

fn to_list<A:copy,IA:iterable<A>>(self: IA) -> [A] {
    foldl::<A,[A],IA>(self, [], {|r, a| r + [a]})
}

// FIXME: This could be made more efficient with an riterable interface
fn reversed<A:copy,IA:iterable<A>>(self: IA, blk: fn(A)) {
    vec::riter(to_list(self), blk)
}

fn count<A,IA:iterable<A>>(self: IA, x: A) -> uint {
    foldl(self, 0u) {|count, value|
        if value == x {
            count + 1u
        } else {
            count
        }
    }
}

fn repeat(times: uint, blk: fn()) {
    let i = 0u;
    while i < times {
        blk();
        i += 1u;
    }
}

fn min<A:copy,IA:iterable<A>>(self: IA) -> A {
    alt foldl::<A,option<A>,IA>(self, none) {|a, b|
        alt a {
          some(a_) if a_ < b {
            // FIXME: Not sure if this is successfully optimized to a move
            a
          }
          _ { some(b) }
        }
    } {
        some(val) { val }
        none { fail "min called on empty iterator" }
    }
}

fn max<A:copy,IA:iterable<A>>(self: IA) -> A {
    alt foldl::<A,option<A>,IA>(self, none) {|a, b|
        alt a {
          some(a_) if a_ > b {
            // FIXME: Not sure if this is successfully optimized to a move
            a
          }
          _ { some(b) }
        }
    } {
        some(val) { val }
        none { fail "max called on empty iterator" }
    }
}

#[test]
fn test_enumerate() {
    enumerate(["0", "1", "2"]) {|i,j|
        assert #fmt["%u",i] == j;
    }
}

#[test]
fn test_map_and_to_list() {
    let a = bind vec::iter([0, 1, 2], _);
    let b = bind map(a, {|i| i*2}, _);
    let c = to_list(b);
    assert c == [0, 2, 4];
}

#[test]
fn test_map_directly_on_vec() {
    let b = bind map([0, 1, 2], {|i| i*2}, _);
    let c = to_list(b);
    assert c == [0, 2, 4];
}

#[test]
fn test_filter_on_int_range() {
    fn is_even(&&i: int) -> bool {
        ret (i % 2) == 0;
    }

    let l = to_list(bind filter(bind int::range(0, 10, _), is_even, _));
    assert l == [0, 2, 4, 6, 8];
}

#[test]
fn test_filter_on_uint_range() {
    fn is_even(&&i: uint) -> bool {
        ret (i % 2u) == 0u;
    }

    let l = to_list(bind filter(bind uint::range(0u, 10u, _), is_even, _));
    assert l == [0u, 2u, 4u, 6u, 8u];
}

#[test]
fn test_flat_map_with_option() {
    fn if_even(&&i: int) -> option<int> {
        if (i % 2) == 0 { some(i) }
        else { none }
    }

    let a = bind vec::iter([0, 1, 2], _);
    let b = bind flat_map(a, if_even, _);
    let c = to_list(b);
    assert c == [0, 2];
}

#[test]
fn test_flat_map_with_list() {
    fn repeat(&&i: int) -> [int] {
        let r = [];
        int::range(0, i) {|_j| r += [i]; }
        r
    }

    let a = bind vec::iter([0, 1, 2, 3], _);
    let b = bind flat_map(a, repeat, _);
    let c = to_list(b);
    #debug["c = %?", c];
    assert c == [1, 2, 2, 3, 3, 3];
}

#[test]
fn test_repeat() {
    let c = [],
        i = 0u;
    repeat(5u) {||
        c += [(i * i)];
        i += 1u;
    };
    #debug["c = %?", c];
    assert c == [0u, 1u, 4u, 9u, 16u];
}

#[test]
fn test_min() {
    assert min([5, 4, 1, 2, 3]) == 1;
}

#[test]
#[should_fail]
#[ignore(cfg(target_os = "win32"))]
fn test_min_empty() {
    min::<int, [int]>([]);
}

#[test]
fn test_max() {
    assert max([1, 2, 4, 2, 3]) == 4;
}

#[test]
#[should_fail]
#[ignore(cfg(target_os = "win32"))]
fn test_max_empty() {
    max::<int, [int]>([]);
}

#[test]
fn test_reversed() {
    assert to_list(bind reversed([1, 2, 3], _)) == [3, 2, 1];
}

#[test]
fn test_count() {
    assert count([1, 2, 1, 2, 1], 1) == 3u;
}

#[test]
fn test_foldr() {
    fn sub(&&a: int, -b: int) -> int {
        a - b
    }
    let sum = foldr([1, 2, 3, 4], 0, sub);
    assert sum == -2;
}<|endoftext|>