Allows for calculated defaults.
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1s

This commit is contained in:
2025-09-19 08:03:05 -04:00
parent 85e12e20d4
commit 586ccd99bd
2 changed files with 348 additions and 172 deletions

View File

@@ -1030,7 +1030,7 @@ enum Field {
Boolean(bool),
DateTime(DateTime<Utc>),
Duration(Duration),
Integer(u128),
Integer(i128),
None,
StaticString(String),
Uuid(Uuid),
@@ -1078,8 +1078,8 @@ impl From<Uuid> for Field {
}
}
impl From<u128> for Field {
fn from(value: u128) -> Self {
impl From<i128> for Field {
fn from(value: i128) -> Self {
Self::Integer(value)
}
}
@@ -1138,19 +1138,32 @@ mod fields {
#[derive(Clone, Debug)]
struct FieldSetting {
fieldtype: FieldType,
use_default: bool,
default_value: Field,
default_value: Option<Calculation>,
// use_default: bool,
// default_value: Field,
}
impl FieldSetting {
fn new(ftype: FieldType) -> Self {
Self {
fieldtype: ftype,
use_default: false,
default_value: Field::None,
default_value: None,
// use_default: false,
// default_value: Field::None,
}
}
fn set_default(&mut self, value: Calculation) -> Result<(), MTTError> {
let data = value.calculate();
match self.validate(Some(data)) {
Ok(_) => {}
Err(err) => return Err(err),
}
self.default_value = Some(value);
Ok(())
}
/*
fn set_default(&mut self, value: Option<Field>) -> Result<(), MTTError> {
match value {
Some(data) => {
@@ -1165,6 +1178,7 @@ impl FieldSetting {
self.use_default = true;
Ok(())
}
*/
fn validate(&self, value: Option<Field>) -> Result<Field, MTTError> {
match value {
@@ -1179,6 +1193,11 @@ impl FieldSetting {
Ok(data.clone())
}
None => {
match &self.default_value {
Some(calc) => Ok(calc.calculate()),
None => Err(MTTError::DocumentFieldMissing("".to_string())),
}
/*
if self.use_default {
match self.default_value {
Field::None => Ok(self.fieldtype.get_default()),
@@ -1187,6 +1206,7 @@ impl FieldSetting {
} else {
Err(MTTError::DocumentFieldMissing("".to_string()))
}
*/
}
}
}
@@ -1237,7 +1257,9 @@ mod fieldsettings {
#[test]
fn returns_value_if_default_is_set() {
let mut fset = FieldSetting::new(FieldType::StaticString);
fset.set_default(None);
let mut calc = Calculation::new(Operand::Assign);
calc.add_value(FieldType::StaticString);
fset.set_default(calc);
match fset.validate(None) {
Ok(data) => assert_eq!(data, "".into()),
Err(err) => unreachable!("got {:?}: should have gotten a value", err),
@@ -1248,18 +1270,23 @@ mod fieldsettings {
fn returns_default_value() {
let mut fset = FieldSetting::new(FieldType::StaticString);
let input = "fred";
fset.set_default(Some(input.into()));
let mut calc = Calculation::new(Operand::Assign);
calc.add_value(input);
fset.set_default(calc);
match fset.validate(None) {
Ok(data) => assert_eq!(data, input.into()),
Err(err) => unreachable!("got {:?}: should have gotten a value", err),
}
}
//#[test]
#[test]
fn can_default_be_calculated() {
let mut fset = FieldSetting::new(FieldType::DateTime);
fset.set_default(None);
let duration = Duration::from_secs(3600);
let mut calc = Calculation::new(Operand::Add);
calc.add_value(FieldType::DateTime);
calc.add_value(duration);
fset.set_default(calc);
let start = Utc::now() + duration;
let result = match fset.validate(None).unwrap() {
Field::DateTime(data) => data,
@@ -1273,7 +1300,7 @@ mod fieldsettings {
start
);
assert!(
result > stop,
result < stop,
"{:?} should have been less than {:?}",
result,
stop
@@ -1406,7 +1433,7 @@ impl DocDef {
setting.validate(value)
}
fn set_default(&mut self, field_name: &str, value: Option<Field>) -> Result<(), MTTError> {
fn set_default(&mut self, field_name: &str, value: Calculation) -> Result<(), MTTError> {
let setting = match self.get_field_mut(field_name) {
Ok(data) => data,
Err(err) => return Err(err),
@@ -1487,7 +1514,9 @@ mod docdefs {
let mut docdef = DocDef::new();
let name = "defaultfunction";
docdef.add_field(name.to_string(), FieldType::StaticString);
docdef.set_default(name, None);
let mut calc = Calculation::new(Operand::Assign);
calc.add_value(FieldType::StaticString);
docdef.set_default(name, calc);
match docdef.get_field(name).unwrap().validate(None) {
Ok(data) => match data {
Field::StaticString(result) => assert_eq!(result, ""),
@@ -1501,7 +1530,8 @@ mod docdefs {
fn does_set_default_function_error_on_bad_field_name() {
let mut docdef = DocDef::new();
let field_name = Uuid::new_v4().to_string();
match docdef.set_default(field_name.as_str(), None) {
let calc = Calculation::new(Operand::Assign);
match docdef.set_default(field_name.as_str(), calc) {
Ok(_) => unreachable!("should be an error"),
Err(err) => match err {
MTTError::DocumentFieldNotFound(data) => assert_eq!(data, field_name),
@@ -1514,7 +1544,9 @@ mod docdefs {
fn does_set_default_value_error_on_bad_field_name() {
let mut docdef = DocDef::new();
let field_name = Uuid::new_v4().to_string();
match docdef.set_default(field_name.as_str(), Some(Uuid::nil().into())) {
let mut calc = Calculation::new(Operand::Assign);
calc.add_value(Uuid::new_v4());
match docdef.set_default(field_name.as_str(), calc) {
Ok(_) => unreachable!("should be an error"),
Err(err) => match err {
MTTError::DocumentFieldNotFound(data) => assert_eq!(data, field_name),
@@ -1528,7 +1560,9 @@ mod docdefs {
let mut docdef = DocDef::new();
let name = "defaultvalue";
docdef.add_field(name.to_string(), FieldType::Uuid);
match docdef.set_default(name, Some("".into())) {
let mut calc = Calculation::new(Operand::Assign);
calc.add_value("fred");
match docdef.set_default(name, calc) {
Ok(data) => unreachable!("got {:?}, should be an error", data),
Err(err) => match err {
MTTError::DocumentFieldWrongDataType(expected, got) => {
@@ -1626,8 +1660,8 @@ impl From<Duration> for CalcValue {
}
}
impl From<u128> for CalcValue {
fn from(value: u128) -> Self {
impl From<i128> for CalcValue {
fn from(value: i128) -> Self {
let output: Field = value.into();
Self::from(output).into()
}
@@ -1726,7 +1760,7 @@ mod calcvalues {
#[test]
fn from_integer() {
let value: u128 = 5;
let value: i128 = 5;
let expected: Field = value.clone().into();
let result: CalcValue = value.into();
match result {
@@ -1768,13 +1802,15 @@ impl Calculation {
} else {
match self.operation {
Operand::Add => {
if self.values[0].get().get_type() == holder.get().get_type() {
let mut base = self.values[0].get().get_type();
if base == FieldType::DateTime {
base = FieldType::Duration;
}
let ftype = holder.get().get_type();
if base == ftype {
self.values.push(holder);
} else {
return Err(MTTError::DocumentFieldWrongDataType(
FieldType::None,
FieldType::None,
));
return Err(MTTError::DocumentFieldWrongDataType(base, ftype));
}
}
_ => self.values.push(holder),
@@ -1788,8 +1824,19 @@ impl Calculation {
Operand::Add => {
let values = self.get_fields();
match values[0].get_type() {
FieldType::DateTime => {
let mut output = Utc::now();
for item in values.iter() {
match item {
Field::DateTime(datetime) => output = datetime.clone(),
Field::Duration(duration) => output += duration.clone(),
_ => unreachable!("got {:?}, should have been a duration", item),
}
}
output.into()
}
FieldType::Integer => {
let mut output: u128 = 0;
let mut output: i128 = 0;
for item in values.iter() {
match item {
Field::Integer(data) => output += data,
@@ -1856,8 +1903,8 @@ mod calculations {
#[test]
fn can_add_numbers() {
let mut calc = Calculation::new(Operand::Add);
let value1: u128 = random::<u8>().into();
let value2: u128 = random::<u8>().into();
let value1: i128 = random::<u8>().into();
let value2: i128 = random::<u8>().into();
let expected: Field = { value1 + value2 }.into();
let value1: Field = value1.into();
let value2: Field = value2.into();
@@ -1873,7 +1920,34 @@ mod calculations {
calc.add_value(Uuid::nil());
match calc.add_value("mismatch") {
Ok(_) => unreachable!("should have returned an error"),
Err(_) => {}
Err(err) => match err {
MTTError::DocumentFieldWrongDataType(expected, got) => {
assert_eq!(got, FieldType::StaticString);
assert_eq!(expected, FieldType::Uuid);
}
_ => unreachable!("got {:?}, expected wrong field type", err),
},
}
}
#[test]
fn datetime_accepts_duration() {
let mut calc = Calculation::new(Operand::Add);
let duration = Duration::from_secs(3600);
let start = Utc::now() + duration;
calc.add_value(FieldType::DateTime).unwrap();
match calc.add_value(duration.clone()) {
Ok(_) => {}
Err(err) => unreachable!("got {:?}, should have returned normally", err),
}
let result = calc.calculate();
let stop = Utc::now() + duration;
match result {
Field::DateTime(data) => {
assert!(data > start);
assert!(data < stop);
}
_ => unreachable!("got {:?}, should have been datetime", result),
}
}
}
@@ -3036,7 +3110,9 @@ mod document_files {
#[test]
fn can_use_default_values() {
let (mut docdef, doc_name) = create_docdef([FieldType::StaticString].to_vec());
docdef.set_default("field0", None);
let mut calc = Calculation::new(Operand::Assign);
calc.add_value(FieldType::StaticString);
docdef.set_default("field0", calc);
let (queue, rx) = test_doc(doc_name.as_str(), docdef, standard_routes());
let new_doc = Addition::new();
let msg = Message::new(doc_name, new_doc);
@@ -3059,7 +3135,9 @@ mod document_files {
fn can_a_default_value_be_set() {
let (mut docdef, doc_name) = create_docdef([FieldType::Uuid].to_vec());
let input = Uuid::nil();
docdef.set_default("field0", Some(input.into()));
let mut calc = Calculation::new(Operand::Assign);
calc.add_value(input.clone());
docdef.set_default("field0", calc);
let (queue, rx) = test_doc(doc_name.as_str(), docdef, standard_routes());
let new_doc = Addition::new();
let msg = Message::new(doc_name, new_doc);
@@ -3081,7 +3159,9 @@ mod document_files {
#[test]
fn can_default_values_be_overridden() {
let (mut docdef, doc_name) = create_docdef([FieldType::Uuid].to_vec());
docdef.set_default("field0", None);
let mut calc = Calculation::new(Operand::Assign);
calc.add_value(FieldType::Uuid);
docdef.set_default("field0", calc);
let (queue, rx) = test_doc(doc_name.as_str(), docdef, standard_routes());
let mut new_doc = Addition::new();
new_doc.add_field("field0".to_string(), Uuid::nil());