From aa7d5ae1f66ed524ff042d742ced65a2bde30ea3 Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Sun, 8 Feb 2026 11:59:54 -0500 Subject: [PATCH] Moved CalcValue into action. --- src/action.rs | 9 +- src/action/calculation.rs | 217 +++++++++++++++++++++++++++++++++++++ src/action/request_data.rs | 11 +- src/document/clock.rs | 4 +- src/document/create.rs | 9 +- src/document/definition.rs | 8 +- src/document/session.rs | 7 +- src/lib.rs | 13 +-- src/message/wrapper.rs | 4 +- 9 files changed, 239 insertions(+), 43 deletions(-) create mode 100644 src/action/calculation.rs diff --git a/src/action.rs b/src/action.rs index 7f6d9e6..01a5289 100644 --- a/src/action.rs +++ b/src/action.rs @@ -1,12 +1,17 @@ mod action_type; +mod calculation; mod message; mod query; mod request_data; mod user; +pub use crate::document::{ + definition::DocDef, + field::{Field, FieldType}, +}; pub use action_type::Action; -pub use crate::document::{definition::DocDef, field::FieldType}; +pub use calculation::CalcValue; pub use message::MsgAction; pub use query::Query; -pub use user::UserAction; use request_data::RequestData; +pub use user::UserAction; diff --git a/src/action/calculation.rs b/src/action/calculation.rs new file mode 100644 index 0000000..721385f --- /dev/null +++ b/src/action/calculation.rs @@ -0,0 +1,217 @@ +use super::{Field, FieldType}; +use crate::message::wrapper::{Calculation, Operand}; +use chrono::{DateTime, Utc}; +use std::time::Duration; +use uuid::Uuid; + +#[derive(Clone, Debug)] +pub enum CalcValue { + Calculate(Calculation), + Existing(FieldType), + FType(FieldType), + None, + Value(Field), +} + +impl CalcValue { + pub fn get(&self, existing: &Field) -> Field { + match self { + Self::Calculate(calc) => calc.calculate(existing), + Self::Existing(_) => existing.clone(), + Self::FType(ftype) => ftype.get_default(), + Self::None => Field::None, + Self::Value(field) => field.clone(), + } + } + + pub fn get_type(&self) -> FieldType { + match self { + Self::Calculate(calc) => calc.get_type(), + Self::Existing(ftype) => ftype.clone(), + Self::FType(ftype) => ftype.clone(), + Self::None => FieldType::None, + Self::Value(field) => field.into(), + } + } +} + +impl From for CalcValue { + fn from(value: Calculation) -> Self { + Self::Calculate(value) + } +} + +impl From for CalcValue { + fn from(value: Field) -> Self { + Self::Value(value) + } +} + +impl From<&Field> for CalcValue { + fn from(value: &Field) -> Self { + Self::from(value.clone()) + } +} + +impl From for CalcValue { + fn from(value: FieldType) -> Self { + Self::FType(value) + } +} + +impl From for CalcValue { + fn from(value: bool) -> Self { + let output: Field = value.into(); + Self::from(output).into() + } +} + +impl From> for CalcValue { + fn from(value: DateTime) -> Self { + let output: Field = value.into(); + Self::from(output).into() + } +} + +impl From for CalcValue { + fn from(value: Duration) -> Self { + let output: Field = value.into(); + Self::from(output).into() + } +} + +impl From for CalcValue { + fn from(value: i128) -> Self { + let output: Field = value.into(); + Self::from(output).into() + } +} + +impl From<&str> for CalcValue { + fn from(value: &str) -> Self { + let output: Field = value.into(); + Self::from(output).into() + } +} + +impl From for CalcValue { + fn from(value: String) -> Self { + let output: Field = value.into(); + Self::from(output).into() + } +} + +impl From for CalcValue { + fn from(value: Uuid) -> Self { + let output: Field = value.into(); + Self::from(output).into() + } +} + +#[cfg(test)] +mod calcvalues { + use super::*; + + #[test] + fn from_uuid() { + let value = Uuid::new_v4(); + let expected: Field = value.into(); + let result: CalcValue = value.into(); + match result.clone() { + CalcValue::Value(data) => assert_eq!(data, expected), + _ => unreachable!("got {:?}, should have gotten a field", result), + } + assert_eq!(result.get(&Field::None), expected); + } + + #[test] + fn from_str() { + let value = "something"; + let expected: Field = value.into(); + let result: CalcValue = value.into(); + match result.clone() { + CalcValue::Value(data) => assert_eq!(data, expected), + _ => unreachable!("got {:?}, should have gotten a field", result), + } + assert_eq!(result.get(&Field::None), expected); + } + + #[test] + fn from_string() { + let value = "data".to_string(); + let expected: Field = value.clone().into(); + let result: CalcValue = value.into(); + match result.clone() { + CalcValue::Value(data) => assert_eq!(data, expected), + _ => unreachable!("got {:?}, should have gotten a field", result), + } + assert_eq!(result.get(&Field::None), expected); + } + + #[test] + fn from_boolean() { + let value = true; + let expected: Field = value.clone().into(); + let result: CalcValue = value.into(); + match result.clone() { + CalcValue::Value(data) => assert_eq!(data, expected), + _ => unreachable!("got {:?}, should have gotten a field", result), + } + assert_eq!(result.get(&Field::None), expected); + } + + #[test] + fn from_datetime() { + let value = Utc::now(); + let expected: Field = value.clone().into(); + let result: CalcValue = value.into(); + match result.clone() { + CalcValue::Value(data) => assert_eq!(data, expected), + _ => unreachable!("got {:?}, should have gotten a field", result), + } + assert_eq!(result.get(&Field::None), expected); + } + + #[test] + fn from_duration() { + let value = Duration::from_secs(5); + let expected: Field = value.clone().into(); + let result: CalcValue = value.into(); + match result.clone() { + CalcValue::Value(data) => assert_eq!(data, expected), + _ => unreachable!("got {:?}, should have gotten a field", result), + } + assert_eq!(result.get(&Field::None), expected); + } + + #[test] + fn from_integer() { + let value: i128 = 5; + let expected: Field = value.clone().into(); + let result: CalcValue = value.into(); + match result.clone() { + CalcValue::Value(data) => assert_eq!(data, expected), + _ => unreachable!("got {:?}, should have gotten a field", result), + } + assert_eq!(result.get(&Field::None), expected); + } + + #[test] + fn from_calculation() { + let duration = Duration::from_secs(300); + let start = Utc::now() + duration; + let mut calc = Calculation::new(Operand::Add); + calc.add_value(FieldType::DateTime).unwrap(); + calc.add_value(duration.clone()).unwrap(); + let result: CalcValue = calc.into(); + let data = match result.get(&Field::None) { + Field::DateTime(data) => data, + _ => unreachable!(), + }; + let stop = Utc::now() + duration; + assert!( + data > start && data < stop, + "should be about 5 minutes ahead" + ); + } +} diff --git a/src/action/request_data.rs b/src/action/request_data.rs index 92ff3e6..882dead 100644 --- a/src/action/request_data.rs +++ b/src/action/request_data.rs @@ -1,6 +1,5 @@ use crate::{ - document::field::Field, - message::wrapper::CalcValue, + action::{CalcValue, Field}, name::NameType, }; use std::collections::HashMap; @@ -35,14 +34,6 @@ impl RequestData { } } - fn get_all(&self) -> Vec<(NameType, Field)> { - let mut output = Vec::new(); - for (key, value) in self.data.iter() { - output.push((key.clone(), value.get(&Field::None))); - } - output - } - pub fn iter(&self) -> impl Iterator { self.data.iter() } diff --git a/src/document/clock.rs b/src/document/clock.rs index 78cd2e3..5590486 100644 --- a/src/document/clock.rs +++ b/src/document/clock.rs @@ -1,8 +1,6 @@ use crate::{ action::{Action, MsgAction}, - message::{ - wrapper::{Message, Records}, - }, + message::wrapper::{Message, Records}, name::{Name, NameType, Names}, queue::{ data_director::{Include, Path, RegMsg, Register}, diff --git a/src/document/create.rs b/src/document/create.rs index d7cc9fe..3878d79 100644 --- a/src/document/create.rs +++ b/src/document/create.rs @@ -1,14 +1,11 @@ use crate::{ - action::{Action, MsgAction, Query}, + action::{Action, CalcValue, MsgAction, Query}, document::{ definition::{DocDef, DocFuncType}, field::Field, }, - message::{ - wrapper::{ - CalcValue, Calculation, InternalRecord, InternalRecords, Message, Oid, Records, Reply, - Update, - }, + message::wrapper::{ + Calculation, InternalRecord, InternalRecords, Message, Oid, Records, Reply, Update, }, mtterror::MTTError, name::NameType, diff --git a/src/document/definition.rs b/src/document/definition.rs index 3cb7cc1..c093125 100644 --- a/src/document/definition.rs +++ b/src/document/definition.rs @@ -1,10 +1,6 @@ use crate::{ - action::{Action, MsgAction}, - document::{ - create::IndexType, - field::{Field, FieldType}, - }, - message::wrapper::CalcValue, + action::{Action, CalcValue, Field, FieldType, MsgAction}, + document::create::IndexType, mtterror::MTTError, name::{Name, NameType, Names}, queue::data_director::{Include, Path}, diff --git a/src/document/session.rs b/src/document/session.rs index 8886a7c..6a28ae7 100644 --- a/src/document/session.rs +++ b/src/document/session.rs @@ -1,14 +1,11 @@ use crate::{ - action::{Action, Query}, + action::{Action, CalcValue, FieldType, Query}, document::{ clock::Clock, create::IndexType, definition::{DocDef, DocFuncType}, - field::FieldType, - }, - message::{ - wrapper::{CalcValue, Calculation, Delete, Message, Operand, Update}, }, + message::wrapper::{Calculation, Delete, Message, Operand, Update}, name::{Name, NameType}, queue::{ data_director::{Include, Path, RegMsg, Register}, diff --git a/src/lib.rs b/src/lib.rs index 7a56c02..2661b3a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,16 +5,9 @@ mod mtterror; mod name; mod queue; -use action::{Action, DocDef, MsgAction, Query, UserAction}; -use document::{ - clock::Clock, - create::CreateDoc, - field::{Field, FieldType}, - session::Session, -}; -use message::{ - wrapper::{Addition, CalcValue, Calculation, Message, Operand}, -}; +use action::{Action, CalcValue, DocDef, Field, FieldType, MsgAction, Query, UserAction}; +use document::{clock::Clock, create::CreateDoc, session::Session}; +use message::wrapper::{Addition, Calculation, Message, Operand}; pub use mtterror::MTTError; pub use name::{Name, NameType}; use queue::{ diff --git a/src/message/wrapper.rs b/src/message/wrapper.rs index 6d42add..b0bc020 100644 --- a/src/message/wrapper.rs +++ b/src/message/wrapper.rs @@ -1,5 +1,5 @@ use crate::{ - action::{MsgAction, Query}, + action::{CalcValue, MsgAction, Query}, document::field::{Field, FieldType}, mtterror::MTTError, name::{NameType, Names}, @@ -407,6 +407,7 @@ mod operands { } } +/* #[derive(Clone, Debug)] pub enum CalcValue { Calculate(Calculation), @@ -618,6 +619,7 @@ mod calcvalues { ); } } +*/ #[derive(Clone, Debug)] pub struct Calculation {