From 2fa92904a9a3a873112079e127e58f06b7cf9337 Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Wed, 6 Aug 2025 13:41:35 -0400 Subject: [PATCH] Got the document file responding to the addition. --- src/message.rs | 215 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 184 insertions(+), 31 deletions(-) diff --git a/src/message.rs b/src/message.rs index 5165ca6..cca8371 100644 --- a/src/message.rs +++ b/src/message.rs @@ -449,7 +449,7 @@ impl From<&RouteID> for Route { } #[cfg(test)] -mod roiutes { +mod routes { use super::*; #[test] @@ -909,7 +909,7 @@ impl CreateDoc { fn listen(&self) { loop { let msg = self.rx.recv().unwrap(); - Documents::start(self.queue.clone(), msg); + DocumentFile::start(self.queue.clone(), msg); } } } @@ -941,6 +941,12 @@ impl From for Field { } } +impl From<&str> for Field { + fn from(value: &str) -> Self { + Self::from(value.to_string()) + } +} + impl From for Field { fn from(value: Uuid) -> Self { Self::Uuid(value) @@ -963,7 +969,20 @@ mod fields { } #[test] - fn create_uuid() { + fn can_create_from_str() { + let holder = ["one", "two"]; + for data in holder.into_iter() { + let result: Field = data.into(); + match result.clone() { + Field::StaticString(output) => assert_eq!(output, data), + _ => unreachable!("got {:?}: should have been static string", result), + } + assert_eq!(result.get_type(), FieldType::StaticString); + } + } + + #[test] + fn create_from_uuid() { let data = Uuid::new_v4(); let result: Field = data.clone().into(); match result.clone() { @@ -974,7 +993,6 @@ mod fields { } } - #[derive(Clone, Debug)] struct FieldSetting { fieldtype: FieldType, @@ -982,9 +1000,7 @@ struct FieldSetting { impl FieldSetting { fn new(ftype: FieldType) -> Self { - Self { - fieldtype: ftype, - } + Self { fieldtype: ftype } } fn get_type(&self) -> &FieldType { @@ -1008,22 +1024,29 @@ mod fieldsettings { #[derive(Clone, Debug)] struct Addition { - data: HashMap, + data: Document, } impl Addition { fn new() -> Self { Self { - data: HashMap::new(), + data: Document::new(), } } - fn add_field(&mut self, name: String, field: F) where F: Into { - self.data.insert(name, field.into()); + fn add_field(&mut self, name: String, field: F) + where + F: Into, + { + self.data.add_field(name, field); } fn get_field(&self, name: &str) -> Option<&Field> { - self.data.get(name) + self.data.get_field(name) + } + + fn get_document(&self) -> Document { + self.data.clone() } } @@ -1055,6 +1078,18 @@ mod additions { _ => unreachable!("got {:?}: should have received uuid", result), } } + + fn can_get_document() { + let mut add = Addition::new(); + let name = Uuid::new_v4().to_string(); + let data = Uuid::new_v4(); + add.add_field(name.clone(), data.clone()); + let doc: Document = add.get_document(); + match doc.get_field(&name).unwrap() { + Field::Uuid(result) => assert_eq!(result, &data), + _ => unreachable!("should have received uuid"), + } + } } #[derive(Clone, Debug)] @@ -1064,7 +1099,9 @@ struct DocDef { impl DocDef { fn new() -> Self { - Self { fields: HashMap::new() } + Self { + fields: HashMap::new(), + } } fn add_field(&mut self, name: String, ftype: FieldType) { @@ -1074,7 +1111,7 @@ impl DocDef { fn get_field(&self, name: &str) -> Result<&FieldSetting, MTTError> { match self.fields.get(name) { Some(data) => Ok(data), - None => Err(MTTError::DocumentFieldNotFound(name.to_string())) + None => Err(MTTError::DocumentFieldNotFound(name.to_string())), } } } @@ -1131,15 +1168,33 @@ impl Query { } #[derive(Clone, Debug)] -struct Reply; +struct Reply { + data: Vec, +} impl Reply { fn new() -> Self { - Self {} + Self { data: Vec::new() } } - fn count(&self) -> usize { - 0 + fn add(&mut self, doc: Document) { + self.data.push(doc); + } + + fn len(&self) -> usize { + self.data.len() + } +} + +impl Iterator for Reply { + type Item = Document; + + fn next(&mut self) -> Option { + if self.data.len() > 0 { + Some(self.data.remove(0)) + } else { + None + } } } @@ -1150,10 +1205,47 @@ mod replies { #[test] fn is_new_empty() { let reply = Reply::new(); - assert_eq!(reply.count(), 0, "should have no records"); + assert_eq!(reply.len(), 0, "should have no records"); + } + + #[test] + fn can_add_documents() { + let mut reply = Reply::new(); + let doc = Document::new(); + reply.add(doc.clone()); + assert_eq!(reply.len(), 1); + reply.add(doc.clone()); + assert_eq!(reply.len(), 2); + } + + #[test] + fn can_retrieve_documents() { + let fieldname = "field".to_string(); + let mut doc1 = Document::new(); + doc1.add_field(fieldname.clone(), "one"); + let mut doc2 = Document::new(); + doc2.add_field(fieldname.clone(), "two"); + let mut reply = Reply::new(); + reply.add(doc1); + reply.add(doc2); + let result1 = reply.next().unwrap(); + match result1.get_field(&fieldname).unwrap() { + Field::StaticString(output) => assert_eq!(output, "one"), + _ => unreachable!("got {:?}: should have been static string", result1), + } + let result2 = reply.next().unwrap(); + match result2.get_field(&fieldname).unwrap() { + Field::StaticString(output) => assert_eq!(output, "two"), + _ => unreachable!("got {:?}: should have been static string", result2), + } + match reply.next() { + None => {} + Some(_) => unreachable!("should be out of data"), + } } } +#[derive(Clone, Debug)] struct Document { data: HashMap, } @@ -1164,14 +1256,55 @@ impl Document { data: HashMap::new(), } } + + fn add_field(&mut self, name: String, field: F) + where + F: Into, + { + self.data.insert(name, field.into()); + } + + fn get_field(&self, name: &str) -> Option<&Field> { + self.data.get(name) + } } -struct Documents { +#[cfg(test)] +mod documents { + use super::*; + + #[test] + fn can_add_static_string() { + let mut add = Document::new(); + let name = Uuid::new_v4().to_string(); + let data = Uuid::new_v4().to_string(); + add.add_field(name.clone(), data.clone()); + let result = add.get_field(&name).unwrap(); + match result { + Field::StaticString(result) => assert_eq!(result, &data), + _ => unreachable!("got {:?}: should have received static string", result), + } + } + + fn can_add_uuid() { + let mut add = Document::new(); + let name = Uuid::new_v4().to_string(); + let data = Uuid::new_v4(); + add.add_field(name.clone(), data.clone()); + let result = add.get_field(&name).unwrap(); + match result { + Field::Uuid(result) => assert_eq!(result, &data), + _ => unreachable!("got {:?}: should have received uuid", result), + } + } +} + +struct DocumentFile { queue: Queue, rx: Receiver, } -impl Documents { +impl DocumentFile { fn new(queue: Queue, rx: Receiver) -> Self { Self { queue: queue, @@ -1186,6 +1319,7 @@ impl Documents { NameID::ID(id) => id.to_string(), }; let routes = [ + RouteRequest::new(Include::All, Include::All, Include::Some(Action::Addition)), RouteRequest::new( Include::All, Include::Some(name.clone()), @@ -1206,7 +1340,7 @@ impl Documents { return; } } - let doc = Documents::new(queue.clone(), rx); + let mut doc = DocumentFile::new(queue.clone(), rx); spawn(move || { doc.listen(); }); @@ -1214,17 +1348,26 @@ impl Documents { queue.send(reply).unwrap(); } - fn listen(&self) { + fn listen(&mut self) { loop { let msg = self.rx.recv().unwrap(); - let reply = msg.reply(Reply::new()); - self.queue.send(reply).unwrap(); + let reply = match msg.get_action() { + MsgAction::Addition(data) => self.add_document(data), + _ => Reply::new(), + }; + self.queue.send(msg.reply(reply)).unwrap(); } } + + fn add_document(&mut self, new_doc: &Addition) -> Reply { + let mut reply = Reply::new(); + reply.add(new_doc.get_document()); + reply + } } #[cfg(test)] -mod documents { +mod document_files { use super::{support_test::TIMEOUT, *}; use std::sync::mpsc::RecvTimeoutError; @@ -1236,7 +1379,7 @@ mod documents { let (tx, rx) = channel(); let mut queue = Queue::new(); let msg = Message::new(name, docdef); - Documents::start(queue.clone(), msg); + DocumentFile::start(queue.clone(), msg); queue .register(tx, Uuid::new_v4().to_string(), routes) .unwrap(); @@ -1270,12 +1413,15 @@ mod documents { )] .to_vec(); let (queue, rx) = test_doc(name, docdef, routes); - let query = Message::new(name, Query::new()); + let query = Message::new(name, Query::new()); queue.send(query).unwrap(); let result = rx.recv_timeout(TIMEOUT).unwrap(); match result.get_action() { - MsgAction::Reply(data) => assert_eq!(data.count(), 0), - _ => unreachable!("got {:?}: should have received a reply", result.get_action()), + MsgAction::Reply(data) => assert_eq!(data.len(), 0), + _ => unreachable!( + "got {:?}: should have received a reply", + result.get_action() + ), } } @@ -1341,8 +1487,15 @@ mod documents { Include::Some(Action::Reply), )] .to_vec(); - let (mut queue, rx) = test_doc(name, docdef, routes); + let (queue, rx) = test_doc(name, docdef, routes); let msg = Message::new(name, Addition::new()); + queue.send(msg.clone()).unwrap(); + let result = rx.recv_timeout(TIMEOUT).unwrap(); + assert_eq!(result.get_message_id(), msg.get_message_id()); + match result.get_action() { + MsgAction::Reply(output) => assert_eq!(output.len(), 1), + _ => unreachable!("got {:?}: should have been a reply", result), + } // Finish the test. // Need to add addition message. }