Added language inforation into session.
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1s

This commit is contained in:
2026-03-20 09:31:56 -04:00
parent 9e81e17a23
commit 5ec1330a73
5 changed files with 117 additions and 24 deletions

View File

@@ -16,6 +16,7 @@ pub enum Field {
DateTime(DateTime<Utc>), DateTime(DateTime<Utc>),
Duration(Duration), Duration(Duration),
Integer(i128), Integer(i128),
Language(Language),
None, None,
StaticString(String), StaticString(String),
Uuid(Uuid), Uuid(Uuid),
@@ -111,6 +112,12 @@ impl From<i32> for Field {
} }
} }
impl From<Language> for Field {
fn from(value: Language) -> Self {
Self::Language(value)
}
}
impl PartialOrd for Field { impl PartialOrd for Field {
fn partial_cmp(&self, other: &Field) -> Option<Ordering> { fn partial_cmp(&self, other: &Field) -> Option<Ordering> {
match (self, other) { match (self, other) {
@@ -272,6 +279,7 @@ pub enum FieldType {
DateTime, DateTime,
Duration, Duration,
Integer, Integer,
Language,
None, None,
StaticString, StaticString,
Uuid, Uuid,
@@ -284,6 +292,7 @@ impl FieldType {
FieldType::DateTime => Utc::now().into(), FieldType::DateTime => Utc::now().into(),
FieldType::Duration => Duration::from_secs(0).into(), FieldType::Duration => Duration::from_secs(0).into(),
FieldType::Integer => 0.into(), FieldType::Integer => 0.into(),
FieldType::Language => Language::from_639_1("en").unwrap().into(),
FieldType::None => Field::None, FieldType::None => Field::None,
FieldType::StaticString => "".into(), FieldType::StaticString => "".into(),
FieldType::Uuid => Uuid::new_v4().into(), FieldType::Uuid => Uuid::new_v4().into(),
@@ -298,6 +307,7 @@ impl From<&Field> for FieldType {
Field::DateTime(_) => Self::DateTime, Field::DateTime(_) => Self::DateTime,
Field::Duration(_) => Self::Duration, Field::Duration(_) => Self::Duration,
Field::Integer(_) => Self::Integer, Field::Integer(_) => Self::Integer,
Field::Language(_) => Self::Language,
Field::None => Self::None, Field::None => Self::None,
Field::StaticString(_) => Self::StaticString, Field::StaticString(_) => Self::StaticString,
Field::Uuid(_) => Self::Uuid, Field::Uuid(_) => Self::Uuid,

View File

@@ -38,9 +38,17 @@ impl Session {
names names
} }
pub fn language_field_names() -> Vec<Name> {
let mut names = Vec::new();
names.push(Name::english("language"));
names.push(Name::japanese("言語"));
names
}
pub fn document_definition() -> DocDef { pub fn document_definition() -> DocDef {
let name_id = Self::id_field_names()[0].clone(); let name_id = Self::id_field_names()[0].clone();
let name_expire = Self::expire_field_names()[0].clone(); let name_expire = Self::expire_field_names()[0].clone();
let name_lang = Self::language_field_names()[0].clone();
let mut docdef = DocDef::with_names(Self::doc_names()); let mut docdef = DocDef::with_names(Self::doc_names());
@@ -56,6 +64,9 @@ impl Session {
docdef.set_default(&name_expire, calc.clone()).unwrap(); docdef.set_default(&name_expire, calc.clone()).unwrap();
docdef.add_index(&name_expire, IndexType::Index).unwrap(); docdef.add_index(&name_expire, IndexType::Index).unwrap();
docdef.add_field(Self::language_field_names(), FieldType::Language);
docdef.set_default(&name_lang, FieldType::Language).unwrap();
let mut update = Update::new(Session::doc_names()[0].clone()); let mut update = Update::new(Session::doc_names()[0].clone());
update update
.get_values_mut() .get_values_mut()

View File

@@ -6,6 +6,7 @@ pub mod name;
mod queue; mod queue;
use document::{Clock, CreateDoc, Session}; use document::{Clock, CreateDoc, Session};
use isolang::Language;
use message::{wrapper::Message, MessageAction}; use message::{wrapper::Message, MessageAction};
use queue::{ use queue::{
data_director::{RegMsg, Register}, data_director::{RegMsg, Register},
@@ -56,18 +57,27 @@ impl MoreThanText {
output output
} }
fn new_session() -> ClientAction { fn new_session(lang: Option<Language>) -> ClientAction {
Addition::new(Session::doc_names()[0].clone()).into() let mut output = Addition::new(Session::doc_names()[0].clone());
match lang {
Some(data) => {
let name = Session::language_field_names()[0].clone();
let field: Field = data.into();
output.add_field(name, field);
}
None => {}
}
output.into()
} }
fn recursive_message_request<UA>(&mut self, action: UA) -> Uuid fn recursive_message_request<CA>(&mut self, action: CA, lang: Option<Language>) -> Uuid
where where
UA: Into<ClientAction>, CA: Into<ClientAction>,
{ {
match self.records(action) { match self.records(action) {
Ok(data) => { Ok(data) => {
if data.len() == 0 { if data.len() == 0 {
self.recursive_message_request(MoreThanText::new_session()) self.recursive_message_request(MoreThanText::new_session(lang), lang)
} else { } else {
let rec = data.iter().last().unwrap(); let rec = data.iter().last().unwrap();
match rec.get(Name::english("id")).unwrap() { match rec.get(Name::english("id")).unwrap() {
@@ -76,11 +86,11 @@ impl MoreThanText {
} }
} }
} }
Err(_) => self.recursive_message_request(MoreThanText::new_session()), Err(_) => self.recursive_message_request(MoreThanText::new_session(lang), lang),
} }
} }
pub fn validate_session(&mut self, session: Option<String>) -> Uuid { pub fn validate_session(&mut self, session: Option<String>, lang: Option<Language>) -> Uuid {
let action = match session { let action = match session {
Some(data) => match Uuid::try_from(data.as_str()) { Some(data) => match Uuid::try_from(data.as_str()) {
Ok(id) => { Ok(id) => {
@@ -92,11 +102,11 @@ impl MoreThanText {
query.add(Name::english("id"), calc); query.add(Name::english("id"), calc);
query.into() query.into()
} }
Err(_) => MoreThanText::new_session(), Err(_) => MoreThanText::new_session(lang),
}, },
None => MoreThanText::new_session(), None => MoreThanText::new_session(lang),
}; };
self.recursive_message_request(action) self.recursive_message_request(action, lang)
} }
pub fn records<UA>(&mut self, request: UA) -> Result<Records, MTTError> pub fn records<UA>(&mut self, request: UA) -> Result<Records, MTTError>

View File

@@ -73,7 +73,9 @@ where
let requested = req_id.clone(); let requested = req_id.clone();
let (tx, mut rx) = channel(1); let (tx, mut rx) = channel(1);
spawn(async move { spawn(async move {
tx.send(state.validate_session(requested)).await.unwrap(); tx.send(state.validate_session(requested, None))
.await
.unwrap();
}); });
let id = rx.recv().await.unwrap(); let id = rx.recv().await.unwrap();
if !req_id.is_some_and(|x| x == id.to_string()) { if !req_id.is_some_and(|x| x == id.to_string()) {

View File

@@ -1,4 +1,5 @@
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use isolang::Language;
use morethantext::{ use morethantext::{
action::{Addition, CalcValue, Calculation, Field, FieldType, Operand, Query, Record}, action::{Addition, CalcValue, Calculation, Field, FieldType, Operand, Query, Record},
Action, ErrorID, Include, MTTError, MoreThanText, Name, Path, TestMoreThanText, Update, Action, ErrorID, Include, MTTError, MoreThanText, Name, Path, TestMoreThanText, Update,
@@ -29,7 +30,7 @@ fn are_session_ids_unique() {
let count = 10; let count = 10;
let mut result: Vec<Uuid> = Vec::new(); let mut result: Vec<Uuid> = Vec::new();
for _ in 0..count { for _ in 0..count {
let id = mtt.validate_session(None); let id = mtt.validate_session(None, None);
assert!(!result.contains(&id), "found {} in {:?}", id, result); assert!(!result.contains(&id), "found {} in {:?}", id, result);
result.push(id); result.push(id);
} }
@@ -38,24 +39,24 @@ fn are_session_ids_unique() {
#[test] #[test]
fn bad_session_id_returns_new_id() { fn bad_session_id_returns_new_id() {
let mut mtt = MoreThanText::new(); let mut mtt = MoreThanText::new();
let id1 = mtt.validate_session(Some("stuff".to_string())); let id1 = mtt.validate_session(Some("stuff".to_string()), None);
let id2 = mtt.validate_session(Some("stuff".to_string())); let id2 = mtt.validate_session(Some("stuff".to_string()), None);
assert_ne!(id1, id2); assert_ne!(id1, id2);
} }
#[test] #[test]
fn creates_new_session_if_bad_or_expired() { fn creates_new_session_if_bad_or_expired() {
let mut mtt = MoreThanText::new(); let mut mtt = MoreThanText::new();
let id1 = mtt.validate_session(Some(Uuid::nil().to_string())); let id1 = mtt.validate_session(Some(Uuid::nil().to_string()), None);
let id2 = mtt.validate_session(Some(Uuid::nil().to_string())); let id2 = mtt.validate_session(Some(Uuid::nil().to_string()), None);
assert_ne!(id1, id2); assert_ne!(id1, id2);
} }
#[test] #[test]
fn returns_same_session_id_when_valid() { fn returns_same_session_id_when_valid() {
let mut mtt = MoreThanText::new(); let mut mtt = MoreThanText::new();
let id = mtt.validate_session(None); let id = mtt.validate_session(None, None);
let result = mtt.validate_session(Some(id.to_string())); let result = mtt.validate_session(Some(id.to_string()), None);
assert_eq!(result, id); assert_eq!(result, id);
} }
@@ -63,7 +64,7 @@ fn returns_same_session_id_when_valid() {
fn is_expiration_date_set_in_the_future() { fn is_expiration_date_set_in_the_future() {
let mut mtt = MoreThanText::new(); let mut mtt = MoreThanText::new();
let start_time = Utc::now() + Duration::from_hours(1); let start_time = Utc::now() + Duration::from_hours(1);
let id = mtt.validate_session(None); let id = mtt.validate_session(None, None);
let end_time = Utc::now() + Duration::from_hours(1); let end_time = Utc::now() + Duration::from_hours(1);
let rec = get_session(&mut mtt, &id).unwrap(); let rec = get_session(&mut mtt, &id).unwrap();
let holder = rec.get(Name::english("expire")).unwrap(); let holder = rec.get(Name::english("expire")).unwrap();
@@ -80,7 +81,7 @@ fn is_expiration_date_set_in_the_future() {
fn are_session_ids_unique_on_update() { fn are_session_ids_unique_on_update() {
let mut mtt = MoreThanText::new(); let mut mtt = MoreThanText::new();
let id_name = Name::english("id"); let id_name = Name::english("id");
let id = mtt.validate_session(None); let id = mtt.validate_session(None, None);
let mut addition = Addition::new(doc_name()); let mut addition = Addition::new(doc_name());
addition.add_field(id_name.clone(), id); addition.add_field(id_name.clone(), id);
let mut error = MTTError::new(ErrorID::IndexEntryAlreadyExists(id.into())); let mut error = MTTError::new(ErrorID::IndexEntryAlreadyExists(id.into()));
@@ -98,7 +99,7 @@ fn does_expire_updates_on_query() {
let expire_name = Name::english("expire"); let expire_name = Name::english("expire");
let mut test_env = TestMoreThanText::new(); let mut test_env = TestMoreThanText::new();
let mut mtt = test_env.get_morethantext(); let mut mtt = test_env.get_morethantext();
let id = mtt.validate_session(None); let id = mtt.validate_session(None, None);
let path = Path::new( let path = Path::new(
Include::All, Include::All,
Include::Just(doc_name().into()), Include::Just(doc_name().into()),
@@ -106,7 +107,7 @@ fn does_expire_updates_on_query() {
); );
test_env.register_channel(vec![path]); test_env.register_channel(vec![path]);
let start_time: Field = (Utc::now() + Duration::from_secs(3600)).into(); let start_time: Field = (Utc::now() + Duration::from_secs(3600)).into();
mtt.validate_session(Some(id.to_string())); mtt.validate_session(Some(id.to_string()), None);
let end_time: Field = (Utc::now() + Duration::from_secs(3601)).into(); let end_time: Field = (Utc::now() + Duration::from_secs(3601)).into();
let result = test_env.get_trigger_records(Action::OnUpdate); let result = test_env.get_trigger_records(Action::OnUpdate);
assert_eq!(result.len(), 1); assert_eq!(result.len(), 1);
@@ -123,9 +124,9 @@ fn are_expired_sessions_removed() {
let mut test_env = TestMoreThanText::new(); let mut test_env = TestMoreThanText::new();
let mut mtt = test_env.get_morethantext(); let mut mtt = test_env.get_morethantext();
for _ in 0..5 { for _ in 0..5 {
mtt.validate_session(None); mtt.validate_session(None, None);
} }
let id = mtt.validate_session(None); let id = mtt.validate_session(None, None);
let mut update = Update::new(doc_name()); let mut update = Update::new(doc_name());
let mut calc = Calculation::new(Operand::Equal); let mut calc = Calculation::new(Operand::Equal);
calc.add_value(CalcValue::Existing(FieldType::Uuid)) calc.add_value(CalcValue::Existing(FieldType::Uuid))
@@ -149,3 +150,62 @@ fn are_expired_sessions_removed() {
let rec = result.iter().last().unwrap(); let rec = result.iter().last().unwrap();
assert_eq!(rec.get(id_name).unwrap(), id.into()); assert_eq!(rec.get(id_name).unwrap(), id.into());
} }
#[test]
fn is_english_the_default_language() {
let lang_name = Name::english("language");
let lang = Language::from_639_1("en").unwrap();
let mut test_env = TestMoreThanText::new();
let mut mtt = test_env.get_morethantext();
let path = Path::new(
Include::All,
Include::Just(doc_name().into()),
Include::Just(Action::OnAddition),
);
test_env.register_channel(vec![path]);
let id = mtt.validate_session(None, None);
let result = test_env.get_trigger_records(Action::OnAddition);
assert_eq!(result.len(), 1, "incorrect number of records");
let rec = result.iter().last().unwrap();
assert_eq!(rec.get(&lang_name).unwrap(), lang.into());
}
#[test]
fn can_language_be_assigned() {
let lang_name = Name::english("language");
let lang = Language::from_639_1("ja").unwrap();
let mut test_env = TestMoreThanText::new();
let mut mtt = test_env.get_morethantext();
let path = Path::new(
Include::All,
Include::Just(doc_name().into()),
Include::Just(Action::OnAddition),
);
test_env.register_channel(vec![path]);
let id = mtt.validate_session(None, Some(lang.clone()));
let result = test_env.get_trigger_records(Action::OnAddition);
assert_eq!(result.len(), 1, "incorrect number of records");
let rec = result.iter().last().unwrap();
assert_eq!(rec.get(&lang_name).unwrap(), lang.into());
}
#[test]
fn does_not_change_language() {
let lang_name = Name::english("language");
let elang = Language::from_639_1("en").unwrap();
let jlang = Language::from_639_1("ja").unwrap();
let mut test_env = TestMoreThanText::new();
let mut mtt = test_env.get_morethantext();
let id = mtt.validate_session(None, Some(jlang.clone()));
let path = Path::new(
Include::All,
Include::Just(doc_name().into()),
Include::Just(Action::OnUpdate),
);
test_env.register_channel(vec![path]);
mtt.validate_session(Some(id.to_string()), Some(elang.clone()));
let result = test_env.get_trigger_records(Action::OnUpdate);
assert_eq!(result.len(), 1, "incorrect number of records");
let rec = result.iter().last().unwrap();
assert_eq!(rec.get(&lang_name).unwrap(), jlang.into());
}