Added names structure to establish routes.
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1s
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1s
This commit is contained in:
parent
7ba0740ce5
commit
3490116775
329
src/message.rs
329
src/message.rs
@ -27,6 +27,10 @@ enum MTTError {
|
||||
DocumentFieldWrongDataType(FieldType, FieldType),
|
||||
DocumentNotFound(String),
|
||||
FieldDuplicate(String, Field),
|
||||
NameDuplicate(Name),
|
||||
NameInvalidID(Uuid),
|
||||
NameMissingTranslation(Language),
|
||||
NameNotFound(Name),
|
||||
QueryCannotChangeData,
|
||||
}
|
||||
|
||||
@ -77,7 +81,7 @@ impl NameID {
|
||||
fn is_none(&self) -> bool {
|
||||
match self {
|
||||
Self::None => true,
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -397,7 +401,7 @@ mod messages {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Eq, Hash)]
|
||||
enum Include<T> {
|
||||
All,
|
||||
Some(T),
|
||||
@ -458,19 +462,30 @@ impl From<Route> for RouteID {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
struct Name {
|
||||
name: String,
|
||||
lang: Language,
|
||||
}
|
||||
|
||||
impl Name {
|
||||
fn get_language(&self) -> &Language {
|
||||
&self.lang
|
||||
}
|
||||
|
||||
fn english(name: String) -> Self {
|
||||
Self {
|
||||
name: name,
|
||||
lang: Language::from_639_1("en").unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn japanese(name: String) -> Self {
|
||||
Self {
|
||||
name: name,
|
||||
lang: Language::from_639_1("ja").unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Name {
|
||||
@ -479,8 +494,226 @@ impl ToString for Name {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Names {
|
||||
names: HashMap<Name, Uuid>,
|
||||
ids: HashMap<Uuid, HashMap<Language, Name>>,
|
||||
}
|
||||
|
||||
impl Names {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
names: HashMap::new(),
|
||||
ids: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_name(&mut self, name: Name) -> Result<Uuid, MTTError> {
|
||||
if self.names.contains_key(&name) {
|
||||
return Err(MTTError::NameDuplicate(name));
|
||||
}
|
||||
let mut id = Uuid::new_v4();
|
||||
while self.ids.contains_key(&id) {
|
||||
id = Uuid::new_v4();
|
||||
}
|
||||
self.names.insert(name.clone(), id.clone());
|
||||
let mut holder: HashMap<Language, Name> = HashMap::new();
|
||||
holder.insert(name.get_language().clone(), name);
|
||||
self.ids.insert(id.clone(), holder);
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
fn add_translation(&mut self, name: Name, translation: Name) -> Result<Uuid, MTTError> {
|
||||
let id = match self.get_id(&name) {
|
||||
Ok(data) => data.clone(),
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
match self.get_id(&translation) {
|
||||
Ok(_) => return Err(MTTError::NameDuplicate(translation)),
|
||||
Err(_) => {}
|
||||
}
|
||||
let holder = self.ids.get_mut(&id).unwrap();
|
||||
holder.insert(translation.get_language().clone(), translation.clone());
|
||||
self.names.insert(translation, id);
|
||||
Ok(id.clone())
|
||||
}
|
||||
|
||||
fn get_name(&self, id: &Uuid, lang: &Language) -> Result<Name, MTTError> {
|
||||
match self.ids.get(id) {
|
||||
Some(langdb) => match langdb.get(lang) {
|
||||
Some(name) => Ok(name.clone()),
|
||||
None => Err(MTTError::NameMissingTranslation(lang.clone())),
|
||||
},
|
||||
None => Err(MTTError::NameInvalidID(id.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_id(&self, name: &Name) -> Result<&Uuid, MTTError> {
|
||||
match self.names.get(name) {
|
||||
Some(id) => Ok(id),
|
||||
None => Err(MTTError::NameNotFound(name.clone())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod names {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn are_name_ids_unique() {
|
||||
let mut names = Names::new();
|
||||
let data = ["one", "two", "three", "four", "five"];
|
||||
let mut ids: HashSet<Uuid> = HashSet::new();
|
||||
for item in data.iter() {
|
||||
let name = Name::english(item.to_string());
|
||||
ids.insert(names.add_name(name).unwrap());
|
||||
}
|
||||
assert_eq!(ids.len(), data.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_id_return_name() {
|
||||
let mut names = Names::new();
|
||||
let data = ["one", "two"];
|
||||
let mut ids: HashMap<Name, Uuid> = HashMap::new();
|
||||
for item in data.iter() {
|
||||
let name = Name::english(item.to_string());
|
||||
ids.insert(name.clone(), names.add_name(name).unwrap());
|
||||
}
|
||||
for (name, id) in ids.iter() {
|
||||
assert_eq!(
|
||||
&names
|
||||
.get_name(id, &Language::from_639_1("en").unwrap())
|
||||
.unwrap(),
|
||||
name
|
||||
);
|
||||
assert_eq!(names.get_id(name).unwrap(), id);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errors_on_name_not_found() {
|
||||
let mut names = Names::new();
|
||||
let name = Name::english("missing".to_string());
|
||||
let result = names.get_id(&name);
|
||||
match result {
|
||||
Ok(_) => unreachable!("got {:?}, should have been error", result),
|
||||
Err(err) => match err {
|
||||
MTTError::NameNotFound(output) => assert_eq!(output, name),
|
||||
_ => unreachable!("got {:?}, should have been name not found", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errors_on_bad_id() {
|
||||
let mut names = Names::new();
|
||||
let id = Uuid::new_v4();
|
||||
let result = names.get_name(&id, &Language::from_639_1("en").unwrap());
|
||||
match result {
|
||||
Ok(_) => unreachable!("got {:?}, should be invalid id error", result),
|
||||
Err(err) => match err {
|
||||
MTTError::NameInvalidID(data) => assert_eq!(data, id),
|
||||
_ => unreachable!("got {:?}, should have been invalid id", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errors_on_missing_translation() {
|
||||
let mut names = Names::new();
|
||||
let name = Name::english("task".to_string());
|
||||
let lang = Language::from_639_1("ja").unwrap();
|
||||
let id = names.add_name(name).unwrap();
|
||||
let result = names.get_name(&id, &lang);
|
||||
match result {
|
||||
Ok(_) => unreachable!("got {:?}, should be invalid id error", result),
|
||||
Err(err) => match err {
|
||||
MTTError::NameMissingTranslation(data) => assert_eq!(data, lang),
|
||||
_ => unreachable!("got {:?}, should have been invalid id", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errors_on_duplicate_names() {
|
||||
let mut names = Names::new();
|
||||
let data = "test".to_string();
|
||||
let name = Name::english(data.clone());
|
||||
let id = names.add_name(name.clone());
|
||||
let output = names.add_name(name.clone());
|
||||
match output {
|
||||
Ok(_) => unreachable!(
|
||||
"got {:?}, should have produced duplicate name error",
|
||||
output
|
||||
),
|
||||
Err(err) => match err {
|
||||
MTTError::NameDuplicate(result) => assert_eq!(result, name),
|
||||
_ => unreachable!("got {:?}, should have been duplicate name", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allows_alternate_names() {
|
||||
let mut names = Names::new();
|
||||
let data = "test".to_string();
|
||||
let alt = "テスト".to_string();
|
||||
let english = Name::english(data.clone());
|
||||
let japanese = Name::japanese(alt.clone());
|
||||
let id = names.add_name(english.clone()).unwrap();
|
||||
let result = names.add_translation(english, japanese.clone()).unwrap();
|
||||
assert_eq!(result, id);
|
||||
println!("\n{:?}", names);
|
||||
let output = names.get_name(&id, &Language::from_639_1("ja").unwrap());
|
||||
assert_eq!(output.unwrap().to_string(), alt);
|
||||
assert_eq!(names.get_id(&japanese).unwrap(), &id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errors_on_bad_translation() {
|
||||
let mut names = Names::new();
|
||||
let data = "test".to_string();
|
||||
let alt = "テスト".to_string();
|
||||
let english = Name::english(data.clone());
|
||||
let japanese = Name::japanese(alt.clone());
|
||||
let result = names.add_translation(japanese.clone(), english);
|
||||
match result {
|
||||
Ok(_) => unreachable!("got {:?}, should be invalid id error", result),
|
||||
Err(err) => match err {
|
||||
MTTError::NameNotFound(output) => assert_eq!(output, japanese),
|
||||
_ => unreachable!("got {:?}, should have been invalid id", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errors_on_translation_duplicates() {
|
||||
let mut names = Names::new();
|
||||
let data = "test".to_string();
|
||||
let alt = "テスト".to_string();
|
||||
let english = Name::english(data.clone());
|
||||
let japanese = Name::japanese(alt.clone());
|
||||
let id = names.add_name(english.clone()).unwrap();
|
||||
let id = names.add_name(japanese.clone()).unwrap();
|
||||
let result = names.add_translation(english, japanese.clone());
|
||||
match result {
|
||||
Ok(_) => unreachable!(
|
||||
"got {:?}, should have produced duplicate name error",
|
||||
result
|
||||
),
|
||||
Err(err) => match err {
|
||||
MTTError::NameDuplicate(result) => assert_eq!(result, japanese),
|
||||
_ => unreachable!("got {:?}, should have been duplicate name", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum RegMsg {
|
||||
AddRoute(RouteRequest),
|
||||
DocName(Name),
|
||||
Error(MTTError),
|
||||
Ok,
|
||||
@ -499,7 +732,7 @@ impl Register {
|
||||
sender_id: sender_id,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn get_msg(&self) -> &RegMsg {
|
||||
&self.msg
|
||||
}
|
||||
@ -650,7 +883,7 @@ mod routes {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
struct RouteRequest {
|
||||
msg_id: Include<Uuid>,
|
||||
doc_name: Include<String>,
|
||||
@ -968,6 +1201,7 @@ struct DocRegistry {
|
||||
doc_names: Vec<Name>,
|
||||
queue: Queue,
|
||||
receiver: Receiver<Message>,
|
||||
routes: HashMap<RouteRequest, Uuid>,
|
||||
}
|
||||
|
||||
impl DocRegistry {
|
||||
@ -976,6 +1210,7 @@ impl DocRegistry {
|
||||
doc_names: Vec::new(),
|
||||
queue: queue,
|
||||
receiver: rx,
|
||||
routes: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -994,8 +1229,8 @@ impl DocRegistry {
|
||||
let id = data.get_sender_id();
|
||||
let reply = msg.response(self.register_action(data));
|
||||
self.queue.forward(id, reply);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1004,12 +1239,19 @@ impl DocRegistry {
|
||||
match reg.get_msg() {
|
||||
RegMsg::DocName(name) => {
|
||||
if self.doc_names.contains(name) {
|
||||
reg.response(RegMsg::Error(MTTError::DocumentAlreadyExists(name.to_string())))
|
||||
reg.response(RegMsg::Error(MTTError::DocumentAlreadyExists(
|
||||
name.to_string(),
|
||||
)))
|
||||
} else {
|
||||
self.doc_names.push(name.clone());
|
||||
reg.response(RegMsg::Ok)
|
||||
}
|
||||
},
|
||||
}
|
||||
RegMsg::AddRoute(route) => {
|
||||
self.routes
|
||||
.insert(route.clone(), reg.get_sender_id().clone());
|
||||
reg.response(RegMsg::Ok)
|
||||
}
|
||||
_ => reg.response(RegMsg::Ok),
|
||||
}
|
||||
}
|
||||
@ -1157,6 +1399,8 @@ mod queues {
|
||||
sender_id: Uuid,
|
||||
queue: Queue,
|
||||
receiver: Receiver<Message>,
|
||||
doc_id: HashMap<String, Uuid>,
|
||||
doc_rx: HashMap<String, Receiver<Message>>,
|
||||
}
|
||||
|
||||
impl TestQueue {
|
||||
@ -1168,9 +1412,22 @@ mod queues {
|
||||
sender_id: id,
|
||||
queue: queue,
|
||||
receiver: rx,
|
||||
doc_id: HashMap::new(),
|
||||
doc_rx: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_document(&mut self, name: String) {
|
||||
let (tx, rx) = channel();
|
||||
let id = self.add_sender(tx);
|
||||
let reg_msg = Register::new(id.clone(), RegMsg::DocName(Name::english(name.clone())));
|
||||
let msg = Message::new(NameID::None, reg_msg);
|
||||
self.send(msg.clone()).unwrap();
|
||||
let result = rx.recv_timeout(TIMEOUT).unwrap();
|
||||
self.doc_id.insert(name.clone(), id);
|
||||
self.doc_rx.insert(name.clone(), rx);
|
||||
}
|
||||
|
||||
fn get_preset_id(&self) -> &Uuid {
|
||||
&self.sender_id
|
||||
}
|
||||
@ -1179,6 +1436,14 @@ mod queues {
|
||||
&self.receiver
|
||||
}
|
||||
|
||||
fn get_doc_rx_id(&self, name: &str) -> &Uuid {
|
||||
self.doc_id.get(name).unwrap()
|
||||
}
|
||||
|
||||
fn get_doc_rx(&self, name: &str) -> &Receiver<Message> {
|
||||
self.doc_rx.get(name).unwrap()
|
||||
}
|
||||
|
||||
fn add_sender(&mut self, sender: Sender<Message>) -> Uuid {
|
||||
self.queue.add_sender(sender)
|
||||
}
|
||||
@ -1217,7 +1482,10 @@ mod queues {
|
||||
fn can_register_document_name() {
|
||||
let mut queue = TestQueue::new();
|
||||
let doc_name = Name::english(Uuid::new_v4().to_string());
|
||||
let reg_msg = Register::new(queue.get_preset_id().clone(), RegMsg::DocName(doc_name.clone()));
|
||||
let reg_msg = Register::new(
|
||||
queue.get_preset_id().clone(),
|
||||
RegMsg::DocName(doc_name.clone()),
|
||||
);
|
||||
let msg = Message::new(NameID::None, reg_msg);
|
||||
queue.send(msg.clone()).unwrap();
|
||||
let result = queue.get_preset_rx().recv_timeout(TIMEOUT).unwrap();
|
||||
@ -1225,7 +1493,7 @@ mod queues {
|
||||
let action = result.get_action();
|
||||
match action {
|
||||
MsgAction::Register(data) => match data.get_msg() {
|
||||
RegMsg::Ok => {},
|
||||
RegMsg::Ok => {}
|
||||
_ => unreachable!("got {:?}, should have been register ok", action),
|
||||
},
|
||||
_ => unreachable!("got {:?}, should have been register ok", action),
|
||||
@ -1235,12 +1503,12 @@ mod queues {
|
||||
#[test]
|
||||
fn errors_on_duplicate_names() {
|
||||
let mut queue = TestQueue::new();
|
||||
//let mut queue = Queue::new();
|
||||
//let (sender, receiver) = channel();
|
||||
//let id = queue.add_sender(sender);
|
||||
let receiver = queue.get_preset_rx();
|
||||
let doc_name = Name::english(Uuid::new_v4().to_string());
|
||||
let reg_msg = Register::new(queue.get_preset_id().clone(), RegMsg::DocName(doc_name.clone()));
|
||||
let reg_msg = Register::new(
|
||||
queue.get_preset_id().clone(),
|
||||
RegMsg::DocName(doc_name.clone()),
|
||||
);
|
||||
let msg = Message::new(NameID::None, reg_msg.clone());
|
||||
queue.send(msg.clone()).unwrap();
|
||||
receiver.recv_timeout(TIMEOUT).unwrap();
|
||||
@ -1252,7 +1520,9 @@ mod queues {
|
||||
match action {
|
||||
MsgAction::Register(data) => match data.get_msg() {
|
||||
RegMsg::Error(err) => match err {
|
||||
MTTError::DocumentAlreadyExists(name) => assert_eq!(name.to_string(), doc_name.to_string()),
|
||||
MTTError::DocumentAlreadyExists(name) => {
|
||||
assert_eq!(name.to_string(), doc_name.to_string())
|
||||
}
|
||||
_ => unreachable!("got {:?}, should have been duplicate error", err),
|
||||
},
|
||||
_ => unreachable!("got {:?}, should have been error", data),
|
||||
@ -1261,20 +1531,25 @@ mod queues {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_register_routes() {
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn default_send_does_nothing() {
|
||||
let mut queue = Queue::new();
|
||||
let (sender, receiver) = channel();
|
||||
let id = queue.add_sender(sender);
|
||||
let msg = Message::new("wiki", Query::new());
|
||||
fn can_register_routes() {
|
||||
let mut queue = TestQueue::new();
|
||||
let names = ["task", "recipe"];
|
||||
for name in names.iter() {
|
||||
queue.add_document(name.to_string());
|
||||
}
|
||||
let route_req = RouteRequest::new(Include::All, Include::All, Include::All);
|
||||
let reg_msg = RegMsg::AddRoute(route_req);
|
||||
let reg = Register::new(queue.get_doc_rx_id(names[0]).clone(), reg_msg);
|
||||
let msg = Message::new(NameID::None, reg);
|
||||
queue.send(msg).unwrap();
|
||||
match receiver.recv_timeout(TIMEOUT) {
|
||||
queue.get_doc_rx(names[0]).recv_timeout(TIMEOUT).unwrap();
|
||||
let msg = Message::new(NameID::None, Query::new());
|
||||
queue.send(msg.clone()).unwrap();
|
||||
let result = queue.get_doc_rx(names[0]).recv_timeout(TIMEOUT).unwrap();
|
||||
assert_eq!(result.get_message_id(), msg.get_message_id());
|
||||
match queue.get_doc_rx(names[1]).recv_timeout(TIMEOUT) {
|
||||
Ok(msg) => unreachable!("should not receive: {:?}", msg),
|
||||
Err(err) => match err {
|
||||
RecvTimeoutError::Timeout => {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user