diff --git a/src/message.rs b/src/message.rs index 80a6d0f..d371ea4 100644 --- a/src/message.rs +++ b/src/message.rs @@ -215,6 +215,14 @@ impl Message { &self.action } + fn response(&self, action: A) -> Self where A: Into { + Self { + msg_id: self.msg_id.clone(), + document_id: self.document_id.clone(), + action: action.into(), + } + } + fn reply(&self, resp: Reply) -> Self { Self { msg_id: self.msg_id.clone(), @@ -330,6 +338,32 @@ mod messages { _ => unreachable!("should have been a reply"), } } + + #[test] + fn can_make_a_response_message() { + let doc_id = Uuid::new_v4(); + let msg = Message::new(doc_id.clone(), MsgAction::Query(Query::new())); + let data = Uuid::new_v4().to_string(); + let result1 = msg.response(MTTError::DocumentNotFound(data.clone())); + let result2 = msg.response(Reply::new()); + assert_eq!(result1.get_message_id(), msg.get_message_id()); + assert_eq!(result2.get_message_id(), msg.get_message_id()); + assert_eq!(result1.get_document_id(), msg.get_document_id()); + assert_eq!(result2.get_document_id(), msg.get_document_id()); + let action1 = result1.get_action(); + match action1 { + MsgAction::Error(err) => match err { + MTTError::DocumentNotFound(output) => assert_eq!(output, &data), + _ => unreachable!("got {:?}: should have received document not found", err), + }, + _ => unreachable!("got {:?}: should have received error", action1), + } + let action2 = result2.get_action(); + match action2 { + MsgAction::Reply(data) => assert_eq!(data.len(), 0), + _ => unreachable!("got {:?}: should have received a reply", action2), + } + } } #[derive(Clone, Debug)] @@ -1243,6 +1277,8 @@ mod replies { } } +type DocumentMap = HashMap; + #[derive(Clone, Debug)] struct Document { data: HashMap, @@ -1267,6 +1303,15 @@ impl Document { } } +impl<'a> IntoIterator for &'a Document { + type Item = <&'a DocumentMap as IntoIterator>::Item; + type IntoIter = <&'a DocumentMap as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + (&self.data).into_iter() + } +} + #[cfg(test)] mod documents { use super::*; @@ -1298,14 +1343,16 @@ mod documents { } struct DocumentFile { + docdef: DocDef, docs: Vec, queue: Queue, rx: Receiver, } impl DocumentFile { - fn new(queue: Queue, rx: Receiver) -> Self { + fn new(queue: Queue, rx: Receiver, docdef: DocDef) -> Self { Self { + docdef: docdef, docs: Vec::new(), queue: queue, rx: rx, @@ -1344,7 +1391,12 @@ impl DocumentFile { return; } } - let mut doc = DocumentFile::new(queue.clone(), rx); + let action = msg.get_action(); + let docdef = match action { + MsgAction::Create(data) => data.clone(), + _ => unreachable!("got {:?}: should have been a create message", action), + }; + let mut doc = DocumentFile::new(queue.clone(), rx, docdef); spawn(move || { doc.listen(); }); @@ -1355,29 +1407,35 @@ impl DocumentFile { fn listen(&mut self) { loop { let msg = self.rx.recv().unwrap(); - let reply = match msg.get_action() { + let result = match msg.get_action() { MsgAction::Addition(data) => self.add_document(data), MsgAction::Query(query) => self.query(query), - _ => Reply::new(), + _ => Reply::new().into(), }; - self.queue.send(msg.reply(reply)).unwrap(); + self.queue.send(msg.response(result)).unwrap(); } } - fn add_document(&mut self, addition: &Addition) -> Reply { + fn add_document(&mut self, addition: &Addition) -> MsgAction { let mut reply = Reply::new(); let doc = addition.get_document(); + for (key, value) in doc.into_iter() { + match self.docdef.get_field(&key) { + Err(err) => return err.into(), + Ok(_) => {}, + } + } self.docs.push(doc.clone()); reply.add(doc); - reply + reply.into() } - fn query(&self, query: &Query) -> Reply { + fn query(&self, query: &Query) -> MsgAction { let mut reply = Reply::new(); for doc in self.docs.iter() { reply.add(doc.clone()); } - reply + reply.into() } } @@ -1394,6 +1452,14 @@ mod document_files { .to_vec() } + fn create_docdef(num: usize) -> DocDef { + let mut output = DocDef::new(); + for count in 0..num { + output.add_field(format!("field{}", count), FieldType::Uuid); + } + output + } + fn test_doc( name: &str, docdef: DocDef, @@ -1590,6 +1656,25 @@ mod document_files { _ => unreachable!("got {:?}: should have been a reply", result.get_action()), } } + + #[test] + fn errors_on_wrong_field_name() { + let doc_name = "mismatch"; + let field_name = Uuid::new_v4().to_string(); + let (queue, rx) = test_doc(doc_name, create_docdef(1), standard_routes()); + let mut addition = Addition::new(); + addition.add_field(field_name.clone(), Uuid::new_v4()); + let msg = Message::new(doc_name, addition); + queue.send(msg).unwrap(); + let result = rx.recv_timeout(TIMEOUT).unwrap(); + match result.get_action() { + MsgAction::Error(err) => match err { + MTTError::DocumentFieldNotFound(data) => assert_eq!(data, &field_name), + _ => unreachable!("got {:?}: should have been document field not found.", err), + } + _ => unreachable!("got {:?}: should have been an error", result.get_action()), + } + } } #[cfg(test)]