Added basic field definitions.

This commit is contained in:
Jeff Baskin 2025-08-05 09:56:48 -04:00
parent ad094b23f3
commit 20f798043f

View File

@ -24,6 +24,7 @@ enum MTTError {
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
enum Action {
Addition,
Create,
Error,
Query,
@ -34,6 +35,7 @@ enum Action {
impl From<MsgAction> for Action {
fn from(value: MsgAction) -> Self {
match value {
MsgAction::Addition(_) => Action::Addition,
MsgAction::Create(_) => Action::Create,
MsgAction::Error(_) => Action::Error,
MsgAction::Query(_) => Action::Query,
@ -82,17 +84,23 @@ impl From<&NameID> for NameID {
#[derive(Clone, Debug)]
enum MsgAction {
Addition(Addition),
Create(DocDef),
// Alter
// Remove
Error(MTTError),
Query(Access),
Reply(Response),
Query(Query),
Reply(Reply),
Show,
// Add
// Delete
}
impl From<Addition> for MsgAction {
fn from(value: Addition) -> Self {
MsgAction::Addition(value)
}
}
impl From<DocDef> for MsgAction {
fn from(value: DocDef) -> Self {
MsgAction::Create(value)
@ -105,14 +113,14 @@ impl From<MTTError> for MsgAction {
}
}
impl From<Access> for MsgAction {
fn from(value: Access) -> Self {
impl From<Query> for MsgAction {
fn from(value: Query) -> Self {
MsgAction::Query(value)
}
}
impl From<Response> for MsgAction {
fn from(value: Response) -> Self {
impl From<Reply> for MsgAction {
fn from(value: Reply) -> Self {
MsgAction::Reply(value)
}
}
@ -156,7 +164,7 @@ mod msgactions {
#[test]
fn turn_query_into_action() {
let value = Access::new();
let value = Query::new();
let result: MsgAction = value.into();
match result {
MsgAction::Query(_) => {}
@ -166,7 +174,7 @@ mod msgactions {
#[test]
fn turn_reply_into_action() {
let value = Response::new();
let value = Reply::new();
let result: MsgAction = value.into();
match result {
MsgAction::Reply(_) => {}
@ -207,7 +215,7 @@ impl Message {
&self.action
}
fn reply(&self, resp: Response) -> Self {
fn reply(&self, resp: Reply) -> Self {
Self {
msg_id: self.msg_id.clone(),
document_id: self.document_id.clone(),
@ -248,7 +256,7 @@ mod messages {
fn can_the_document_be_a_string() {
let dts = ["one".to_string(), "two".to_string()];
for document in dts.into_iter() {
let msg = Message::new(document.clone(), MsgAction::Query(Access::new()));
let msg = Message::new(document.clone(), MsgAction::Query(Query::new()));
match msg.get_document_id() {
NameID::ID(_) => unreachable!("should have been a string id"),
NameID::Name(data) => assert_eq!(data, &document),
@ -263,7 +271,7 @@ mod messages {
#[test]
fn can_the_document_be_an_id() {
let document = Uuid::new_v4();
let msg = Message::new(document.clone(), MsgAction::Query(Access::new()));
let msg = Message::new(document.clone(), MsgAction::Query(Query::new()));
match msg.get_document_id() {
NameID::ID(data) => assert_eq!(data, &document),
NameID::Name(_) => unreachable!("should have been an id"),
@ -288,8 +296,8 @@ mod messages {
#[test]
fn Can_make_reply_message() {
let name = "testing";
let msg = Message::new(name, MsgAction::Query(Access::new()));
let responce = Response::new();
let msg = Message::new(name, MsgAction::Query(Query::new()));
let responce = Reply::new();
let reply = msg.reply(responce);
assert_eq!(reply.get_message_id(), msg.get_message_id());
match reply.get_document_id() {
@ -305,7 +313,7 @@ mod messages {
#[test]
fn Can_make_error_message() {
let name = "testing";
let msg = Message::new(name, MsgAction::Query(Access::new()));
let msg = Message::new(name, MsgAction::Query(Query::new()));
let err_msg = Uuid::new_v4().to_string();
let result = msg.error(MTTError::DocumentNotFound(err_msg.clone()));
@ -674,8 +682,8 @@ mod queuedatas {
]
.to_vec();
queuedata.register(tx, name.clone(), routes).unwrap();
let msg1 = Message::new(name.clone(), MsgAction::Query(Access::new()));
let msg2 = Message::new(name.clone(), MsgAction::Reply(Response::new()));
let msg1 = Message::new(name.clone(), MsgAction::Query(Query::new()));
let msg2 = Message::new(name.clone(), MsgAction::Reply(Reply::new()));
let msg3 = Message::new(name.clone(), MsgAction::Create(DocDef::new()));
queuedata.send(msg1.clone()).unwrap();
queuedata.send(msg2.clone()).unwrap();
@ -778,7 +786,7 @@ mod queuedatas {
fn does_a_bad_document_name_fail() {
let docname = Uuid::new_v4().to_string();
let queuedata = QueueData::new();
let msg = Message::new(docname.clone(), MsgAction::Query(Access::new()));
let msg = Message::new(docname.clone(), MsgAction::Query(Query::new()));
match queuedata.send(msg) {
Ok(_) => unreachable!("should have been an error"),
Err(data) => match data {
@ -808,7 +816,7 @@ mod queuedatas {
let mut queuedata = QueueData::new();
let name1 = "task";
let name2 = "work";
let action = MsgAction::Query(Access::new());
let action = MsgAction::Query(Query::new());
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
let routes = [RouteRequest::new(
@ -901,7 +909,7 @@ impl CreateDoc {
fn listen(&self) {
loop {
let msg = self.rx.recv().unwrap();
Document::start(self.queue.clone(), msg);
Documents::start(self.queue.clone(), msg);
}
}
}
@ -909,9 +917,35 @@ impl CreateDoc {
#[derive(Clone, Debug, PartialEq)]
enum FieldType {
StaticString,
UUID,
Uuid,
}
enum Field {
StaticString(String),
Uuid(Uuid),
}
impl Field {
fn get_type(&self) -> FieldType {
match self {
Self::StaticString(_) => FieldType::StaticString,
}
}
}
#[cfg(test)]
mod fields {
use super::*;
#[test]
fn can_create_static_string() {
let data = Uuid::new_v4();
let sstring = Field::StaticString(data.to_string());
assert_eq!(sstring.get_type(), FieldType::StaticString);
}
}
#[derive(Clone, Debug)]
struct FieldSetting {
fieldtype: FieldType,
@ -935,7 +969,7 @@ mod fieldsettings {
#[test]
fn can_field_type_be_assigned() {
let ftypes = [FieldType::StaticString, FieldType::UUID];
let ftypes = [FieldType::StaticString, FieldType::Uuid];
for ftype in ftypes.into_iter() {
let fieldinfo = FieldSetting::new(ftype.clone());
assert_eq!(fieldinfo.get_type(), &ftype);
@ -943,6 +977,15 @@ mod fieldsettings {
}
}
#[derive(Clone, Debug)]
struct Addition;
impl Addition {
fn new() -> Self {
Self {}
}
}
#[derive(Clone, Debug)]
struct DocDef {
fields: HashMap<String, FieldSetting>,
@ -973,7 +1016,7 @@ mod docdefs {
fn can_field_be_added() {
let mut docdef = DocDef::new();
let name = Uuid::new_v4().to_string();
let field_type = FieldType::UUID;
let field_type = FieldType::Uuid;
docdef.add_field(name.clone(), field_type.clone());
let result = docdef.get_field(name.as_str()).unwrap();
assert_eq!(result.get_type(), &field_type);
@ -1008,29 +1051,56 @@ mod docdefs {
}
#[derive(Clone, Debug)]
struct Access;
struct Query;
impl Access {
impl Query {
fn new() -> Self {
Self {}
}
}
#[derive(Clone, Debug)]
struct Response;
struct Reply;
impl Response {
impl Reply {
fn new() -> Self {
Self {}
}
fn count(&self) -> usize {
0
}
}
#[cfg(test)]
mod replies {
use super::*;
#[test]
fn is_new_empty() {
let reply = Reply::new();
assert_eq!(reply.count(), 0, "should have no records");
}
}
struct Document {
data: HashMap<String, Field>,
}
impl Document {
fn new() -> Self {
Self {
data: HashMap::new(),
}
}
}
struct Documents {
queue: Queue,
rx: Receiver<Message>,
}
impl Document {
impl Documents {
fn new(queue: Queue, rx: Receiver<Message>) -> Self {
Self {
queue: queue,
@ -1065,18 +1135,18 @@ impl Document {
return;
}
}
let doc = Document::new(queue.clone(), rx);
let doc = Documents::new(queue.clone(), rx);
spawn(move || {
doc.listen();
});
let reply = msg.reply(Response::new());
let reply = msg.reply(Reply::new());
queue.send(reply).unwrap();
}
fn listen(&self) {
loop {
let msg = self.rx.recv().unwrap();
let reply = msg.reply(Response::new());
let reply = msg.reply(Reply::new());
self.queue.send(reply).unwrap();
}
}
@ -1095,7 +1165,7 @@ mod documents {
let (tx, rx) = channel();
let mut queue = Queue::new();
let msg = Message::new(name, docdef);
Document::start(queue.clone(), msg);
Documents::start(queue.clone(), msg);
queue
.register(tx, Uuid::new_v4().to_string(), routes)
.unwrap();
@ -1118,6 +1188,26 @@ mod documents {
let show = rx.recv_timeout(TIMEOUT).unwrap();
}
#[test]
fn can_query_new_document() {
let docdef = DocDef::new();
let name = "second";
let routes = [RouteRequest::new(
Include::All,
Include::All,
Include::Some(Action::Reply),
)]
.to_vec();
let (queue, rx) = test_doc(name, docdef, routes);
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()),
}
}
#[test]
fn only_responses_to_its_show_request() {
let docdef = DocDef::new();
@ -1142,6 +1232,49 @@ mod documents {
},
}
}
#[test]
fn only_responses_to_its_query_request() {
let docdef = DocDef::new();
let name = "quiet";
let routes = [RouteRequest::new(
Include::All,
Include::All,
Include::Some(Action::Reply),
)]
.to_vec();
let (mut queue, rx) = test_doc(name, docdef, routes);
let other = "alternate";
let (tx, _) = channel();
queue.register(tx, other.to_string(), Vec::new()).unwrap();
let msg = Message::new(other, Query::new());
queue.send(msg).unwrap();
match rx.recv_timeout(TIMEOUT) {
Ok(msg) => unreachable!("should not receive: {:?}", msg),
Err(err) => match err {
RecvTimeoutError::Timeout => {}
_ => unreachable!("should have timed out"),
},
}
}
#[test]
fn can_document_be_added() {
let mut docdef = DocDef::new();
let name = "field";
let data = Uuid::new_v4();
docdef.add_field(name.to_string(), FieldType::Uuid);
let routes = [RouteRequest::new(
Include::All,
Include::All,
Include::Some(Action::Reply),
)]
.to_vec();
let (mut queue, rx) = test_doc(name, docdef, routes);
let msg = Message::new(name, Addition::new());
// Finish the test.
// Need to add addition message.
}
}
#[cfg(test)]
@ -1178,7 +1311,7 @@ mod createdocs {
MsgAction::Reply(_) => {}
_ => unreachable!("got {:?}: should have been a reply.", result1.get_action()),
}
let msg2 = Message::new(name, MsgAction::Query(Access::new()));
let msg2 = Message::new(name, MsgAction::Query(Query::new()));
queue.send(msg2.clone()).unwrap();
let result2 = rx.recv_timeout(TIMEOUT).unwrap();
assert_eq!(result2.get_message_id(), msg2.get_message_id());