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
use std::any::TypeId;
use std::collections::HashMap;
use log::debug;
use crate::dddk::aliases::Events;
use crate::dddk::command::command::Command;
use crate::dddk::command::command_bus::CommandBus;
use crate::dddk::command::command_handler::CommandHandlerInBus;
use crate::dddk::errors::NoCommandHandlerRegisterForGivenCommand;

pub struct CommandDispatcher {
    command_handlers: HashMap<TypeId, Box<dyn CommandHandlerInBus>>,
}

impl CommandDispatcher {
    pub fn new(command_handler_values: Vec<Box<dyn CommandHandlerInBus>>) -> CommandDispatcher {
        let mut map = HashMap::new();
        command_handler_values.into_iter().for_each(|item| {
            if let Some(_) = map.get(&item.get_associated_command_from_bus()) {
                panic!("A CommandHandler has already been registered for this command");
            }
            debug!("[CommandDispatcher]: register handler {}", item.get_command_handler_name());
            map.insert(item.get_associated_command_from_bus(), item);
        });
        return CommandDispatcher {
            command_handlers: map
        };
    }

    pub fn get_command_handler_by_its_command(&self, type_id: TypeId) -> Option<&Box<dyn CommandHandlerInBus>> {
        if let Some(command_handler) = self.command_handlers.get(&type_id) {
            return Some(command_handler);
        }
        None
    }
}

impl CommandBus for CommandDispatcher {
    fn dispatch<'b>(&self, command: &'b dyn Command) -> Events {
        if let Option::Some(command_handler) = self.command_handlers.get(&command.as_any().type_id()) {
            let events = command_handler.handle_from_bus(command);
            return events;
        }
        Err(Box::new(NoCommandHandlerRegisterForGivenCommand {}))
    }
}