1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use { ExtDynamicEventMapper, ExtEventMapper, ExtFuncMapper };
use libflo_dynamic_event::DynamicEventMapper;
use libflo_dynamic_event::serialization::DynamicEventSerde;
use libflo_event::EventMapper;
use libflo_func::FuncMapper;
use libflo_module::ModuleMapper;
use libflo_module::PathResolver;
use error::*;
use serde::Serialize;
use std::any::Any;
use std::fmt::Debug;
use std::io::Write;
use std::mem;
use std::ops::DerefMut;
use std::sync::{ RwLock, RwLockReadGuard, RwLockWriteGuard };

pub struct Libflo {
    dynamic_event_mapper: DynamicEventMapper,
    event_mapper: EventMapper,
    func_mapper: FuncMapper,
    module_mapper: ModuleMapper,
    path_resolver: PathResolver,
    module_data: Vec<RwLock<Option<Box<Any + Send + Sync>>>>,
    out_stream: RwLock<Box<Write + Send + Sync>>,
}

impl Libflo {
    pub fn new(
        dynamic_event_mapper: DynamicEventMapper,
        event_mapper: EventMapper,
        func_mapper: FuncMapper,
        module_mapper: ModuleMapper,
        path_resolver: PathResolver,
        out_stream: RwLock<Box<Write + Send + Sync>>,
    ) -> Self {
        let module_data = (0..module_mapper.get_raw_map().len()).into_iter().map(|_| RwLock::new(None)).collect();
        Libflo {
            dynamic_event_mapper: dynamic_event_mapper,
            event_mapper: event_mapper,
            func_mapper: func_mapper,
            module_mapper: module_mapper,
            path_resolver: path_resolver,
            module_data: module_data,
            out_stream: out_stream,
        }
    }

    pub fn get_dynamic_event_mapper(&self) -> ExtDynamicEventMapper {
        ExtDynamicEventMapper::new(&self.dynamic_event_mapper, &self.module_mapper)
    }

    pub fn get_event_mapper(&self) -> ExtEventMapper {
        ExtEventMapper::new(&self.event_mapper, &self.module_mapper)
    }

    pub fn get_func_mapper(&self) -> ExtFuncMapper {
        ExtFuncMapper::new(&self.func_mapper, &self.module_mapper)
    }

    pub fn get_module_mapper(&self) -> &ModuleMapper {
        &self.module_mapper
    }

    pub fn get_output_stream_mut(&self) -> Result<RwLockWriteGuard<Box<Write + Send + Sync>>> {
        self.out_stream.write().map_err(|err| ErrorKind::OutputStreamLockError(err.to_string()).into())
    }

    pub fn send_event<TArgs>(&self, dynamic_event_id: usize, data: &TArgs) -> Result<()>
        where TArgs: Clone + Debug + Serialize + Eq + PartialEq {
        let dynamic_event_serde = DynamicEventSerde::new(dynamic_event_id, &data);

        self.get_output_stream_mut()?
            .write(format!("{}\n", dynamic_event_serde.to_json()?).as_bytes())
            .map(|_| ())
            .map_err(|err| Error::from(ErrorKind::IoError(err)))
            .chain_err(|| ErrorKind::ErrorWritingOutputStream)
    }

    pub fn send_event_by_name<TStr: AsRef<str>, TArgs>(&self, module_id: usize, dynamic_event_name: TStr, data: &TArgs) -> Result<()>
        where TArgs: Clone + Debug + Serialize + Eq + PartialEq {
        let dynamic_event_id = self.get_dynamic_event_mapper().get(module_id, dynamic_event_name)?;
        self.send_event(dynamic_event_id, data)
    }

    pub fn send_event_by_module_name<TStr0: AsRef<str>, TStr1: AsRef<str>, TArgs>(
        &self,
        module_name: TStr0,
        dynamic_event_name: TStr1,
        data: &TArgs,
    ) -> Result<()>
        where TArgs: Clone + Debug + Serialize + Eq + PartialEq {
        let dynamic_event_id = self.get_dynamic_event_mapper().get_by_module_name(module_name, dynamic_event_name)?;
        self.send_event(dynamic_event_id, data)
    }

    pub fn get_path_resolver(&self) -> &PathResolver {
        &self.path_resolver
    }

    pub fn get_module_data(&self, module_id: usize) -> Result<RwLockReadGuard<Option<Box<Any + Send + Sync>>>> {
        let module_datum_vec_slot = self.module_data.get(module_id);
        if let Some(module_datum) = module_datum_vec_slot {
            module_datum.read().map_err(|err| ErrorKind::ModuleLockError(err.to_string()).into())
        } else {
            Err(ErrorKind::ModuleDoesNotExist(module_id).into())
        }
    }

    pub fn get_module_data_mut(&self, module_id: usize) -> Result<RwLockWriteGuard<Option<Box<Any + Send + Sync>>>> {
        let module_datum_vec_slot = self.module_data.get(module_id);
        if let Some(module_datum) = module_datum_vec_slot {
            module_datum.write().map_err(|err| ErrorKind::ModuleLockError(err.to_string()).into())
        } else {
            Err(ErrorKind::ModuleDoesNotExist(module_id).into())
        }
    }

    pub fn set_module_data(&self, module_id: usize, value: Box<Any + Send + Sync>) -> Result<()> {
        let mut module_data = self.get_module_data_mut(module_id)?;
        mem::replace(module_data.deref_mut(), Some(value));
        Ok(())
    }
}