libflo_func 0.1.1

A library for loading modules containing shared libs into libflo.
Documentation
use { file_funcs, FuncMapper, Payload, string };
use error::*;
use func::Func;
use libflo_module::{ ModuleMapper, PathResolver, self_module_name };
use serialization::{ Dll, Func as SerialFunc };
use sharedlib::LibArc;
use std::collections::HashMap;

pub unsafe fn load(
    module_mapper: &ModuleMapper,
    path_resolver: &PathResolver,
) -> Result<Payload> {
    let my_id = module_mapper.get(self_module_name())?;
    let func_file_name = string::func_file_name();

    let mut pre_func_list = Vec::new();
    let mut pre_func_map = module_mapper.get_raw_map().into_iter().map(|_| None).collect();

    for (module_name, module_id) in module_mapper.get_raw_map() {
        if let Some(dll_json_path) = path_resolver.try_find_submodule_file_path(func_file_name, *module_id, my_id)? {
            let dll_json = file_funcs::dll_from_path(dll_json_path)?;
            create_funcs(dll_json, module_name, *module_id, my_id, &path_resolver, &mut pre_func_list, &mut pre_func_map)?;
        };
    }

    let func_mapper = FuncMapper::new(pre_func_map, pre_func_list);

    let result =
        Payload::new(
            func_mapper,
        );
    Ok(result)
}

unsafe fn create_funcs(
    dll: Dll,
    module_name: &String,
    module_id: usize,
    self_module_id: usize,
    path_resolver: &PathResolver,
    pre_func_list: &mut Vec<Func>,
    pre_func_map: &mut Vec<Option<HashMap<String, usize>>>,
) -> Result<()> {
    let (path, funcs) = dll.destructure();
    let dll_full_path = path_resolver.find_submodule_file_path(path, module_id, self_module_id)?;
    let library = LibArc::new(dll_full_path.clone())
        .chain_err(|| ErrorKind::DllCouldNotLoad(dll_full_path, module_id))?;
    for func in funcs {
        create_func(func, &library, module_name, module_id, pre_func_list, pre_func_map)?;
    }

    Ok(())
}

unsafe fn create_func(
    func: SerialFunc,
    library: &LibArc,
    module_name: &String,
    module_id: usize,
    pre_func_list: &mut Vec<Func>,
    pre_func_map: &mut Vec<Option<HashMap<String, usize>>>,
) -> Result<()> {
    let (func_type, has_input, has_output, symbol, use_as) = func.destructure();

    let name = use_as.unwrap_or(symbol.clone());
    let func_id = pre_func_list.len();

    if let Some(&None) = pre_func_map.get(module_id) {
        pre_func_map[module_id] = Some(HashMap::new());
    }

    if let Some(&mut Some(ref mut inner_func_map)) = pre_func_map.get_mut(module_id) {
        if let Some(_) = inner_func_map.insert(name.clone(), func_id) {
            return Err(ErrorKind::FuncLoadNameCollision(name, module_name.clone()).into());
        }
    }

    let has_input = has_input.unwrap_or(false);
    let has_output = has_output.unwrap_or(false);
    let func = Func::new(library, &symbol, func_type, has_input, has_output)?;
    pre_func_list.push(func);

    Ok(())
}