use super::*;
pub(crate) fn parse_key_schema(val: &Value) -> Result<Vec<KeySchemaElement>, AwsServiceError> {
let arr = val.as_array().ok_or_else(|| {
AwsServiceError::aws_error(
StatusCode::BAD_REQUEST,
"ValidationException",
"KeySchema is required",
)
})?;
Ok(arr
.iter()
.map(|elem| KeySchemaElement {
attribute_name: elem["AttributeName"]
.as_str()
.unwrap_or_default()
.to_string(),
key_type: elem["KeyType"].as_str().unwrap_or("HASH").to_string(),
})
.collect())
}
pub(crate) fn parse_attribute_definitions(
val: &Value,
) -> Result<Vec<AttributeDefinition>, AwsServiceError> {
let arr = val.as_array().ok_or_else(|| {
AwsServiceError::aws_error(
StatusCode::BAD_REQUEST,
"ValidationException",
"AttributeDefinitions is required",
)
})?;
Ok(arr
.iter()
.map(|elem| AttributeDefinition {
attribute_name: elem["AttributeName"]
.as_str()
.unwrap_or_default()
.to_string(),
attribute_type: elem["AttributeType"].as_str().unwrap_or("S").to_string(),
})
.collect())
}
pub(crate) fn parse_provisioned_throughput(
val: &Value,
) -> Result<ProvisionedThroughput, AwsServiceError> {
Ok(ProvisionedThroughput {
read_capacity_units: val["ReadCapacityUnits"].as_i64().unwrap_or(5),
write_capacity_units: val["WriteCapacityUnits"].as_i64().unwrap_or(5),
})
}
pub fn parse_gsi(val: &Value, billing_mode: &str) -> Vec<GlobalSecondaryIndex> {
let Some(arr) = val.as_array() else {
return Vec::new();
};
arr.iter()
.filter_map(|g| {
Some(GlobalSecondaryIndex {
index_name: g["IndexName"].as_str()?.to_string(),
key_schema: parse_key_schema(&g["KeySchema"]).ok()?,
projection: parse_projection(&g["Projection"]),
provisioned_throughput: Some(parse_gsi_throughput(
&g["ProvisionedThroughput"],
billing_mode,
)),
on_demand_throughput: parse_on_demand_throughput(&g["OnDemandThroughput"]),
})
})
.collect()
}
pub fn parse_gsi_throughput(val: &Value, billing_mode: &str) -> ProvisionedThroughput {
if billing_mode == "PAY_PER_REQUEST" {
return ProvisionedThroughput {
read_capacity_units: 0,
write_capacity_units: 0,
};
}
ProvisionedThroughput {
read_capacity_units: val["ReadCapacityUnits"].as_i64().unwrap_or(5),
write_capacity_units: val["WriteCapacityUnits"].as_i64().unwrap_or(5),
}
}
pub fn parse_lsi(val: &Value) -> Vec<LocalSecondaryIndex> {
let Some(arr) = val.as_array() else {
return Vec::new();
};
arr.iter()
.filter_map(|l| {
Some(LocalSecondaryIndex {
index_name: l["IndexName"].as_str()?.to_string(),
key_schema: parse_key_schema(&l["KeySchema"]).ok()?,
projection: parse_projection(&l["Projection"]),
})
})
.collect()
}
pub fn parse_tags(val: &Value) -> BTreeMap<String, String> {
let mut tags = BTreeMap::new();
if let Some(arr) = val.as_array() {
for tag in arr {
if let (Some(k), Some(v)) = (tag["Key"].as_str(), tag["Value"].as_str()) {
tags.insert(k.to_string(), v.to_string());
}
}
}
tags
}
pub(crate) fn parse_expression_attribute_names(body: &Value) -> HashMap<String, String> {
let mut names = HashMap::new();
if let Some(obj) = body["ExpressionAttributeNames"].as_object() {
for (k, v) in obj {
if let Some(s) = v.as_str() {
names.insert(k.clone(), s.to_string());
}
}
}
names
}
pub(crate) fn parse_expression_attribute_values(body: &Value) -> HashMap<String, Value> {
let mut values = HashMap::new();
if let Some(obj) = body["ExpressionAttributeValues"].as_object() {
for (k, v) in obj {
values.insert(k.clone(), v.clone());
}
}
values
}