Rust中如何将rusoto_dynamodbstream::AttributeValue序列化为JSON?
解决AttributeValue无法序列化为JSON的问题
问题根源
rusoto_dynamodbstreams::AttributeValue 结构体并未实现Serde的Serialize trait,因此直接调用serde_json::to_string会序列化失败。
解决方案:自定义序列化逻辑
由于无法直接修改外部 crate 的结构体,我们可以通过新类型包装的方式,为包装后的类型实现Serialize trait,手动处理不同类型的AttributeValue序列化:
1. 定义可序列化的包装类型
use serde::Serialize; use rusoto_dynamodbstreams::AttributeValue; use base64; // 用新类型包装AttributeValue,为其实现自定义序列化 struct SerializableAttributeValue(AttributeValue); impl Serialize for SerializableAttributeValue { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer, { match &self.0 { // 处理字符串类型 AttributeValue { s: Some(val), .. } => serializer.serialize_str(val), // 处理数字类型(DynamoDB数字以字符串存储) AttributeValue { n: Some(val), .. } => serializer.serialize_str(val), // 处理布尔类型 AttributeValue { bool: Some(val), .. } => serializer.serialize_bool(*val), // 处理二进制类型,转base64字符串 AttributeValue { b: Some(val), .. } => serializer.serialize_str(&base64::encode(val)), // 处理字符串数组 AttributeValue { ss: Some(vals), .. } => serializer.serialize_seq(vals.into_iter().map(|v| v.as_str())), // 处理数字数组 AttributeValue { ns: Some(vals), .. } => serializer.serialize_seq(vals.into_iter().map(|v| v.as_str())), // 按需补充其他类型(如二进制数组bs、映射m、列表l等) _ => serializer.serialize_none(), } } }
2. 修改业务代码使用包装类型
将原代码中需要序列化的old_image转换为包含包装类型的集合,再进行序列化:
async fn function_handler(event: LambdaEvent<Payload>) -> Result<(), Error> { // 初始化S3客户端和gzip流的代码 for record in event.payload.records { let old_image = record.dynamodb.unwrap().old_image.unwrap().to_owned(); // 将每个AttributeValue包装为可序列化类型 let serializable_map: Vec<(String, SerializableAttributeValue)> = old_image .into_iter() .map(|(key, attr)| (key, SerializableAttributeValue(attr))) .collect(); // 替换unwrap为?,正确处理序列化错误 let json = serde_json::to_string(&serializable_map)?; stream.write_all(json.as_bytes())?; } // ... Ok(()) }
补充说明
- 上述代码仅覆盖了常见的DynamoDB数据类型,你需要根据实际业务中使用的类型,补充
bs(二进制数组)、m(嵌套映射)、l(列表)等变体的序列化逻辑。 - 避免使用
unwrap()直接忽略错误,改用?来向上传递错误,保证程序的健壮性。
内容的提问来源于stack exchange,提问作者Jerry Palmiotto
相关产品推荐
相关产品推荐

