Adjusted system to allow on_blank messages.
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 0s

This commit is contained in:
Jeff Baskin 2025-11-23 16:15:17 -05:00
parent d7e8e3db46
commit 830189a58d

View File

@ -22,6 +22,7 @@ mod support_test {
#[derive(Clone, Debug)]
enum MTTError {
AdditionMissingField(Name),
CannotConvertMessageToRouteID,
DocumentAlreadyExists(String),
DocumentFieldAlreadyExists(String, Field),
DocumentFieldMissing(String),
@ -495,6 +496,61 @@ impl From<Route> for RouteID {
}
}
impl TryFrom<Message> for RouteID {
type Error = MTTError;
fn try_from(value: Message) -> Result<Self, Self::Error> {
let doc_id = match value.get_document_id() {
NameType::ID(data) => data,
_ => return Err(MTTError::CannotConvertMessageToRouteID),
};
Ok(RouteID {
action: Some(value.get_action().into()),
doc_type: Some(doc_id.clone()),
msg_id: Some(value.get_message_id().clone()),
})
}
}
#[cfg(test)]
mod route_ids {
use super::*;
#[test]
fn can_get_message_route_id() {
let actions: Vec<MsgAction> = vec![Query::new().into(), MsgAction::Show];
let doc_id = Uuid::new_v4();
for action in actions.iter() {
let msg = Message::new(doc_id.clone(), action.clone());
let route_id: RouteID = msg.clone().try_into().unwrap();
match route_id.msg_id {
Some(data) => assert_eq!(&data, msg.get_message_id()),
None => unreachable!("should have had a message id"),
}
match route_id.doc_type {
Some(data) => assert_eq!(data, doc_id),
None => unreachable!("should have had doc type"),
}
match route_id.action {
Some(data) => assert_eq!(data, action.into()),
None => unreachable!("should have had doc type"),
}
}
}
#[test]
fn errors_when_doc_id_is_not_id() {
let msg = Message::new(Name::english("nope"), Query::new());
match TryInto::<RouteID>::try_into(msg) {
Ok(_) => unreachable!("should be an error"),
Err(err) => match err {
MTTError::CannotConvertMessageToRouteID => {}
_ => unreachable!("got {:?}, should have been covert error", err),
},
}
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
enum NameType {
ID(Uuid),
@ -2623,28 +2679,106 @@ impl IndexType {
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
enum DocFuncType {
Action,
Add,
Delete,
Query,
Show,
Update,
}
#[derive(Clone, Debug)]
struct PathAction {
path: Path,
func_type: DocFuncType,
}
impl PathAction {
fn new(path: Path, func_type: DocFuncType) -> Self {
Self {
path: path,
func_type: func_type,
}
}
fn path(&self) -> Path {
self.path.clone()
}
fn doc_function(&self) -> DocFuncType {
self.func_type.clone()
}
}
#[derive(Clone, Debug)]
struct DocDef {
doc_names: Vec<Name>,
field_names: Names,
fields: HashMap<Uuid, FieldSetting>,
indexes: HashMap<Uuid, IndexType>,
routes: Vec<PathAction>,
}
impl DocDef {
fn new(name: Name) -> Self {
let names = vec![name];
Self::with_names(names)
}
fn with_names(names: Vec<Name>) -> Self {
let routes = vec![
PathAction::new(
Path::new(
Include::All,
Include::Some(names[0].clone().into()),
Include::Some(Action::Addition),
),
DocFuncType::Add,
),
PathAction::new(
Path::new(
Include::All,
Include::Some(names[0].clone().into()),
Include::Some(Action::Delete),
),
DocFuncType::Delete,
),
PathAction::new(
Path::new(
Include::All,
Include::Some(names[0].clone().into()),
Include::Some(Action::Query),
),
DocFuncType::Query,
),
PathAction::new(
Path::new(
Include::All,
Include::Some(names[0].clone().into()),
Include::Some(Action::Show),
),
DocFuncType::Show,
),
PathAction::new(
Path::new(
Include::All,
Include::Some(names[0].clone().into()),
Include::Some(Action::Update),
),
DocFuncType::Update,
),
];
Self {
doc_names: [name].to_vec(),
doc_names: names,
field_names: Names::new(),
fields: HashMap::new(),
indexes: HashMap::new(),
routes: routes,
}
}
fn with_names(names: Name) -> Self {
todo!("with an existing list of names");
}
fn get_document_names(&self) -> &Vec<Name> {
&self.doc_names
}
@ -2739,6 +2873,10 @@ impl DocDef {
fn iter(&self) -> impl Iterator<Item = (&Uuid, &FieldSetting)> {
self.fields.iter()
}
fn iter_routes(&self) -> impl Iterator<Item = &PathAction> {
self.routes.iter()
}
}
#[cfg(test)]
@ -2835,6 +2973,67 @@ mod docdefs {
},
}
}
#[test]
fn does_default_routes_get_set() {
let default_num = 5;
let docname = Name::english(Uuid::new_v4().to_string().as_str());
let docdef = DocDef::new(docname.clone());
assert_eq!(
docdef.iter_routes().count(),
default_num,
"routes contained the following:\n{:?}",
docdef.routes
);
let mut actions: HashSet<Action> = HashSet::new();
let mut doc_funcs: HashSet<DocFuncType> = HashSet::new();
for path_action in docdef.iter_routes() {
let path = path_action.path();
match &path.msg_id {
Include::All => {}
_ => unreachable!("got {:?}, message id should include all", path.msg_id),
}
match &path.doc {
Include::Some(output) => match output {
NameType::Name(data) => assert_eq!(data, &docname),
_ => unreachable!("got {:?}, name type should be {:?}", path.doc, docname),
},
_ => unreachable!("got {:?}, name type should be {:?}", path.doc, docname),
};
match &path.action {
Include::Some(output) => match output {
Action::Addition => actions.insert(output.clone()),
Action::Delete => actions.insert(output.clone()),
Action::Query => actions.insert(output.clone()),
Action::Show => actions.insert(output.clone()),
Action::Update => actions.insert(output.clone()),
_ => unreachable!("got {:?} which is not a default action", output),
},
_ => unreachable!("got {:?}, which is not a default action", path.action),
};
let file_func = path_action.doc_function();
match file_func {
DocFuncType::Add => doc_funcs.insert(file_func),
DocFuncType::Delete => doc_funcs.insert(file_func),
DocFuncType::Query => doc_funcs.insert(file_func),
DocFuncType::Show => doc_funcs.insert(file_func),
DocFuncType::Update => doc_funcs.insert(file_func),
_ => unreachable!("got {:?}, which is not a default function", file_func),
};
}
assert_eq!(
actions.len(),
default_num,
"got {:?}, missing some actions",
actions
);
assert_eq!(
doc_funcs.len(),
default_num,
"got {:?}, missing some actions",
doc_funcs
);
}
}
#[derive(Clone, Debug)]
@ -4199,16 +4398,23 @@ struct DocumentFile {
docs: InternalRecords,
indexes: Indexes,
queue: Queue,
routes: HashMap<RouteID, DocFuncType>,
rx: Receiver<Message>,
}
impl DocumentFile {
fn new(queue: Queue, rx: Receiver<Message>, docdef: DocDef) -> Self {
fn new(
queue: Queue,
rx: Receiver<Message>,
docdef: DocDef,
routes: HashMap<RouteID, DocFuncType>,
) -> Self {
Self {
docdef: docdef.clone(),
docs: InternalRecords::new(),
indexes: docdef.create_indexes(),
queue: queue,
routes: routes,
rx: rx,
}
}
@ -4238,40 +4444,27 @@ impl DocumentFile {
},
_ => unreachable!("should only return a name id or an error"),
};
let routes = [
Path::new(
Include::All,
Include::Some(name_id.into()),
Include::Some(Action::Addition),
),
Path::new(
Include::All,
Include::Some(name_id.into()),
Include::Some(Action::Delete),
),
Path::new(
Include::All,
Include::Some(name_id.into()),
Include::Some(Action::Query),
),
Path::new(
Include::All,
Include::Some(name_id.into()),
Include::Some(Action::Show),
),
Path::new(
Include::All,
Include::Some(name_id.into()),
Include::Some(Action::Update),
),
];
for route in routes.iter() {
let request = reg_msg.response(RegMsg::AddRoute(route.clone()));
let mut route_action: HashMap<RouteID, DocFuncType> = HashMap::new();
for path_action in docdef.iter_routes() {
let request = reg_msg.response(RegMsg::AddRoute(path_action.path()));
let add_route = rmsg.response(request);
queue.send(add_route).unwrap();
rx.recv().unwrap();
let result = rx.recv().unwrap();
let route_id = match result.get_action() {
MsgAction::Register(data) => match data.get_msg() {
RegMsg::RouteID(data) => data,
RegMsg::Error(err) => {
queue.remove_sender(&id);
queue.send(msg.response(err.clone())).unwrap();
return;
}
let mut doc = DocumentFile::new(queue.clone(), rx, docdef);
_ => unreachable!("should only return a route id or an error"),
},
_ => unreachable!("should only return a route id or an error"),
};
route_action.insert(route_id.clone(), path_action.doc_function());
}
let mut doc = DocumentFile::new(queue.clone(), rx, docdef, route_action);
spawn(move || {
doc.listen();
});
@ -4282,14 +4475,19 @@ impl DocumentFile {
fn listen(&mut self) {
loop {
let msg = self.rx.recv().unwrap();
let result = match msg.get_action() {
MsgAction::Addition(data) => self.add_document(data),
MsgAction::Delete(delete) => self.delete(delete),
MsgAction::Query(query) => self.query(query),
MsgAction::Update(update) => self.update(update),
_ => Reply::new().into(),
};
self.queue.send(msg.response(result)).unwrap();
let route: Route = msg.get_path().try_into().unwrap();
for (route_id, doc_func) in self.routes.clone().iter() {
if route == route_id.into() {
match doc_func {
DocFuncType::Add => self.add_document(&msg),
DocFuncType::Delete => self.delete(&msg),
DocFuncType::Query => self.query(&msg),
DocFuncType::Show => self.queue.send(msg.response(Reply::new())).unwrap(),
DocFuncType::Update => self.update(&msg),
_ => {}
}
}
}
}
}
@ -4339,12 +4537,20 @@ impl DocumentFile {
self.indexes.remove_from_index(&field_id, field, oid);
}
fn add_document(&mut self, addition: &Addition) -> MsgAction {
fn add_document(&mut self, msg: &Message) {
let addition = match msg.get_action() {
MsgAction::Addition(data) => data,
_ => return,
};
let mut holder = InternalRecord::new();
for (name_id, value) in addition.iter() {
let field_id = match self.docdef.get_field_id(name_id) {
Ok(id) => id,
Err(err) => return MsgAction::Error(err),
Err(err) => {
let reply = msg.response(err);
self.queue.send(reply).unwrap();
return;
}
};
holder.insert(field_id.clone(), value.get(&Field::None));
}
@ -4355,7 +4561,11 @@ impl DocumentFile {
};
let corrected = match self.validate(field_id, value) {
Ok(data) => data,
Err(err) => return MsgAction::Error(err),
Err(err) => {
let reply = msg.response(err);
self.queue.send(reply).unwrap();
return;
}
};
holder.insert(field_id.clone(), corrected.clone());
}
@ -4372,13 +4582,22 @@ impl DocumentFile {
self.docs.insert(oid.clone(), holder.clone());
records.insert(oid, holder);
}
records.into()
let reply = msg.response(records);
self.queue.send(reply).unwrap();
}
fn delete(&mut self, delete: &Delete) -> MsgAction {
fn delete(&mut self, msg: &Message) {
let delete = match msg.get_action() {
MsgAction::Delete(data) => data,
_ => unreachable!("should always be delete action"),
};
let records = match self.run_query(delete.get_query()) {
Ok(data) => data,
Err(err) => return err.into(),
Err(err) => {
let reply = msg.response(err);
self.queue.send(reply).unwrap();
return;
}
};
for (oid, record) in records.iter() {
for (field_id, index) in self.indexes.iter_mut() {
@ -4386,7 +4605,8 @@ impl DocumentFile {
}
self.docs.remove(oid);
}
Records::with_data(self.docdef.get_field_names().clone(), records).into()
let rec = Records::with_data(self.docdef.get_field_names().clone(), records);
self.queue.send(msg.response(rec)).unwrap();
}
fn run_query(&self, query: &Query) -> Result<InternalRecords, MTTError> {
@ -4440,26 +4660,45 @@ impl DocumentFile {
Ok(records)
}
fn query(&self, query: &Query) -> MsgAction {
fn query(&self, msg: &Message) {
let query = match msg.get_action() {
MsgAction::Query(data) => data,
_ => unreachable!("should receive a query"),
};
let records = match self.run_query(query) {
Ok(data) => data,
Err(err) => return err.into(),
Err(err) => {
let reply = msg.response(err);
self.queue.send(reply).unwrap();
return;
}
};
let recs = Records::with_data(self.docdef.get_field_names().clone(), records);
//self.queue.
recs.into()
self.queue.send(msg.response(recs)).unwrap();
}
fn update(&mut self, update: &Update) -> MsgAction {
fn update(&mut self, msg: &Message) {
let update = match msg.get_action() {
MsgAction::Update(data) => data,
_ => unreachable!("should receive a update"),
};
let original = match self.run_query(update.get_query()) {
Ok(result) => result,
Err(err) => return err.into(),
Err(err) => {
let reply = msg.response(err);
self.queue.send(reply).unwrap();
return;
}
};
let mut changes: HashMap<Uuid, &CalcValue> = HashMap::new();
for (key, value) in update.get_values().iter() {
let field_id = match self.docdef.get_field_id(key) {
Ok(data) => data,
Err(err) => return err.into(),
Err(err) => {
let reply = msg.response(err);
self.queue.send(reply).unwrap();
return;
}
};
changes.insert(field_id, value);
}
@ -4471,12 +4710,20 @@ impl DocumentFile {
let field = value.get(holder.get(field_id).unwrap());
let correction = match self.validate(field_id, &field) {
Ok(data) => data,
Err(err) => return err.into(),
Err(err) => {
let reply = msg.response(err);
self.queue.send(reply).unwrap();
return;
}
};
holder.insert(field_id.clone(), correction.clone());
match indexes.add_to_index(&field_id, correction, oid.clone()) {
Ok(_) => {}
Err(err) => return err.into(),
Err(err) => {
let reply = msg.response(err);
self.queue.send(reply).unwrap();
return;
}
}
}
updates.insert(oid.clone(), holder);
@ -4489,7 +4736,8 @@ impl DocumentFile {
}
self.docs.insert(oid.clone(), new_rec.clone());
}
Records::with_data(self.docdef.get_field_names().clone(), updates).into()
let recs = Records::with_data(self.docdef.get_field_names().clone(), updates);
self.queue.send(msg.response(recs)).unwrap();
}
}