Changeset View
Changeset View
Standalone View
Standalone View
services/feature-flags/src/database.rs
use aws_sdk_dynamodb::{model::AttributeValue, Error as DynamoDBError}; | use aws_sdk_dynamodb::{model::AttributeValue, Error as DynamoDBError}; | ||||||||||||||||||||||
use std::collections::HashMap; | |||||||||||||||||||||||
use std::fmt::{Display, Formatter}; | use std::fmt::{Display, Formatter}; | ||||||||||||||||||||||
use std::num::ParseIntError; | |||||||||||||||||||||||
#[derive( | #[derive( | ||||||||||||||||||||||
Debug, derive_more::Display, derive_more::From, derive_more::Error, | Debug, derive_more::Display, derive_more::From, derive_more::Error, | ||||||||||||||||||||||
)] | )] | ||||||||||||||||||||||
pub enum Error { | pub enum Error { | ||||||||||||||||||||||
#[display(...)] | #[display(...)] | ||||||||||||||||||||||
AwsSdk(DynamoDBError), | AwsSdk(DynamoDBError), | ||||||||||||||||||||||
#[display(...)] | #[display(...)] | ||||||||||||||||||||||
Attribute(DBItemError), | Attribute(DBItemError), | ||||||||||||||||||||||
} | } | ||||||||||||||||||||||
#[derive(Debug)] | |||||||||||||||||||||||
pub enum Value { | |||||||||||||||||||||||
AttributeValue(Option<AttributeValue>), | |||||||||||||||||||||||
String(String), | |||||||||||||||||||||||
} | |||||||||||||||||||||||
#[derive(Debug, derive_more::Error, derive_more::Constructor)] | #[derive(Debug, derive_more::Error, derive_more::Constructor)] | ||||||||||||||||||||||
pub struct DBItemError { | pub struct DBItemError { | ||||||||||||||||||||||
attribute_name: &'static str, | attribute_name: &'static str, | ||||||||||||||||||||||
attribute_value: Option<AttributeValue>, | attribute_value: Value, | ||||||||||||||||||||||
attribute_error: DBItemAttributeError, | attribute_error: DBItemAttributeError, | ||||||||||||||||||||||
} | } | ||||||||||||||||||||||
impl Display for DBItemError { | impl Display for DBItemError { | ||||||||||||||||||||||
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { | fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { | ||||||||||||||||||||||
match &self.attribute_error { | match &self.attribute_error { | ||||||||||||||||||||||
DBItemAttributeError::Missing => { | DBItemAttributeError::Missing => { | ||||||||||||||||||||||
write!(f, "Attribute {} is missing", self.attribute_name) | write!(f, "Attribute {} is missing", self.attribute_name) | ||||||||||||||||||||||
} | } | ||||||||||||||||||||||
DBItemAttributeError::IncorrectType => write!( | DBItemAttributeError::IncorrectType => write!( | ||||||||||||||||||||||
f, | f, | ||||||||||||||||||||||
"Value for attribute {} has incorrect type: {:?}", | "Value for attribute {} has incorrect type: {:?}", | ||||||||||||||||||||||
self.attribute_name, self.attribute_value | self.attribute_name, self.attribute_value | ||||||||||||||||||||||
), | ), | ||||||||||||||||||||||
error => write!( | |||||||||||||||||||||||
f, | |||||||||||||||||||||||
"Error regarding attribute {} with value {:?}: {}", | |||||||||||||||||||||||
self.attribute_name, self.attribute_value, error | |||||||||||||||||||||||
), | |||||||||||||||||||||||
tomek: This is copied from other services. I had to remove it from the previous diff as this case… | |||||||||||||||||||||||
} | } | ||||||||||||||||||||||
} | } | ||||||||||||||||||||||
} | } | ||||||||||||||||||||||
#[derive(Debug, derive_more::Display, derive_more::Error)] | #[derive(Debug, derive_more::Display, derive_more::Error)] | ||||||||||||||||||||||
pub enum DBItemAttributeError { | pub enum DBItemAttributeError { | ||||||||||||||||||||||
#[display(...)] | #[display(...)] | ||||||||||||||||||||||
Missing, | Missing, | ||||||||||||||||||||||
#[display(...)] | #[display(...)] | ||||||||||||||||||||||
IncorrectType, | IncorrectType, | ||||||||||||||||||||||
#[display(...)] | |||||||||||||||||||||||
InvalidNumberFormat(ParseIntError), | |||||||||||||||||||||||
} | } | ||||||||||||||||||||||
fn _parse_string_attribute( | fn _parse_string_attribute( | ||||||||||||||||||||||
attribute_name: &'static str, | attribute_name: &'static str, | ||||||||||||||||||||||
attribute_value: Option<AttributeValue>, | attribute_value: Option<AttributeValue>, | ||||||||||||||||||||||
) -> Result<String, DBItemError> { | ) -> Result<String, DBItemError> { | ||||||||||||||||||||||
match attribute_value { | match attribute_value { | ||||||||||||||||||||||
Some(AttributeValue::S(value)) => Ok(value), | Some(AttributeValue::S(value)) => Ok(value), | ||||||||||||||||||||||
Some(_) => Err(DBItemError::new( | Some(_) => Err(DBItemError::new( | ||||||||||||||||||||||
attribute_name, | attribute_name, | ||||||||||||||||||||||
attribute_value, | Value::AttributeValue(attribute_value), | ||||||||||||||||||||||
DBItemAttributeError::IncorrectType, | DBItemAttributeError::IncorrectType, | ||||||||||||||||||||||
)), | )), | ||||||||||||||||||||||
None => Err(DBItemError::new( | None => Err(DBItemError::new( | ||||||||||||||||||||||
attribute_name, | attribute_name, | ||||||||||||||||||||||
attribute_value, | Value::AttributeValue(attribute_value), | ||||||||||||||||||||||
DBItemAttributeError::Missing, | DBItemAttributeError::Missing, | ||||||||||||||||||||||
)), | )), | ||||||||||||||||||||||
} | } | ||||||||||||||||||||||
} | } | ||||||||||||||||||||||
fn _parse_bool_attribute( | fn _parse_bool_attribute( | ||||||||||||||||||||||
attribute_name: &'static str, | attribute_name: &'static str, | ||||||||||||||||||||||
attribute_value: Option<AttributeValue>, | attribute_value: Option<AttributeValue>, | ||||||||||||||||||||||
) -> Result<bool, DBItemError> { | ) -> Result<bool, DBItemError> { | ||||||||||||||||||||||
match attribute_value { | match attribute_value { | ||||||||||||||||||||||
Some(AttributeValue::Bool(value)) => Ok(value), | Some(AttributeValue::Bool(value)) => Ok(value), | ||||||||||||||||||||||
Some(_) => Err(DBItemError::new( | Some(_) => Err(DBItemError::new( | ||||||||||||||||||||||
attribute_name, | attribute_name, | ||||||||||||||||||||||
attribute_value, | Value::AttributeValue(attribute_value), | ||||||||||||||||||||||
DBItemAttributeError::IncorrectType, | DBItemAttributeError::IncorrectType, | ||||||||||||||||||||||
)), | )), | ||||||||||||||||||||||
None => Err(DBItemError::new( | None => Err(DBItemError::new( | ||||||||||||||||||||||
attribute_name, | attribute_name, | ||||||||||||||||||||||
attribute_value, | Value::AttributeValue(attribute_value), | ||||||||||||||||||||||
DBItemAttributeError::Missing, | DBItemAttributeError::Missing, | ||||||||||||||||||||||
)), | )), | ||||||||||||||||||||||
} | } | ||||||||||||||||||||||
} | } | ||||||||||||||||||||||
fn _parse_map_attribute( | |||||||||||||||||||||||
attribute_name: &'static str, | |||||||||||||||||||||||
attribute_value: Option<AttributeValue>, | |||||||||||||||||||||||
) -> Result<HashMap<String, AttributeValue>, DBItemError> { | |||||||||||||||||||||||
if let Some(AttributeValue::M(map)) = attribute_value { | |||||||||||||||||||||||
Ok(map) | |||||||||||||||||||||||
} else { | |||||||||||||||||||||||
Err(DBItemError::new( | |||||||||||||||||||||||
attribute_name, | |||||||||||||||||||||||
Value::AttributeValue(attribute_value), | |||||||||||||||||||||||
DBItemAttributeError::Missing, | |||||||||||||||||||||||
)) | |||||||||||||||||||||||
} | |||||||||||||||||||||||
bartekUnsubmitted Not Done Inline Actions
Don't you want to distinguish between IncorrectType and Missing, the same way as in parse_{string,bool}_attribute? If this is done deliberately, just let me know bartek: Don't you want to distinguish between `IncorrectType` and `Missing`, the same way as in… | |||||||||||||||||||||||
tomekAuthorUnsubmitted Done Inline ActionsThat makes sense - changed tomek: That makes sense - changed | |||||||||||||||||||||||
} | |||||||||||||||||||||||
fn _parse_number( | |||||||||||||||||||||||
attribute_name: &'static str, | |||||||||||||||||||||||
attribute_value: &str, | |||||||||||||||||||||||
) -> Result<i32, DBItemError> { | |||||||||||||||||||||||
let result = attribute_value.parse::<i32>().map_err(|e| { | |||||||||||||||||||||||
DBItemError::new( | |||||||||||||||||||||||
attribute_name, | |||||||||||||||||||||||
Value::String(attribute_value.to_string()), | |||||||||||||||||||||||
DBItemAttributeError::InvalidNumberFormat(e), | |||||||||||||||||||||||
) | |||||||||||||||||||||||
})?; | |||||||||||||||||||||||
Ok(result) | |||||||||||||||||||||||
bartekUnsubmitted Not Done Inline Actions
Wouldn't it work this way? Or are error types incompatible? bartek: Wouldn't it work this way? Or are error types incompatible? | |||||||||||||||||||||||
tomekAuthorUnsubmitted Done Inline ActionsIt should work. I updated the diff and will test it later, after I'm done with rebasing. tomek: It should work. I updated the diff and will test it later, after I'm done with rebasing. | |||||||||||||||||||||||
} |
This is copied from other services. I had to remove it from the previous diff as this case couldn't be matched.