From 88cd6cd6069ada205cce9e5a05bdc4dd156d01f1 Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Wed, 22 Apr 2026 12:24:05 -0400 Subject: [PATCH] Beginning the process of moving session table into the queue. --- src/action/addition.rs | 6 +- src/queue/data_director.rs | 142 ++++++++++++++++++++++++++++++++++++- 2 files changed, 144 insertions(+), 4 deletions(-) diff --git a/src/action/addition.rs b/src/action/addition.rs index b0e8a7a..fb5bd7d 100644 --- a/src/action/addition.rs +++ b/src/action/addition.rs @@ -1,6 +1,5 @@ -use super::{CalcValue, Field, RequestData}; +use super::{CalcValue, RequestData}; use crate::{message::MessageAction, name::NameType}; -use uuid::Uuid; #[derive(Clone, Debug)] pub struct Addition { @@ -41,7 +40,8 @@ impl MessageAction for Addition { #[cfg(test)] mod additions { use super::*; - use crate::name::Name; + use crate::{name::Name, Field}; + use uuid::Uuid; #[test] fn is_default_addition_empty() { diff --git a/src/queue/data_director.rs b/src/queue/data_director.rs index a73e698..8757c95 100644 --- a/src/queue/data_director.rs +++ b/src/queue/data_director.rs @@ -1,6 +1,6 @@ use super::SenderID; use crate::{ - action::{Action, MsgAction}, + action::{Action, Field, MsgAction}, message::{Message, MessageAction, MessageID}, mtterror::MTTError, name::{Name, NameID, NameType, Names}, @@ -484,6 +484,146 @@ mod route_storeage { } } +#[derive(Clone, Debug)] +struct SessionEntry { + id: Field, +} + +impl SessionEntry { + fn id(&self) -> &Field { + &self.id + } +} + +#[cfg(test)] +mod session_entries { + use super::*; + + #[test] + fn does_entry_return_id() { + let id: Field = Uuid::new_v4().into(); + let entry = SessionEntry { id: id.clone() }; + assert_eq!(entry.id(), &id); + } +} + +struct Session { + entries: HashMap, +} + +impl Session { + fn new() -> Self { + Self { + entries: HashMap::new(), + } + } + + fn get(&mut self, id: &Field) -> SessionEntry { + let converted = match id { + Field::Uuid(data) => Field::Uuid(data.clone()), + Field::StaticString(data) => match Uuid::try_from(data.clone()) { + Ok(id) => Field::Uuid(id.clone()), + Err(_) => Field::None, + }, + _ => Field::None, + }; + match self.entries.get(&converted) { + Some(data) => data.clone(), + None => { + let mut new_id: Field = Uuid::new_v4().into(); + while self.entries.contains_key(&new_id) { + new_id = Uuid::new_v4().into(); + } + let output = SessionEntry { id: new_id.clone() }; + self.entries.insert(new_id, output.clone()); + output + } + } + } +} + +#[cfg(test)] +mod sessions { + use super::*; + use crate::FieldType; + + #[test] + fn are_session_ids_unique() { + let count = 10; + let mut ids: Vec = Vec::new(); + let mut sess = Session::new(); + for _ in 0..count { + let result = sess.get(&Field::None); + let id = result.id().clone(); + let id_type: FieldType = (&id).into(); + assert_eq!(id_type, FieldType::Uuid); + assert!(!ids.contains(&id), "{:?} is not unique in {:?}", id, ids); + ids.push(id); + } + } + + #[test] + fn are_valid_uuids_returned() { + let mut sess = Session::new(); + let data = sess.get(&Field::None); + let result = sess.get(data.id()); + assert_eq!(result.id(), data.id()); + } + + #[test] + fn do_bad_ids_generate_new_ids() { + let mut sess = Session::new(); + let data: Field = Uuid::nil().into(); + let result = sess.get(&data); + assert_ne!(result.id(), &data); + } + + #[test] + fn can_string_ids_be_accepted() { + let mut sess = Session::new(); + let data = sess.get(&Field::None); + let id = sess.get(&Field::None).id().clone(); + let text: Field = match id { + Field::Uuid(id) => id.to_string().into(), + _ => unreachable!("entry id should always return a uuid"), + }; + let result = sess.get(&text); + assert_eq!(result.id(), &id); + } + + #[test] + fn does_mismatched_string_produce_new_id() { + let mut sess = Session::new(); + let input = Uuid::nil(); + let id: Field = input.to_string().into(); + let test_data: Field = input.into(); + let result = sess.get(&id); + assert_ne!(result.id(), &test_data); + } + + #[test] + fn does_bad_string_produce_id() { + let mut sess = Session::new(); + let id: Field = "not a uuid".into(); + let result = sess.get(&id); + match result.id() { + Field::Uuid(_) => {} + _ => panic!("session id should always return a uuid field"), + } + } + + #[test] + fn do_other_fields_return_uuid() { + let mut sess = Session::new(); + let id: Field = 2.into(); + let result = sess.get(&id); + match result.id() { + Field::Uuid(_) => {} + _ => panic!("session id should always return a uuid field"), + } + } +} + pub struct DocRegistry { doc_names: Names, queue: Queue,