diff --git a/services/comm-services-lib/src/database.rs b/services/comm-services-lib/src/database.rs --- a/services/comm-services-lib/src/database.rs +++ b/services/comm-services-lib/src/database.rs @@ -1,6 +1,8 @@ use aws_sdk_dynamodb::{model::AttributeValue, Error as DynamoDBError}; use chrono::{DateTime, Utc}; +use std::collections::HashMap; use std::fmt::{Display, Formatter}; +use std::num::ParseIntError; #[derive( Debug, derive_more::Display, derive_more::From, derive_more::Error, @@ -12,10 +14,16 @@ Attribute(DBItemError), } +#[derive(Debug)] +pub enum Value { + AttributeValue(Option), + String(String), +} + #[derive(Debug, derive_more::Error, derive_more::Constructor)] pub struct DBItemError { attribute_name: &'static str, - attribute_value: Option, + attribute_value: Value, attribute_error: DBItemAttributeError, } @@ -47,6 +55,8 @@ IncorrectType, #[display(...)] InvalidTimestamp(chrono::ParseError), + #[display(...)] + InvalidNumberFormat(ParseIntError), } pub fn parse_string_attribute( @@ -57,12 +67,12 @@ Some(AttributeValue::S(value)) => Ok(value), Some(_) => Err(DBItemError::new( attribute_name, - attribute_value, + Value::AttributeValue(attribute_value), DBItemAttributeError::IncorrectType, )), None => Err(DBItemError::new( attribute_name, - attribute_value, + Value::AttributeValue(attribute_value), DBItemAttributeError::Missing, )), } @@ -76,12 +86,12 @@ Some(AttributeValue::Bool(value)) => Ok(value), Some(_) => Err(DBItemError::new( attribute_name, - attribute_value, + Value::AttributeValue(attribute_value), DBItemAttributeError::IncorrectType, )), None => Err(DBItemError::new( attribute_name, - attribute_value, + Value::AttributeValue(attribute_value), DBItemAttributeError::Missing, )), } @@ -96,15 +106,47 @@ datetime.parse().map_err(|e| { DBItemError::new( attribute_name, - attribute_value, + Value::AttributeValue(attribute_value), DBItemAttributeError::InvalidTimestamp(e), ) }) } else { Err(DBItemError::new( attribute_name, - attribute_value, + Value::AttributeValue(attribute_value), DBItemAttributeError::Missing, )) } } + +pub fn parse_map_attribute( + attribute_name: &'static str, + attribute_value: Option, +) -> Result, DBItemError> { + match attribute_value { + Some(AttributeValue::M(map)) => Ok(map), + Some(_) => Err(DBItemError::new( + attribute_name, + Value::AttributeValue(attribute_value), + DBItemAttributeError::IncorrectType, + )), + None => Err(DBItemError::new( + attribute_name, + Value::AttributeValue(attribute_value), + DBItemAttributeError::Missing, + )), + } +} + +pub fn parse_number( + attribute_name: &'static str, + attribute_value: &str, +) -> Result { + attribute_value.parse::().map_err(|e| { + DBItemError::new( + attribute_name, + Value::String(attribute_value.to_string()), + DBItemAttributeError::InvalidNumberFormat(e), + ) + }) +}