Added basic field definitions.
This commit is contained in:
parent
ad094b23f3
commit
20f798043f
199
src/message.rs
199
src/message.rs
@ -24,6 +24,7 @@ enum MTTError {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||||
enum Action {
|
enum Action {
|
||||||
|
Addition,
|
||||||
Create,
|
Create,
|
||||||
Error,
|
Error,
|
||||||
Query,
|
Query,
|
||||||
@ -34,6 +35,7 @@ enum Action {
|
|||||||
impl From<MsgAction> for Action {
|
impl From<MsgAction> for Action {
|
||||||
fn from(value: MsgAction) -> Self {
|
fn from(value: MsgAction) -> Self {
|
||||||
match value {
|
match value {
|
||||||
|
MsgAction::Addition(_) => Action::Addition,
|
||||||
MsgAction::Create(_) => Action::Create,
|
MsgAction::Create(_) => Action::Create,
|
||||||
MsgAction::Error(_) => Action::Error,
|
MsgAction::Error(_) => Action::Error,
|
||||||
MsgAction::Query(_) => Action::Query,
|
MsgAction::Query(_) => Action::Query,
|
||||||
@ -82,17 +84,23 @@ impl From<&NameID> for NameID {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum MsgAction {
|
enum MsgAction {
|
||||||
|
Addition(Addition),
|
||||||
Create(DocDef),
|
Create(DocDef),
|
||||||
// Alter
|
// Alter
|
||||||
// Remove
|
// Remove
|
||||||
Error(MTTError),
|
Error(MTTError),
|
||||||
Query(Access),
|
Query(Query),
|
||||||
Reply(Response),
|
Reply(Reply),
|
||||||
Show,
|
Show,
|
||||||
// Add
|
|
||||||
// Delete
|
// Delete
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Addition> for MsgAction {
|
||||||
|
fn from(value: Addition) -> Self {
|
||||||
|
MsgAction::Addition(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<DocDef> for MsgAction {
|
impl From<DocDef> for MsgAction {
|
||||||
fn from(value: DocDef) -> Self {
|
fn from(value: DocDef) -> Self {
|
||||||
MsgAction::Create(value)
|
MsgAction::Create(value)
|
||||||
@ -105,14 +113,14 @@ impl From<MTTError> for MsgAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Access> for MsgAction {
|
impl From<Query> for MsgAction {
|
||||||
fn from(value: Access) -> Self {
|
fn from(value: Query) -> Self {
|
||||||
MsgAction::Query(value)
|
MsgAction::Query(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Response> for MsgAction {
|
impl From<Reply> for MsgAction {
|
||||||
fn from(value: Response) -> Self {
|
fn from(value: Reply) -> Self {
|
||||||
MsgAction::Reply(value)
|
MsgAction::Reply(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,7 +164,7 @@ mod msgactions {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn turn_query_into_action() {
|
fn turn_query_into_action() {
|
||||||
let value = Access::new();
|
let value = Query::new();
|
||||||
let result: MsgAction = value.into();
|
let result: MsgAction = value.into();
|
||||||
match result {
|
match result {
|
||||||
MsgAction::Query(_) => {}
|
MsgAction::Query(_) => {}
|
||||||
@ -166,7 +174,7 @@ mod msgactions {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn turn_reply_into_action() {
|
fn turn_reply_into_action() {
|
||||||
let value = Response::new();
|
let value = Reply::new();
|
||||||
let result: MsgAction = value.into();
|
let result: MsgAction = value.into();
|
||||||
match result {
|
match result {
|
||||||
MsgAction::Reply(_) => {}
|
MsgAction::Reply(_) => {}
|
||||||
@ -207,7 +215,7 @@ impl Message {
|
|||||||
&self.action
|
&self.action
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reply(&self, resp: Response) -> Self {
|
fn reply(&self, resp: Reply) -> Self {
|
||||||
Self {
|
Self {
|
||||||
msg_id: self.msg_id.clone(),
|
msg_id: self.msg_id.clone(),
|
||||||
document_id: self.document_id.clone(),
|
document_id: self.document_id.clone(),
|
||||||
@ -248,7 +256,7 @@ mod messages {
|
|||||||
fn can_the_document_be_a_string() {
|
fn can_the_document_be_a_string() {
|
||||||
let dts = ["one".to_string(), "two".to_string()];
|
let dts = ["one".to_string(), "two".to_string()];
|
||||||
for document in dts.into_iter() {
|
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() {
|
match msg.get_document_id() {
|
||||||
NameID::ID(_) => unreachable!("should have been a string id"),
|
NameID::ID(_) => unreachable!("should have been a string id"),
|
||||||
NameID::Name(data) => assert_eq!(data, &document),
|
NameID::Name(data) => assert_eq!(data, &document),
|
||||||
@ -263,7 +271,7 @@ mod messages {
|
|||||||
#[test]
|
#[test]
|
||||||
fn can_the_document_be_an_id() {
|
fn can_the_document_be_an_id() {
|
||||||
let document = Uuid::new_v4();
|
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() {
|
match msg.get_document_id() {
|
||||||
NameID::ID(data) => assert_eq!(data, &document),
|
NameID::ID(data) => assert_eq!(data, &document),
|
||||||
NameID::Name(_) => unreachable!("should have been an id"),
|
NameID::Name(_) => unreachable!("should have been an id"),
|
||||||
@ -288,8 +296,8 @@ mod messages {
|
|||||||
#[test]
|
#[test]
|
||||||
fn Can_make_reply_message() {
|
fn Can_make_reply_message() {
|
||||||
let name = "testing";
|
let name = "testing";
|
||||||
let msg = Message::new(name, MsgAction::Query(Access::new()));
|
let msg = Message::new(name, MsgAction::Query(Query::new()));
|
||||||
let responce = Response::new();
|
let responce = Reply::new();
|
||||||
let reply = msg.reply(responce);
|
let reply = msg.reply(responce);
|
||||||
assert_eq!(reply.get_message_id(), msg.get_message_id());
|
assert_eq!(reply.get_message_id(), msg.get_message_id());
|
||||||
match reply.get_document_id() {
|
match reply.get_document_id() {
|
||||||
@ -305,7 +313,7 @@ mod messages {
|
|||||||
#[test]
|
#[test]
|
||||||
fn Can_make_error_message() {
|
fn Can_make_error_message() {
|
||||||
let name = "testing";
|
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 err_msg = Uuid::new_v4().to_string();
|
||||||
let result = msg.error(MTTError::DocumentNotFound(err_msg.clone()));
|
let result = msg.error(MTTError::DocumentNotFound(err_msg.clone()));
|
||||||
|
|
||||||
@ -674,8 +682,8 @@ mod queuedatas {
|
|||||||
]
|
]
|
||||||
.to_vec();
|
.to_vec();
|
||||||
queuedata.register(tx, name.clone(), routes).unwrap();
|
queuedata.register(tx, name.clone(), routes).unwrap();
|
||||||
let msg1 = Message::new(name.clone(), MsgAction::Query(Access::new()));
|
let msg1 = Message::new(name.clone(), MsgAction::Query(Query::new()));
|
||||||
let msg2 = Message::new(name.clone(), MsgAction::Reply(Response::new()));
|
let msg2 = Message::new(name.clone(), MsgAction::Reply(Reply::new()));
|
||||||
let msg3 = Message::new(name.clone(), MsgAction::Create(DocDef::new()));
|
let msg3 = Message::new(name.clone(), MsgAction::Create(DocDef::new()));
|
||||||
queuedata.send(msg1.clone()).unwrap();
|
queuedata.send(msg1.clone()).unwrap();
|
||||||
queuedata.send(msg2.clone()).unwrap();
|
queuedata.send(msg2.clone()).unwrap();
|
||||||
@ -778,7 +786,7 @@ mod queuedatas {
|
|||||||
fn does_a_bad_document_name_fail() {
|
fn does_a_bad_document_name_fail() {
|
||||||
let docname = Uuid::new_v4().to_string();
|
let docname = Uuid::new_v4().to_string();
|
||||||
let queuedata = QueueData::new();
|
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) {
|
match queuedata.send(msg) {
|
||||||
Ok(_) => unreachable!("should have been an error"),
|
Ok(_) => unreachable!("should have been an error"),
|
||||||
Err(data) => match data {
|
Err(data) => match data {
|
||||||
@ -808,7 +816,7 @@ mod queuedatas {
|
|||||||
let mut queuedata = QueueData::new();
|
let mut queuedata = QueueData::new();
|
||||||
let name1 = "task";
|
let name1 = "task";
|
||||||
let name2 = "work";
|
let name2 = "work";
|
||||||
let action = MsgAction::Query(Access::new());
|
let action = MsgAction::Query(Query::new());
|
||||||
let (tx1, rx1) = channel();
|
let (tx1, rx1) = channel();
|
||||||
let (tx2, rx2) = channel();
|
let (tx2, rx2) = channel();
|
||||||
let routes = [RouteRequest::new(
|
let routes = [RouteRequest::new(
|
||||||
@ -901,7 +909,7 @@ impl CreateDoc {
|
|||||||
fn listen(&self) {
|
fn listen(&self) {
|
||||||
loop {
|
loop {
|
||||||
let msg = self.rx.recv().unwrap();
|
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)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
enum FieldType {
|
enum FieldType {
|
||||||
StaticString,
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
struct FieldSetting {
|
struct FieldSetting {
|
||||||
fieldtype: FieldType,
|
fieldtype: FieldType,
|
||||||
@ -935,7 +969,7 @@ mod fieldsettings {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_field_type_be_assigned() {
|
fn can_field_type_be_assigned() {
|
||||||
let ftypes = [FieldType::StaticString, FieldType::UUID];
|
let ftypes = [FieldType::StaticString, FieldType::Uuid];
|
||||||
for ftype in ftypes.into_iter() {
|
for ftype in ftypes.into_iter() {
|
||||||
let fieldinfo = FieldSetting::new(ftype.clone());
|
let fieldinfo = FieldSetting::new(ftype.clone());
|
||||||
assert_eq!(fieldinfo.get_type(), &ftype);
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
struct DocDef {
|
struct DocDef {
|
||||||
fields: HashMap<String, FieldSetting>,
|
fields: HashMap<String, FieldSetting>,
|
||||||
@ -973,7 +1016,7 @@ mod docdefs {
|
|||||||
fn can_field_be_added() {
|
fn can_field_be_added() {
|
||||||
let mut docdef = DocDef::new();
|
let mut docdef = DocDef::new();
|
||||||
let name = Uuid::new_v4().to_string();
|
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());
|
docdef.add_field(name.clone(), field_type.clone());
|
||||||
let result = docdef.get_field(name.as_str()).unwrap();
|
let result = docdef.get_field(name.as_str()).unwrap();
|
||||||
assert_eq!(result.get_type(), &field_type);
|
assert_eq!(result.get_type(), &field_type);
|
||||||
@ -1008,29 +1051,56 @@ mod docdefs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct Access;
|
struct Query;
|
||||||
|
|
||||||
impl Access {
|
impl Query {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {}
|
Self {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct Response;
|
struct Reply;
|
||||||
|
|
||||||
impl Response {
|
impl Reply {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
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 {
|
struct Document {
|
||||||
|
data: HashMap<String, Field>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Document {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
data: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Documents {
|
||||||
queue: Queue,
|
queue: Queue,
|
||||||
rx: Receiver<Message>,
|
rx: Receiver<Message>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Document {
|
impl Documents {
|
||||||
fn new(queue: Queue, rx: Receiver<Message>) -> Self {
|
fn new(queue: Queue, rx: Receiver<Message>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
queue: queue,
|
queue: queue,
|
||||||
@ -1065,18 +1135,18 @@ impl Document {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let doc = Document::new(queue.clone(), rx);
|
let doc = Documents::new(queue.clone(), rx);
|
||||||
spawn(move || {
|
spawn(move || {
|
||||||
doc.listen();
|
doc.listen();
|
||||||
});
|
});
|
||||||
let reply = msg.reply(Response::new());
|
let reply = msg.reply(Reply::new());
|
||||||
queue.send(reply).unwrap();
|
queue.send(reply).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn listen(&self) {
|
fn listen(&self) {
|
||||||
loop {
|
loop {
|
||||||
let msg = self.rx.recv().unwrap();
|
let msg = self.rx.recv().unwrap();
|
||||||
let reply = msg.reply(Response::new());
|
let reply = msg.reply(Reply::new());
|
||||||
self.queue.send(reply).unwrap();
|
self.queue.send(reply).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1095,7 +1165,7 @@ mod documents {
|
|||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
let mut queue = Queue::new();
|
let mut queue = Queue::new();
|
||||||
let msg = Message::new(name, docdef);
|
let msg = Message::new(name, docdef);
|
||||||
Document::start(queue.clone(), msg);
|
Documents::start(queue.clone(), msg);
|
||||||
queue
|
queue
|
||||||
.register(tx, Uuid::new_v4().to_string(), routes)
|
.register(tx, Uuid::new_v4().to_string(), routes)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1118,6 +1188,26 @@ mod documents {
|
|||||||
let show = rx.recv_timeout(TIMEOUT).unwrap();
|
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]
|
#[test]
|
||||||
fn only_responses_to_its_show_request() {
|
fn only_responses_to_its_show_request() {
|
||||||
let docdef = DocDef::new();
|
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)]
|
#[cfg(test)]
|
||||||
@ -1178,7 +1311,7 @@ mod createdocs {
|
|||||||
MsgAction::Reply(_) => {}
|
MsgAction::Reply(_) => {}
|
||||||
_ => unreachable!("got {:?}: should have been a reply.", result1.get_action()),
|
_ => 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();
|
queue.send(msg2.clone()).unwrap();
|
||||||
let result2 = rx.recv_timeout(TIMEOUT).unwrap();
|
let result2 = rx.recv_timeout(TIMEOUT).unwrap();
|
||||||
assert_eq!(result2.get_message_id(), msg2.get_message_id());
|
assert_eq!(result2.get_message_id(), msg2.get_message_id());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user