1- use crate :: { custom_serde:: serialize_headers, encodings:: Base64Data , iam:: IamPolicyDocument } ;
1+ use crate :: {
2+ custom_serde:: { serialize_headers, serialize_non_null} ,
3+ encodings:: Base64Data ,
4+ iam:: IamPolicyDocument ,
5+ } ;
26#[ cfg( feature = "builders" ) ]
37use bon:: Builder ;
48use http:: HeaderMap ;
@@ -141,6 +145,9 @@ pub struct IoTCoreCustomAuthorizerResponse {
141145 pub principal_id : Option < String > ,
142146 pub disconnect_after_in_seconds : u32 ,
143147 pub refresh_after_in_seconds : u32 ,
148+ /// Policy documents returned to AWS IoT. `None` entries are omitted during serialization because AWS IoT rejects
149+ /// null policy documents.
150+ #[ serde( serialize_with = "serialize_non_null" ) ]
144151 pub policy_documents : Vec < Option < IamPolicyDocument > > ,
145152 /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
146153 /// Enabled with Cargo feature `catch-all-fields`.
@@ -156,6 +163,28 @@ pub struct IoTCoreCustomAuthorizerResponse {
156163mod test {
157164 use super :: * ;
158165
166+ fn custom_auth_response_with_policy_documents (
167+ policy_documents : Vec < Option < IamPolicyDocument > > ,
168+ ) -> IoTCoreCustomAuthorizerResponse {
169+ let data = include_bytes ! ( "../../fixtures/example-iot-custom-auth-response.json" ) ;
170+ let mut response: IoTCoreCustomAuthorizerResponse = serde_json:: from_slice ( data) . unwrap ( ) ;
171+ response. policy_documents = policy_documents;
172+ response
173+ }
174+
175+ fn policy_document ( version : & str ) -> IamPolicyDocument {
176+ serde_json:: from_value ( serde_json:: json!( {
177+ "Version" : version,
178+ "Statement" : [ ]
179+ } ) )
180+ . unwrap ( )
181+ }
182+
183+ fn serialized_policy_documents ( policy_documents : Vec < Option < IamPolicyDocument > > ) -> serde_json:: Value {
184+ let response = custom_auth_response_with_policy_documents ( policy_documents) ;
185+ serde_json:: to_value ( response) . unwrap ( ) [ "policyDocuments" ] . clone ( )
186+ }
187+
159188 #[ test]
160189 #[ cfg( feature = "iot" ) ]
161190 fn example_iot_custom_auth_request ( ) {
@@ -185,4 +214,46 @@ mod test {
185214 let reparsed: IoTCoreCustomAuthorizerResponse = serde_json:: from_slice ( output. as_bytes ( ) ) . unwrap ( ) ;
186215 assert_eq ! ( parsed, reparsed) ;
187216 }
217+
218+ #[ test]
219+ fn iot_custom_auth_response_serializes_policy_document ( ) {
220+ let policy = policy_document ( "2012-10-17" ) ;
221+
222+ assert_eq ! (
223+ serde_json:: json!( [ policy] ) ,
224+ serialized_policy_documents( vec![ Some ( policy) ] )
225+ ) ;
226+ }
227+
228+ #[ test]
229+ fn iot_custom_auth_response_filters_none_policy_documents ( ) {
230+ let first_policy = policy_document ( "2012-10-17" ) ;
231+ let second_policy = policy_document ( "2008-10-17" ) ;
232+
233+ assert_eq ! (
234+ serde_json:: json!( [ first_policy, second_policy] ) ,
235+ serialized_policy_documents( vec![ Some ( first_policy) , None , Some ( second_policy) ] )
236+ ) ;
237+ }
238+
239+ #[ test]
240+ fn iot_custom_auth_response_serializes_only_none_as_empty_array ( ) {
241+ assert_eq ! ( serde_json:: json!( [ ] ) , serialized_policy_documents( vec![ None ] ) ) ;
242+ }
243+
244+ #[ test]
245+ fn iot_custom_auth_response_serializes_empty_policy_documents_as_empty_array ( ) {
246+ assert_eq ! ( serde_json:: json!( [ ] ) , serialized_policy_documents( vec![ ] ) ) ;
247+ }
248+
249+ #[ test]
250+ fn iot_custom_auth_response_deserializes_null_policy_document ( ) {
251+ let response = custom_auth_response_with_policy_documents ( vec ! [ None ] ) ;
252+ let mut serialized = serde_json:: to_value ( response) . unwrap ( ) ;
253+ serialized[ "policyDocuments" ] = serde_json:: json!( [ null] ) ;
254+
255+ let deserialized: IoTCoreCustomAuthorizerResponse = serde_json:: from_value ( serialized) . unwrap ( ) ;
256+
257+ assert_eq ! ( vec![ None ] , deserialized. policy_documents) ;
258+ }
188259}
0 commit comments