1#[cfg(feature = "builders")]
2use bon::Builder;
3use http::HeaderMap;
4use serde::{de::DeserializeOwned, Deserialize, Serialize};
5use serde_json::Value;
6use std::collections::HashMap;
7
8use crate::custom_serde::{deserialize_headers, serialize_headers};
9
10#[non_exhaustive]
13#[cfg_attr(feature = "builders", derive(Builder))]
14#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
15#[serde(rename_all = "camelCase")]
16pub struct S3ObjectLambdaEvent<P = Value>
17where
18 P: DeserializeOwned,
19 P: Serialize,
20{
21 pub x_amz_request_id: String,
22 pub get_object_context: Option<GetObjectContext>,
23 pub head_object_context: Option<HeadObjectContext>,
24 pub list_objects_context: Option<ListObjectsContext>,
25 pub list_objects_v2_context: Option<ListObjectsV2Context>,
26 #[serde(default, bound = "")]
27 pub configuration: Configuration<P>,
28 pub user_request: UserRequest,
29 pub user_identity: UserIdentity,
30 pub protocol_version: String,
31 #[cfg(feature = "catch-all-fields")]
35 #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
36 #[serde(flatten)]
37 #[cfg_attr(feature = "builders", builder(default))]
38 pub other: serde_json::Map<String, Value>,
39}
40
41#[non_exhaustive]
44#[cfg_attr(feature = "builders", derive(Builder))]
45#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
46#[serde(rename_all = "camelCase")]
47pub struct GetObjectContext {
48 pub input_s3_url: String,
49 pub output_route: String,
50 pub output_token: String,
51 #[cfg(feature = "catch-all-fields")]
55 #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
56 #[serde(flatten)]
57 #[cfg_attr(feature = "builders", builder(default))]
58 pub other: serde_json::Map<String, Value>,
59}
60
61#[non_exhaustive]
64#[cfg_attr(feature = "builders", derive(Builder))]
65#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
66#[serde(rename_all = "camelCase")]
67pub struct HeadObjectContext {
68 pub input_s3_url: String,
69 #[cfg(feature = "catch-all-fields")]
73 #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
74 #[serde(flatten)]
75 #[cfg_attr(feature = "builders", builder(default))]
76 pub other: serde_json::Map<String, Value>,
77}
78
79#[non_exhaustive]
82#[cfg_attr(feature = "builders", derive(Builder))]
83#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
84#[serde(rename_all = "camelCase")]
85pub struct ListObjectsContext {
86 pub input_s3_url: String,
87 #[cfg(feature = "catch-all-fields")]
91 #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
92 #[serde(flatten)]
93 #[cfg_attr(feature = "builders", builder(default))]
94 pub other: serde_json::Map<String, Value>,
95}
96
97#[non_exhaustive]
100#[cfg_attr(feature = "builders", derive(Builder))]
101#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
102#[serde(rename_all = "camelCase")]
103pub struct ListObjectsV2Context {
104 pub input_s3_url: String,
105 #[cfg(feature = "catch-all-fields")]
109 #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
110 #[serde(flatten)]
111 #[cfg_attr(feature = "builders", builder(default))]
112 pub other: serde_json::Map<String, Value>,
113}
114
115#[non_exhaustive]
117#[cfg_attr(feature = "builders", derive(Builder))]
118#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
119#[serde(rename_all = "camelCase")]
120pub struct Configuration<P = Value>
121where
122 P: DeserializeOwned,
123 P: Serialize,
124{
125 pub access_point_arn: String,
126 pub supporting_access_point_arn: String,
127 #[serde(default, bound = "")]
128 pub payload: P,
129 #[cfg(feature = "catch-all-fields")]
133 #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
134 #[serde(flatten)]
135 #[cfg_attr(feature = "builders", builder(default))]
136 pub other: serde_json::Map<String, Value>,
137}
138
139#[non_exhaustive]
141#[cfg_attr(feature = "builders", derive(Builder))]
142#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
143#[serde(rename_all = "camelCase")]
144pub struct UserRequest {
145 pub url: String,
146 #[serde(deserialize_with = "deserialize_headers", default)]
147 #[serde(serialize_with = "serialize_headers")]
148 pub headers: HeaderMap,
149 #[cfg(feature = "catch-all-fields")]
153 #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
154 #[serde(flatten)]
155 #[cfg_attr(feature = "builders", builder(default))]
156 pub other: serde_json::Map<String, Value>,
157}
158
159#[non_exhaustive]
161#[cfg_attr(feature = "builders", derive(Builder))]
162#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
163#[serde(rename_all = "camelCase")]
164pub struct UserIdentity {
165 pub r#type: String,
166 pub principal_id: String,
167 pub arn: String,
168 pub account_id: String,
169 pub access_key_id: String,
170 pub session_context: Option<SessionContext>,
171 #[cfg(feature = "catch-all-fields")]
175 #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
176 #[serde(flatten)]
177 #[cfg_attr(feature = "builders", builder(default))]
178 pub other: serde_json::Map<String, Value>,
179}
180
181#[non_exhaustive]
182#[cfg_attr(feature = "builders", derive(Builder))]
183#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
184#[serde(rename_all = "camelCase")]
185pub struct SessionContext {
186 pub attributes: HashMap<String, String>,
187 #[serde(default)]
188 pub session_issuer: Option<SessionIssuer>,
189 #[cfg(feature = "catch-all-fields")]
193 #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
194 #[serde(flatten)]
195 #[cfg_attr(feature = "builders", builder(default))]
196 pub other: serde_json::Map<String, Value>,
197}
198
199#[non_exhaustive]
200#[cfg_attr(feature = "builders", derive(Builder))]
201#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
202#[serde(rename_all = "camelCase")]
203pub struct SessionIssuer {
204 pub r#type: String,
205 pub principal_id: String,
206 pub arn: String,
207 pub account_id: String,
208 pub user_name: String,
209 #[cfg(feature = "catch-all-fields")]
213 #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
214 #[serde(flatten)]
215 #[cfg_attr(feature = "builders", builder(default))]
216 pub other: serde_json::Map<String, Value>,
217}
218
219#[cfg(test)]
220mod test {
221 use super::*;
222
223 #[test]
224 #[cfg(feature = "s3")]
225 fn example_object_lambda_event_get_object_assumed_role() {
226 let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-assumed-role.json");
227 let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap();
228 let output: String = serde_json::to_string(&parsed).unwrap();
229 let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap();
230 assert_eq!(parsed, reparsed);
231 }
232
233 #[test]
234 #[cfg(feature = "s3")]
235 fn example_object_lambda_event_get_object_iam() {
236 let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-iam.json");
237 let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap();
238 let output: String = serde_json::to_string(&parsed).unwrap();
239 let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap();
240 assert_eq!(parsed, reparsed);
241 }
242
243 #[test]
244 #[cfg(feature = "s3")]
245 fn example_object_lambda_event_head_object_iam() {
246 let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-head-object-iam.json");
247 let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap();
248 let output: String = serde_json::to_string(&parsed).unwrap();
249 let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap();
250 assert_eq!(parsed, reparsed);
251 }
252
253 #[test]
254 #[cfg(feature = "s3")]
255 fn example_object_lambda_event_list_objects_iam() {
256 let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-iam.json");
257 let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap();
258 let output: String = serde_json::to_string(&parsed).unwrap();
259 let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap();
260 assert_eq!(parsed, reparsed);
261 }
262
263 #[test]
264 #[cfg(feature = "s3")]
265 fn example_object_lambda_event_list_objects_v2_iam() {
266 let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-v2-iam.json");
267 let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap();
268 let output: String = serde_json::to_string(&parsed).unwrap();
269 let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap();
270 assert_eq!(parsed, reparsed);
271 }
272}