diff --git a/src/document/field.rs b/src/document/field.rs index 864ee9d..de3fbfe 100644 --- a/src/document/field.rs +++ b/src/document/field.rs @@ -16,6 +16,7 @@ pub enum Field { DateTime(DateTime), Duration(Duration), Integer(i128), + Language(Language), None, StaticString(String), Uuid(Uuid), @@ -111,6 +112,12 @@ impl From for Field { } } +impl From for Field { + fn from(value: Language) -> Self { + Self::Language(value) + } +} + impl PartialOrd for Field { fn partial_cmp(&self, other: &Field) -> Option { match (self, other) { @@ -272,6 +279,7 @@ pub enum FieldType { DateTime, Duration, Integer, + Language, None, StaticString, Uuid, @@ -284,6 +292,7 @@ impl FieldType { FieldType::DateTime => Utc::now().into(), FieldType::Duration => Duration::from_secs(0).into(), FieldType::Integer => 0.into(), + FieldType::Language => Language::from_639_1("en").unwrap().into(), FieldType::None => Field::None, FieldType::StaticString => "".into(), FieldType::Uuid => Uuid::new_v4().into(), @@ -298,6 +307,7 @@ impl From<&Field> for FieldType { Field::DateTime(_) => Self::DateTime, Field::Duration(_) => Self::Duration, Field::Integer(_) => Self::Integer, + Field::Language(_) => Self::Language, Field::None => Self::None, Field::StaticString(_) => Self::StaticString, Field::Uuid(_) => Self::Uuid, diff --git a/src/document/session.rs b/src/document/session.rs index f26795f..ce26a03 100644 --- a/src/document/session.rs +++ b/src/document/session.rs @@ -38,9 +38,17 @@ impl Session { names } + pub fn language_field_names() -> Vec { + let mut names = Vec::new(); + names.push(Name::english("language")); + names.push(Name::japanese("言語")); + names + } + pub fn document_definition() -> DocDef { let name_id = Self::id_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()); @@ -56,6 +64,9 @@ impl Session { docdef.set_default(&name_expire, calc.clone()).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()); update .get_values_mut() diff --git a/src/lib.rs b/src/lib.rs index a6263c0..c569deb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ pub mod name; mod queue; use document::{Clock, CreateDoc, Session}; +use isolang::Language; use message::{wrapper::Message, MessageAction}; use queue::{ data_director::{RegMsg, Register}, @@ -56,18 +57,27 @@ impl MoreThanText { output } - fn new_session() -> ClientAction { - Addition::new(Session::doc_names()[0].clone()).into() + fn new_session(lang: Option) -> ClientAction { + 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(&mut self, action: UA) -> Uuid + fn recursive_message_request(&mut self, action: CA, lang: Option) -> Uuid where - UA: Into, + CA: Into, { match self.records(action) { Ok(data) => { if data.len() == 0 { - self.recursive_message_request(MoreThanText::new_session()) + self.recursive_message_request(MoreThanText::new_session(lang), lang) } else { let rec = data.iter().last().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) -> Uuid { + pub fn validate_session(&mut self, session: Option, lang: Option) -> Uuid { let action = match session { Some(data) => match Uuid::try_from(data.as_str()) { Ok(id) => { @@ -92,11 +102,11 @@ impl MoreThanText { query.add(Name::english("id"), calc); 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(&mut self, request: UA) -> Result diff --git a/src/main.rs b/src/main.rs index 7359965..f6f47a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -73,7 +73,9 @@ where let requested = req_id.clone(); let (tx, mut rx) = channel(1); 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(); if !req_id.is_some_and(|x| x == id.to_string()) { diff --git a/tests/session_test.rs b/tests/session_test.rs index bc359fa..c2dcc00 100644 --- a/tests/session_test.rs +++ b/tests/session_test.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, Utc}; +use isolang::Language; use morethantext::{ action::{Addition, CalcValue, Calculation, Field, FieldType, Operand, Query, Record}, Action, ErrorID, Include, MTTError, MoreThanText, Name, Path, TestMoreThanText, Update, @@ -29,7 +30,7 @@ fn are_session_ids_unique() { let count = 10; let mut result: Vec = Vec::new(); 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); result.push(id); } @@ -38,24 +39,24 @@ fn are_session_ids_unique() { #[test] fn bad_session_id_returns_new_id() { let mut mtt = MoreThanText::new(); - let id1 = mtt.validate_session(Some("stuff".to_string())); - let id2 = 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()), None); assert_ne!(id1, id2); } #[test] fn creates_new_session_if_bad_or_expired() { let mut mtt = MoreThanText::new(); - let id1 = mtt.validate_session(Some(Uuid::nil().to_string())); - let id2 = 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()), None); assert_ne!(id1, id2); } #[test] fn returns_same_session_id_when_valid() { let mut mtt = MoreThanText::new(); - let id = mtt.validate_session(None); - let result = mtt.validate_session(Some(id.to_string())); + let id = mtt.validate_session(None, None); + let result = mtt.validate_session(Some(id.to_string()), None); assert_eq!(result, id); } @@ -63,7 +64,7 @@ fn returns_same_session_id_when_valid() { fn is_expiration_date_set_in_the_future() { let mut mtt = MoreThanText::new(); 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 rec = get_session(&mut mtt, &id).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() { let mut mtt = MoreThanText::new(); 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()); addition.add_field(id_name.clone(), id); 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 mut test_env = TestMoreThanText::new(); let mut mtt = test_env.get_morethantext(); - let id = mtt.validate_session(None); + let id = mtt.validate_session(None, None); let path = Path::new( Include::All, Include::Just(doc_name().into()), @@ -106,7 +107,7 @@ fn does_expire_updates_on_query() { ); test_env.register_channel(vec![path]); 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 result = test_env.get_trigger_records(Action::OnUpdate); assert_eq!(result.len(), 1); @@ -123,9 +124,9 @@ fn are_expired_sessions_removed() { let mut test_env = TestMoreThanText::new(); let mut mtt = test_env.get_morethantext(); 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 calc = Calculation::new(Operand::Equal); calc.add_value(CalcValue::Existing(FieldType::Uuid)) @@ -149,3 +150,62 @@ fn are_expired_sessions_removed() { let rec = result.iter().last().unwrap(); 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()); +}