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
//use domain_patterns::command::{Command, GenericHandler, CommandHandler, MassHandler};
//use std::any::Any;
//use std::error::Error;
//use std::collections::HashMap;
//use domain_patterns::collections::Repository;
//use uuid::Uuid;
//use crate::common::{MockUserRepository, NaiveUser, ValidationError};
//
//pub struct GenericHandle<T: Command + 'static>(Box<dyn CommandHandler<T>>);
//
//impl<T: Command + 'static> GenericHandler for GenericHandle<T> {
// fn handle(&mut self, command: Box<dyn Any>) -> Result<(), Box<dyn Error>>{
// self.0.handle(*command.downcast::<T>().unwrap())
// }
//
// fn handles(&self) -> String {
// self.0.handles()
// }
//}
//
//pub struct CreateUserCommand {
// pub id: Uuid,
// pub first_name: String,
// pub last_name: String,
// pub email: String,
//}
//
//impl Command for CreateUserCommand {
// fn kind(&self) -> String {
// "CreateUserCommand".to_string()
// }
//}
//
//pub struct CreateUserCommandHandler {
// // This would be an abstraction over a database connection in a real example.
// repo: MockUserRepository,
//}
//
//impl CreateUserCommandHandler {
// pub fn new(repo: MockUserRepository) -> CreateUserCommandHandler {
// CreateUserCommandHandler {
// repo,
// }
// }
//
// // This normally wouldn't be here at all, but this is so we can get back a result in mock testing
// pub fn contains_key(&self, key: String) -> bool {
// self.repo.contains_key(&key).unwrap()
// }
//}
//
//impl CommandHandler<CreateUserCommand> for CreateUserCommandHandler {
// // TODO: This is not accurate to what we would do in the real world. make failure root node and use that
// type Error = ValidationError;
//
// fn handle(&mut self, command: CreateUserCommand) -> Result<(), Self::Error> {
// let user = NaiveUser::new(command.id, command.first_name, command.last_name, command.email)?;
// self.repo.insert(&user);
//
// Ok(())
// }
//
// fn handles(&self) -> String {
// "CreateUserCommand".to_string()
// }
//}
//
//pub struct CommandGateway {
// // Hashmap key is a string version of the Command type.
// handlers: HashMap<String, Box<dyn GenericHandler>>,
//}
//
//impl MassHandler for CommandGateway {
// type Error = ValidationError;
//
// fn handle<T: Command + 'static>(&mut self, command: T) -> Result<(), Self::Error> {
// self.handlers.get_mut(&command.kind()).unwrap().handle(Box::new(command));
// Ok(())
// }
//
// fn register<T: Command + 'static, U: CommandHandler<T> + 'static>(&mut self, handler: U) -> Result<(), Self::Error> {
// self.handlers.insert(handler.handles(), Box::new(GenericHandle(Box::new(handler))));
// Ok(())
// }
//}
//
//impl CommandGateway {
// pub fn new() -> CommandGateway {
// CommandGateway {
// handlers: HashMap::new()
// }
// }
//
// // This normally wouldn't be here at all, but this is so we can get back a result in mock testing
// // The key in this case is the name of the command.
// pub fn contains_key(&self, key: String) -> bool {
// self.handlers.contains_key(&key)
// }
//}
//
//impl From<Vec<Box<dyn GenericHandler>>> for CommandGateway {
// fn from(handlers: Vec<Box<dyn GenericHandler>>) -> Self {
// let handlers_map: HashMap<String, Box<dyn GenericHandler>> = handlers.into_iter().map(|h| (h.handles(), h)).collect();
// CommandGateway {
// handlers: handlers_map,
// }
// }
//}