diff --git a/src/message.rs b/src/message.rs index 5a6c180..30d2c73 100644 --- a/src/message.rs +++ b/src/message.rs @@ -462,6 +462,41 @@ impl From for RouteID { } } +#[derive(Clone, Debug)] +enum NameType { + ID(Uuid), + Name(Name), + None, +} + +impl From for NameType { + fn from(value: Name) -> Self { + Self::Name(value) + } +} + +impl From for NameType { + fn from(value: Uuid) -> Self { + Self::ID(value) + } +} + +struct Path { + msg_id: Include, + doc: Include, + action: Include, +} + +impl Path { + fn new(id: Include, doc: Include, action: Include) -> Self { + Self { + msg_id: id, + doc: doc, + action: action, + } + } +} + #[derive(Clone, Debug, Eq, Hash, PartialEq)] struct Name { name: String, @@ -554,6 +589,30 @@ impl Names { None => Err(MTTError::NameNotFound(name.clone())), } } + + fn path_to_route(&self, path: Path) -> Result { + let doc_id = match path.doc { + Include::Some(id_info) => match id_info { + NameType::ID(id) => { + if self.ids.contains_key(&id) { + Include::Some(id) + } else { + return Err(MTTError::NameInvalidID(id.clone())); + } + } + NameType::Name(name) => { + let id = match self.get_id(&name) { + Ok(data) => data, + Err(err) => return Err(err), + }; + Include::Some(id.clone()) + } + NameType::None => Include::Some(Uuid::nil()), + }, + Include::All => Include::All, + }; + Ok(Route::new(path.msg_id, doc_id, path.action)) + } } #[cfg(test)] @@ -709,6 +768,119 @@ mod names { }, } } + + #[test] + fn convert_path_to_route_with_ids() { + let mut names = Names::new(); + let data = "data".to_string(); + let english = Name::english(data.clone()); + let id = names.add_name(english.clone()).unwrap(); + let msg_id = Uuid::new_v4(); + let action = Action::Query; + let path = Path::new( + Include::Some(msg_id.clone()), + Include::Some(id.into()), + Include::Some(action.clone()), + ); + let result = names.path_to_route(path).unwrap(); + assert_eq!(result.msg_id, Include::Some(msg_id)); + assert_eq!(result.doc_type, Include::Some(id)); + assert_eq!(result.action, Include::Some(action)); + } + + #[test] + fn convert_path_name_to_route() { + let mut names = Names::new(); + let data = "data".to_string(); + let english = Name::english(data.clone()); + let id = names.add_name(english.clone()).unwrap(); + let msg_id = Uuid::new_v4(); + let action = Action::Error; + let path = Path::new( + Include::Some(msg_id.clone()), + Include::Some(english.into()), + Include::Some(action.clone()), + ); + let result = names.path_to_route(path).unwrap(); + assert_eq!(result.msg_id, Include::Some(msg_id)); + assert_eq!(result.doc_type, Include::Some(id)); + assert_eq!(result.action, Include::Some(action)); + } + + #[test] + fn convert_path_with_no_document_to_route() { + let mut names = Names::new(); + let msg_id = Uuid::new_v4(); + let action = Action::Show; + let path = Path::new( + Include::Some(msg_id.clone()), + Include::Some(NameType::None), + Include::Some(action.clone()), + ); + let result = names.path_to_route(path).unwrap(); + assert_eq!(result.msg_id, Include::Some(msg_id)); + assert_eq!(result.doc_type, Include::Some(Uuid::nil())); + assert_eq!(result.action, Include::Some(action)); + } + + #[test] + fn convert_path_to_route_all_documents() { + let mut names = Names::new(); + let msg_id = Uuid::new_v4(); + let action = Action::Query; + let path = Path::new( + Include::Some(msg_id.clone()), + Include::All, + Include::Some(action.clone()), + ); + let result = names.path_to_route(path).unwrap(); + assert_eq!(result.msg_id, Include::Some(msg_id)); + match result.doc_type { + Include::All => {} + Include::Some(_) => unreachable!("should return all"), + } + assert_eq!(result.action, Include::Some(action)); + } + + #[test] + fn convert_path_with_bad_id() { + let mut names = Names::new(); + let msg_id = Uuid::new_v4(); + let id = Uuid::new_v4(); + let action = Action::Query; + let path = Path::new( + Include::Some(msg_id.clone()), + Include::Some(id.into()), + Include::Some(action.clone()), + ); + match names.path_to_route(path) { + Ok(data) => unreachable!("got {:?}, should have been an error", data), + Err(err) => match err { + MTTError::NameInvalidID(output) => assert_eq!(output, id), + _ => unreachable!("got {:?}, should have gotten invalid id", err), + }, + } + } + + #[test] + fn convert_path_with_bad_name() { + let mut names = Names::new(); + let msg_id = Uuid::new_v4(); + let name = Name::english("wrong".to_string()); + let action = Action::Query; + let path = Path::new( + Include::Some(msg_id.clone()), + Include::Some(name.clone().into()), + Include::Some(action.clone()), + ); + match names.path_to_route(path) { + Ok(data) => unreachable!("got {:?}, should have been an error", data), + Err(err) => match err { + MTTError::NameNotFound(output) => assert_eq!(output, name), + _ => unreachable!("got {:?}, should have gotten invalid id", err), + }, + } + } } #[derive(Clone, Debug)] @@ -883,7 +1055,7 @@ mod routes { } } -#[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] struct RouteRequest { msg_id: Include, doc_name: Include, @@ -1201,7 +1373,7 @@ struct DocRegistry { doc_names: Vec, queue: Queue, receiver: Receiver, - routes: HashMap, + routes: HashMap, } impl DocRegistry { @@ -1248,8 +1420,8 @@ impl DocRegistry { } } RegMsg::AddRoute(route) => { - self.routes - .insert(route.clone(), reg.get_sender_id().clone()); + //self.routes + // .insert(route.into(), reg.get_sender_id().clone()); reg.response(RegMsg::Ok) } _ => reg.response(RegMsg::Ok),