Skip to content

Commit d740e6f

Browse files
committed
fix handling of null groupConfiguration
Fixes #1129 . I added the "nullish" serde function and test emulating similar treatment for nullish boolean and map fields. i think the new deserialize_nullish function could supersede deserialize_nullish_boolean, deserialize_lambda_map, and possibly deserialize_lambda_dynamodb_item. but i left that out for a potential follow-up PR, to keep the blast radius small.
1 parent 6f305bb commit d740e6f

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

lambda-events/src/custom_serde/mod.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ where
5858
serializer.serialize_str(&base64::engine::general_purpose::STANDARD.encode(value))
5959
}
6060

61+
/// Deserializes any `Default` type, mapping JSON `null` to `T::default()`.
62+
pub(crate) fn deserialize_nullish<'de, D, T>(deserializer: D) -> Result<T, D::Error>
63+
where
64+
D: Deserializer<'de>,
65+
T: Default + Deserialize<'de>,
66+
{
67+
let opt = Option::deserialize(deserializer)?;
68+
Ok(opt.unwrap_or_default())
69+
}
70+
6171
/// Deserializes `HashMap<_>`, mapping JSON `null` to an empty map.
6272
pub(crate) fn deserialize_lambda_map<'de, D, K, V>(deserializer: D) -> Result<HashMap<K, V>, D::Error>
6373
where
@@ -178,6 +188,28 @@ mod test {
178188
assert_eq!(serde_dynamo::Item::from(HashMap::new()), decoded.v);
179189
}
180190

191+
#[test]
192+
fn test_deserialize_nullish() {
193+
#[derive(Debug, Default, Deserialize, PartialEq)]
194+
struct Inner {
195+
x: u32,
196+
}
197+
#[derive(Deserialize)]
198+
struct Test {
199+
#[serde(default, deserialize_with = "deserialize_nullish")]
200+
v: Inner,
201+
}
202+
203+
let decoded: Test = serde_json::from_str(r#"{"v": null}"#).unwrap();
204+
assert_eq!(decoded.v, Inner::default());
205+
206+
let decoded: Test = serde_json::from_str(r#"{}"#).unwrap();
207+
assert_eq!(decoded.v, Inner::default());
208+
209+
let decoded: Test = serde_json::from_str(r#"{"v": {"x": 42}}"#).unwrap();
210+
assert_eq!(decoded.v, Inner { x: 42 });
211+
}
212+
181213
#[test]
182214
fn test_deserialize_nullish_boolean() {
183215
#[derive(Deserialize)]

lambda-events/src/event/cognito/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
44
use serde_json::Value;
55
use std::collections::HashMap;
66

7-
use crate::custom_serde::{deserialize_lambda_map, deserialize_nullish_boolean};
7+
use crate::custom_serde::{deserialize_lambda_map, deserialize_nullish, deserialize_nullish_boolean};
88

99
/// `CognitoEvent` contains data from an event sent from AWS Cognito Sync
1010
#[non_exhaustive]
@@ -433,6 +433,7 @@ pub struct CognitoEventUserPoolsPreTokenGenRequest {
433433
#[serde(deserialize_with = "deserialize_lambda_map")]
434434
#[serde(default)]
435435
pub user_attributes: HashMap<String, String>,
436+
#[serde(default, deserialize_with = "deserialize_nullish")]
436437
pub group_configuration: GroupConfiguration,
437438
#[serde(deserialize_with = "deserialize_lambda_map")]
438439
#[serde(default)]
@@ -495,6 +496,7 @@ pub struct CognitoEventUserPoolsPreTokenGenRequestV2 {
495496
#[serde(deserialize_with = "deserialize_lambda_map")]
496497
#[serde(default)]
497498
pub user_attributes: HashMap<String, String>,
499+
#[serde(default, deserialize_with = "deserialize_nullish")]
498500
pub group_configuration: GroupConfiguration,
499501
#[serde(deserialize_with = "deserialize_lambda_map")]
500502
#[serde(default)]

0 commit comments

Comments
 (0)