diff --git a/src/message.rs b/src/message.rs index b3a57f2..05acb1d 100644 --- a/src/message.rs +++ b/src/message.rs @@ -948,6 +948,7 @@ impl CreateDoc { #[derive(Clone, Debug, PartialEq)] enum FieldType { + None, StaticString, Uuid, } @@ -955,6 +956,7 @@ enum FieldType { impl FieldType { fn get_default(&self) -> Field { match self { + FieldType::None => Field::None, FieldType::StaticString => "".into(), FieldType::Uuid => Uuid::new_v4().into(), } @@ -964,6 +966,7 @@ impl FieldType { impl From<&Field> for FieldType { fn from(value: &Field) -> Self { match value { + Field::None => Self::None, Field::StaticString(_) => Self::StaticString, Field::Uuid(_) => Self::Uuid, } @@ -1008,6 +1011,7 @@ mod fieldtypes { #[derive(Clone, Debug, PartialEq)] enum Field { + None, StaticString(String), Uuid(Uuid), } @@ -1076,37 +1080,35 @@ mod fields { } } -#[derive(Clone, Debug)] -enum DefaultSetting { - Value(Field), - FieldType, - None, -} - #[derive(Clone, Debug)] struct FieldSetting { fieldtype: FieldType, - default_setting: DefaultSetting, + use_default: bool, + default_value: Field, } impl FieldSetting { fn new(ftype: FieldType) -> Self { Self { fieldtype: ftype, - default_setting: DefaultSetting::None, + use_default: false, + default_value: Field::None, } } - fn get_type(&self) -> &FieldType { - &self.fieldtype - } - - fn set_default(&mut self, value: DefaultSetting) { - self.default_setting = value; - } - - fn get_default(&self) -> &DefaultSetting { - &self.default_setting + fn set_default(&mut self, value: Option) -> Result<(), MTTError> { + match value { + Some(data) => { + match self.check(Some(data.clone())) { + Ok(_) => {} + Err(err) => return Err(err), + } + self.default_value = data.clone(); + } + None => self.default_value = Field::None, + } + self.use_default = true; + Ok(()) } fn check(&self, value: Option) -> Result { @@ -1121,7 +1123,16 @@ impl FieldSetting { } Ok(data.clone()) } - None => Err(MTTError::DocumentFieldMissing("".to_string())), + None => { + if self.use_default { + match self.default_value { + Field::None => Ok(self.fieldtype.get_default()), + _ => Ok(self.default_value.clone()), + } + } else { + Err(MTTError::DocumentFieldMissing("".to_string())) + } + } } } } @@ -1169,27 +1180,23 @@ mod fieldsettings { } #[test] - fn can_field_type_be_assigned() { - let ftypes = [FieldType::StaticString, FieldType::Uuid]; - for ftype in ftypes.into_iter() { - let fieldinfo = FieldSetting::new(ftype.clone()); - assert_eq!(fieldinfo.get_type(), &ftype); - let dset = fieldinfo.get_default(); - match dset { - DefaultSetting::None => {} - _ => unreachable!("got {:?}: should have been none", dset), - } + fn returns_value_if_default_is_set() { + let mut fset = FieldSetting::new(FieldType::StaticString); + fset.set_default(None); + match fset.check(None) { + Ok(data) => assert_eq!(data, "".into()), + Err(err) => unreachable!("got {:?}: should have gotten a value", err), } } #[test] - fn can_default_be_changed() { - let mut fieldinfo = FieldSetting::new(FieldType::Uuid); - fieldinfo.set_default(DefaultSetting::FieldType); - let dset = fieldinfo.get_default(); - match dset { - DefaultSetting::FieldType => {} - _ => unreachable!("got {:?}: should have been none", dset), + fn returns_default_value() { + let mut fset = FieldSetting::new(FieldType::StaticString); + let input = "fred"; + fset.set_default(Some(input.into())); + match fset.check(None) { + Ok(data) => assert_eq!(data, input.into()), + Err(err) => unreachable!("got {:?}: should have gotten a value", err), } } } @@ -1294,32 +1301,14 @@ impl DocDef { } } - fn use_default_function(&mut self, field_name: &str) -> Result<(), MTTError> { + fn set_default(&mut self, field_name: &str, value: Option) -> Result<(), MTTError> { let setting = match self.get_field_mut(field_name) { Ok(data) => data, Err(err) => return Err(err), }; - setting.set_default(DefaultSetting::FieldType); - Ok(()) - } - - fn set_default_value(&mut self, field_name: &str, value: F) -> Result<(), MTTError> - where - F: Into, - { - let setting = match self.get_field_mut(field_name) { - Ok(data) => data, - Err(err) => return Err(err), - }; - let data = value.into(); - if setting.get_type() == &data.get_type() { - setting.set_default(DefaultSetting::Value(data)); - Ok(()) - } else { - Err(MTTError::DocumentFieldWrongDataType( - setting.get_type().clone(), - data.get_type(), - )) + match setting.set_default(value) { + Ok(_) => Ok(()), + Err(err) => Err(err), } } @@ -1339,7 +1328,10 @@ mod docdefs { let field_type = FieldType::Uuid; docdef.add_field(name.clone(), field_type.clone()); let result = docdef.get_field(name.as_str()).unwrap(); - assert_eq!(result.get_type(), &field_type); + match result.check(Some(Uuid::new_v4().into())) { + Ok(_) => {} + Err(err) => unreachable!("got {:?}: should have been a value", err), + } } #[test] @@ -1365,7 +1357,10 @@ mod docdefs { } for name in names.iter() { let result = docdef.get_field(name).unwrap(); - assert_eq!(result.get_type(), &field_type); + match result.check(Some("".into())) { + Ok(_) => {} + Err(err) => unreachable!("got {:?}: should have been a value", err), + } } } @@ -1374,11 +1369,13 @@ mod docdefs { let mut docdef = DocDef::new(); let name = "defaultfunction"; docdef.add_field(name.to_string(), FieldType::StaticString); - docdef.use_default_function(name); - let dset = docdef.get_field(name).unwrap().get_default(); - match dset { - DefaultSetting::FieldType => {} - _ => unreachable!("got {:?}: should have been field type", dset), + docdef.set_default(name, None); + match docdef.get_field(name).unwrap().check(None) { + Ok(data) => match data { + Field::StaticString(result) => assert_eq!(result, ""), + _ => unreachable!("got {:?}: should return a static string", data), + }, + Err(err) => unreachable!("got {:?}: should return a value", err), } } @@ -1386,7 +1383,7 @@ 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.use_default_function(field_name.as_str()) { + match docdef.set_default(field_name.as_str(), None) { Ok(_) => unreachable!("should be an error"), Err(err) => match err { MTTError::DocumentFieldNotFound(data) => assert_eq!(data, field_name), @@ -1399,7 +1396,7 @@ 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_value(field_name.as_str(), Uuid::nil()) { + match docdef.set_default(field_name.as_str(), Some(Uuid::nil().into())) { Ok(_) => unreachable!("should be an error"), Err(err) => match err { MTTError::DocumentFieldNotFound(data) => assert_eq!(data, field_name), @@ -1413,8 +1410,8 @@ mod docdefs { let mut docdef = DocDef::new(); let name = "defaultvalue"; docdef.add_field(name.to_string(), FieldType::Uuid); - match docdef.set_default_value(name, "") { - Ok(_) => unreachable!("should be an error"), + match docdef.set_default(name, Some("".into())) { + Ok(data) => unreachable!("got {:?}, should be an error", data), Err(err) => match err { MTTError::DocumentFieldWrongDataType(expected, got) => { assert_eq!(expected, FieldType::Uuid); @@ -1742,30 +1739,26 @@ impl DocumentFile { let doc = addition.get_document(); for (key, value) in doc.iter() { match self.docdef.get_field(&key) { + Ok(field_info) => match field_info.check(Some(value.clone())) { + Ok(data) => holder.add_field(key.clone(), value.clone()), + Err(err) => return err.into(), + }, Err(err) => return err.into(), - Ok(field_info) => { - if field_info.get_type() == &value.get_type() { - holder.add_field(key.clone(), value.clone()); - } else { - return MTTError::DocumentFieldWrongDataType( - value.get_type(), - field_info.get_type().clone(), - ) - .into(); - } - } } } for (key, value) in self.docdef.iter() { match holder.get_field(key) { Some(_) => {} - None => match value.get_default() { - DefaultSetting::Value(data) => holder.add_field(key.clone(), data.clone()), - DefaultSetting::FieldType => { - holder.add_field(key.clone(), value.get_type().get_default()) - } - DefaultSetting::None => { - return MTTError::DocumentFieldMissing(key.clone()).into() + None => match value.check(None) { + Ok(data) => holder.add_field(key.clone(), data.clone()), + Err(err) => { + let error = match err { + MTTError::DocumentFieldMissing(_) => { + MTTError::DocumentFieldMissing(key.clone()) + } + _ => err.clone(), + }; + return error.into(); } }, } @@ -1784,16 +1777,10 @@ impl DocumentFile { let mut reply = Reply::new(); for specifier in query.iter() { match self.docdef.get_field(&specifier.field_name) { - Ok(spec) => { - let value_type: FieldType = (&specifier.value).into(); - let wanted_type = spec.get_type(); - if &value_type != wanted_type { - return Err(MTTError::DocumentFieldWrongDataType( - wanted_type.clone(), - value_type.clone(), - )); - } - } + Ok(spec) => match spec.check(Some(specifier.value.clone())) { + Ok(_) => {} + Err(err) => return Err(err), + }, Err(err) => return Err(err), } } @@ -2099,8 +2086,8 @@ mod document_files { let result = rx.recv_timeout(TIMEOUT).unwrap(); match result.get_action() { MsgAction::Error(err) => match err { - MTTError::DocumentFieldWrongDataType(found, expected) => { - assert_eq!(found, &FieldType::StaticString); + MTTError::DocumentFieldWrongDataType(expected, got) => { + assert_eq!(got, &FieldType::StaticString); assert_eq!(expected, &FieldType::Uuid); } _ => unreachable!( @@ -2303,7 +2290,7 @@ mod document_files { #[test] fn can_use_default_values() { let (mut docdef, doc_name) = create_docdef([FieldType::StaticString].to_vec()); - docdef.use_default_function("field0"); + docdef.set_default("field0", None); 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); @@ -2326,7 +2313,7 @@ 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_value("field0", input.clone()); + docdef.set_default("field0", Some(input.into())); 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); @@ -2348,7 +2335,7 @@ mod document_files { #[test] fn can_default_values_be_overridden() { let (mut docdef, doc_name) = create_docdef([FieldType::Uuid].to_vec()); - docdef.use_default_function("field0"); + docdef.set_default("field0", None); 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());