From f522ea8021142658dbcf2403085776b3395adb56 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 18 Oct 2024 19:23:11 +0200 Subject: [PATCH 01/44] Support simd_json as an optional alternative to serde_json The approach is to abstract _all_ original serde_json references to a new lib crate in the workspace - json-impl. That crate as a feature swicth between serde_json and simd_json. In The initial phase, is to to get all the other crates to depend on json-impl with the serde feature, instead of serde_json directly, so in the end nothing should change. The next phase is to activate the simd feature and see what fails, then start mitigating the failures. --- Cargo.toml | 1 + README.md | 4 +- .../producer/src/main.rs | 2 +- examples/basic-error-handling/src/main.rs | 2 +- examples/basic-streaming-response/src/main.rs | 2 +- .../http-axum-apigw-authorizer/src/main.rs | 2 +- examples/http-axum-middleware/src/main.rs | 2 +- examples/http-axum/src/main.rs | 2 +- examples/lambda-rds-iam-auth/src/main.rs | 2 +- json-impl/Cargo.toml | 23 +++ json-impl/src/lib.rs | 48 +++++ lambda-events/Cargo.toml | 2 +- .../src/custom_serde/codebuild_time.rs | 8 +- lambda-events/src/custom_serde/headers.rs | 24 +-- lambda-events/src/custom_serde/http_method.rs | 20 +- lambda-events/src/custom_serde/mod.rs | 30 +-- lambda-events/src/encodings/http.rs | 6 +- lambda-events/src/encodings/time.rs | 38 ++-- lambda-events/src/event/activemq/mod.rs | 6 +- lambda-events/src/event/alb/mod.rs | 18 +- lambda-events/src/event/apigw/mod.rs | 154 +++++++-------- lambda-events/src/event/appsync/mod.rs | 26 +-- lambda-events/src/event/autoscaling/mod.rs | 38 ++-- .../src/event/bedrock_agent_runtime/mod.rs | 18 +- lambda-events/src/event/clientvpn/mod.rs | 6 +- lambda-events/src/event/cloudformation/mod.rs | 26 +-- .../src/event/cloudformation/provider.rs | 26 +-- .../src/event/cloudwatch_alarms/mod.rs | 30 +-- .../src/event/cloudwatch_events/cloudtrail.rs | 20 +- .../src/event/cloudwatch_events/mod.rs | 2 +- .../src/event/cloudwatch_events/signin.rs | 2 +- .../src/event/cloudwatch_logs/mod.rs | 16 +- lambda-events/src/event/code_commit/mod.rs | 6 +- lambda-events/src/event/codebuild/mod.rs | 14 +- lambda-events/src/event/codedeploy/mod.rs | 18 +- .../src/event/codepipeline_cloudwatch/mod.rs | 18 +- .../src/event/codepipeline_job/mod.rs | 6 +- lambda-events/src/event/cognito/mod.rs | 182 +++++++++--------- lambda-events/src/event/config/mod.rs | 6 +- lambda-events/src/event/connect/mod.rs | 12 +- .../event/documentdb/events/commom_types.rs | 2 +- lambda-events/src/event/documentdb/mod.rs | 6 +- .../src/event/dynamodb/attributes.rs | 58 +++--- lambda-events/src/event/dynamodb/mod.rs | 12 +- lambda-events/src/event/ecr_scan/mod.rs | 12 +- lambda-events/src/event/eventbridge/mod.rs | 14 +- lambda-events/src/event/firehose/mod.rs | 6 +- lambda-events/src/event/iam/mod.rs | 12 +- lambda-events/src/event/iot/mod.rs | 12 +- lambda-events/src/event/iot_1_click/mod.rs | 6 +- lambda-events/src/event/iot_button/mod.rs | 6 +- lambda-events/src/event/kafka/mod.rs | 6 +- lambda-events/src/event/kinesis/event.rs | 12 +- lambda-events/src/event/lex/mod.rs | 12 +- lambda-events/src/event/rabbitmq/mod.rs | 8 +- lambda-events/src/event/s3/event.rs | 12 +- lambda-events/src/event/s3/object_lambda.rs | 32 +-- lambda-events/src/event/secretsmanager/mod.rs | 6 +- lambda-events/src/event/ses/mod.rs | 18 +- lambda-events/src/event/sns/mod.rs | 32 +-- lambda-events/src/event/sqs/mod.rs | 24 +-- lambda-events/src/time_window.rs | 4 +- lambda-http/Cargo.toml | 2 +- lambda-http/README.md | 8 +- lambda-http/src/deserializer.rs | 26 +-- lambda-http/src/ext/request.rs | 6 +- lambda-http/src/request.rs | 6 +- lambda-http/src/response.rs | 34 ++-- lambda-integration-tests/Cargo.toml | 2 +- lambda-integration-tests/src/authorizer.rs | 2 +- 70 files changed, 669 insertions(+), 597 deletions(-) create mode 100644 json-impl/Cargo.toml create mode 100644 json-impl/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 867e9c0d..8c3294cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "json-impl", "lambda-http", "lambda-integration-tests", "lambda-runtime-api-client", diff --git a/README.md b/README.md index 31ba399b..66f29c26 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ If you'd like to manually create your first function, the code below shows you a ```rust,no_run use lambda_runtime::{service_fn, LambdaEvent, Error}; -use serde_json::{json, Value}; +use aws_lambda_json_impl::{json, Value}; #[tokio::main] async fn main() -> Result<(), Error> { @@ -375,7 +375,7 @@ To serialize and deserialize events and responses, we suggest using the [`serde` ```rust,no_run use serde::{Serialize, Deserialize}; -use serde_json::json; +use aws_lambda_json_impl::json; use std::error::Error; #[derive(Serialize, Deserialize)] diff --git a/examples/advanced-sqs-multiple-functions-shared-data/producer/src/main.rs b/examples/advanced-sqs-multiple-functions-shared-data/producer/src/main.rs index 2a70dce3..e7f9414f 100644 --- a/examples/advanced-sqs-multiple-functions-shared-data/producer/src/main.rs +++ b/examples/advanced-sqs-multiple-functions-shared-data/producer/src/main.rs @@ -1,6 +1,6 @@ use lambda_runtime::{service_fn, tracing, Error, LambdaEvent}; use pizza_lib::Pizza; -use serde_json::{json, Value}; +use aws_lambda_json_impl::{json, Value}; struct SQSManager { client: aws_sdk_sqs::Client, diff --git a/examples/basic-error-handling/src/main.rs b/examples/basic-error-handling/src/main.rs index 3bc76936..6886ef15 100644 --- a/examples/basic-error-handling/src/main.rs +++ b/examples/basic-error-handling/src/main.rs @@ -1,7 +1,7 @@ /// See https://github.com/awslabs/aws-lambda-rust-runtime for more info on Rust runtime for AWS Lambda use lambda_runtime::{service_fn, tracing, Error, LambdaEvent}; use serde::{Deserialize, Serialize}; -use serde_json::json; +use aws_lambda_json_impl::json; use std::fs::File; /// A simple Lambda request structure with just one field diff --git a/examples/basic-streaming-response/src/main.rs b/examples/basic-streaming-response/src/main.rs index 8533c8e3..938b6ba6 100644 --- a/examples/basic-streaming-response/src/main.rs +++ b/examples/basic-streaming-response/src/main.rs @@ -3,7 +3,7 @@ use lambda_runtime::{ streaming::{channel, Body, Response}, tracing, Error, LambdaEvent, }; -use serde_json::Value; +use aws_lambda_json_impl::Value; use std::{thread, time::Duration}; async fn func(_event: LambdaEvent) -> Result, Error> { diff --git a/examples/http-axum-apigw-authorizer/src/main.rs b/examples/http-axum-apigw-authorizer/src/main.rs index 513a6cd8..7a254e88 100644 --- a/examples/http-axum-apigw-authorizer/src/main.rs +++ b/examples/http-axum-apigw-authorizer/src/main.rs @@ -7,7 +7,7 @@ use axum::{ Router, }; use lambda_http::{run, tracing, Error, RequestExt}; -use serde_json::{json, Value}; +use aws_lambda_json_impl::{json, Value}; use std::{collections::HashMap, env::set_var}; struct AuthorizerField(String); diff --git a/examples/http-axum-middleware/src/main.rs b/examples/http-axum-middleware/src/main.rs index b1e92811..b9f8672d 100644 --- a/examples/http-axum-middleware/src/main.rs +++ b/examples/http-axum-middleware/src/main.rs @@ -12,7 +12,7 @@ use axum::{response::Json, routing::post, Router}; use lambda_http::request::RequestContext::ApiGatewayV1; use lambda_http::{run, tracing, Error}; -use serde_json::{json, Value}; +use aws_lambda_json_impl::{json, Value}; // Sample middleware that logs the request id async fn mw_sample(req: axum::extract::Request, next: axum::middleware::Next) -> impl axum::response::IntoResponse { diff --git a/examples/http-axum/src/main.rs b/examples/http-axum/src/main.rs index dcd5d154..df8f7a70 100644 --- a/examples/http-axum/src/main.rs +++ b/examples/http-axum/src/main.rs @@ -16,7 +16,7 @@ use axum::{ }; use lambda_http::{run, tracing, Error}; use serde::{Deserialize, Serialize}; -use serde_json::{json, Value}; +use aws_lambda_json_impl::{json, Value}; use std::env::set_var; #[derive(Deserialize, Serialize)] diff --git a/examples/lambda-rds-iam-auth/src/main.rs b/examples/lambda-rds-iam-auth/src/main.rs index 32cf3580..4e523591 100644 --- a/examples/lambda-rds-iam-auth/src/main.rs +++ b/examples/lambda-rds-iam-auth/src/main.rs @@ -5,7 +5,7 @@ use aws_sigv4::{ sign::v4, }; use lambda_runtime::{run, service_fn, Error, LambdaEvent}; -use serde_json::{json, Value}; +use aws_lambda_json_impl::{json, Value}; use sqlx::postgres::PgConnectOptions; use std::env; use std::time::{Duration, SystemTime}; diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml new file mode 100644 index 00000000..10e33f3c --- /dev/null +++ b/json-impl/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "aws_lambda_json_impl" +version = "0.15.1" +description = "AWS Lambda JSON adapter switch between serde_json and simd_json" +authors = [ + "Martin Bartmett ", +] +license = "MIT" +homepage = "https://github.com/awslabs/aws-lambda-rust-runtime" +repository = "https://github.com/awslabs/aws-lambda-rust-runtime" +readme = "README.md" +keywords = ["lambda", "aws", "amazon", "events", "S3", "json"] +categories = ["api-bindings", "encoding", "web-programming"] +edition = "2021" + +[features] +default = [ "serde" ] +serde = [ "serde_json" ] +simd = [ "simd-json" ] + +[dependencies] +serde_json = { version = "^1", features = ["raw_value"], optional = true } +simd-json = { version = "^0", optional = true } diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs new file mode 100644 index 00000000..bdda98f0 --- /dev/null +++ b/json-impl/src/lib.rs @@ -0,0 +1,48 @@ +// Using serde_json as the JSON handler +#[cfg(feature = "serde")] +pub use serde::*; +// Using simd_json as the JSON handler +#[cfg(feature = "simd")] +pub use simd::*; + +// Implementations + +#[cfg(feature = "serde")] +mod serde { + pub use serde_json::{ + from_reader, + from_slice, + from_str, + from_value, + json, + to_string_pretty, + to_string, + to_value, + to_writer, + Deserializer as JsonDeserializer, + Value, + error::Error as JsonError, + value::RawValue as RawValue, + }; +} + +#[cfg(feature = "simd")] +mod simd { + pub use simd_json::{ + serde::{ + from_reader, + from_slice, //THIS is mutable! + from_str, //THIS is mutable and is unsafe! + from_owned_value as from_value, + json, + to_string_pretty, + to_string, + to_owned_value as to_value, + to_writer, + }, + Deserializer as JsonDeserializer, + owned::Value, + Error as JsonError, + tape::Value as RawValue, //THIS is gonna be the fun one! + }; +} diff --git a/lambda-events/Cargo.toml b/lambda-events/Cargo.toml index d9774104..bc441998 100644 --- a/lambda-events/Cargo.toml +++ b/lambda-events/Cargo.toml @@ -29,7 +29,7 @@ query_map = { version = "^0.7", features = [ ], optional = true } serde = { version = "^1", features = ["derive"] } serde_with = { version = "^3", features = ["json"], optional = true } -serde_json = "^1" +aws_lambda_json_impl = { version = "0", features = ["serde"], path = "../json-impl" } serde_dynamo = { version = "^4.1", optional = true } [features] diff --git a/lambda-events/src/custom_serde/codebuild_time.rs b/lambda-events/src/custom_serde/codebuild_time.rs index 07bd0a5c..81105017 100644 --- a/lambda-events/src/custom_serde/codebuild_time.rs +++ b/lambda-events/src/custom_serde/codebuild_time.rs @@ -78,14 +78,14 @@ mod tests { #[serde(with = "str_time")] pub date: TestTime, } - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "date": "Sep 1, 2017 4:12:29 PM" }); let expected = NaiveDateTime::parse_from_str("Sep 1, 2017 4:12:29 PM", CODEBUILD_TIME_FORMAT) .unwrap() .and_utc(); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(expected, decoded.date); } @@ -96,14 +96,14 @@ mod tests { #[serde(with = "optional_time")] pub date: Option, } - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "date": "Sep 1, 2017 4:12:29 PM" }); let expected = NaiveDateTime::parse_from_str("Sep 1, 2017 4:12:29 PM", CODEBUILD_TIME_FORMAT) .unwrap() .and_utc(); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(Some(expected), decoded.date); } } diff --git a/lambda-events/src/custom_serde/headers.rs b/lambda-events/src/custom_serde/headers.rs index 44884649..5cbbcbf5 100644 --- a/lambda-events/src/custom_serde/headers.rs +++ b/lambda-events/src/custom_serde/headers.rs @@ -145,13 +145,13 @@ mod tests { #[serde(deserialize_with = "deserialize_headers", default)] pub headers: HeaderMap, } - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "not_headers": {} }); let expected = HeaderMap::new(); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(expected, decoded.headers); } @@ -163,16 +163,16 @@ mod tests { #[serde(serialize_with = "serialize_multi_value_headers")] headers: HeaderMap, } - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "headers": { "Accept": ["*/*"] } }); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(&"*/*", decoded.headers.get("Accept").unwrap()); - let recoded = serde_json::to_value(decoded).unwrap(); - let decoded: Test = serde_json::from_value(recoded).unwrap(); + let recoded = aws_lambda_json_impl::to_value(decoded).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(recoded).unwrap(); assert_eq!(&"*/*", decoded.headers.get("Accept").unwrap()); } @@ -183,9 +183,9 @@ mod tests { #[serde(deserialize_with = "deserialize_headers")] headers: HeaderMap, } - let data = serde_json::json!({ "headers": null }); + let data = aws_lambda_json_impl::json!({ "headers": null }); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert!(decoded.headers.is_empty()); } @@ -203,7 +203,7 @@ mod tests { let content_disposition = "inline; filename=\"Schillers schönste Szenenanweisungen -Kabale und Liebe.mp4.avif\""; - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "headers": { "Content-Disposition": content_disposition }, @@ -211,15 +211,15 @@ mod tests { "Content-Disposition": content_disposition } }); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(content_disposition, decoded.headers.get("Content-Disposition").unwrap()); assert_eq!( content_disposition, decoded.multi_value_headers.get("Content-Disposition").unwrap() ); - let recoded = serde_json::to_value(decoded).unwrap(); - let decoded: Test = serde_json::from_value(recoded).unwrap(); + let recoded = aws_lambda_json_impl::to_value(decoded).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(recoded).unwrap(); assert_eq!(content_disposition, decoded.headers.get("Content-Disposition").unwrap()); assert_eq!( content_disposition, diff --git a/lambda-events/src/custom_serde/http_method.rs b/lambda-events/src/custom_serde/http_method.rs index 42a94dd7..cdf5b16e 100644 --- a/lambda-events/src/custom_serde/http_method.rs +++ b/lambda-events/src/custom_serde/http_method.rs @@ -67,13 +67,13 @@ mod tests { #[serde(with = "crate::custom_serde::http_method")] pub method: http::Method, } - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "method": "DELETE" }); - let decoded: Test = serde_json::from_value(data.clone()).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data.clone()).unwrap(); assert_eq!(http::Method::DELETE, decoded.method); - let recoded = serde_json::to_value(decoded).unwrap(); + let recoded = aws_lambda_json_impl::to_value(decoded).unwrap(); assert_eq!(data, recoded); } @@ -86,21 +86,21 @@ mod tests { #[serde(default)] pub method: Option, } - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "method": "DELETE" }); - let decoded: Test = serde_json::from_value(data.clone()).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data.clone()).unwrap(); assert_eq!(Some(http::Method::DELETE), decoded.method); - let recoded = serde_json::to_value(decoded).unwrap(); + let recoded = aws_lambda_json_impl::to_value(decoded).unwrap(); assert_eq!(data, recoded); - let data = serde_json::json!({ "method": null }); - let decoded: Test = serde_json::from_value(data).unwrap(); + let data = aws_lambda_json_impl::json!({ "method": null }); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(None, decoded.method); - let data = serde_json::json!({}); - let decoded: Test = serde_json::from_value(data).unwrap(); + let data = aws_lambda_json_impl::json!({}); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(None, decoded.method); } } diff --git a/lambda-events/src/custom_serde/mod.rs b/lambda-events/src/custom_serde/mod.rs index 729dee3d..26865b13 100644 --- a/lambda-events/src/custom_serde/mod.rs +++ b/lambda-events/src/custom_serde/mod.rs @@ -107,10 +107,10 @@ mod test { #[serde(deserialize_with = "deserialize_base64")] v: Vec, } - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "v": "SGVsbG8gV29ybGQ=", }); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(String::from_utf8(decoded.v).unwrap(), "Hello World".to_string()); } @@ -124,7 +124,7 @@ mod test { let instance = Test { v: "Hello World".as_bytes().to_vec(), }; - let encoded = serde_json::to_string(&instance).unwrap(); + let encoded = aws_lambda_json_impl::to_string(&instance).unwrap(); assert_eq!(encoded, r#"{"v":"SGVsbG8gV29ybGQ="}"#.to_string()); } @@ -135,16 +135,16 @@ mod test { #[serde(deserialize_with = "deserialize_lambda_map")] v: HashMap, } - let input = serde_json::json!({ + let input = aws_lambda_json_impl::json!({ "v": {}, }); - let decoded: Test = serde_json::from_value(input).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(input).unwrap(); assert_eq!(HashMap::new(), decoded.v); - let input = serde_json::json!({ + let input = aws_lambda_json_impl::json!({ "v": null, }); - let decoded: Test = serde_json::from_value(input).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(input).unwrap(); assert_eq!(HashMap::new(), decoded.v); } @@ -156,16 +156,16 @@ mod test { #[serde(deserialize_with = "deserialize_lambda_dynamodb_item")] v: serde_dynamo::Item, } - let input = serde_json::json!({ + let input = aws_lambda_json_impl::json!({ "v": {}, }); - let decoded: Test = serde_json::from_value(input).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(input).unwrap(); assert_eq!(serde_dynamo::Item::from(HashMap::new()), decoded.v); - let input = serde_json::json!({ + let input = aws_lambda_json_impl::json!({ "v": null, }); - let decoded: Test = serde_json::from_value(input).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(input).unwrap(); assert_eq!(serde_dynamo::Item::from(HashMap::new()), decoded.v); } @@ -178,19 +178,19 @@ mod test { } let test = r#"{"v": null}"#; - let decoded: Test = serde_json::from_str(test).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); assert!(!decoded.v); let test = r#"{}"#; - let decoded: Test = serde_json::from_str(test).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); assert!(!decoded.v); let test = r#"{"v": true}"#; - let decoded: Test = serde_json::from_str(test).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); assert!(decoded.v); let test = r#"{"v": false}"#; - let decoded: Test = serde_json::from_str(test).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); assert!(!decoded.v); } } diff --git a/lambda-events/src/encodings/http.rs b/lambda-events/src/encodings/http.rs index 56cce76a..523c124d 100644 --- a/lambda-events/src/encodings/http.rs +++ b/lambda-events/src/encodings/http.rs @@ -304,21 +304,21 @@ mod tests { fn serialize_text() { let mut map = HashMap::new(); map.insert("foo", Body::from("bar")); - assert_eq!(serde_json::to_string(&map).unwrap(), r#"{"foo":"bar"}"#); + assert_eq!(aws_lambda_json_impl::to_string(&map).unwrap(), r#"{"foo":"bar"}"#); } #[test] fn serialize_binary() { let mut map = HashMap::new(); map.insert("foo", Body::from("bar".as_bytes())); - assert_eq!(serde_json::to_string(&map).unwrap(), r#"{"foo":"YmFy"}"#); + assert_eq!(aws_lambda_json_impl::to_string(&map).unwrap(), r#"{"foo":"YmFy"}"#); } #[test] fn serialize_empty() { let mut map = HashMap::new(); map.insert("foo", Body::Empty); - assert_eq!(serde_json::to_string(&map).unwrap(), r#"{"foo":null}"#); + assert_eq!(aws_lambda_json_impl::to_string(&map).unwrap(), r#"{"foo":null}"#); } #[test] diff --git a/lambda-events/src/encodings/time.rs b/lambda-events/src/encodings/time.rs index d4903360..fbe4e9e2 100644 --- a/lambda-events/src/encodings/time.rs +++ b/lambda-events/src/encodings/time.rs @@ -228,19 +228,19 @@ mod test { let expected = Utc.ymd(2017, 10, 5).and_hms_nano(15, 33, 44, 302_000_000); // Test parsing strings. - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "v": "1507217624302", }); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(expected, decoded.v,); // Test parsing ints. - let decoded: Test = serde_json::from_slice(r#"{"v":1507217624302}"#.as_bytes()).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_slice(r#"{"v":1507217624302}"#.as_bytes()).unwrap(); assert_eq!(expected, decoded.v,); // Test parsing floats. - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "v": 1507217624302.0, }); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(expected, decoded.v,); } @@ -254,7 +254,7 @@ mod test { let instance = Test { v: Utc.ymd(1983, 7, 22).and_hms_nano(1, 0, 0, 99_888_777), }; - let encoded = serde_json::to_string(&instance).unwrap(); + let encoded = aws_lambda_json_impl::to_string(&instance).unwrap(); assert_eq!(encoded, String::from(r#"{"v":"427683600099"}"#)); } @@ -270,21 +270,21 @@ mod test { let instance = Test { v: Utc.ymd(1983, 7, 22).and_hms_nano(1, 0, 0, 99), }; - let encoded = serde_json::to_string(&instance).unwrap(); + let encoded = aws_lambda_json_impl::to_string(&instance).unwrap(); assert_eq!(encoded, String::from(r#"{"v":"427683600"}"#)); // Make sure milliseconds are included. let instance = Test { v: Utc.ymd(1983, 7, 22).and_hms_nano(1, 0, 0, 2_000_000), }; - let encoded = serde_json::to_string(&instance).unwrap(); + let encoded = aws_lambda_json_impl::to_string(&instance).unwrap(); assert_eq!(encoded, String::from(r#"{"v":"427683600.002"}"#)); // Make sure leap seconds are included. let instance = Test { v: Utc.ymd(1983, 7, 22).and_hms_nano(23, 59, 59, 1_999_999_999), }; - let encoded = serde_json::to_string(&instance).unwrap(); + let encoded = aws_lambda_json_impl::to_string(&instance).unwrap(); assert_eq!(encoded, String::from(r#"{"v":"427766400.999"}"#)); } @@ -298,16 +298,16 @@ mod test { let expected = TimeDelta::try_seconds(36).unwrap(); - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "v": 36, }); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(expected, decoded.v,); - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "v": 36.1, }); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(expected, decoded.v,); } @@ -321,7 +321,7 @@ mod test { let instance = Test { v: TimeDelta::try_seconds(36).unwrap(), }; - let encoded = serde_json::to_string(&instance).unwrap(); + let encoded = aws_lambda_json_impl::to_string(&instance).unwrap(); assert_eq!(encoded, String::from(r#"{"v":36}"#)); } @@ -335,16 +335,16 @@ mod test { let expected = TimeDelta::try_minutes(36).unwrap(); - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "v": 36, }); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(expected, decoded.v,); - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "v": 36.1, }); - let decoded: Test = serde_json::from_value(data).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(expected, decoded.v,); } @@ -358,7 +358,7 @@ mod test { let instance = Test { v: TimeDelta::try_minutes(36).unwrap(), }; - let encoded = serde_json::to_string(&instance).unwrap(); + let encoded = aws_lambda_json_impl::to_string(&instance).unwrap(); assert_eq!(encoded, String::from(r#"{"v":36}"#)); } } diff --git a/lambda-events/src/event/activemq/mod.rs b/lambda-events/src/event/activemq/mod.rs index 89cfda1c..c6885d62 100644 --- a/lambda-events/src/event/activemq/mod.rs +++ b/lambda-events/src/event/activemq/mod.rs @@ -58,9 +58,9 @@ mod test { #[cfg(feature = "activemq")] fn example_activemq_event() { let data = include_bytes!("../../fixtures/example-activemq-event.json"); - let parsed: ActiveMqEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ActiveMqEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ActiveMqEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ActiveMqEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/alb/mod.rs b/lambda-events/src/event/alb/mod.rs index 3b4ce9d5..6429e096 100644 --- a/lambda-events/src/event/alb/mod.rs +++ b/lambda-events/src/event/alb/mod.rs @@ -75,9 +75,9 @@ mod test { #[cfg(feature = "alb")] fn example_alb_lambda_target_request_headers_only() { let data = include_bytes!("../../fixtures/example-alb-lambda-target-request-headers-only.json"); - let parsed: AlbTargetGroupRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AlbTargetGroupRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -85,9 +85,9 @@ mod test { #[cfg(feature = "alb")] fn example_alb_lambda_target_request_multivalue_headers() { let data = include_bytes!("../../fixtures/example-alb-lambda-target-request-multivalue-headers.json"); - let parsed: AlbTargetGroupRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AlbTargetGroupRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -95,9 +95,9 @@ mod test { #[cfg(feature = "alb")] fn example_alb_lambda_target_response() { let data = include_bytes!("../../fixtures/example-alb-lambda-target-response.json"); - let parsed: AlbTargetGroupResponse = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AlbTargetGroupResponse = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AlbTargetGroupResponse = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AlbTargetGroupResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/apigw/mod.rs b/lambda-events/src/event/apigw/mod.rs index e0aa1e8c..8f0fdecc 100644 --- a/lambda-events/src/event/apigw/mod.rs +++ b/lambda-events/src/event/apigw/mod.rs @@ -9,7 +9,7 @@ use crate::{ use http::{HeaderMap, Method}; use query_map::QueryMap; use serde::{de::DeserializeOwned, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; -use serde_json::Value; +use aws_lambda_json_impl::Value; use std::collections::HashMap; /// `ApiGatewayProxyRequest` contains data coming from the API Gateway proxy @@ -785,9 +785,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_custom_auth_request_type_request() { let data = include_bytes!("../../fixtures/example-apigw-custom-auth-request-type-request.json"); - let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -795,9 +795,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_custom_auth_request_type_request_websocket() { let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-websocket-request.json"); - let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -805,9 +805,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_custom_auth_request() { let data = include_bytes!("../../fixtures/example-apigw-custom-auth-request.json"); - let parsed: ApiGatewayCustomAuthorizerRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -815,9 +815,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_custom_auth_response() { let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response.json"); - let parsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -825,9 +825,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_custom_auth_response_with_single_value_action() { let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-action.json"); - let parsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -835,9 +835,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_custom_auth_response_with_single_value_resource() { let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-resource.json"); - let parsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -845,9 +845,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_request() { let data = include_bytes!("../../fixtures/example-apigw-request.json"); - let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -855,9 +855,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_response() { let data = include_bytes!("../../fixtures/example-apigw-response.json"); - let parsed: ApiGatewayProxyResponse = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyResponse = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayProxyResponse = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayProxyResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -865,9 +865,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_request_multi_value_parameters() { let data = include_bytes!("../../fixtures/example-apigw-request-multi-value-parameters.json"); - let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); assert!(output.contains(r#""multiValueQueryStringParameters":{"name":["me","me2"]}"#)); @@ -880,9 +880,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_restapi_openapi_request() { let data = include_bytes!("../../fixtures/example-apigw-restapi-openapi-request.json"); - let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -890,9 +890,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_v2_request_iam() { let data = include_bytes!("../../fixtures/example-apigw-v2-request-iam.json"); - let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -900,9 +900,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_v2_request_jwt_authorizer() { let data = include_bytes!("../../fixtures/example-apigw-v2-request-jwt-authorizer.json"); - let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -910,9 +910,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_v2_request_lambda_authorizer() { let data = include_bytes!("../../fixtures/example-apigw-v2-request-lambda-authorizer.json"); - let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -920,9 +920,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_v2_request_multi_value_parameters() { let data = include_bytes!("../../fixtures/example-apigw-v2-request-multi-value-parameters.json"); - let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); assert!(output.contains(r#""header2":"value1,value2""#)); @@ -933,9 +933,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_v2_request_no_authorizer() { let data = include_bytes!("../../fixtures/example-apigw-v2-request-no-authorizer.json"); - let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -943,9 +943,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_websocket_request() { let data = include_bytes!("../../fixtures/example-apigw-websocket-request.json"); - let parsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -953,9 +953,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_console_test_request() { let data = include_bytes!("../../fixtures/example-apigw-console-test-request.json"); - let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -963,9 +963,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_websocket_request_without_method() { let data = include_bytes!("../../fixtures/example-apigw-websocket-request-without-method.json"); - let parsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -973,9 +973,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_websocket_request_disconnect_route() { let data = include_bytes!("../../fixtures/example-apigw-websocket-request-disconnect-route.json"); - let parsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -983,9 +983,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_v2_custom_authorizer_v1_request() { let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v1-request.json"); - let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); assert_eq!("REQUEST", parsed.kind.unwrap()); assert_eq!(Method::GET, parsed.http_method); @@ -995,9 +995,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_v2_custom_authorizer_v2_request() { let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request.json"); - let parsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -1005,9 +1005,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_v2_custom_authorizer_v2_request_without_cookies() { let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-cookies.json"); - let parsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -1016,9 +1016,9 @@ mod test { fn example_apigw_v2_custom_authorizer_v2_request_without_identity_source() { let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-identity-source.json"); - let parsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -1026,9 +1026,9 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_console_request() { let data = include_bytes!("../../fixtures/example-apigw-console-request.json"); - let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -1036,7 +1036,7 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_request_authorizer_fields() { let data = include_bytes!("../../fixtures/example-apigw-request.json"); - let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); let fields = parsed.request_context.authorizer.fields; assert_eq!(Some("admin"), fields.get("principalId").unwrap().as_str()); @@ -1050,9 +1050,9 @@ mod test { use crate::iam::IamPolicyEffect; let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-condition.json"); - let parsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); let statement = parsed.policy_document.statement.first().unwrap(); diff --git a/lambda-events/src/event/appsync/mod.rs b/lambda-events/src/event/appsync/mod.rs index 63f9ac74..e1460c19 100644 --- a/lambda-events/src/event/appsync/mod.rs +++ b/lambda-events/src/event/appsync/mod.rs @@ -1,5 +1,5 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; @@ -125,9 +125,9 @@ mod test { #[cfg(feature = "appsync")] fn example_appsync_identity_cognito() { let data = include_bytes!("../../fixtures/example-appsync-identity-cognito.json"); - let parsed: AppSyncCognitoIdentity = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AppSyncCognitoIdentity = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AppSyncCognitoIdentity = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AppSyncCognitoIdentity = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -135,9 +135,9 @@ mod test { #[cfg(feature = "appsync")] fn example_appsync_identity_iam() { let data = include_bytes!("../../fixtures/example-appsync-identity-iam.json"); - let parsed: AppSyncIamIdentity = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AppSyncIamIdentity = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AppSyncIamIdentity = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AppSyncIamIdentity = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -145,9 +145,9 @@ mod test { #[cfg(feature = "appsync")] fn example_appsync_lambda_auth_request() { let data = include_bytes!("../../fixtures/example-appsync-lambda-auth-request.json"); - let parsed: AppSyncLambdaAuthorizerRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AppSyncLambdaAuthorizerRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AppSyncLambdaAuthorizerRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AppSyncLambdaAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -155,9 +155,9 @@ mod test { #[cfg(feature = "appsync")] fn example_appsync_lambda_auth_response() { let data = include_bytes!("../../fixtures/example-appsync-lambda-auth-response.json"); - let parsed: AppSyncLambdaAuthorizerResponse = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AppSyncLambdaAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AppSyncLambdaAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AppSyncLambdaAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/autoscaling/mod.rs b/lambda-events/src/event/autoscaling/mod.rs index 601e8774..e51c2b9f 100644 --- a/lambda-events/src/event/autoscaling/mod.rs +++ b/lambda-events/src/event/autoscaling/mod.rs @@ -1,6 +1,6 @@ use chrono::{DateTime, Utc}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; @@ -51,9 +51,9 @@ mod test { #[cfg(feature = "autoscaling")] fn example_autoscaling_event_launch_successful() { let data = include_bytes!("../../fixtures/example-autoscaling-event-launch-successful.json"); - let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -61,9 +61,9 @@ mod test { #[cfg(feature = "autoscaling")] fn example_autoscaling_event_launch_unsuccessful() { let data = include_bytes!("../../fixtures/example-autoscaling-event-launch-unsuccessful.json"); - let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -71,9 +71,9 @@ mod test { #[cfg(feature = "autoscaling")] fn example_autoscaling_event_lifecycle_action() { let data = include_bytes!("../../fixtures/example-autoscaling-event-lifecycle-action.json"); - let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -81,9 +81,9 @@ mod test { #[cfg(feature = "autoscaling")] fn example_autoscaling_event_terminate_action() { let data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-action.json"); - let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -91,9 +91,9 @@ mod test { #[cfg(feature = "autoscaling")] fn example_autoscaling_event_terminate_successful() { let data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-successful.json"); - let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -101,9 +101,9 @@ mod test { #[cfg(feature = "autoscaling")] fn example_autoscaling_event_terminate_unsuccessful() { let data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-unsuccessful.json"); - let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/bedrock_agent_runtime/mod.rs b/lambda-events/src/event/bedrock_agent_runtime/mod.rs index c1425b85..bfef23cc 100644 --- a/lambda-events/src/event/bedrock_agent_runtime/mod.rs +++ b/lambda-events/src/event/bedrock_agent_runtime/mod.rs @@ -89,27 +89,27 @@ mod tests { #[cfg(feature = "bedrock_agent_runtime")] fn example_bedrock_agent_runtime_event() { let data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event.json"); - let parsed: AgentEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AgentEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "bedrock_agent_runtime")] fn example_bedrock_agent_runtime_event_without_parameters() { let data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-parameters.json"); - let parsed: AgentEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AgentEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "bedrock_agent_runtime")] fn example_bedrock_agent_runtime_event_without_request_body() { let data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-request-body.json"); - let parsed: AgentEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AgentEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/clientvpn/mod.rs b/lambda-events/src/event/clientvpn/mod.rs index 163abe72..c05acf7d 100644 --- a/lambda-events/src/event/clientvpn/mod.rs +++ b/lambda-events/src/event/clientvpn/mod.rs @@ -53,9 +53,9 @@ mod test { #[cfg(feature = "clientvpn")] fn example_clientvpn_connectionhandler_request() { let data = include_bytes!("../../fixtures/example-clientvpn-connectionhandler-request.json"); - let parsed: ClientVpnConnectionHandlerRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ClientVpnConnectionHandlerRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ClientVpnConnectionHandlerRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ClientVpnConnectionHandlerRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudformation/mod.rs b/lambda-events/src/event/cloudformation/mod.rs index 44156b97..bb6bdcb7 100644 --- a/lambda-events/src/event/cloudformation/mod.rs +++ b/lambda-events/src/event/cloudformation/mod.rs @@ -1,5 +1,5 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; use std::collections::HashMap; pub mod provider; @@ -117,54 +117,54 @@ mod test { #[test] fn example_cloudformation_custom_resource_create_request() { let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-create-request.json"); - let parsed: TestRequest = serde_json::from_slice(data).unwrap(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); match parsed { Create(_) => (), _ => panic!("expected Create request"), } - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_cloudformation_custom_resource_update_request() { let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-update-request.json"); - let parsed: TestRequest = serde_json::from_slice(data).unwrap(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); match parsed { Update(_) => (), _ => panic!("expected Update request"), } - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_cloudformation_custom_resource_delete_request() { let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-delete-request.json"); - let parsed: TestRequest = serde_json::from_slice(data).unwrap(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); match parsed { Delete(_) => (), _ => panic!("expected Delete request"), } - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_cloudformation_custom_resource_response() { let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-response.json"); - let parsed: CloudFormationCustomResourceResponse = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CloudFormationCustomResourceResponse = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudformation/provider.rs b/lambda-events/src/event/cloudformation/provider.rs index a1594eb4..269c64a2 100644 --- a/lambda-events/src/event/cloudformation/provider.rs +++ b/lambda-events/src/event/cloudformation/provider.rs @@ -5,7 +5,7 @@ //! See https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.custom_resources-readme.html for details. use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(tag = "RequestType")] @@ -105,54 +105,54 @@ mod test { #[test] fn example_create_request() { let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-create-request.json"); - let parsed: TestRequest = serde_json::from_slice(data).unwrap(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); match parsed { Create(_) => (), _ => panic!("expected Create request"), } - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_update_request() { let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-update-request.json"); - let parsed: TestRequest = serde_json::from_slice(data).unwrap(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); match parsed { Update(_) => (), _ => panic!("expected Update request"), } - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_delete_request() { let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-delete-request.json"); - let parsed: TestRequest = serde_json::from_slice(data).unwrap(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); match parsed { Delete(_) => (), _ => panic!("expected Delete request"), } - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_response() { let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-response.json"); - let parsed: CloudFormationCustomResourceResponse = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CloudFormationCustomResourceResponse = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudwatch_alarms/mod.rs b/lambda-events/src/event/cloudwatch_alarms/mod.rs index 01174566..c848eaa6 100644 --- a/lambda-events/src/event/cloudwatch_alarms/mod.rs +++ b/lambda-events/src/event/cloudwatch_alarms/mod.rs @@ -6,7 +6,7 @@ use serde::{ ser::Error as SerError, Deserialize, Serialize, }; -use serde_json::Value; +use aws_lambda_json_impl::Value; /// `CloudWatchAlarm` is the generic outer structure of an event triggered by a CloudWatch Alarm. /// You probably want to use `CloudWatchMetricAlarm` or `CloudWatchCompositeAlarm` if you know which kind of alarm your function is receiving. @@ -220,9 +220,9 @@ impl Serialize for CloudWatchAlarmStateReasonData { S: serde::Serializer, { let r = match self { - Self::Metric(m) => serde_json::to_string(m), - Self::Composite(m) => serde_json::to_string(m), - Self::Generic(m) => serde_json::to_string(m), + Self::Metric(m) => aws_lambda_json_impl::to_string(m), + Self::Composite(m) => aws_lambda_json_impl::to_string(m), + Self::Generic(m) => aws_lambda_json_impl::to_string(m), }; let s = r.map_err(|e| SerError::custom(format!("failed to serialize struct as string {}", e)))?; @@ -243,10 +243,10 @@ impl<'de> Visitor<'de> for ReasonDataVisitor { where E: serde::de::Error, { - if let Ok(metric) = serde_json::from_str::(v) { + if let Ok(metric) = aws_lambda_json_impl::from_str::(v) { return Ok(CloudWatchAlarmStateReasonData::Metric(metric)); } - if let Ok(aggregate) = serde_json::from_str::(v) { + if let Ok(aggregate) = aws_lambda_json_impl::from_str::(v) { return Ok(CloudWatchAlarmStateReasonData::Composite(aggregate)); } Ok(CloudWatchAlarmStateReasonData::Generic(Value::String(v.to_owned()))) @@ -261,7 +261,7 @@ mod test { #[cfg(feature = "cloudwatch_alarms")] fn example_cloudwatch_alarm_metric() { let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-metric.json"); - let parsed: CloudWatchMetricAlarm = serde_json::from_slice(data).unwrap(); + let parsed: CloudWatchMetricAlarm = aws_lambda_json_impl::from_slice(data).unwrap(); let state = parsed.alarm_data.previous_state.clone().unwrap(); let data = state.reason_data.unwrap(); match &data { @@ -272,8 +272,8 @@ mod test { _ => panic!("unexpected reason data {data:?}"), } - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CloudWatchMetricAlarm = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CloudWatchMetricAlarm = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -281,7 +281,7 @@ mod test { #[cfg(feature = "cloudwatch_alarms")] fn example_cloudwatch_alarm_composite() { let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-composite.json"); - let parsed: CloudWatchCompositeAlarm = serde_json::from_slice(data).unwrap(); + let parsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(data).unwrap(); let state = parsed.alarm_data.state.clone().unwrap(); let data = state.reason_data.unwrap(); @@ -296,8 +296,8 @@ mod test { _ => panic!("unexpected reason data {data:?}"), } - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CloudWatchCompositeAlarm = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -305,7 +305,7 @@ mod test { #[cfg(feature = "cloudwatch_alarms")] fn example_cloudwatch_alarm_composite_with_suppressor_alarm() { let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-composite-with-suppressor-alarm.json"); - let parsed: CloudWatchCompositeAlarm = serde_json::from_slice(data).unwrap(); + let parsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(data).unwrap(); let state = parsed.alarm_data.state.clone().unwrap(); assert_eq!("WaitPeriod", state.actions_suppressed_by.unwrap()); assert_eq!( @@ -313,8 +313,8 @@ mod test { state.actions_suppressed_reason.unwrap() ); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CloudWatchCompositeAlarm = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudwatch_events/cloudtrail.rs b/lambda-events/src/event/cloudwatch_events/cloudtrail.rs index fc332306..35fa9008 100644 --- a/lambda-events/src/event/cloudwatch_events/cloudtrail.rs +++ b/lambda-events/src/event/cloudwatch_events/cloudtrail.rs @@ -1,6 +1,6 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] @@ -89,27 +89,27 @@ mod tests { #[cfg(feature = "cloudwatch_events")] fn example_cloudwatch_cloudtrail_unknown_assumed_role() { let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-assumed-role.json"); - let parsed: AWSAPICall = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AWSAPICall = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cloudwatch_events")] fn example_cloudwatch_cloudtrail_unknown_federate() { let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-federate.json"); - let parsed: AWSAPICall = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AWSAPICall = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cloudwatch_events")] fn example_cloudwatch_cloudtrail_assumed_role() { let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-user-auth.json"); - let parsed: AWSAPICall = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: AWSAPICall = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudwatch_events/mod.rs b/lambda-events/src/event/cloudwatch_events/mod.rs index 6384406e..923765b7 100644 --- a/lambda-events/src/event/cloudwatch_events/mod.rs +++ b/lambda-events/src/event/cloudwatch_events/mod.rs @@ -1,6 +1,6 @@ use chrono::{DateTime, Utc}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; pub mod cloudtrail; pub mod codedeploy; diff --git a/lambda-events/src/event/cloudwatch_events/signin.rs b/lambda-events/src/event/cloudwatch_events/signin.rs index 1cd73e6e..65e1a013 100644 --- a/lambda-events/src/event/cloudwatch_events/signin.rs +++ b/lambda-events/src/event/cloudwatch_events/signin.rs @@ -1,5 +1,5 @@ use serde::{Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/cloudwatch_logs/mod.rs b/lambda-events/src/event/cloudwatch_logs/mod.rs index 0c9ad4a8..090b20c3 100644 --- a/lambda-events/src/event/cloudwatch_logs/mod.rs +++ b/lambda-events/src/event/cloudwatch_logs/mod.rs @@ -80,7 +80,7 @@ impl<'de> Deserialize<'de> for AwsLogs { })?; let bytes = flate2::read::GzDecoder::new(&bytes[..]); - let mut de = serde_json::Deserializer::from_reader(BufReader::new(bytes)); + let mut de = aws_lambda_json_impl::JsonDeserializer::from_reader(BufReader::new(bytes)); data = Some(LogData::deserialize(&mut de).map_err(Error::custom)?); } _ => return Err(Error::unknown_field(key, FIELDS)), @@ -105,7 +105,7 @@ impl Serialize for AwsLogs { let base = base64::write::EncoderWriter::new(Vec::new(), &base64::engine::general_purpose::STANDARD_NO_PAD); let mut gzip = flate2::write::GzEncoder::new(base, flate2::Compression::default()); - serde_json::to_writer(&mut gzip, &self.data).map_err(SeError::custom)?; + aws_lambda_json_impl::to_writer(&mut gzip, &self.data).map_err(SeError::custom)?; let mut base = gzip.finish().map_err(SeError::custom)?; let data = base.finish().map_err(SeError::custom)?; let string = std::str::from_utf8(data.as_slice()).map_err(SeError::custom)?; @@ -128,7 +128,7 @@ mod test { "data": "H4sIAFETomIAA12Ry27bMBBF9/4KQuiyqsQ36Z2DqEGBGC0sdRUHAS0NExV6uCJVNw3y76Fkx03CFTH3cubwztMChRO14Jy5h+JxD9ESRZerYnW3zvJ8dZVFn4+W/tDBMImYUMaFVDrF5FVs+vuroR/3k56Yg0sa0+4qk0D50MddX8Ev98aa+wFMO3lJinWS0gTT5ObT9arI8uJWM2uUkMCpZIxiorGRtsQMiOXCgHxt5MadK4d67+u++1o3HgYXWt7M4my4nhmOw+7Kph+rg/HlQwBwM1M0W2//c2V/oPPvmzydb7OpriZqygQhFItUa6GlUkymgrNUS5EKpQhRfMpGCEzC/xgWjCpNOBMn8nM3X4fcvWmn2DDnhGNFWXiffvCdtjON3mQ/vm8KtIHfY3j6rVoiEdaxsxZizLSJd4KRWGFrYwIKqBSVMtZu/eU4mCmoJWLii2KodVt/UTcNVOiNJEMdbf0a2n54RHn9DwKYJmh9EYrmLzoJPx2EwfJY33bRmfb5mOjiefECiB5LsVgCAAA=" } }"#; - let event: LogsEvent = serde_json::from_str(json).expect("failed to deserialize"); + let event: LogsEvent = aws_lambda_json_impl::from_str(json).expect("failed to deserialize"); let data = event.clone().aws_logs.data; assert_eq!("DATA_MESSAGE", data.message_type); @@ -145,8 +145,8 @@ mod test { assert_eq!(1552518348220, data.log_events[0].timestamp); assert_eq!("REPORT RequestId: 6234bffe-149a-b642-81ff-2e8e376d8aff\tDuration: 46.84 ms\tBilled Duration: 47 ms \tMemory Size: 192 MB\tMax Memory Used: 72 MB\t\n", data.log_events[0].message); - let new_json: String = serde_json::to_string_pretty(&event).unwrap(); - let new_event: LogsEvent = serde_json::from_str(&new_json).expect("failed to deserialize"); + let new_json: String = aws_lambda_json_impl::to_string_pretty(&event).unwrap(); + let new_event: LogsEvent = aws_lambda_json_impl::from_str(&new_json).expect("failed to deserialize"); assert_eq!(new_event, event); } @@ -154,9 +154,9 @@ mod test { #[cfg(feature = "cloudwatch_logs")] fn example_cloudwatch_logs_event() { let data = include_bytes!("../../fixtures/example-cloudwatch_logs-event.json"); - let parsed: LogsEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: LogsEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: LogsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: LogsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/code_commit/mod.rs b/lambda-events/src/event/code_commit/mod.rs index 7d5edfaa..4bf94153 100644 --- a/lambda-events/src/event/code_commit/mod.rs +++ b/lambda-events/src/event/code_commit/mod.rs @@ -73,9 +73,9 @@ mod test { #[cfg(feature = "code_commit")] fn example_code_commit_event() { let data = include_bytes!("../../fixtures/example-code_commit-event.json"); - let parsed: CodeCommitEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CodeCommitEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CodeCommitEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CodeCommitEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/codebuild/mod.rs b/lambda-events/src/event/codebuild/mod.rs index d4970f5a..3e001b01 100644 --- a/lambda-events/src/event/codebuild/mod.rs +++ b/lambda-events/src/event/codebuild/mod.rs @@ -4,7 +4,7 @@ use crate::{ }; use chrono::{DateTime, Utc}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; pub type CodeBuildPhaseStatus = String; @@ -218,9 +218,9 @@ mod test { #[cfg(feature = "codebuild")] fn example_codebuild_phase_change() { let data = include_bytes!("../../fixtures/example-codebuild-phase-change.json"); - let parsed: CodeBuildEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CodeBuildEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -228,9 +228,9 @@ mod test { #[cfg(feature = "codebuild")] fn example_codebuild_state_change() { let data = include_bytes!("../../fixtures/example-codebuild-state-change.json"); - let parsed: CodeBuildEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CodeBuildEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/codedeploy/mod.rs b/lambda-events/src/event/codedeploy/mod.rs index d51bf8aa..acbf440b 100644 --- a/lambda-events/src/event/codedeploy/mod.rs +++ b/lambda-events/src/event/codedeploy/mod.rs @@ -80,13 +80,13 @@ mod test { #[cfg(feature = "codedeploy")] fn example_codedeploy_lifecycle_event() { let data = include_bytes!("../../fixtures/example-codedeploy-lifecycle-event.json"); - let parsed: CodeDeployLifecycleEvent = serde_json::from_slice(data).unwrap(); + let parsed: CodeDeployLifecycleEvent = aws_lambda_json_impl::from_slice(data).unwrap(); assert_eq!(parsed.deployment_id, "d-deploymentId".to_string()); assert_eq!(parsed.lifecycle_event_hook_execution_id, "eyJlbmNyeXB0ZWREYXRhIjoiY3VHU2NjdkJXUTJQUENVd2dkYUNGRVg0dWlpME9UWVdHTVhZcDRXVW5LYUVKc21EaUFPMkNLNXMwMWFrNDlYVStlbXdRb29xS3NJTUNVQ3RYRGFZSXc1VTFwUllvMDhmMzdlbDZFeDVVdjZrNFc0eU5waGh6YTRvdkNWcmVveVR6OWdERlM2SmlIYW1TZz09IiwiaXZQYXJhbWV0ZXJTcGVjIjoiTm1ZNFR6RzZxQVhHamhhLyIsIm1hdGVyaWFsU2V0U2VyaWFsIjoxfQ==".to_string()); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CodeDeployLifecycleEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CodeDeployLifecycleEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -94,9 +94,9 @@ mod test { #[cfg(feature = "codedeploy")] fn example_codedeploy_deployment_event() { let data = include_bytes!("../../fixtures/example-codedeploy-deployment-event.json"); - let parsed: CodeDeployEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CodeDeployEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -104,9 +104,9 @@ mod test { #[cfg(feature = "codedeploy")] fn example_codedeploy_instance_event() { let data = include_bytes!("../../fixtures/example-codedeploy-instance-event.json"); - let parsed: CodeDeployEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CodeDeployEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/codepipeline_cloudwatch/mod.rs b/lambda-events/src/event/codepipeline_cloudwatch/mod.rs index 22db26b1..6c0b04ca 100644 --- a/lambda-events/src/event/codepipeline_cloudwatch/mod.rs +++ b/lambda-events/src/event/codepipeline_cloudwatch/mod.rs @@ -85,9 +85,9 @@ mod test { #[cfg(feature = "codepipeline_cloudwatch")] fn example_codepipeline_action_execution_stage_change_event() { let data = include_bytes!("../../fixtures/example-codepipeline-action-execution-stage-change-event.json"); - let parsed: CodePipelineCloudWatchEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CodePipelineCloudWatchEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -95,9 +95,9 @@ mod test { #[cfg(feature = "codepipeline_cloudwatch")] fn example_codepipeline_execution_stage_change_event() { let data = include_bytes!("../../fixtures/example-codepipeline-execution-stage-change-event.json"); - let parsed: CodePipelineCloudWatchEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CodePipelineCloudWatchEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -105,9 +105,9 @@ mod test { #[cfg(feature = "codepipeline_cloudwatch")] fn example_codepipeline_execution_state_change_event() { let data = include_bytes!("../../fixtures/example-codepipeline-execution-state-change-event.json"); - let parsed: CodePipelineCloudWatchEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CodePipelineCloudWatchEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/codepipeline_job/mod.rs b/lambda-events/src/event/codepipeline_job/mod.rs index 888e77b7..e4d25322 100644 --- a/lambda-events/src/event/codepipeline_job/mod.rs +++ b/lambda-events/src/event/codepipeline_job/mod.rs @@ -121,9 +121,9 @@ mod test { #[cfg(feature = "codepipeline_job")] fn example_codepipeline_job_event() { let data = include_bytes!("../../fixtures/example-codepipeline_job-event.json"); - let parsed: CodePipelineJobEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CodePipelineJobEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CodePipelineJobEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CodePipelineJobEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cognito/mod.rs b/lambda-events/src/event/cognito/mod.rs index a0ebd8d9..a8a17f65 100644 --- a/lambda-events/src/event/cognito/mod.rs +++ b/lambda-events/src/event/cognito/mod.rs @@ -1,5 +1,5 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; use std::collections::HashMap; use crate::custom_serde::{deserialize_lambda_map, deserialize_nullish_boolean}; @@ -636,9 +636,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event() { let data = include_bytes!("../../fixtures/example-cognito-event.json"); - let parsed: CognitoEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -646,9 +646,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_create_auth_challenge() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge.json"); - let parsed: CognitoEventUserPoolsCreateAuthChallenge = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsCreateAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -657,12 +657,12 @@ mod test { fn example_cognito_event_userpools_create_auth_challenge_user_not_found() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge-user-not-found.json"); - let parsed: CognitoEventUserPoolsCreateAuthChallenge = serde_json::from_slice(data).unwrap(); + let parsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); assert!(parsed.request.user_not_found); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsCreateAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -670,9 +670,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_custommessage() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-custommessage.json"); - let parsed: CognitoEventUserPoolsCustomMessage = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsCustomMessage = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsCustomMessage = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsCustomMessage = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -680,9 +680,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_define_auth_challenge() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge.json"); - let parsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -692,13 +692,13 @@ mod test { let data = include_bytes!( "../../fixtures/example-cognito-event-userpools-define-auth-challenge-optional-response-fields.json" ); - let parsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(data).unwrap(); + let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); assert!(!parsed.response.fail_authentication); assert!(!parsed.response.issue_tokens); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -707,12 +707,12 @@ mod test { fn example_cognito_event_userpools_define_auth_challenge_user_not_found() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge-user-not-found.json"); - let parsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(data).unwrap(); + let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); assert!(parsed.request.user_not_found); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -720,9 +720,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_migrateuser() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-migrateuser.json"); - let parsed: CognitoEventUserPoolsMigrateUser = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsMigrateUser = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsMigrateUser = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsMigrateUser = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -730,9 +730,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_postauthentication() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-postauthentication.json"); - let parsed: CognitoEventUserPoolsPostAuthentication = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPostAuthentication = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsPostAuthentication = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsPostAuthentication = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -740,9 +740,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_postconfirmation() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-postconfirmation.json"); - let parsed: CognitoEventUserPoolsPostConfirmation = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPostConfirmation = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsPostConfirmation = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsPostConfirmation = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -750,9 +750,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_preauthentication() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-preauthentication.json"); - let parsed: CognitoEventUserPoolsPreAuthentication = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreAuthentication = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsPreAuthentication = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsPreAuthentication = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -760,9 +760,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_presignup() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-presignup.json"); - let parsed: CognitoEventUserPoolsPreSignup = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreSignup = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsPreSignup = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsPreSignup = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -770,9 +770,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_pretokengen_incoming() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-incoming.json"); - let parsed: CognitoEventUserPoolsPreTokenGen = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreTokenGen = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -780,9 +780,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_pretokengen_v2_incoming() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json"); - let parsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -790,9 +790,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_pretokengen() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen.json"); - let parsed: CognitoEventUserPoolsPreTokenGen = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreTokenGen = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -800,9 +800,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_v2_pretokengen() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2.json"); - let parsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -810,9 +810,9 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_verify_auth_challenge() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge.json"); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -822,12 +822,12 @@ mod test { let data = include_bytes!( "../../fixtures/example-cognito-event-userpools-verify-auth-challenge-optional-answer-correct.json" ); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(data).unwrap(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); assert!(!parsed.response.answer_correct); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -837,12 +837,12 @@ mod test { let data = include_bytes!( "../../fixtures/example-cognito-event-userpools-verify-auth-challenge-null-answer-correct.json" ); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(data).unwrap(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); assert!(!parsed.response.answer_correct); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -851,12 +851,12 @@ mod test { fn example_cognito_event_userpools_verify_auth_challenge_user_not_found() { let data = include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge-user-not-found.json"); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(data).unwrap(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); assert!(parsed.request.user_not_found); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } @@ -893,9 +893,9 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - serde_json::from_str(&header).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&header).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -906,9 +906,9 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - serde_json::from_str(&header).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&header).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -922,9 +922,9 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - serde_json::from_str(&header).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&header).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -935,9 +935,9 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - serde_json::from_str(&header).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&header).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -948,9 +948,9 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - serde_json::from_str(&header).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&header).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -962,9 +962,9 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - serde_json::from_str(&header).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&header).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -975,9 +975,9 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - serde_json::from_str(&header).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&header).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -994,9 +994,9 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - serde_json::from_str(&header).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&header).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -1007,9 +1007,9 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - serde_json::from_str(&header).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&header).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -1028,9 +1028,9 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - serde_json::from_str(&header).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&header).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); }); } diff --git a/lambda-events/src/event/config/mod.rs b/lambda-events/src/event/config/mod.rs index 7c06e13b..8812c159 100644 --- a/lambda-events/src/event/config/mod.rs +++ b/lambda-events/src/event/config/mod.rs @@ -44,9 +44,9 @@ mod test { #[cfg(feature = "config")] fn example_config_event() { let data = include_bytes!("../../fixtures/example-config-event.json"); - let parsed: ConfigEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ConfigEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ConfigEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ConfigEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/connect/mod.rs b/lambda-events/src/event/connect/mod.rs index 04f26eb5..2e527e9a 100644 --- a/lambda-events/src/event/connect/mod.rs +++ b/lambda-events/src/event/connect/mod.rs @@ -98,9 +98,9 @@ mod test { #[cfg(feature = "connect")] fn example_connect_event() { let data = include_bytes!("../../fixtures/example-connect-event.json"); - let parsed: ConnectEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ConnectEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ConnectEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ConnectEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -108,9 +108,9 @@ mod test { #[cfg(feature = "connect")] fn example_connect_event_without_queue() { let data = include_bytes!("../../fixtures/example-connect-event-without-queue.json"); - let parsed: ConnectEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: ConnectEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: ConnectEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: ConnectEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/documentdb/events/commom_types.rs b/lambda-events/src/event/documentdb/events/commom_types.rs index 5d1bdc19..5479f34b 100644 --- a/lambda-events/src/event/documentdb/events/commom_types.rs +++ b/lambda-events/src/event/documentdb/events/commom_types.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; pub type AnyDocument = HashMap; diff --git a/lambda-events/src/event/documentdb/mod.rs b/lambda-events/src/event/documentdb/mod.rs index 67f7c9ad..67f3674f 100644 --- a/lambda-events/src/event/documentdb/mod.rs +++ b/lambda-events/src/event/documentdb/mod.rs @@ -43,9 +43,9 @@ mod test { pub type Event = DocumentDbEvent; fn test_example(data: &[u8]) { - let parsed: Event = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: Event = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: Event = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: Event = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } diff --git a/lambda-events/src/event/dynamodb/attributes.rs b/lambda-events/src/event/dynamodb/attributes.rs index e1a42c83..6bae4f80 100644 --- a/lambda-events/src/event/dynamodb/attributes.rs +++ b/lambda-events/src/event/dynamodb/attributes.rs @@ -8,59 +8,59 @@ mod test { #[test] fn test_null_attribute() { - let value = serde_json::json!({ + let value = aws_lambda_json_impl::json!({ "NULL": true }); - let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap(); + let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap(); match attr { AttributeValue::Null(true) => {} other => panic!("unexpected value {:?}", other), } - let reparsed = serde_json::to_value(attr).unwrap(); + let reparsed = aws_lambda_json_impl::to_value(attr).unwrap(); assert_eq!(value, reparsed); } #[test] fn test_string_attribute() { - let value = serde_json::json!({ + let value = aws_lambda_json_impl::json!({ "S": "value" }); - let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap(); + let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap(); match attr { AttributeValue::S(ref s) => assert_eq!("value", s.as_str()), other => panic!("unexpected value {:?}", other), } - let reparsed = serde_json::to_value(attr).unwrap(); + let reparsed = aws_lambda_json_impl::to_value(attr).unwrap(); assert_eq!(value, reparsed); } #[test] fn test_number_attribute() { - let value = serde_json::json!({ + let value = aws_lambda_json_impl::json!({ "N": "123.45" }); - let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap(); + let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap(); match attr { AttributeValue::N(ref n) => assert_eq!("123.45", n.as_str()), other => panic!("unexpected value {:?}", other), } - let reparsed = serde_json::to_value(attr).unwrap(); + let reparsed = aws_lambda_json_impl::to_value(attr).unwrap(); assert_eq!(value, reparsed); } #[test] fn test_binary_attribute() { - let value = serde_json::json!({ + let value = aws_lambda_json_impl::json!({ "B": "dGhpcyB0ZXh0IGlzIGJhc2U2NC1lbmNvZGVk" }); - let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap(); + let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap(); match attr { AttributeValue::B(ref b) => { let expected = base64::engine::general_purpose::STANDARD @@ -71,33 +71,33 @@ mod test { other => panic!("unexpected value {:?}", other), } - let reparsed = serde_json::to_value(attr).unwrap(); + let reparsed = aws_lambda_json_impl::to_value(attr).unwrap(); assert_eq!(value, reparsed); } #[test] fn test_boolean_attribute() { - let value = serde_json::json!({ + let value = aws_lambda_json_impl::json!({ "BOOL": true }); - let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap(); + let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap(); match attr { AttributeValue::Bool(b) => assert!(b), other => panic!("unexpected value {:?}", other), } - let reparsed = serde_json::to_value(attr).unwrap(); + let reparsed = aws_lambda_json_impl::to_value(attr).unwrap(); assert_eq!(value, reparsed); } #[test] fn test_string_set_attribute() { - let value = serde_json::json!({ + let value = aws_lambda_json_impl::json!({ "SS": ["Giraffe", "Hippo" ,"Zebra"] }); - let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap(); + let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap(); match attr { AttributeValue::Ss(ref s) => { let expected = vec!["Giraffe", "Hippo", "Zebra"]; @@ -106,17 +106,17 @@ mod test { other => panic!("unexpected value {:?}", other), } - let reparsed = serde_json::to_value(attr).unwrap(); + let reparsed = aws_lambda_json_impl::to_value(attr).unwrap(); assert_eq!(value, reparsed); } #[test] fn test_number_set_attribute() { - let value = serde_json::json!({ + let value = aws_lambda_json_impl::json!({ "NS": ["42.2", "-19", "7.5", "3.14"] }); - let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap(); + let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap(); match attr { AttributeValue::Ns(ref s) => { let expected = vec!["42.2", "-19", "7.5", "3.14"]; @@ -125,17 +125,17 @@ mod test { other => panic!("unexpected value {:?}", other), } - let reparsed = serde_json::to_value(attr).unwrap(); + let reparsed = aws_lambda_json_impl::to_value(attr).unwrap(); assert_eq!(value, reparsed); } #[test] fn test_binary_set_attribute() { - let value = serde_json::json!({ + let value = aws_lambda_json_impl::json!({ "BS": ["U3Vubnk=", "UmFpbnk=", "U25vd3k="] }); - let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap(); + let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap(); match attr { AttributeValue::Bs(ref s) => { let expected = vec!["U3Vubnk=", "UmFpbnk=", "U25vd3k="] @@ -147,17 +147,17 @@ mod test { other => panic!("unexpected value {:?}", other), } - let reparsed = serde_json::to_value(attr).unwrap(); + let reparsed = aws_lambda_json_impl::to_value(attr).unwrap(); assert_eq!(value, reparsed); } #[test] fn test_attribute_list_attribute() { - let value = serde_json::json!({ + let value = aws_lambda_json_impl::json!({ "L": [ {"S": "Cookies"} , {"S": "Coffee"}, {"N": "3.14159"}] }); - let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap(); + let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap(); match attr { AttributeValue::L(ref s) => { let expected = vec![ @@ -170,17 +170,17 @@ mod test { other => panic!("unexpected value {:?}", other), } - let reparsed = serde_json::to_value(attr).unwrap(); + let reparsed = aws_lambda_json_impl::to_value(attr).unwrap(); assert_eq!(value, reparsed); } #[test] fn test_attribute_map_attribute() { - let value = serde_json::json!({ + let value = aws_lambda_json_impl::json!({ "M": {"Name": {"S": "Joe"}, "Age": {"N": "35"}} }); - let attr: AttributeValue = serde_json::from_value(value).unwrap(); + let attr: AttributeValue = aws_lambda_json_impl::from_value(value).unwrap(); match attr { AttributeValue::M(s) => { let mut expected = HashMap::new(); diff --git a/lambda-events/src/event/dynamodb/mod.rs b/lambda-events/src/event/dynamodb/mod.rs index 2a3d7558..8ab0caf7 100644 --- a/lambda-events/src/event/dynamodb/mod.rs +++ b/lambda-events/src/event/dynamodb/mod.rs @@ -260,9 +260,9 @@ mod test { #[cfg(feature = "dynamodb")] fn example_dynamodb_event() { let data = include_bytes!("../../fixtures/example-dynamodb-event.json"); - let mut parsed: Event = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: Event = serde_json::from_slice(output.as_bytes()).unwrap(); + let mut parsed: Event = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: Event = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); let event = parsed.records.pop().unwrap(); @@ -274,9 +274,9 @@ mod test { #[cfg(feature = "dynamodb")] fn example_dynamodb_event_with_optional_fields() { let data = include_bytes!("../../fixtures/example-dynamodb-event-record-with-optional-fields.json"); - let parsed: EventRecord = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: EventRecord = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: EventRecord = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: EventRecord = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); let date = Utc.timestamp_micros(0).unwrap(); // 1970-01-01T00:00:00Z assert_eq!(date, reparsed.change.approximate_creation_date_time); diff --git a/lambda-events/src/event/ecr_scan/mod.rs b/lambda-events/src/event/ecr_scan/mod.rs index 5502e81a..1250c475 100644 --- a/lambda-events/src/event/ecr_scan/mod.rs +++ b/lambda-events/src/event/ecr_scan/mod.rs @@ -71,9 +71,9 @@ mod test { #[cfg(feature = "ecr_scan")] fn example_ecr_image_scan_event() { let data = include_bytes!("../../fixtures/example-ecr-image-scan-event.json"); - let parsed: EcrScanEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: EcrScanEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: EcrScanEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: EcrScanEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -81,9 +81,9 @@ mod test { #[cfg(feature = "ecr_scan")] fn example_ecr_image_scan_event_with_missing_severities() { let data = include_bytes!("../../fixtures/example-ecr-image-scan-event-with-missing-severities.json"); - let parsed: EcrScanEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: EcrScanEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: EcrScanEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: EcrScanEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/eventbridge/mod.rs b/lambda-events/src/event/eventbridge/mod.rs index 7756e0e4..95084cc6 100644 --- a/lambda-events/src/event/eventbridge/mod.rs +++ b/lambda-events/src/event/eventbridge/mod.rs @@ -1,6 +1,6 @@ use chrono::{DateTime, Utc}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; /// Parse EventBridge events. /// Deserialize the event detail into a structure that's `DeserializeOwned`. @@ -48,26 +48,26 @@ mod test { // Example from https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instance-state-changes.html let data = include_bytes!("../../fixtures/example-eventbridge-event-obj.json"); - let parsed: EventBridgeEvent = serde_json::from_slice(data).unwrap(); + let parsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(data).unwrap(); assert_eq!("i-abcd1111", parsed.detail.instance_id); assert_eq!("pending", parsed.detail.state); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: EventBridgeEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_eventbridge_schedule_event() { let data = include_bytes!("../../fixtures/example-eventbridge-schedule.json"); - let parsed: EventBridgeEvent = serde_json::from_slice(data).unwrap(); + let parsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(data).unwrap(); assert_eq!("aws.events", parsed.source); assert_eq!("Scheduled Event", parsed.detail_type); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: EventBridgeEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/firehose/mod.rs b/lambda-events/src/event/firehose/mod.rs index 6a0a13fd..fcef3cc2 100644 --- a/lambda-events/src/event/firehose/mod.rs +++ b/lambda-events/src/event/firehose/mod.rs @@ -80,9 +80,9 @@ mod test { #[cfg(feature = "firehose")] fn example_firehose_event() { let data = include_bytes!("../../fixtures/example-firehose-event.json"); - let parsed: KinesisFirehoseEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: KinesisFirehoseEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: KinesisFirehoseEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: KinesisFirehoseEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/iam/mod.rs b/lambda-events/src/event/iam/mod.rs index 36f59c7b..76b11606 100644 --- a/lambda-events/src/event/iam/mod.rs +++ b/lambda-events/src/event/iam/mod.rs @@ -129,7 +129,7 @@ mod tests { #[test] fn test_deserialize_string_condition() { - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "condition": { "StringEquals": { "iam:RegisterSecurityKey": "Activate", @@ -144,7 +144,7 @@ mod tests { condition: Option, } - let test: Test = serde_json::from_value(data).unwrap(); + let test: Test = aws_lambda_json_impl::from_value(data).unwrap(); let condition = test.condition.unwrap(); assert_eq!(1, condition.len()); @@ -154,7 +154,7 @@ mod tests { #[test] fn test_deserialize_slide_condition() { - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "condition": {"StringLike": {"s3:prefix": ["janedoe/*"]}} }); @@ -164,7 +164,7 @@ mod tests { condition: Option, } - let test: Test = serde_json::from_value(data).unwrap(); + let test: Test = aws_lambda_json_impl::from_value(data).unwrap(); let condition = test.condition.unwrap(); assert_eq!(1, condition.len()); @@ -179,11 +179,11 @@ mod tests { resource: vec!["some:resource".into()], condition: None, }; - let policy_ser = serde_json::to_value(policy).unwrap(); + let policy_ser = aws_lambda_json_impl::to_value(policy).unwrap(); assert_eq!( policy_ser, - serde_json::json!({ + aws_lambda_json_impl::json!({ "Action": ["some:action"], "Effect": "Allow", "Resource": ["some:resource"] diff --git a/lambda-events/src/event/iot/mod.rs b/lambda-events/src/event/iot/mod.rs index 3835b515..470009e9 100644 --- a/lambda-events/src/event/iot/mod.rs +++ b/lambda-events/src/event/iot/mod.rs @@ -78,9 +78,9 @@ mod test { #[cfg(feature = "iot")] fn example_iot_custom_auth_request() { let data = include_bytes!("../../fixtures/example-iot-custom-auth-request.json"); - let parsed: IoTCoreCustomAuthorizerRequest = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: IoTCoreCustomAuthorizerRequest = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: IoTCoreCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: IoTCoreCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -88,9 +88,9 @@ mod test { #[cfg(feature = "iot")] fn example_iot_custom_auth_response() { let data = include_bytes!("../../fixtures/example-iot-custom-auth-response.json"); - let parsed: IoTCoreCustomAuthorizerResponse = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: IoTCoreCustomAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: IoTCoreCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: IoTCoreCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/iot_1_click/mod.rs b/lambda-events/src/event/iot_1_click/mod.rs index bf010b50..ed690b69 100644 --- a/lambda-events/src/event/iot_1_click/mod.rs +++ b/lambda-events/src/event/iot_1_click/mod.rs @@ -64,9 +64,9 @@ mod test { #[cfg(feature = "iot_1_click")] fn example_iot_1_click_event() { let data = include_bytes!("../../fixtures/example-iot_1_click-event.json"); - let parsed: IoTOneClickEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: IoTOneClickEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: IoTOneClickEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: IoTOneClickEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/iot_button/mod.rs b/lambda-events/src/event/iot_button/mod.rs index 2d2e4627..e629ecc5 100644 --- a/lambda-events/src/event/iot_button/mod.rs +++ b/lambda-events/src/event/iot_button/mod.rs @@ -19,9 +19,9 @@ mod test { #[cfg(feature = "iot_button")] fn example_iot_button_event() { let data = include_bytes!("../../fixtures/example-iot_button-event.json"); - let parsed: IoTButtonEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: IoTButtonEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: IoTButtonEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: IoTButtonEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/kafka/mod.rs b/lambda-events/src/event/kafka/mod.rs index 27a1e921..e8f56074 100644 --- a/lambda-events/src/event/kafka/mod.rs +++ b/lambda-events/src/event/kafka/mod.rs @@ -39,9 +39,9 @@ mod test { #[cfg(feature = "kafka")] fn example_kafka_event() { let data = include_bytes!("../../fixtures/example-kafka-event.json"); - let parsed: KafkaEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: KafkaEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: KafkaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: KafkaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/kinesis/event.rs b/lambda-events/src/event/kinesis/event.rs index fac80e07..0b702c88 100644 --- a/lambda-events/src/event/kinesis/event.rs +++ b/lambda-events/src/event/kinesis/event.rs @@ -90,11 +90,11 @@ mod test { #[cfg(feature = "kinesis")] fn example_kinesis_event() { let data = include_bytes!("../../fixtures/example-kinesis-event.json"); - let parsed: KinesisEvent = serde_json::from_slice(data).unwrap(); + let parsed: KinesisEvent = aws_lambda_json_impl::from_slice(data).unwrap(); assert_eq!(KinesisEncryptionType::None, parsed.records[0].kinesis.encryption_type); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: KinesisEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: KinesisEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -102,11 +102,11 @@ mod test { #[cfg(feature = "kinesis")] fn example_kinesis_event_encrypted() { let data = include_bytes!("../../fixtures/example-kinesis-event-encrypted.json"); - let parsed: KinesisEvent = serde_json::from_slice(data).unwrap(); + let parsed: KinesisEvent = aws_lambda_json_impl::from_slice(data).unwrap(); assert_eq!(KinesisEncryptionType::Kms, parsed.records[0].kinesis.encryption_type); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: KinesisEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: KinesisEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/lex/mod.rs b/lambda-events/src/event/lex/mod.rs index d8f9403c..5da9f5e1 100644 --- a/lambda-events/src/event/lex/mod.rs +++ b/lambda-events/src/event/lex/mod.rs @@ -112,9 +112,9 @@ mod test { #[cfg(feature = "lex")] fn example_lex_event() { let data = include_bytes!("../../fixtures/example-lex-event.json"); - let parsed: LexEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: LexEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: LexEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: LexEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -122,9 +122,9 @@ mod test { #[cfg(feature = "lex")] fn example_lex_response() { let data = include_bytes!("../../fixtures/example-lex-response.json"); - let parsed: LexEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: LexEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: LexEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: LexEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/rabbitmq/mod.rs b/lambda-events/src/event/rabbitmq/mod.rs index 23327276..01c40f70 100644 --- a/lambda-events/src/event/rabbitmq/mod.rs +++ b/lambda-events/src/event/rabbitmq/mod.rs @@ -1,5 +1,5 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; @@ -66,9 +66,9 @@ mod test { #[cfg(feature = "rabbitmq")] fn example_rabbitmq_event() { let data = include_bytes!("../../fixtures/example-rabbitmq-event.json"); - let parsed: RabbitMqEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: RabbitMqEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: RabbitMqEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: RabbitMqEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/s3/event.rs b/lambda-events/src/event/s3/event.rs index e062c7d2..600768cf 100644 --- a/lambda-events/src/event/s3/event.rs +++ b/lambda-events/src/event/s3/event.rs @@ -96,9 +96,9 @@ mod test { #[cfg(feature = "s3")] fn example_s3_event() { let data = include_bytes!("../../fixtures/example-s3-event.json"); - let parsed: S3Event = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: S3Event = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: S3Event = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: S3Event = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -106,9 +106,9 @@ mod test { #[cfg(feature = "s3")] fn example_s3_event_with_decoded() { let data = include_bytes!("../../fixtures/example-s3-event-with-decoded.json"); - let parsed: S3Event = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: S3Event = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: S3Event = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: S3Event = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/s3/object_lambda.rs b/lambda-events/src/event/s3/object_lambda.rs index 2abcc797..45bc77eb 100644 --- a/lambda-events/src/event/s3/object_lambda.rs +++ b/lambda-events/src/event/s3/object_lambda.rs @@ -1,6 +1,6 @@ use http::HeaderMap; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use serde_json::Value; +use aws_lambda_json_impl::Value; use std::collections::HashMap; use crate::custom_serde::{deserialize_headers, serialize_headers}; @@ -123,9 +123,9 @@ mod test { #[cfg(feature = "s3")] fn example_object_lambda_event_get_object_assumed_role() { let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-assumed-role.json"); - let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -133,9 +133,9 @@ mod test { #[cfg(feature = "s3")] fn example_object_lambda_event_get_object_iam() { let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-iam.json"); - let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -143,9 +143,9 @@ mod test { #[cfg(feature = "s3")] fn example_object_lambda_event_head_object_iam() { let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-head-object-iam.json"); - let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -153,9 +153,9 @@ mod test { #[cfg(feature = "s3")] fn example_object_lambda_event_list_objects_iam() { let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-iam.json"); - let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -163,9 +163,9 @@ mod test { #[cfg(feature = "s3")] fn example_object_lambda_event_list_objects_v2_iam() { let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-v2-iam.json"); - let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/secretsmanager/mod.rs b/lambda-events/src/event/secretsmanager/mod.rs index 3ed8d238..58a40cc4 100644 --- a/lambda-events/src/event/secretsmanager/mod.rs +++ b/lambda-events/src/event/secretsmanager/mod.rs @@ -16,9 +16,9 @@ mod test { #[cfg(feature = "secretsmanager")] fn example_secretsmanager_secret_rotation_event() { let data = include_bytes!("../../fixtures/example-secretsmanager-secret-rotation-event.json"); - let parsed: SecretsManagerSecretRotationEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SecretsManagerSecretRotationEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: SecretsManagerSecretRotationEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SecretsManagerSecretRotationEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/ses/mod.rs b/lambda-events/src/event/ses/mod.rs index 2a60957a..d17c041b 100644 --- a/lambda-events/src/event/ses/mod.rs +++ b/lambda-events/src/event/ses/mod.rs @@ -126,9 +126,9 @@ mod test { #[cfg(feature = "ses")] fn example_ses_lambda_event() { let data = include_bytes!("../../fixtures/example-ses-lambda-event.json"); - let parsed: SimpleEmailEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SimpleEmailEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -136,9 +136,9 @@ mod test { #[cfg(feature = "ses")] fn example_ses_s3_event() { let data = include_bytes!("../../fixtures/example-ses-s3-event.json"); - let parsed: SimpleEmailEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SimpleEmailEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -146,9 +146,9 @@ mod test { #[cfg(feature = "ses")] fn example_ses_sns_event() { let data = include_bytes!("../../fixtures/example-ses-sns-event.json"); - let parsed: SimpleEmailEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SimpleEmailEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/sns/mod.rs b/lambda-events/src/event/sns/mod.rs index 0fda569d..b1a4fc82 100644 --- a/lambda-events/src/event/sns/mod.rs +++ b/lambda-events/src/event/sns/mod.rs @@ -254,9 +254,9 @@ mod test { #[cfg(feature = "sns")] fn my_example_sns_event() { let data = include_bytes!("../../fixtures/example-sns-event.json"); - let parsed: SnsEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SnsEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -264,9 +264,9 @@ mod test { #[cfg(feature = "sns")] fn my_example_sns_event_pascal_case() { let data = include_bytes!("../../fixtures/example-sns-event-pascal-case.json"); - let parsed: SnsEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SnsEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -274,15 +274,15 @@ mod test { #[cfg(feature = "sns")] fn my_example_sns_event_cloudwatch_single_metric() { let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-single-metric.json"); - let parsed: SnsEvent = serde_json::from_slice(data).unwrap(); + let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); assert_eq!(1, parsed.records.len()); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SnsEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); let parsed: SnsEventObj = - serde_json::from_slice(data).expect("failed to parse CloudWatch Alarm payload"); + aws_lambda_json_impl::from_slice(data).expect("failed to parse CloudWatch Alarm payload"); let record = parsed.records.first().unwrap(); assert_eq!("EXAMPLE", record.sns.message.alarm_name); @@ -292,11 +292,11 @@ mod test { #[cfg(feature = "sns")] fn my_example_sns_event_cloudwatch_multiple_metrics() { let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-multiple-metrics.json"); - let parsed: SnsEvent = serde_json::from_slice(data).unwrap(); + let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); assert_eq!(2, parsed.records.len()); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SnsEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -311,14 +311,14 @@ mod test { bar: i32, } - let parsed: SnsEventObj = serde_json::from_slice(data).unwrap(); + let parsed: SnsEventObj = aws_lambda_json_impl::from_slice(data).unwrap(); println!("{:?}", parsed); assert_eq!(parsed.records[0].sns.message.foo, "Hello world!"); assert_eq!(parsed.records[0].sns.message.bar, 123); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SnsEventObj = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SnsEventObj = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/sqs/mod.rs b/lambda-events/src/event/sqs/mod.rs index 9dd69f66..1f3432fe 100644 --- a/lambda-events/src/event/sqs/mod.rs +++ b/lambda-events/src/event/sqs/mod.rs @@ -186,9 +186,9 @@ mod test { #[cfg(feature = "sqs")] fn example_sqs_event() { let data = include_bytes!("../../fixtures/example-sqs-event.json"); - let parsed: SqsEvent = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SqsEvent = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: SqsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SqsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -202,13 +202,13 @@ mod test { } let data = include_bytes!("../../fixtures/example-sqs-event-obj.json"); - let parsed: SqsEventObj = serde_json::from_slice(data).unwrap(); + let parsed: SqsEventObj = aws_lambda_json_impl::from_slice(data).unwrap(); assert_eq!(parsed.records[0].body.a, "Test"); assert_eq!(parsed.records[0].body.b, 123); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SqsEventObj = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SqsEventObj = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -218,9 +218,9 @@ mod test { // Example sqs batch response fetched 2022-05-13, from: // https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#services-sqs-batchfailurereporting let data = include_bytes!("../../fixtures/example-sqs-batch-response.json"); - let parsed: SqsBatchResponse = serde_json::from_slice(data).unwrap(); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SqsBatchResponse = serde_json::from_slice(output.as_bytes()).unwrap(); + let parsed: SqsBatchResponse = aws_lambda_json_impl::from_slice(data).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SqsBatchResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } @@ -236,13 +236,13 @@ mod test { } let data = include_bytes!("../../fixtures/example-sqs-api-event-obj.json"); - let parsed: SqsApiEventObj = serde_json::from_slice(data).unwrap(); + let parsed: SqsApiEventObj = aws_lambda_json_impl::from_slice(data).unwrap(); assert_eq!(parsed.messages[0].body.city, "provincetown"); assert_eq!(parsed.messages[0].body.country, "usa"); - let output: String = serde_json::to_string(&parsed).unwrap(); - let reparsed: SqsApiEventObj = serde_json::from_slice(output.as_bytes()).unwrap(); + let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let reparsed: SqsApiEventObj = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/time_window.rs b/lambda-events/src/time_window.rs index edc9beb5..f6e1a220 100644 --- a/lambda-events/src/time_window.rs +++ b/lambda-events/src/time_window.rs @@ -68,12 +68,12 @@ mod test { #[test] fn test_window_deserializer() { - let v = serde_json::json!({ + let v = aws_lambda_json_impl::json!({ "start": "2020-12-09T07:04:00Z", "end": "2020-12-09T07:06:00Z", }); - let parsed: Window = serde_json::from_value(v).unwrap(); + let parsed: Window = aws_lambda_json_impl::from_value(v).unwrap(); assert_eq!("2020-12-09T07:04:00+00:00", &parsed.start.to_rfc3339()); assert_eq!("2020-12-09T07:06:00+00:00", &parsed.end.to_rfc3339()); } diff --git a/lambda-http/Cargo.toml b/lambda-http/Cargo.toml index 08b70d4e..9e27548a 100644 --- a/lambda-http/Cargo.toml +++ b/lambda-http/Cargo.toml @@ -43,7 +43,7 @@ mime = "0.3" percent-encoding = "2.2" pin-project-lite = { workspace = true } serde = { version = "1.0", features = ["derive"] } -serde_json = { version = "1.0", features = ["raw_value"] } +aws_lambda_json_impl = { version = "0", features = ["serde"], path = "../json-impl" } serde_urlencoded = "0.7" tokio-stream = "0.1.2" url = "2.2" diff --git a/lambda-http/README.md b/lambda-http/README.md index 6b394964..3fbd8a5a 100644 --- a/lambda-http/README.md +++ b/lambda-http/README.md @@ -45,7 +45,7 @@ The code below creates a simple API Gateway proxy (HTTP, REST) that accepts in i ```rust use lambda_http::{run, http::{StatusCode, Response}, service_fn, Error, IntoResponse, Request, RequestPayloadExt}; use serde::{Deserialize, Serialize}; -use serde_json::json; +use aws_lambda_json_impl::json; #[tokio::main] async fn main() -> Result<(), Error> { @@ -83,7 +83,7 @@ pub struct MyPayload { ```rust use lambda_http::{run, http::{StatusCode, Response}, service_fn, Error, RequestExt, IntoResponse, Request}; -use serde_json::json; +use aws_lambda_json_impl::json; #[tokio::main] async fn main() -> Result<(), Error> { @@ -124,7 +124,7 @@ use aws_lambda_events::apigw::{ ApiGatewayCustomAuthorizerRequestTypeRequest, ApiGatewayCustomAuthorizerResponse, ApiGatewayCustomAuthorizerPolicy, IamPolicyStatement, }; use lambda_runtime::{run, service_fn, Error, LambdaEvent}; -use serde_json::json; +use aws_lambda_json_impl::json; #[tokio::main] async fn main() -> Result<(), Error> { @@ -183,7 +183,7 @@ One of the [best practices](https://docs.aws.amazon.com/lambda/latest/dg/best-pr use aws_sdk_dynamodb::model::AttributeValue; use chrono::Utc; use lambda_http::{run, http::{StatusCode, Response}, service_fn, Error, RequestExt, IntoResponse, Request}; -use serde_json::json; +use aws_lambda_json_impl::json; #[tokio::main] async fn main() -> Result<(), Error> { diff --git a/lambda-http/src/deserializer.rs b/lambda-http/src/deserializer.rs index 4c0ad519..11991f52 100644 --- a/lambda-http/src/deserializer.rs +++ b/lambda-http/src/deserializer.rs @@ -8,7 +8,7 @@ use aws_lambda_events::apigw::ApiGatewayV2httpRequest; #[cfg(feature = "apigw_websockets")] use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest; use serde::{de::Error, Deserialize}; -use serde_json::value::RawValue; +use aws_lambda_json_impl::RawValue; const ERROR_CONTEXT: &str = "this function expects a JSON payload from Amazon API Gateway, Amazon Elastic Load Balancer, or AWS Lambda Function URLs, but the data doesn't match any of those services' events"; @@ -24,19 +24,19 @@ impl<'de> Deserialize<'de> for LambdaRequest { let data = raw_value.get(); #[cfg(feature = "apigw_rest")] - if let Ok(res) = serde_json::from_str::(data) { + if let Ok(res) = aws_lambda_json_impl::from_str::(data) { return Ok(LambdaRequest::ApiGatewayV1(res)); } #[cfg(feature = "apigw_http")] - if let Ok(res) = serde_json::from_str::(data) { + if let Ok(res) = aws_lambda_json_impl::from_str::(data) { return Ok(LambdaRequest::ApiGatewayV2(res)); } #[cfg(feature = "alb")] - if let Ok(res) = serde_json::from_str::(data) { + if let Ok(res) = aws_lambda_json_impl::from_str::(data) { return Ok(LambdaRequest::Alb(res)); } #[cfg(feature = "apigw_websockets")] - if let Ok(res) = serde_json::from_str::(data) { + if let Ok(res) = aws_lambda_json_impl::from_str::(data) { return Ok(LambdaRequest::WebSocket(res)); } #[cfg(feature = "pass_through")] @@ -56,7 +56,7 @@ mod tests { fn test_deserialize_apigw_rest() { let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-request.json"); - let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize apigw rest data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw rest data"); match req { LambdaRequest::ApiGatewayV1(req) => { assert_eq!("12345678912", req.request_context.account_id.unwrap()); @@ -69,7 +69,7 @@ mod tests { fn test_deserialize_apigw_http() { let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-v2-request-iam.json"); - let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize apigw http data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw http data"); match req { LambdaRequest::ApiGatewayV2(req) => { assert_eq!("123456789012", req.request_context.account_id.unwrap()); @@ -82,7 +82,7 @@ mod tests { fn test_deserialize_sam_rest() { let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-sam-rest-request.json"); - let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize SAM rest data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize SAM rest data"); match req { LambdaRequest::ApiGatewayV1(req) => { assert_eq!("123456789012", req.request_context.account_id.unwrap()); @@ -95,7 +95,7 @@ mod tests { fn test_deserialize_sam_http() { let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-sam-http-request.json"); - let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize SAM http data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize SAM http data"); match req { LambdaRequest::ApiGatewayV2(req) => { assert_eq!("123456789012", req.request_context.account_id.unwrap()); @@ -110,7 +110,7 @@ mod tests { "../../lambda-events/src/fixtures/example-alb-lambda-target-request-multivalue-headers.json" ); - let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize alb rest data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize alb rest data"); match req { LambdaRequest::Alb(req) => { assert_eq!( @@ -127,7 +127,7 @@ mod tests { let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json"); - let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize apigw websocket data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw websocket data"); match req { LambdaRequest::WebSocket(req) => { assert_eq!("CONNECT", req.request_context.event_type.unwrap()); @@ -142,7 +142,7 @@ mod tests { let data = include_bytes!("../../lambda-events/src/fixtures/example-bedrock-agent-runtime-event.json"); let req: LambdaRequest = - serde_json::from_slice(data).expect("failed to deserialize bedrock agent request data"); + aws_lambda_json_impl::from_slice(data).expect("failed to deserialize bedrock agent request data"); match req { LambdaRequest::PassThrough(req) => { assert_eq!(String::from_utf8_lossy(data), req); @@ -156,7 +156,7 @@ mod tests { fn test_deserialize_sqs() { let data = include_bytes!("../../lambda-events/src/fixtures/example-sqs-event.json"); - let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize sqs event data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize sqs event data"); match req { LambdaRequest::PassThrough(req) => { assert_eq!(String::from_utf8_lossy(data), req); diff --git a/lambda-http/src/ext/request.rs b/lambda-http/src/ext/request.rs index c56518f6..66a5f5cf 100644 --- a/lambda-http/src/ext/request.rs +++ b/lambda-http/src/ext/request.rs @@ -15,7 +15,7 @@ use crate::Body; #[derive(Debug)] pub enum PayloadError { /// Returned when `application/json` bodies fail to deserialize a payload - Json(serde_json::Error), + Json(aws_lambda_json_impl::JsonError), /// Returned when `application/x-www-form-urlencoded` bodies fail to deserialize a payload WwwFormUrlEncoded(SerdeError), } @@ -24,7 +24,7 @@ pub enum PayloadError { #[derive(Debug)] pub enum JsonPayloadError { /// Problem deserializing a JSON payload. - Parsing(serde_json::Error), + Parsing(aws_lambda_json_impl::JsonError), } /// Indicates a problem processing an x-www-form-urlencoded payload. @@ -251,7 +251,7 @@ impl RequestPayloadExt for http::Request { if self.body().is_empty() { return Ok(None); } - serde_json::from_slice::(self.body().as_ref()) + aws_lambda_json_impl::from_slice::(self.body().as_ref()) .map(Some) .map_err(JsonPayloadError::Parsing) } diff --git a/lambda-http/src/request.rs b/lambda-http/src/request.rs index a9281b46..974329aa 100644 --- a/lambda-http/src/request.rs +++ b/lambda-http/src/request.rs @@ -29,7 +29,7 @@ use aws_lambda_events::{encodings::Body, query_map::QueryMap}; use http::{header::HeaderName, HeaderMap, HeaderValue}; use serde::{Deserialize, Serialize}; -use serde_json::error::Error as JsonError; +use aws_lambda_json_impl::JsonError; use std::{env, future::Future, io::Read, pin::Pin}; use url::Url; @@ -463,7 +463,7 @@ pub fn from_reader(rdr: R) -> Result where R: Read, { - serde_json::from_reader(rdr).map(LambdaRequest::into) + aws_lambda_json_impl::from_reader(rdr).map(LambdaRequest::into) } /// Deserializes a `Request` from a string of JSON text. @@ -483,7 +483,7 @@ where /// } /// ``` pub fn from_str(s: &str) -> Result { - serde_json::from_str(s).map(LambdaRequest::into) + aws_lambda_json_impl::from_str(s).map(LambdaRequest::into) } fn x_forwarded_proto() -> HeaderName { diff --git a/lambda-http/src/response.rs b/lambda-http/src/response.rs index e8528fdf..0a68566a 100644 --- a/lambda-http/src/response.rs +++ b/lambda-http/src/response.rs @@ -51,7 +51,7 @@ pub enum LambdaResponse { #[cfg(feature = "alb")] Alb(AlbTargetGroupResponse), #[cfg(feature = "pass_through")] - PassThrough(serde_json::Value), + PassThrough(aws_lambda_json_impl::Value), } /// Transformation from http type to internal type @@ -133,9 +133,9 @@ impl LambdaResponse { RequestOrigin::PassThrough => { match body { // text body must be a valid json string - Some(Body::Text(body)) => {LambdaResponse::PassThrough(serde_json::from_str(&body).unwrap_or_default())}, + Some(Body::Text(body)) => {LambdaResponse::PassThrough(aws_lambda_json_impl::from_str(&body).unwrap_or_default())}, // binary body and other cases return Value::Null - _ => LambdaResponse::PassThrough(serde_json::Value::Null), + _ => LambdaResponse::PassThrough(aws_lambda_json_impl::Value::Null), } } #[cfg(not(any( @@ -195,14 +195,14 @@ impl IntoResponse for Vec { } } -impl IntoResponse for serde_json::Value { +impl IntoResponse for aws_lambda_json_impl::Value { fn into_response(self) -> ResponseFuture { Box::pin(async move { Response::builder() .header(CONTENT_TYPE, "application/json") .body( - serde_json::to_string(&self) - .expect("unable to serialize serde_json::Value") + aws_lambda_json_impl::to_string(&self) + .expect("unable to serialize aws_lambda_json_impl::Value") .into(), ) .expect("unable to build http::Response") @@ -258,7 +258,7 @@ impl IntoResponse for (StatusCode, Vec) { } } -impl IntoResponse for (StatusCode, serde_json::Value) { +impl IntoResponse for (StatusCode, aws_lambda_json_impl::Value) { fn into_response(self) -> ResponseFuture { let (status, body) = self; Box::pin(async move { @@ -266,8 +266,8 @@ impl IntoResponse for (StatusCode, serde_json::Value) { .status(status) .header(CONTENT_TYPE, "application/json") .body( - serde_json::to_string(&body) - .expect("unable to serialize serde_json::Value") + aws_lambda_json_impl::to_string(&body) + .expect("unable to serialize aws_lambda_json_impl::Value") .into(), ) .expect("unable to build http::Response") @@ -378,7 +378,7 @@ mod tests { Response, StatusCode, }; use lambda_runtime_api_client::body::Body as HyperBody; - use serde_json::{self, json}; + use aws_lambda_json_impl::json; const SVG_LOGO: &str = include_str!("../tests/data/svg_logo.svg"); @@ -475,7 +475,7 @@ mod tests { let response = response.into_response().await; let response = LambdaResponse::from_response(&RequestOrigin::ApiGatewayV2, response); - let json = serde_json::to_string(&response).expect("failed to serialize to json"); + let json = aws_lambda_json_impl::to_string(&response).expect("failed to serialize to json"); assert_eq!( json, r#"{"statusCode":200,"headers":{"content-encoding":"gzip"},"multiValueHeaders":{},"body":"MDAwMDAw","isBase64Encoded":true,"cookies":[]}"# @@ -493,7 +493,7 @@ mod tests { let response = response.into_response().await; let response = LambdaResponse::from_response(&RequestOrigin::ApiGatewayV2, response); - let json = serde_json::to_string(&response).expect("failed to serialize to json"); + let json = aws_lambda_json_impl::to_string(&response).expect("failed to serialize to json"); assert_eq!( json, r#"{"statusCode":200,"headers":{"content-type":"application/json"},"multiValueHeaders":{},"body":"000000","isBase64Encoded":false,"cookies":[]}"# @@ -511,7 +511,7 @@ mod tests { let response = response.into_response().await; let response = LambdaResponse::from_response(&RequestOrigin::ApiGatewayV2, response); - let json = serde_json::to_string(&response).expect("failed to serialize to json"); + let json = aws_lambda_json_impl::to_string(&response).expect("failed to serialize to json"); assert_eq!( json, r#"{"statusCode":200,"headers":{"content-type":"application/json; charset=utf-16"},"multiValueHeaders":{},"body":"〰〰〰","isBase64Encoded":false,"cookies":[]}"# @@ -529,7 +529,7 @@ mod tests { let response = response.into_response().await; let response = LambdaResponse::from_response(&RequestOrigin::ApiGatewayV2, response); - let json = serde_json::to_string(&response).expect("failed to serialize to json"); + let json = aws_lambda_json_impl::to_string(&response).expect("failed to serialize to json"); assert_eq!( json, r#"{"statusCode":200,"headers":{"content-type":"application/graphql-response+json; charset=utf-16"},"multiValueHeaders":{},"body":"〰〰〰","isBase64Encoded":false,"cookies":[]}"# @@ -546,7 +546,7 @@ mod tests { let response = response.into_response().await; let response = LambdaResponse::from_response(&RequestOrigin::ApiGatewayV2, response); - let json = serde_json::to_string(&response).expect("failed to serialize to json"); + let json = aws_lambda_json_impl::to_string(&response).expect("failed to serialize to json"); assert_eq!( json, r#"{"statusCode":200,"headers":{},"multiValueHeaders":{},"body":"000000","isBase64Encoded":false,"cookies":[]}"# @@ -563,7 +563,7 @@ mod tests { .body(Body::from(())) .expect("failed to create response"), ); - let json = serde_json::to_string(&res).expect("failed to serialize to json"); + let json = aws_lambda_json_impl::to_string(&res).expect("failed to serialize to json"); assert_eq!( json, r#"{"statusCode":200,"headers":{},"multiValueHeaders":{"multi":["a","b"]},"isBase64Encoded":false}"# @@ -580,7 +580,7 @@ mod tests { .body(Body::from(())) .expect("failed to create response"), ); - let json = serde_json::to_string(&res).expect("failed to serialize to json"); + let json = aws_lambda_json_impl::to_string(&res).expect("failed to serialize to json"); assert_eq!( "{\"statusCode\":200,\"headers\":{},\"multiValueHeaders\":{},\"isBase64Encoded\":false,\"cookies\":[\"cookie1=a\",\"cookie2=b\"]}", json diff --git a/lambda-integration-tests/Cargo.toml b/lambda-integration-tests/Cargo.toml index ee44a969..d4fabe56 100644 --- a/lambda-integration-tests/Cargo.toml +++ b/lambda-integration-tests/Cargo.toml @@ -13,7 +13,7 @@ readme = "../README.md" [dependencies] lambda_runtime = { path = "../lambda-runtime" } aws_lambda_events = { path = "../lambda-events" } -serde_json = "1.0.121" +aws_lambda_json_impl = { version = "0", features = ["serde"], path = "../json-impl" } tokio = { version = "1", features = ["full"] } serde = { version = "1.0.204", features = ["derive"] } diff --git a/lambda-integration-tests/src/authorizer.rs b/lambda-integration-tests/src/authorizer.rs index 41ddd2d8..24e9f4e1 100644 --- a/lambda-integration-tests/src/authorizer.rs +++ b/lambda-integration-tests/src/authorizer.rs @@ -6,7 +6,7 @@ use aws_lambda_events::{ }; use lambda_runtime::{service_fn, tracing, Error, LambdaEvent}; use serde::Deserialize; -use serde_json::json; +use aws_lambda_json_impl::json; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] From 08076755a09e628954d0385161ef3a534d655098 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Sat, 19 Oct 2024 17:58:12 +0200 Subject: [PATCH 02/44] Start hacking stuff into mutable slices The _problem_ with simd_json is that it requires _mutable_ slices to operate while serde_json does not. This FIRST PASS (certainly not the end solution) is to provide &mut adapter of the from_slice function for serde_json, a pseudo-safe adapter of from_str for simd_json, and then change all the places where stuff is flagged as needing to be mutable to be so - MOSTLY, however, this is in TESTS - so eventually we'll clean that up. --- json-impl/Cargo.toml | 3 ++- json-impl/src/lib.rs | 24 +++++++++++++++++++++--- lambda-events/Cargo.toml | 2 +- lambda-events/src/custom_serde/mod.rs | 18 ++++++++++-------- lambda-events/src/encodings/time.rs | 3 ++- lambda-events/src/event/activemq/mod.rs | 7 ++++--- lambda-http/Cargo.toml | 2 +- lambda-integration-tests/Cargo.toml | 2 +- 8 files changed, 42 insertions(+), 19 deletions(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 10e33f3c..5ffcbdde 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -14,10 +14,11 @@ categories = ["api-bindings", "encoding", "web-programming"] edition = "2021" [features] -default = [ "serde" ] +default = [ ] serde = [ "serde_json" ] simd = [ "simd-json" ] [dependencies] serde_json = { version = "^1", features = ["raw_value"], optional = true } simd-json = { version = "^0", optional = true } +serde = { version = "^1", no-default-features = true } diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index bdda98f0..afe1f847 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -9,6 +9,7 @@ pub use simd::*; #[cfg(feature = "serde")] mod serde { + use serde_json::{from_str as serde_json_from_str, from_slice as serde_json_from_slice}; pub use serde_json::{ from_reader, from_slice, @@ -24,25 +25,42 @@ mod serde { error::Error as JsonError, value::RawValue as RawValue, }; + pub fn from_str<'a, T>(s: &'a mut str) -> serde_json::Result + where + T: Deserialize<'a> { + serde_json_from_str(s) + } + pub fn from_slice<'a, T>(s: &'a mut [u8]) -> serde_json::Result + where + T: Deserialize<'a> { + serde_json_from_slice(s) + } } #[cfg(feature = "simd")] mod simd { + use serde::Deserialize; + use simd_json::serde::from_str as unsafe_from_str; //THIS is mutable and is unsafe! pub use simd_json::{ serde::{ from_reader, - from_slice, //THIS is mutable! - from_str, //THIS is mutable and is unsafe! + from_slice, //THIS is mutable! from_owned_value as from_value, - json, to_string_pretty, to_string, to_owned_value as to_value, to_writer, }, Deserializer as JsonDeserializer, + json, owned::Value, Error as JsonError, tape::Value as RawValue, //THIS is gonna be the fun one! }; + + pub fn from_str<'a, T>(s: &'a mut str) -> simd_json::Result + where + T: Deserialize<'a> { + unsafe { unsafe_from_str(s) } + } } diff --git a/lambda-events/Cargo.toml b/lambda-events/Cargo.toml index bc441998..61cd8021 100644 --- a/lambda-events/Cargo.toml +++ b/lambda-events/Cargo.toml @@ -29,7 +29,7 @@ query_map = { version = "^0.7", features = [ ], optional = true } serde = { version = "^1", features = ["derive"] } serde_with = { version = "^3", features = ["json"], optional = true } -aws_lambda_json_impl = { version = "0", features = ["serde"], path = "../json-impl" } +aws_lambda_json_impl = { version = "0", features = ["simd"], path = "../json-impl" } serde_dynamo = { version = "^4.1", optional = true } [features] diff --git a/lambda-events/src/custom_serde/mod.rs b/lambda-events/src/custom_serde/mod.rs index 26865b13..ffd51385 100644 --- a/lambda-events/src/custom_serde/mod.rs +++ b/lambda-events/src/custom_serde/mod.rs @@ -97,6 +97,8 @@ where #[cfg(test)] #[allow(deprecated)] mod test { + use std::str::FromStr; + use super::*; use serde::{Deserialize, Serialize}; @@ -177,20 +179,20 @@ mod test { v: bool, } - let test = r#"{"v": null}"#; - let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); + let mut test = String::from_str(r#"{"v": null}"#).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test.as_mut()).unwrap(); assert!(!decoded.v); - let test = r#"{}"#; - let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); + let mut test = String::from_str(r#"{}"#).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test.as_mut()).unwrap(); assert!(!decoded.v); - let test = r#"{"v": true}"#; - let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); + let mut test = String::from_str(r#"{"v": true}"#).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test.as_mut()).unwrap(); assert!(decoded.v); - let test = r#"{"v": false}"#; - let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); + let mut test = String::from_str(r#"{"v": false}"#).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test.as_mut()).unwrap(); assert!(!decoded.v); } } diff --git a/lambda-events/src/encodings/time.rs b/lambda-events/src/encodings/time.rs index fbe4e9e2..f4a87e2b 100644 --- a/lambda-events/src/encodings/time.rs +++ b/lambda-events/src/encodings/time.rs @@ -234,7 +234,8 @@ mod test { let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap(); assert_eq!(expected, decoded.v,); // Test parsing ints. - let decoded: Test = aws_lambda_json_impl::from_slice(r#"{"v":1507217624302}"#.as_bytes()).unwrap(); + let mut test = r#"{"v":1507217624302}"#.as_bytes().to_vec(); + let decoded: Test = aws_lambda_json_impl::from_slice(test.as_mut_slice()).unwrap(); assert_eq!(expected, decoded.v,); // Test parsing floats. let data = aws_lambda_json_impl::json!({ diff --git a/lambda-events/src/event/activemq/mod.rs b/lambda-events/src/event/activemq/mod.rs index c6885d62..6d46bfb9 100644 --- a/lambda-events/src/event/activemq/mod.rs +++ b/lambda-events/src/event/activemq/mod.rs @@ -58,9 +58,10 @@ mod test { #[cfg(feature = "activemq")] fn example_activemq_event() { let data = include_bytes!("../../fixtures/example-activemq-event.json"); - let parsed: ActiveMqEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ActiveMqEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = data.to_vec(); + let parsed: ActiveMqEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ActiveMqEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-http/Cargo.toml b/lambda-http/Cargo.toml index 9e27548a..0b63a419 100644 --- a/lambda-http/Cargo.toml +++ b/lambda-http/Cargo.toml @@ -43,7 +43,7 @@ mime = "0.3" percent-encoding = "2.2" pin-project-lite = { workspace = true } serde = { version = "1.0", features = ["derive"] } -aws_lambda_json_impl = { version = "0", features = ["serde"], path = "../json-impl" } +aws_lambda_json_impl = { features = ["simd"], path = "../json-impl" } serde_urlencoded = "0.7" tokio-stream = "0.1.2" url = "2.2" diff --git a/lambda-integration-tests/Cargo.toml b/lambda-integration-tests/Cargo.toml index d4fabe56..bedbf5a5 100644 --- a/lambda-integration-tests/Cargo.toml +++ b/lambda-integration-tests/Cargo.toml @@ -13,7 +13,7 @@ readme = "../README.md" [dependencies] lambda_runtime = { path = "../lambda-runtime" } aws_lambda_events = { path = "../lambda-events" } -aws_lambda_json_impl = { version = "0", features = ["serde"], path = "../json-impl" } +aws_lambda_json_impl = { features = ["simd"], path = "../json-impl" } tokio = { version = "1", features = ["full"] } serde = { version = "1.0.204", features = ["derive"] } From cba3fdf7f31300c538f588681e040870eb1d031b Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Sat, 19 Oct 2024 19:16:39 +0200 Subject: [PATCH 03/44] Hack tests to use mutable strings/slices Now we see the REAL problems: * No "std::cmp::Eq" available on simd::OwnedValue (at least as it is now) * SOME use of &str passed to a deser visitor and then fed back into simd_json::from_str ... which needs a mut reference (and is technically unsafe) --- lambda-events/src/event/activemq/mod.rs | 2 +- lambda-events/src/event/alb/mod.rs | 24 +- lambda-events/src/event/apigw/mod.rs | 216 +++++++-------- lambda-events/src/event/appsync/mod.rs | 32 +-- lambda-events/src/event/autoscaling/mod.rs | 48 ++-- .../src/event/bedrock_agent_runtime/mod.rs | 24 +- lambda-events/src/event/clientvpn/mod.rs | 8 +- lambda-events/src/event/cloudformation/mod.rs | 32 +-- .../src/event/cloudformation/provider.rs | 32 +-- .../src/event/cloudwatch_alarms/mod.rs | 24 +- .../src/event/cloudwatch_events/cloudtrail.rs | 24 +- .../src/event/cloudwatch_logs/mod.rs | 20 +- lambda-events/src/event/code_commit/mod.rs | 8 +- lambda-events/src/event/codebuild/mod.rs | 16 +- lambda-events/src/event/codedeploy/mod.rs | 24 +- .../src/event/codepipeline_cloudwatch/mod.rs | 24 +- .../src/event/codepipeline_job/mod.rs | 8 +- lambda-events/src/event/cognito/mod.rs | 249 +++++++++--------- lambda-events/src/event/config/mod.rs | 8 +- lambda-events/src/event/connect/mod.rs | 16 +- lambda-events/src/event/documentdb/mod.rs | 7 +- lambda-events/src/event/dynamodb/mod.rs | 16 +- lambda-events/src/event/ecr_scan/mod.rs | 16 +- lambda-events/src/event/eventbridge/mod.rs | 16 +- lambda-events/src/event/firehose/mod.rs | 8 +- lambda-events/src/event/iot/mod.rs | 16 +- lambda-events/src/event/iot_1_click/mod.rs | 8 +- lambda-events/src/event/iot_button/mod.rs | 8 +- lambda-events/src/event/kafka/mod.rs | 8 +- lambda-events/src/event/kinesis/event.rs | 16 +- lambda-events/src/event/lex/mod.rs | 16 +- lambda-events/src/event/rabbitmq/mod.rs | 8 +- lambda-events/src/event/s3/event.rs | 16 +- lambda-events/src/event/s3/object_lambda.rs | 40 +-- lambda-events/src/event/secretsmanager/mod.rs | 8 +- lambda-events/src/event/ses/mod.rs | 24 +- lambda-events/src/event/sns/mod.rs | 42 +-- lambda-events/src/event/sqs/mod.rs | 32 +-- 38 files changed, 574 insertions(+), 570 deletions(-) diff --git a/lambda-events/src/event/activemq/mod.rs b/lambda-events/src/event/activemq/mod.rs index 6d46bfb9..a13a64d5 100644 --- a/lambda-events/src/event/activemq/mod.rs +++ b/lambda-events/src/event/activemq/mod.rs @@ -57,7 +57,7 @@ mod test { #[test] #[cfg(feature = "activemq")] fn example_activemq_event() { - let data = include_bytes!("../../fixtures/example-activemq-event.json"); + let mut data = include_bytes!("../../fixtures/example-activemq-event.json").to_vec(); let mut data = data.to_vec(); let parsed: ActiveMqEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); diff --git a/lambda-events/src/event/alb/mod.rs b/lambda-events/src/event/alb/mod.rs index 6429e096..97643657 100644 --- a/lambda-events/src/event/alb/mod.rs +++ b/lambda-events/src/event/alb/mod.rs @@ -74,30 +74,30 @@ mod test { #[test] #[cfg(feature = "alb")] fn example_alb_lambda_target_request_headers_only() { - let data = include_bytes!("../../fixtures/example-alb-lambda-target-request-headers-only.json"); - let parsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-alb-lambda-target-request-headers-only.json").to_vec(); + let parsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "alb")] fn example_alb_lambda_target_request_multivalue_headers() { - let data = include_bytes!("../../fixtures/example-alb-lambda-target-request-multivalue-headers.json"); - let parsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-alb-lambda-target-request-multivalue-headers.json").to_vec(); + let parsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "alb")] fn example_alb_lambda_target_response() { - let data = include_bytes!("../../fixtures/example-alb-lambda-target-response.json"); - let parsed: AlbTargetGroupResponse = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AlbTargetGroupResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-alb-lambda-target-response.json").to_vec(); + let parsed: AlbTargetGroupResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AlbTargetGroupResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/apigw/mod.rs b/lambda-events/src/event/apigw/mod.rs index 8f0fdecc..1d8327b1 100644 --- a/lambda-events/src/event/apigw/mod.rs +++ b/lambda-events/src/event/apigw/mod.rs @@ -784,208 +784,214 @@ mod test { #[test] #[cfg(feature = "apigw")] fn example_apigw_custom_auth_request_type_request() { - let data = include_bytes!("../../fixtures/example-apigw-custom-auth-request-type-request.json"); - let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-request-type-request.json").to_vec(); + let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_custom_auth_request_type_request_websocket() { - let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-websocket-request.json"); - let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-websocket-request.json").to_vec(); + let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_custom_auth_request() { - let data = include_bytes!("../../fixtures/example-apigw-custom-auth-request.json"); - let parsed: ApiGatewayCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-request.json").to_vec(); + let parsed: ApiGatewayCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_custom_auth_response() { - let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response.json"); - let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-response.json").to_vec(); + let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_custom_auth_response_with_single_value_action() { - let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-action.json"); - let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-action.json").to_vec(); + let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_custom_auth_response_with_single_value_resource() { - let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-resource.json"); - let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-resource.json").to_vec(); + let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_request() { - let data = include_bytes!("../../fixtures/example-apigw-request.json"); - let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-request.json").to_vec(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_response() { - let data = include_bytes!("../../fixtures/example-apigw-response.json"); - let parsed: ApiGatewayProxyResponse = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-response.json").to_vec(); + let parsed: ApiGatewayProxyResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayProxyResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_request_multi_value_parameters() { - let data = include_bytes!("../../fixtures/example-apigw-request-multi-value-parameters.json"); - let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); - assert_eq!(parsed, reparsed); + let mut data = include_bytes!("../../fixtures/example-apigw-request-multi-value-parameters.json").to_vec(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let output = aws_lambda_json_impl::to_string(&parsed).unwrap(); assert!(output.contains(r#""multiValueQueryStringParameters":{"name":["me","me2"]}"#)); assert!(output.contains(r#""queryStringParameters":{"name":"me"}"#)); assert!(output.contains(r#""headername":["headerValue","headerValue2"]"#)); assert!(output.contains(r#""headername":"headerValue2""#)); + + let mut output = output.into_bytes(); + let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + assert_eq!(parsed, reparsed); + } #[test] #[cfg(feature = "apigw")] fn example_apigw_restapi_openapi_request() { - let data = include_bytes!("../../fixtures/example-apigw-restapi-openapi-request.json"); - let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-restapi-openapi-request.json").to_vec(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_v2_request_iam() { - let data = include_bytes!("../../fixtures/example-apigw-v2-request-iam.json"); - let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-v2-request-iam.json").to_vec(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_v2_request_jwt_authorizer() { - let data = include_bytes!("../../fixtures/example-apigw-v2-request-jwt-authorizer.json"); - let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-v2-request-jwt-authorizer.json").to_vec(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_v2_request_lambda_authorizer() { - let data = include_bytes!("../../fixtures/example-apigw-v2-request-lambda-authorizer.json"); - let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-v2-request-lambda-authorizer.json").to_vec(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_v2_request_multi_value_parameters() { - let data = include_bytes!("../../fixtures/example-apigw-v2-request-multi-value-parameters.json"); - let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); - assert_eq!(parsed, reparsed); + let mut data = include_bytes!("../../fixtures/example-apigw-v2-request-multi-value-parameters.json").to_vec(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap(); assert!(output.contains(r#""header2":"value1,value2""#)); assert!(output.contains(r#""queryStringParameters":{"Parameter1":"value1,value2"}"#)); + + let mut output = output.into_bytes(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + assert_eq!(parsed, reparsed); + } #[test] #[cfg(feature = "apigw")] fn example_apigw_v2_request_no_authorizer() { - let data = include_bytes!("../../fixtures/example-apigw-v2-request-no-authorizer.json"); - let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-v2-request-no-authorizer.json").to_vec(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_websocket_request() { - let data = include_bytes!("../../fixtures/example-apigw-websocket-request.json"); - let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-websocket-request.json").to_vec(); + let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_console_test_request() { - let data = include_bytes!("../../fixtures/example-apigw-console-test-request.json"); - let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-console-test-request.json").to_vec(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_websocket_request_without_method() { - let data = include_bytes!("../../fixtures/example-apigw-websocket-request-without-method.json"); - let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-websocket-request-without-method.json").to_vec(); + let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_websocket_request_disconnect_route() { - let data = include_bytes!("../../fixtures/example-apigw-websocket-request-disconnect-route.json"); - let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-websocket-request-disconnect-route.json").to_vec(); + let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_v2_custom_authorizer_v1_request() { - let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v1-request.json"); - let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v1-request.json").to_vec(); + let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); assert_eq!("REQUEST", parsed.kind.unwrap()); assert_eq!(Method::GET, parsed.http_method); @@ -994,51 +1000,51 @@ mod test { #[test] #[cfg(feature = "apigw")] fn example_apigw_v2_custom_authorizer_v2_request() { - let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request.json"); - let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request.json").to_vec(); + let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_v2_custom_authorizer_v2_request_without_cookies() { - let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-cookies.json"); - let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-cookies.json").to_vec(); + let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_v2_custom_authorizer_v2_request_without_identity_source() { - let data = - include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-identity-source.json"); - let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-identity-source.json").to_vec(); + let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_console_request() { - let data = include_bytes!("../../fixtures/example-apigw-console-request.json"); - let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-console-request.json").to_vec(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_request_authorizer_fields() { - let data = include_bytes!("../../fixtures/example-apigw-request.json"); - let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-request.json").to_vec(); + let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let fields = parsed.request_context.authorizer.fields; + assert_eq!(Some("admin"), fields.get("principalId").unwrap().as_str()); assert_eq!(Some(1), fields.get("clientId").unwrap().as_u64()); assert_eq!(Some("Exata"), fields.get("clientName").unwrap().as_str()); @@ -1049,10 +1055,10 @@ mod test { fn example_apigw_custom_auth_response_with_statement_condition() { use crate::iam::IamPolicyEffect; - let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-condition.json"); - let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-condition.json").to_vec(); + let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); let statement = parsed.policy_document.statement.first().unwrap(); diff --git a/lambda-events/src/event/appsync/mod.rs b/lambda-events/src/event/appsync/mod.rs index e1460c19..0e0e3dcd 100644 --- a/lambda-events/src/event/appsync/mod.rs +++ b/lambda-events/src/event/appsync/mod.rs @@ -124,40 +124,40 @@ mod test { #[test] #[cfg(feature = "appsync")] fn example_appsync_identity_cognito() { - let data = include_bytes!("../../fixtures/example-appsync-identity-cognito.json"); - let parsed: AppSyncCognitoIdentity = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AppSyncCognitoIdentity = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-appsync-identity-cognito.json").to_vec(); + let parsed: AppSyncCognitoIdentity = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AppSyncCognitoIdentity = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "appsync")] fn example_appsync_identity_iam() { - let data = include_bytes!("../../fixtures/example-appsync-identity-iam.json"); - let parsed: AppSyncIamIdentity = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AppSyncIamIdentity = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-appsync-identity-iam.json").to_vec(); + let parsed: AppSyncIamIdentity = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AppSyncIamIdentity = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "appsync")] fn example_appsync_lambda_auth_request() { - let data = include_bytes!("../../fixtures/example-appsync-lambda-auth-request.json"); - let parsed: AppSyncLambdaAuthorizerRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AppSyncLambdaAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-appsync-lambda-auth-request.json").to_vec(); + let parsed: AppSyncLambdaAuthorizerRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AppSyncLambdaAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "appsync")] fn example_appsync_lambda_auth_response() { - let data = include_bytes!("../../fixtures/example-appsync-lambda-auth-response.json"); - let parsed: AppSyncLambdaAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AppSyncLambdaAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-appsync-lambda-auth-response.json").to_vec(); + let parsed: AppSyncLambdaAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AppSyncLambdaAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/autoscaling/mod.rs b/lambda-events/src/event/autoscaling/mod.rs index e51c2b9f..d0e074d9 100644 --- a/lambda-events/src/event/autoscaling/mod.rs +++ b/lambda-events/src/event/autoscaling/mod.rs @@ -50,60 +50,60 @@ mod test { #[test] #[cfg(feature = "autoscaling")] fn example_autoscaling_event_launch_successful() { - let data = include_bytes!("../../fixtures/example-autoscaling-event-launch-successful.json"); - let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-autoscaling-event-launch-successful.json").to_vec(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "autoscaling")] fn example_autoscaling_event_launch_unsuccessful() { - let data = include_bytes!("../../fixtures/example-autoscaling-event-launch-unsuccessful.json"); - let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-autoscaling-event-launch-unsuccessful.json").to_vec(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "autoscaling")] fn example_autoscaling_event_lifecycle_action() { - let data = include_bytes!("../../fixtures/example-autoscaling-event-lifecycle-action.json"); - let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-autoscaling-event-lifecycle-action.json").to_vec(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "autoscaling")] fn example_autoscaling_event_terminate_action() { - let data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-action.json"); - let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-action.json").to_vec(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "autoscaling")] fn example_autoscaling_event_terminate_successful() { - let data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-successful.json"); - let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-successful.json").to_vec(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "autoscaling")] fn example_autoscaling_event_terminate_unsuccessful() { - let data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-unsuccessful.json"); - let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-unsuccessful.json").to_vec(); + let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/bedrock_agent_runtime/mod.rs b/lambda-events/src/event/bedrock_agent_runtime/mod.rs index bfef23cc..d9075e59 100644 --- a/lambda-events/src/event/bedrock_agent_runtime/mod.rs +++ b/lambda-events/src/event/bedrock_agent_runtime/mod.rs @@ -88,28 +88,28 @@ mod tests { #[test] #[cfg(feature = "bedrock_agent_runtime")] fn example_bedrock_agent_runtime_event() { - let data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event.json"); - let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event.json").to_vec(); + let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "bedrock_agent_runtime")] fn example_bedrock_agent_runtime_event_without_parameters() { - let data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-parameters.json"); - let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-parameters.json").to_vec(); + let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "bedrock_agent_runtime")] fn example_bedrock_agent_runtime_event_without_request_body() { - let data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-request-body.json"); - let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-request-body.json").to_vec(); + let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/clientvpn/mod.rs b/lambda-events/src/event/clientvpn/mod.rs index c05acf7d..c9c2306c 100644 --- a/lambda-events/src/event/clientvpn/mod.rs +++ b/lambda-events/src/event/clientvpn/mod.rs @@ -52,10 +52,10 @@ mod test { #[test] #[cfg(feature = "clientvpn")] fn example_clientvpn_connectionhandler_request() { - let data = include_bytes!("../../fixtures/example-clientvpn-connectionhandler-request.json"); - let parsed: ClientVpnConnectionHandlerRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ClientVpnConnectionHandlerRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-clientvpn-connectionhandler-request.json").to_vec(); + let parsed: ClientVpnConnectionHandlerRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ClientVpnConnectionHandlerRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudformation/mod.rs b/lambda-events/src/event/cloudformation/mod.rs index bb6bdcb7..32112201 100644 --- a/lambda-events/src/event/cloudformation/mod.rs +++ b/lambda-events/src/event/cloudformation/mod.rs @@ -116,55 +116,55 @@ mod test { #[test] fn example_cloudformation_custom_resource_create_request() { - let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-create-request.json"); - let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-create-request.json").to_vec(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { Create(_) => (), _ => panic!("expected Create request"), } - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_cloudformation_custom_resource_update_request() { - let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-update-request.json"); - let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-update-request.json").to_vec(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { Update(_) => (), _ => panic!("expected Update request"), } - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_cloudformation_custom_resource_delete_request() { - let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-delete-request.json"); - let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-delete-request.json").to_vec(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { Delete(_) => (), _ => panic!("expected Delete request"), } - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_cloudformation_custom_resource_response() { - let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-response.json"); - let parsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-response.json").to_vec(); + let parsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudformation/provider.rs b/lambda-events/src/event/cloudformation/provider.rs index 269c64a2..ae7bb10c 100644 --- a/lambda-events/src/event/cloudformation/provider.rs +++ b/lambda-events/src/event/cloudformation/provider.rs @@ -104,55 +104,55 @@ mod test { #[test] fn example_create_request() { - let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-create-request.json"); - let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-create-request.json").to_vec(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { Create(_) => (), _ => panic!("expected Create request"), } - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_update_request() { - let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-update-request.json"); - let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-update-request.json").to_vec(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { Update(_) => (), _ => panic!("expected Update request"), } - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_delete_request() { - let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-delete-request.json"); - let parsed: TestRequest = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-delete-request.json").to_vec(); + let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { Delete(_) => (), _ => panic!("expected Delete request"), } - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_response() { - let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-response.json"); - let parsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-response.json").to_vec(); + let parsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudwatch_alarms/mod.rs b/lambda-events/src/event/cloudwatch_alarms/mod.rs index c848eaa6..3b84f6bf 100644 --- a/lambda-events/src/event/cloudwatch_alarms/mod.rs +++ b/lambda-events/src/event/cloudwatch_alarms/mod.rs @@ -260,8 +260,8 @@ mod test { #[test] #[cfg(feature = "cloudwatch_alarms")] fn example_cloudwatch_alarm_metric() { - let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-metric.json"); - let parsed: CloudWatchMetricAlarm = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudwatch-alarm-metric.json").to_vec(); + let parsed: CloudWatchMetricAlarm = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let state = parsed.alarm_data.previous_state.clone().unwrap(); let data = state.reason_data.unwrap(); match &data { @@ -272,16 +272,16 @@ mod test { _ => panic!("unexpected reason data {data:?}"), } - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CloudWatchMetricAlarm = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CloudWatchMetricAlarm = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cloudwatch_alarms")] fn example_cloudwatch_alarm_composite() { - let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-composite.json"); - let parsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudwatch-alarm-composite.json").to_vec(); + let parsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let state = parsed.alarm_data.state.clone().unwrap(); let data = state.reason_data.unwrap(); @@ -296,16 +296,16 @@ mod test { _ => panic!("unexpected reason data {data:?}"), } - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cloudwatch_alarms")] fn example_cloudwatch_alarm_composite_with_suppressor_alarm() { - let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-composite-with-suppressor-alarm.json"); - let parsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudwatch-alarm-composite-with-suppressor-alarm.json").to_vec(); + let parsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let state = parsed.alarm_data.state.clone().unwrap(); assert_eq!("WaitPeriod", state.actions_suppressed_by.unwrap()); assert_eq!( @@ -313,8 +313,8 @@ mod test { state.actions_suppressed_reason.unwrap() ); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudwatch_events/cloudtrail.rs b/lambda-events/src/event/cloudwatch_events/cloudtrail.rs index 35fa9008..7497e686 100644 --- a/lambda-events/src/event/cloudwatch_events/cloudtrail.rs +++ b/lambda-events/src/event/cloudwatch_events/cloudtrail.rs @@ -88,28 +88,28 @@ mod tests { #[test] #[cfg(feature = "cloudwatch_events")] fn example_cloudwatch_cloudtrail_unknown_assumed_role() { - let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-assumed-role.json"); - let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-assumed-role.json").to_vec(); + let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cloudwatch_events")] fn example_cloudwatch_cloudtrail_unknown_federate() { - let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-federate.json"); - let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-federate.json").to_vec(); + let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cloudwatch_events")] fn example_cloudwatch_cloudtrail_assumed_role() { - let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-user-auth.json"); - let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-user-auth.json").to_vec(); + let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudwatch_logs/mod.rs b/lambda-events/src/event/cloudwatch_logs/mod.rs index 090b20c3..54e3eb59 100644 --- a/lambda-events/src/event/cloudwatch_logs/mod.rs +++ b/lambda-events/src/event/cloudwatch_logs/mod.rs @@ -80,7 +80,7 @@ impl<'de> Deserialize<'de> for AwsLogs { })?; let bytes = flate2::read::GzDecoder::new(&bytes[..]); - let mut de = aws_lambda_json_impl::JsonDeserializer::from_reader(BufReader::new(bytes)); + let mut de = aws_lambda_json_impl::from_reader(BufReader::new(bytes)); data = Some(LogData::deserialize(&mut de).map_err(Error::custom)?); } _ => return Err(Error::unknown_field(key, FIELDS)), @@ -123,12 +123,12 @@ mod test { #[test] #[cfg(feature = "cloudwatch_logs")] fn test_deserialize_example() { - let json = r#"{ + let mut json = r#"{ "awslogs": { "data": "H4sIAFETomIAA12Ry27bMBBF9/4KQuiyqsQ36Z2DqEGBGC0sdRUHAS0NExV6uCJVNw3y76Fkx03CFTH3cubwztMChRO14Jy5h+JxD9ESRZerYnW3zvJ8dZVFn4+W/tDBMImYUMaFVDrF5FVs+vuroR/3k56Yg0sa0+4qk0D50MddX8Ev98aa+wFMO3lJinWS0gTT5ObT9arI8uJWM2uUkMCpZIxiorGRtsQMiOXCgHxt5MadK4d67+u++1o3HgYXWt7M4my4nhmOw+7Kph+rg/HlQwBwM1M0W2//c2V/oPPvmzydb7OpriZqygQhFItUa6GlUkymgrNUS5EKpQhRfMpGCEzC/xgWjCpNOBMn8nM3X4fcvWmn2DDnhGNFWXiffvCdtjON3mQ/vm8KtIHfY3j6rVoiEdaxsxZizLSJd4KRWGFrYwIKqBSVMtZu/eU4mCmoJWLii2KodVt/UTcNVOiNJEMdbf0a2n54RHn9DwKYJmh9EYrmLzoJPx2EwfJY33bRmfb5mOjiefECiB5LsVgCAAA=" } -}"#; - let event: LogsEvent = aws_lambda_json_impl::from_str(json).expect("failed to deserialize"); +}"#.to_owned(); + let event: LogsEvent = aws_lambda_json_impl::from_str(&mut json).expect("failed to deserialize"); let data = event.clone().aws_logs.data; assert_eq!("DATA_MESSAGE", data.message_type); @@ -145,18 +145,18 @@ mod test { assert_eq!(1552518348220, data.log_events[0].timestamp); assert_eq!("REPORT RequestId: 6234bffe-149a-b642-81ff-2e8e376d8aff\tDuration: 46.84 ms\tBilled Duration: 47 ms \tMemory Size: 192 MB\tMax Memory Used: 72 MB\t\n", data.log_events[0].message); - let new_json: String = aws_lambda_json_impl::to_string_pretty(&event).unwrap(); - let new_event: LogsEvent = aws_lambda_json_impl::from_str(&new_json).expect("failed to deserialize"); + let mut new_json: String = aws_lambda_json_impl::to_string_pretty(&event).unwrap(); + let new_event: LogsEvent = aws_lambda_json_impl::from_str(&mut new_json).expect("failed to deserialize"); assert_eq!(new_event, event); } #[test] #[cfg(feature = "cloudwatch_logs")] fn example_cloudwatch_logs_event() { - let data = include_bytes!("../../fixtures/example-cloudwatch_logs-event.json"); - let parsed: LogsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: LogsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudwatch_logs-event.json").to_vec(); + let parsed: LogsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: LogsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/code_commit/mod.rs b/lambda-events/src/event/code_commit/mod.rs index 4bf94153..769ee854 100644 --- a/lambda-events/src/event/code_commit/mod.rs +++ b/lambda-events/src/event/code_commit/mod.rs @@ -72,10 +72,10 @@ mod test { #[test] #[cfg(feature = "code_commit")] fn example_code_commit_event() { - let data = include_bytes!("../../fixtures/example-code_commit-event.json"); - let parsed: CodeCommitEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CodeCommitEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-code_commit-event.json").to_vec(); + let parsed: CodeCommitEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CodeCommitEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/codebuild/mod.rs b/lambda-events/src/event/codebuild/mod.rs index 3e001b01..333690f1 100644 --- a/lambda-events/src/event/codebuild/mod.rs +++ b/lambda-events/src/event/codebuild/mod.rs @@ -217,20 +217,20 @@ mod test { #[test] #[cfg(feature = "codebuild")] fn example_codebuild_phase_change() { - let data = include_bytes!("../../fixtures/example-codebuild-phase-change.json"); - let parsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-codebuild-phase-change.json").to_vec(); + let parsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "codebuild")] fn example_codebuild_state_change() { - let data = include_bytes!("../../fixtures/example-codebuild-state-change.json"); - let parsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-codebuild-state-change.json").to_vec(); + let parsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/codedeploy/mod.rs b/lambda-events/src/event/codedeploy/mod.rs index acbf440b..72ef1713 100644 --- a/lambda-events/src/event/codedeploy/mod.rs +++ b/lambda-events/src/event/codedeploy/mod.rs @@ -79,34 +79,34 @@ mod test { #[test] #[cfg(feature = "codedeploy")] fn example_codedeploy_lifecycle_event() { - let data = include_bytes!("../../fixtures/example-codedeploy-lifecycle-event.json"); - let parsed: CodeDeployLifecycleEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-codedeploy-lifecycle-event.json").to_vec(); + let parsed: CodeDeployLifecycleEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!(parsed.deployment_id, "d-deploymentId".to_string()); assert_eq!(parsed.lifecycle_event_hook_execution_id, "eyJlbmNyeXB0ZWREYXRhIjoiY3VHU2NjdkJXUTJQUENVd2dkYUNGRVg0dWlpME9UWVdHTVhZcDRXVW5LYUVKc21EaUFPMkNLNXMwMWFrNDlYVStlbXdRb29xS3NJTUNVQ3RYRGFZSXc1VTFwUllvMDhmMzdlbDZFeDVVdjZrNFc0eU5waGh6YTRvdkNWcmVveVR6OWdERlM2SmlIYW1TZz09IiwiaXZQYXJhbWV0ZXJTcGVjIjoiTm1ZNFR6RzZxQVhHamhhLyIsIm1hdGVyaWFsU2V0U2VyaWFsIjoxfQ==".to_string()); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CodeDeployLifecycleEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CodeDeployLifecycleEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "codedeploy")] fn example_codedeploy_deployment_event() { - let data = include_bytes!("../../fixtures/example-codedeploy-deployment-event.json"); - let parsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-codedeploy-deployment-event.json").to_vec(); + let parsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "codedeploy")] fn example_codedeploy_instance_event() { - let data = include_bytes!("../../fixtures/example-codedeploy-instance-event.json"); - let parsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-codedeploy-instance-event.json").to_vec(); + let parsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/codepipeline_cloudwatch/mod.rs b/lambda-events/src/event/codepipeline_cloudwatch/mod.rs index 6c0b04ca..c66c9e8b 100644 --- a/lambda-events/src/event/codepipeline_cloudwatch/mod.rs +++ b/lambda-events/src/event/codepipeline_cloudwatch/mod.rs @@ -84,30 +84,30 @@ mod test { #[test] #[cfg(feature = "codepipeline_cloudwatch")] fn example_codepipeline_action_execution_stage_change_event() { - let data = include_bytes!("../../fixtures/example-codepipeline-action-execution-stage-change-event.json"); - let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-codepipeline-action-execution-stage-change-event.json").to_vec(); + let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "codepipeline_cloudwatch")] fn example_codepipeline_execution_stage_change_event() { - let data = include_bytes!("../../fixtures/example-codepipeline-execution-stage-change-event.json"); - let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-codepipeline-execution-stage-change-event.json").to_vec(); + let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "codepipeline_cloudwatch")] fn example_codepipeline_execution_state_change_event() { - let data = include_bytes!("../../fixtures/example-codepipeline-execution-state-change-event.json"); - let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-codepipeline-execution-state-change-event.json").to_vec(); + let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/codepipeline_job/mod.rs b/lambda-events/src/event/codepipeline_job/mod.rs index e4d25322..69f0510d 100644 --- a/lambda-events/src/event/codepipeline_job/mod.rs +++ b/lambda-events/src/event/codepipeline_job/mod.rs @@ -120,10 +120,10 @@ mod test { #[test] #[cfg(feature = "codepipeline_job")] fn example_codepipeline_job_event() { - let data = include_bytes!("../../fixtures/example-codepipeline_job-event.json"); - let parsed: CodePipelineJobEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CodePipelineJobEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-codepipeline_job-event.json").to_vec(); + let parsed: CodePipelineJobEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CodePipelineJobEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cognito/mod.rs b/lambda-events/src/event/cognito/mod.rs index a8a17f65..67449789 100644 --- a/lambda-events/src/event/cognito/mod.rs +++ b/lambda-events/src/event/cognito/mod.rs @@ -635,228 +635,225 @@ mod test { #[test] #[cfg(feature = "cognito")] fn example_cognito_event() { - let data = include_bytes!("../../fixtures/example-cognito-event.json"); - let parsed: CognitoEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event.json").to_vec(); + let parsed: CognitoEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_create_auth_challenge() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge.json"); - let parsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge.json").to_vec(); + let parsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_create_auth_challenge_user_not_found() { - let data = - include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge-user-not-found.json"); - let parsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge-user-not-found.json").to_vec(); + let parsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(parsed.request.user_not_found); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_custommessage() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-custommessage.json"); - let parsed: CognitoEventUserPoolsCustomMessage = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsCustomMessage = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-custommessage.json").to_vec(); + let parsed: CognitoEventUserPoolsCustomMessage = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsCustomMessage = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_define_auth_challenge() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge.json"); - let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge.json").to_vec(); + let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_define_auth_challenge_optional_response_fields() { - let data = include_bytes!( + let mut data = include_bytes!( "../../fixtures/example-cognito-event-userpools-define-auth-challenge-optional-response-fields.json" - ); - let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); + ).to_vec(); + let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(!parsed.response.fail_authentication); assert!(!parsed.response.issue_tokens); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_define_auth_challenge_user_not_found() { - let data = - include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge-user-not-found.json"); - let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge-user-not-found.json").to_vec(); + let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(parsed.request.user_not_found); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_migrateuser() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-migrateuser.json"); - let parsed: CognitoEventUserPoolsMigrateUser = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsMigrateUser = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-migrateuser.json").to_vec(); + let parsed: CognitoEventUserPoolsMigrateUser = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsMigrateUser = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_postauthentication() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-postauthentication.json"); - let parsed: CognitoEventUserPoolsPostAuthentication = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPostAuthentication = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-postauthentication.json").to_vec(); + let parsed: CognitoEventUserPoolsPostAuthentication = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsPostAuthentication = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_postconfirmation() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-postconfirmation.json"); - let parsed: CognitoEventUserPoolsPostConfirmation = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPostConfirmation = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-postconfirmation.json").to_vec(); + let parsed: CognitoEventUserPoolsPostConfirmation = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsPostConfirmation = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_preauthentication() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-preauthentication.json"); - let parsed: CognitoEventUserPoolsPreAuthentication = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreAuthentication = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-preauthentication.json").to_vec(); + let parsed: CognitoEventUserPoolsPreAuthentication = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsPreAuthentication = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_presignup() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-presignup.json"); - let parsed: CognitoEventUserPoolsPreSignup = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreSignup = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-presignup.json").to_vec(); + let parsed: CognitoEventUserPoolsPreSignup = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsPreSignup = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_pretokengen_incoming() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-incoming.json"); - let parsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-incoming.json").to_vec(); + let parsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_pretokengen_v2_incoming() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json"); - let parsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json").to_vec(); + let parsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_pretokengen() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen.json"); - let parsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen.json").to_vec(); + let parsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_v2_pretokengen() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2.json"); - let parsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2.json").to_vec(); + let parsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_verify_auth_challenge() { - let data = include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge.json"); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge.json").to_vec(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_verify_auth_challenge_optional_answer_correct() { - let data = include_bytes!( + let mut data = include_bytes!( "../../fixtures/example-cognito-event-userpools-verify-auth-challenge-optional-answer-correct.json" - ); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); + ).to_vec(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(!parsed.response.answer_correct); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_verify_auth_challenge_null_answer_correct() { - let data = include_bytes!( + let mut data = include_bytes!( "../../fixtures/example-cognito-event-userpools-verify-auth-challenge-null-answer-correct.json" - ); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); + ).to_vec(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(!parsed.response.answer_correct); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_verify_auth_challenge_user_not_found() { - let data = - include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge-user-not-found.json"); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge-user-not-found.json").to_vec(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(parsed.request.user_not_found); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } @@ -891,11 +888,11 @@ mod trigger_source_tests { "PreSignUp_ExternalProvider", ]; possible_triggers.into_iter().for_each(|trigger| { - let header = gen_header(trigger); + let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&header).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&mut header).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -904,11 +901,11 @@ mod trigger_source_tests { fn pre_authentication() { let possible_triggers = ["PreAuthentication_Authentication"]; possible_triggers.into_iter().for_each(|trigger| { - let header = gen_header(trigger); + let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&header).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&mut header).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -920,11 +917,11 @@ mod trigger_source_tests { ]; possible_triggers.into_iter().for_each(|trigger| { - let header = gen_header(trigger); + let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&header).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&mut header).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -933,11 +930,11 @@ mod trigger_source_tests { let possible_triggers = ["PostAuthentication_Authentication"]; possible_triggers.into_iter().for_each(|trigger| { - let header = gen_header(trigger); + let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&header).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&mut header).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -946,11 +943,11 @@ mod trigger_source_tests { let possible_triggers = ["DefineAuthChallenge_Authentication"]; possible_triggers.into_iter().for_each(|trigger| { - let header = gen_header(trigger); + let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&header).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&mut header).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -960,11 +957,11 @@ mod trigger_source_tests { let possible_triggers = ["CreateAuthChallenge_Authentication"]; possible_triggers.into_iter().for_each(|trigger| { - let header = gen_header(trigger); + let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&header).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&mut header).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -973,11 +970,11 @@ mod trigger_source_tests { let possible_triggers = ["VerifyAuthChallengeResponse_Authentication"]; possible_triggers.into_iter().for_each(|trigger| { - let header = gen_header(trigger); + let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&header).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&mut header).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -992,11 +989,11 @@ mod trigger_source_tests { ]; possible_triggers.into_iter().for_each(|trigger| { - let header = gen_header(trigger); + let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&header).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&mut header).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -1005,11 +1002,11 @@ mod trigger_source_tests { let possible_triggers = ["UserMigration_Authentication", "UserMigration_ForgotPassword"]; possible_triggers.into_iter().for_each(|trigger| { - let header = gen_header(trigger); + let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&header).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&mut header).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -1026,11 +1023,11 @@ mod trigger_source_tests { ]; possible_triggers.into_iter().for_each(|trigger| { - let header = gen_header(trigger); + let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&header).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + aws_lambda_json_impl::from_str(&mut header).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } diff --git a/lambda-events/src/event/config/mod.rs b/lambda-events/src/event/config/mod.rs index 8812c159..5eca5462 100644 --- a/lambda-events/src/event/config/mod.rs +++ b/lambda-events/src/event/config/mod.rs @@ -43,10 +43,10 @@ mod test { #[test] #[cfg(feature = "config")] fn example_config_event() { - let data = include_bytes!("../../fixtures/example-config-event.json"); - let parsed: ConfigEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ConfigEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-config-event.json").to_vec(); + let parsed: ConfigEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ConfigEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/connect/mod.rs b/lambda-events/src/event/connect/mod.rs index 2e527e9a..1eaffe38 100644 --- a/lambda-events/src/event/connect/mod.rs +++ b/lambda-events/src/event/connect/mod.rs @@ -97,20 +97,20 @@ mod test { #[test] #[cfg(feature = "connect")] fn example_connect_event() { - let data = include_bytes!("../../fixtures/example-connect-event.json"); - let parsed: ConnectEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ConnectEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-connect-event.json").to_vec(); + let parsed: ConnectEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ConnectEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "connect")] fn example_connect_event_without_queue() { - let data = include_bytes!("../../fixtures/example-connect-event-without-queue.json"); - let parsed: ConnectEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: ConnectEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-connect-event-without-queue.json").to_vec(); + let parsed: ConnectEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: ConnectEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/documentdb/mod.rs b/lambda-events/src/event/documentdb/mod.rs index 67f3674f..f91d03e9 100644 --- a/lambda-events/src/event/documentdb/mod.rs +++ b/lambda-events/src/event/documentdb/mod.rs @@ -43,9 +43,10 @@ mod test { pub type Event = DocumentDbEvent; fn test_example(data: &[u8]) { - let parsed: Event = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: Event = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = data.to_vec(); + let parsed: Event = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: Event = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } diff --git a/lambda-events/src/event/dynamodb/mod.rs b/lambda-events/src/event/dynamodb/mod.rs index 8ab0caf7..89028363 100644 --- a/lambda-events/src/event/dynamodb/mod.rs +++ b/lambda-events/src/event/dynamodb/mod.rs @@ -259,10 +259,10 @@ mod test { #[test] #[cfg(feature = "dynamodb")] fn example_dynamodb_event() { - let data = include_bytes!("../../fixtures/example-dynamodb-event.json"); - let mut parsed: Event = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: Event = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-dynamodb-event.json").to_vec(); + let mut parsed: Event = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: Event = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); let event = parsed.records.pop().unwrap(); @@ -273,10 +273,10 @@ mod test { #[test] #[cfg(feature = "dynamodb")] fn example_dynamodb_event_with_optional_fields() { - let data = include_bytes!("../../fixtures/example-dynamodb-event-record-with-optional-fields.json"); - let parsed: EventRecord = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: EventRecord = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-dynamodb-event-record-with-optional-fields.json").to_vec(); + let parsed: EventRecord = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: EventRecord = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); let date = Utc.timestamp_micros(0).unwrap(); // 1970-01-01T00:00:00Z assert_eq!(date, reparsed.change.approximate_creation_date_time); diff --git a/lambda-events/src/event/ecr_scan/mod.rs b/lambda-events/src/event/ecr_scan/mod.rs index 1250c475..247ecc0f 100644 --- a/lambda-events/src/event/ecr_scan/mod.rs +++ b/lambda-events/src/event/ecr_scan/mod.rs @@ -70,20 +70,20 @@ mod test { #[test] #[cfg(feature = "ecr_scan")] fn example_ecr_image_scan_event() { - let data = include_bytes!("../../fixtures/example-ecr-image-scan-event.json"); - let parsed: EcrScanEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: EcrScanEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-ecr-image-scan-event.json").to_vec(); + let parsed: EcrScanEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: EcrScanEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "ecr_scan")] fn example_ecr_image_scan_event_with_missing_severities() { - let data = include_bytes!("../../fixtures/example-ecr-image-scan-event-with-missing-severities.json"); - let parsed: EcrScanEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: EcrScanEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-ecr-image-scan-event-with-missing-severities.json").to_vec(); + let parsed: EcrScanEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: EcrScanEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/eventbridge/mod.rs b/lambda-events/src/event/eventbridge/mod.rs index 95084cc6..e754ecbb 100644 --- a/lambda-events/src/event/eventbridge/mod.rs +++ b/lambda-events/src/event/eventbridge/mod.rs @@ -47,27 +47,27 @@ mod test { } // Example from https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instance-state-changes.html - let data = include_bytes!("../../fixtures/example-eventbridge-event-obj.json"); - let parsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-eventbridge-event-obj.json").to_vec(); + let parsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!("i-abcd1111", parsed.detail.instance_id); assert_eq!("pending", parsed.detail.state); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] fn example_eventbridge_schedule_event() { - let data = include_bytes!("../../fixtures/example-eventbridge-schedule.json"); - let parsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-eventbridge-schedule.json").to_vec(); + let parsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!("aws.events", parsed.source); assert_eq!("Scheduled Event", parsed.detail_type); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/firehose/mod.rs b/lambda-events/src/event/firehose/mod.rs index fcef3cc2..5e7ee6a0 100644 --- a/lambda-events/src/event/firehose/mod.rs +++ b/lambda-events/src/event/firehose/mod.rs @@ -79,10 +79,10 @@ mod test { #[test] #[cfg(feature = "firehose")] fn example_firehose_event() { - let data = include_bytes!("../../fixtures/example-firehose-event.json"); - let parsed: KinesisFirehoseEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: KinesisFirehoseEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-firehose-event.json").to_vec(); + let parsed: KinesisFirehoseEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: KinesisFirehoseEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/iot/mod.rs b/lambda-events/src/event/iot/mod.rs index 470009e9..9c419899 100644 --- a/lambda-events/src/event/iot/mod.rs +++ b/lambda-events/src/event/iot/mod.rs @@ -77,20 +77,20 @@ mod test { #[test] #[cfg(feature = "iot")] fn example_iot_custom_auth_request() { - let data = include_bytes!("../../fixtures/example-iot-custom-auth-request.json"); - let parsed: IoTCoreCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: IoTCoreCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-iot-custom-auth-request.json").to_vec(); + let parsed: IoTCoreCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: IoTCoreCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "iot")] fn example_iot_custom_auth_response() { - let data = include_bytes!("../../fixtures/example-iot-custom-auth-response.json"); - let parsed: IoTCoreCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: IoTCoreCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-iot-custom-auth-response.json").to_vec(); + let parsed: IoTCoreCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: IoTCoreCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/iot_1_click/mod.rs b/lambda-events/src/event/iot_1_click/mod.rs index ed690b69..c7fde657 100644 --- a/lambda-events/src/event/iot_1_click/mod.rs +++ b/lambda-events/src/event/iot_1_click/mod.rs @@ -63,10 +63,10 @@ mod test { #[test] #[cfg(feature = "iot_1_click")] fn example_iot_1_click_event() { - let data = include_bytes!("../../fixtures/example-iot_1_click-event.json"); - let parsed: IoTOneClickEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: IoTOneClickEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-iot_1_click-event.json").to_vec(); + let parsed: IoTOneClickEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: IoTOneClickEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/iot_button/mod.rs b/lambda-events/src/event/iot_button/mod.rs index e629ecc5..9c010fd2 100644 --- a/lambda-events/src/event/iot_button/mod.rs +++ b/lambda-events/src/event/iot_button/mod.rs @@ -18,10 +18,10 @@ mod test { #[test] #[cfg(feature = "iot_button")] fn example_iot_button_event() { - let data = include_bytes!("../../fixtures/example-iot_button-event.json"); - let parsed: IoTButtonEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: IoTButtonEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-iot_button-event.json").to_vec(); + let parsed: IoTButtonEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: IoTButtonEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/kafka/mod.rs b/lambda-events/src/event/kafka/mod.rs index e8f56074..d19b51fb 100644 --- a/lambda-events/src/event/kafka/mod.rs +++ b/lambda-events/src/event/kafka/mod.rs @@ -38,10 +38,10 @@ mod test { #[test] #[cfg(feature = "kafka")] fn example_kafka_event() { - let data = include_bytes!("../../fixtures/example-kafka-event.json"); - let parsed: KafkaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: KafkaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-kafka-event.json").to_vec(); + let parsed: KafkaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: KafkaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/kinesis/event.rs b/lambda-events/src/event/kinesis/event.rs index 0b702c88..e35aa0eb 100644 --- a/lambda-events/src/event/kinesis/event.rs +++ b/lambda-events/src/event/kinesis/event.rs @@ -89,24 +89,24 @@ mod test { #[test] #[cfg(feature = "kinesis")] fn example_kinesis_event() { - let data = include_bytes!("../../fixtures/example-kinesis-event.json"); - let parsed: KinesisEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-kinesis-event.json").to_vec(); + let parsed: KinesisEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!(KinesisEncryptionType::None, parsed.records[0].kinesis.encryption_type); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: KinesisEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: KinesisEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "kinesis")] fn example_kinesis_event_encrypted() { - let data = include_bytes!("../../fixtures/example-kinesis-event-encrypted.json"); - let parsed: KinesisEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-kinesis-event-encrypted.json").to_vec(); + let parsed: KinesisEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!(KinesisEncryptionType::Kms, parsed.records[0].kinesis.encryption_type); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: KinesisEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: KinesisEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/lex/mod.rs b/lambda-events/src/event/lex/mod.rs index 5da9f5e1..bae58bd9 100644 --- a/lambda-events/src/event/lex/mod.rs +++ b/lambda-events/src/event/lex/mod.rs @@ -111,20 +111,20 @@ mod test { #[test] #[cfg(feature = "lex")] fn example_lex_event() { - let data = include_bytes!("../../fixtures/example-lex-event.json"); - let parsed: LexEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: LexEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-lex-event.json").to_vec(); + let parsed: LexEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: LexEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "lex")] fn example_lex_response() { - let data = include_bytes!("../../fixtures/example-lex-response.json"); - let parsed: LexEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: LexEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-lex-response.json").to_vec(); + let parsed: LexEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: LexEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/rabbitmq/mod.rs b/lambda-events/src/event/rabbitmq/mod.rs index 01c40f70..3fa043cc 100644 --- a/lambda-events/src/event/rabbitmq/mod.rs +++ b/lambda-events/src/event/rabbitmq/mod.rs @@ -65,10 +65,10 @@ mod test { #[test] #[cfg(feature = "rabbitmq")] fn example_rabbitmq_event() { - let data = include_bytes!("../../fixtures/example-rabbitmq-event.json"); - let parsed: RabbitMqEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: RabbitMqEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-rabbitmq-event.json").to_vec(); + let parsed: RabbitMqEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: RabbitMqEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/s3/event.rs b/lambda-events/src/event/s3/event.rs index 600768cf..d72ea579 100644 --- a/lambda-events/src/event/s3/event.rs +++ b/lambda-events/src/event/s3/event.rs @@ -95,20 +95,20 @@ mod test { #[test] #[cfg(feature = "s3")] fn example_s3_event() { - let data = include_bytes!("../../fixtures/example-s3-event.json"); - let parsed: S3Event = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: S3Event = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-s3-event.json").to_vec(); + let parsed: S3Event = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: S3Event = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "s3")] fn example_s3_event_with_decoded() { - let data = include_bytes!("../../fixtures/example-s3-event-with-decoded.json"); - let parsed: S3Event = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: S3Event = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-s3-event-with-decoded.json").to_vec(); + let parsed: S3Event = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: S3Event = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/s3/object_lambda.rs b/lambda-events/src/event/s3/object_lambda.rs index 45bc77eb..598e6658 100644 --- a/lambda-events/src/event/s3/object_lambda.rs +++ b/lambda-events/src/event/s3/object_lambda.rs @@ -122,50 +122,50 @@ mod test { #[test] #[cfg(feature = "s3")] fn example_object_lambda_event_get_object_assumed_role() { - let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-assumed-role.json"); - let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-assumed-role.json").to_vec(); + let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "s3")] fn example_object_lambda_event_get_object_iam() { - let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-iam.json"); - let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-iam.json").to_vec(); + let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "s3")] fn example_object_lambda_event_head_object_iam() { - let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-head-object-iam.json"); - let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-s3-object-lambda-event-head-object-iam.json").to_vec(); + let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "s3")] fn example_object_lambda_event_list_objects_iam() { - let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-iam.json"); - let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-iam.json").to_vec(); + let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "s3")] fn example_object_lambda_event_list_objects_v2_iam() { - let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-v2-iam.json"); - let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-v2-iam.json").to_vec(); + let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/secretsmanager/mod.rs b/lambda-events/src/event/secretsmanager/mod.rs index 58a40cc4..8f685538 100644 --- a/lambda-events/src/event/secretsmanager/mod.rs +++ b/lambda-events/src/event/secretsmanager/mod.rs @@ -15,10 +15,10 @@ mod test { #[test] #[cfg(feature = "secretsmanager")] fn example_secretsmanager_secret_rotation_event() { - let data = include_bytes!("../../fixtures/example-secretsmanager-secret-rotation-event.json"); - let parsed: SecretsManagerSecretRotationEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SecretsManagerSecretRotationEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-secretsmanager-secret-rotation-event.json").to_vec(); + let parsed: SecretsManagerSecretRotationEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SecretsManagerSecretRotationEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/ses/mod.rs b/lambda-events/src/event/ses/mod.rs index d17c041b..badfdd41 100644 --- a/lambda-events/src/event/ses/mod.rs +++ b/lambda-events/src/event/ses/mod.rs @@ -125,30 +125,30 @@ mod test { #[test] #[cfg(feature = "ses")] fn example_ses_lambda_event() { - let data = include_bytes!("../../fixtures/example-ses-lambda-event.json"); - let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-ses-lambda-event.json").to_vec(); + let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "ses")] fn example_ses_s3_event() { - let data = include_bytes!("../../fixtures/example-ses-s3-event.json"); - let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-ses-s3-event.json").to_vec(); + let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "ses")] fn example_ses_sns_event() { - let data = include_bytes!("../../fixtures/example-ses-sns-event.json"); - let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-ses-sns-event.json").to_vec(); + let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/sns/mod.rs b/lambda-events/src/event/sns/mod.rs index b1a4fc82..537eb166 100644 --- a/lambda-events/src/event/sns/mod.rs +++ b/lambda-events/src/event/sns/mod.rs @@ -253,36 +253,36 @@ mod test { #[test] #[cfg(feature = "sns")] fn my_example_sns_event() { - let data = include_bytes!("../../fixtures/example-sns-event.json"); - let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-sns-event.json").to_vec(); + let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "sns")] fn my_example_sns_event_pascal_case() { - let data = include_bytes!("../../fixtures/example-sns-event-pascal-case.json"); - let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-sns-event-pascal-case.json").to_vec(); + let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "sns")] fn my_example_sns_event_cloudwatch_single_metric() { - let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-single-metric.json"); - let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-single-metric.json").to_vec(); + let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!(1, parsed.records.len()); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); let parsed: SnsEventObj = - aws_lambda_json_impl::from_slice(data).expect("failed to parse CloudWatch Alarm payload"); + aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to parse CloudWatch Alarm payload"); let record = parsed.records.first().unwrap(); assert_eq!("EXAMPLE", record.sns.message.alarm_name); @@ -291,19 +291,19 @@ mod test { #[test] #[cfg(feature = "sns")] fn my_example_sns_event_cloudwatch_multiple_metrics() { - let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-multiple-metrics.json"); - let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-multiple-metrics.json").to_vec(); + let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!(2, parsed.records.len()); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "sns")] fn my_example_sns_obj_event() { - let data = include_bytes!("../../fixtures/example-sns-event-obj.json"); + let mut data = include_bytes!("../../fixtures/example-sns-event-obj.json").to_vec(); #[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] struct CustStruct { @@ -311,14 +311,14 @@ mod test { bar: i32, } - let parsed: SnsEventObj = aws_lambda_json_impl::from_slice(data).unwrap(); + let parsed: SnsEventObj = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); println!("{:?}", parsed); assert_eq!(parsed.records[0].sns.message.foo, "Hello world!"); assert_eq!(parsed.records[0].sns.message.bar, 123); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SnsEventObj = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SnsEventObj = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/sqs/mod.rs b/lambda-events/src/event/sqs/mod.rs index 1f3432fe..633decb9 100644 --- a/lambda-events/src/event/sqs/mod.rs +++ b/lambda-events/src/event/sqs/mod.rs @@ -185,10 +185,10 @@ mod test { #[test] #[cfg(feature = "sqs")] fn example_sqs_event() { - let data = include_bytes!("../../fixtures/example-sqs-event.json"); - let parsed: SqsEvent = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SqsEvent = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-sqs-event.json").to_vec(); + let parsed: SqsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SqsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -201,14 +201,14 @@ mod test { b: u32, } - let data = include_bytes!("../../fixtures/example-sqs-event-obj.json"); - let parsed: SqsEventObj = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-sqs-event-obj.json").to_vec(); + let parsed: SqsEventObj = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!(parsed.records[0].body.a, "Test"); assert_eq!(parsed.records[0].body.b, 123); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SqsEventObj = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SqsEventObj = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -217,10 +217,10 @@ mod test { fn example_sqs_batch_response() { // Example sqs batch response fetched 2022-05-13, from: // https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#services-sqs-batchfailurereporting - let data = include_bytes!("../../fixtures/example-sqs-batch-response.json"); - let parsed: SqsBatchResponse = aws_lambda_json_impl::from_slice(data).unwrap(); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SqsBatchResponse = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut data = include_bytes!("../../fixtures/example-sqs-batch-response.json").to_vec(); + let parsed: SqsBatchResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SqsBatchResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -235,14 +235,14 @@ mod test { country: String, } - let data = include_bytes!("../../fixtures/example-sqs-api-event-obj.json"); - let parsed: SqsApiEventObj = aws_lambda_json_impl::from_slice(data).unwrap(); + let mut data = include_bytes!("../../fixtures/example-sqs-api-event-obj.json").to_vec(); + let parsed: SqsApiEventObj = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!(parsed.messages[0].body.city, "provincetown"); assert_eq!(parsed.messages[0].body.country, "usa"); - let output: String = aws_lambda_json_impl::to_string(&parsed).unwrap(); - let reparsed: SqsApiEventObj = aws_lambda_json_impl::from_slice(output.as_bytes()).unwrap(); + let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); + let reparsed: SqsApiEventObj = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } From 61258360fab3fe412520f1ebe5fbaf6d736b1400 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Tue, 22 Oct 2024 13:57:17 +0200 Subject: [PATCH 04/44] So, now that simd-json Values can be Eq ... ... all we have a couple of missing functions and a mutability difference/error (in the base crates - haven't gotten onto the main client interface crates yet. --- json-impl/Cargo.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 5ffcbdde..62763993 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -20,5 +20,8 @@ simd = [ "simd-json" ] [dependencies] serde_json = { version = "^1", features = ["raw_value"], optional = true } -simd-json = { version = "^0", optional = true } +#simd-json = { version = "^0", optional = true, features = ["ordered-float"] } +simd-json = { git = 'https://github.com/bassmanitram/simd-json', branch = "feature/ordered-float", features = ["ordered-float"], optional = true} serde = { version = "^1", no-default-features = true } + + From f20d03cd26a29b04309ff244c23dd1355ae66c83 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Tue, 22 Oct 2024 15:04:56 +0200 Subject: [PATCH 05/44] Fix "missing method" issues (expose and use the right simd_json trait) --- json-impl/Cargo.toml | 1 - json-impl/src/lib.rs | 6 ++++-- lambda-events/src/event/apigw/mod.rs | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 62763993..8da6d823 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -15,7 +15,6 @@ edition = "2021" [features] default = [ ] -serde = [ "serde_json" ] simd = [ "simd-json" ] [dependencies] diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index afe1f847..74777e09 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -1,5 +1,5 @@ // Using serde_json as the JSON handler -#[cfg(feature = "serde")] +#[cfg(not(feature = "simd"))] pub use serde::*; // Using simd_json as the JSON handler #[cfg(feature = "simd")] @@ -7,10 +7,11 @@ pub use simd::*; // Implementations -#[cfg(feature = "serde")] +#[cfg(not(feature = "simd"))] mod serde { use serde_json::{from_str as serde_json_from_str, from_slice as serde_json_from_slice}; pub use serde_json::{ + self, from_reader, from_slice, from_str, @@ -42,6 +43,7 @@ mod simd { use serde::Deserialize; use simd_json::serde::from_str as unsafe_from_str; //THIS is mutable and is unsafe! pub use simd_json::{ + self, serde::{ from_reader, from_slice, //THIS is mutable! diff --git a/lambda-events/src/event/apigw/mod.rs b/lambda-events/src/event/apigw/mod.rs index 1d8327b1..6839e0a2 100644 --- a/lambda-events/src/event/apigw/mod.rs +++ b/lambda-events/src/event/apigw/mod.rs @@ -1040,6 +1040,10 @@ mod test { #[test] #[cfg(feature = "apigw")] fn example_apigw_request_authorizer_fields() { + + #[cfg(feature = "simd_json")] + use aws_lambda_json_impl::simd_json::base::ValueAsScalar; + let mut data = include_bytes!("../../fixtures/example-apigw-request.json").to_vec(); let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); From 3c696e4cbc097f487f279341a653237f31e3c586 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Tue, 22 Oct 2024 15:34:17 +0200 Subject: [PATCH 06/44] Adaptation to simd json parsing --- lambda-events/src/event/cloudwatch_alarms/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lambda-events/src/event/cloudwatch_alarms/mod.rs b/lambda-events/src/event/cloudwatch_alarms/mod.rs index 3b84f6bf..deddbbf5 100644 --- a/lambda-events/src/event/cloudwatch_alarms/mod.rs +++ b/lambda-events/src/event/cloudwatch_alarms/mod.rs @@ -239,6 +239,7 @@ impl<'de> Visitor<'de> for ReasonDataVisitor { formatter.write_str("a string with the alarm state reason data") } + #[cfg(not(feature = "simd_json"))] fn visit_str(self, v: &str) -> Result where E: serde::de::Error, @@ -251,6 +252,21 @@ impl<'de> Visitor<'de> for ReasonDataVisitor { } Ok(CloudWatchAlarmStateReasonData::Generic(Value::String(v.to_owned()))) } + + #[cfg(feature = "simd_json")] + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + let mut v_mut = v.to_owned().into_bytes(); + if let Ok(metric) = aws_lambda_json_impl::from_slice::(&mut v_mut) { + return Ok(CloudWatchAlarmStateReasonData::Metric(metric)); + } + if let Ok(aggregate) = aws_lambda_json_impl::from_slice::(&mut v_mut) { + return Ok(CloudWatchAlarmStateReasonData::Composite(aggregate)); + } + Ok(CloudWatchAlarmStateReasonData::Generic(Value::String(v.to_owned()))) + } } #[cfg(test)] From f95180be823c78736b200a149ff63d90c57c876a Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Tue, 22 Oct 2024 17:07:01 +0200 Subject: [PATCH 07/44] Amazingly, we appear to have resolved all compile issues outside of lambda_http Of course, lambda_http IS the target for all this and the thing that will expose the mut and unsafe aspects of using simd to the world - that's for another day! --- json-impl/Cargo.toml | 6 +++--- json-impl/src/lib.rs | 3 +-- lambda-events/Cargo.toml | 6 +++++- lambda-events/src/event/cloudwatch_alarms/mod.rs | 15 --------------- lambda-events/src/event/cloudwatch_logs/mod.rs | 2 +- lambda-http/Cargo.toml | 3 ++- lambda-integration-tests/Cargo.toml | 5 ++++- 7 files changed, 16 insertions(+), 24 deletions(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 8da6d823..7ef68028 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -15,12 +15,12 @@ edition = "2021" [features] default = [ ] -simd = [ "simd-json" ] +simd = [ "simd-json/ordered-float" ] [dependencies] -serde_json = { version = "^1", features = ["raw_value"], optional = true } +serde_json = { version = "^1", features = ["raw_value"] } #simd-json = { version = "^0", optional = true, features = ["ordered-float"] } -simd-json = { git = 'https://github.com/bassmanitram/simd-json', branch = "feature/ordered-float", features = ["ordered-float"], optional = true} +simd-json = { git = 'https://github.com/bassmanitram/simd-json', branch = "feature/ordered-float", optional = true} serde = { version = "^1", no-default-features = true } diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index 74777e09..c4c25cbf 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -9,12 +9,11 @@ pub use simd::*; #[cfg(not(feature = "simd"))] mod serde { + use serde::Deserialize; use serde_json::{from_str as serde_json_from_str, from_slice as serde_json_from_slice}; pub use serde_json::{ self, from_reader, - from_slice, - from_str, from_value, json, to_string_pretty, diff --git a/lambda-events/Cargo.toml b/lambda-events/Cargo.toml index 61cd8021..c387f9ce 100644 --- a/lambda-events/Cargo.toml +++ b/lambda-events/Cargo.toml @@ -29,11 +29,14 @@ query_map = { version = "^0.7", features = [ ], optional = true } serde = { version = "^1", features = ["derive"] } serde_with = { version = "^3", features = ["json"], optional = true } -aws_lambda_json_impl = { version = "0", features = ["simd"], path = "../json-impl" } +aws_lambda_json_impl = { path = "../json-impl" } serde_dynamo = { version = "^4.1", optional = true } [features] default = [ + +# "simd_json", + "activemq", "alb", "apigw", @@ -123,3 +126,4 @@ sqs = ["serde_with"] streams = [] documentdb = [] eventbridge = ["chrono", "serde_with"] +simd_json = [ "aws_lambda_json_impl/simd" ] diff --git a/lambda-events/src/event/cloudwatch_alarms/mod.rs b/lambda-events/src/event/cloudwatch_alarms/mod.rs index deddbbf5..175e4e94 100644 --- a/lambda-events/src/event/cloudwatch_alarms/mod.rs +++ b/lambda-events/src/event/cloudwatch_alarms/mod.rs @@ -239,21 +239,6 @@ impl<'de> Visitor<'de> for ReasonDataVisitor { formatter.write_str("a string with the alarm state reason data") } - #[cfg(not(feature = "simd_json"))] - fn visit_str(self, v: &str) -> Result - where - E: serde::de::Error, - { - if let Ok(metric) = aws_lambda_json_impl::from_str::(v) { - return Ok(CloudWatchAlarmStateReasonData::Metric(metric)); - } - if let Ok(aggregate) = aws_lambda_json_impl::from_str::(v) { - return Ok(CloudWatchAlarmStateReasonData::Composite(aggregate)); - } - Ok(CloudWatchAlarmStateReasonData::Generic(Value::String(v.to_owned()))) - } - - #[cfg(feature = "simd_json")] fn visit_str(self, v: &str) -> Result where E: serde::de::Error, diff --git a/lambda-events/src/event/cloudwatch_logs/mod.rs b/lambda-events/src/event/cloudwatch_logs/mod.rs index 54e3eb59..813df9e9 100644 --- a/lambda-events/src/event/cloudwatch_logs/mod.rs +++ b/lambda-events/src/event/cloudwatch_logs/mod.rs @@ -80,7 +80,7 @@ impl<'de> Deserialize<'de> for AwsLogs { })?; let bytes = flate2::read::GzDecoder::new(&bytes[..]); - let mut de = aws_lambda_json_impl::from_reader(BufReader::new(bytes)); + let mut de = aws_lambda_json_impl::JsonDeserializer::from_reader(BufReader::new(bytes)); data = Some(LogData::deserialize(&mut de).map_err(Error::custom)?); } _ => return Err(Error::unknown_field(key, FIELDS)), diff --git a/lambda-http/Cargo.toml b/lambda-http/Cargo.toml index 0b63a419..889bacde 100644 --- a/lambda-http/Cargo.toml +++ b/lambda-http/Cargo.toml @@ -27,6 +27,7 @@ opentelemetry = ["lambda_runtime/opentelemetry"] # enables access to the OpenTel anyhow = ["lambda_runtime/anyhow"] # enables From for Diagnostic for anyhow error types, see README.md for more info eyre = ["lambda_runtime/eyre"] # enables From for Diagnostic for eyre error types, see README.md for more info miette = ["lambda_runtime/miette"] # enables From for Diagnostic for miette error types, see README.md for more info +simd_json = [ "aws_lambda_json_impl/simd", "aws_lambda_events/simd_json" ] [dependencies] base64 = { workspace = true } @@ -43,7 +44,7 @@ mime = "0.3" percent-encoding = "2.2" pin-project-lite = { workspace = true } serde = { version = "1.0", features = ["derive"] } -aws_lambda_json_impl = { features = ["simd"], path = "../json-impl" } +aws_lambda_json_impl = { path = "../json-impl" } serde_urlencoded = "0.7" tokio-stream = "0.1.2" url = "2.2" diff --git a/lambda-integration-tests/Cargo.toml b/lambda-integration-tests/Cargo.toml index bedbf5a5..6ecea0ad 100644 --- a/lambda-integration-tests/Cargo.toml +++ b/lambda-integration-tests/Cargo.toml @@ -13,10 +13,13 @@ readme = "../README.md" [dependencies] lambda_runtime = { path = "../lambda-runtime" } aws_lambda_events = { path = "../lambda-events" } -aws_lambda_json_impl = { features = ["simd"], path = "../json-impl" } +aws_lambda_json_impl = { path = "../json-impl" } tokio = { version = "1", features = ["full"] } serde = { version = "1.0.204", features = ["derive"] } +[features] +simd_json = [ "aws_lambda_json_impl/simd" ] + [dev-dependencies] reqwest = { version = "0.12.5", features = ["blocking"] } openssl = { version = "0.10", features = ["vendored"] } From 12cb88f435605acc8c3cd583d737c9ec60f0d078 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Tue, 22 Oct 2024 18:12:43 +0200 Subject: [PATCH 08/44] Explanations --- json-impl/src/lib.rs | 94 +++++----- lambda-events/src/encodings/time.rs | 4 + lambda-events/src/event/activemq/mod.rs | 7 +- lambda-events/src/event/alb/mod.rs | 7 +- lambda-events/src/event/apigw/mod.rs | 82 ++++++--- lambda-events/src/event/appsync/mod.rs | 9 +- lambda-events/src/event/autoscaling/mod.rs | 6 +- .../src/event/bedrock_agent_runtime/mod.rs | 9 +- lambda-events/src/event/clientvpn/mod.rs | 7 +- lambda-events/src/event/cloudformation/mod.rs | 21 ++- .../src/event/cloudformation/provider.rs | 27 ++- .../src/event/cloudwatch_alarms/mod.rs | 17 +- .../src/event/cloudwatch_events/cloudtrail.rs | 6 +- .../src/event/cloudwatch_events/mod.rs | 2 +- .../src/event/cloudwatch_events/signin.rs | 2 +- .../src/event/cloudwatch_logs/mod.rs | 9 +- lambda-events/src/event/code_commit/mod.rs | 4 + lambda-events/src/event/codebuild/mod.rs | 6 +- lambda-events/src/event/codedeploy/mod.rs | 4 + .../src/event/codepipeline_cloudwatch/mod.rs | 7 +- .../src/event/codepipeline_job/mod.rs | 4 + lambda-events/src/event/cognito/mod.rs | 165 ++++++++++++------ lambda-events/src/event/config/mod.rs | 4 + lambda-events/src/event/connect/mod.rs | 4 + .../event/documentdb/events/commom_types.rs | 2 +- lambda-events/src/event/documentdb/mod.rs | 4 + lambda-events/src/event/dynamodb/mod.rs | 7 +- lambda-events/src/event/ecr_scan/mod.rs | 7 +- lambda-events/src/event/eventbridge/mod.rs | 9 +- lambda-events/src/event/firehose/mod.rs | 4 + lambda-events/src/event/iot/mod.rs | 7 +- lambda-events/src/event/iot_1_click/mod.rs | 4 + lambda-events/src/event/iot_button/mod.rs | 4 + lambda-events/src/event/kafka/mod.rs | 4 + lambda-events/src/event/kinesis/event.rs | 4 + lambda-events/src/event/lex/mod.rs | 4 + lambda-events/src/event/rabbitmq/mod.rs | 6 +- lambda-events/src/event/s3/event.rs | 4 + lambda-events/src/event/s3/object_lambda.rs | 12 +- lambda-events/src/event/secretsmanager/mod.rs | 7 +- lambda-events/src/event/ses/mod.rs | 4 + lambda-events/src/event/sns/mod.rs | 10 +- lambda-events/src/event/sqs/mod.rs | 4 + lambda-http/src/deserializer.rs | 7 +- lambda-http/src/request.rs | 2 +- lambda-http/src/response.rs | 2 +- lambda-integration-tests/src/authorizer.rs | 2 +- 47 files changed, 444 insertions(+), 183 deletions(-) diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index c4c25cbf..88c5fc72 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -9,59 +9,53 @@ pub use simd::*; #[cfg(not(feature = "simd"))] mod serde { - use serde::Deserialize; - use serde_json::{from_str as serde_json_from_str, from_slice as serde_json_from_slice}; - pub use serde_json::{ - self, - from_reader, - from_value, - json, - to_string_pretty, - to_string, - to_value, - to_writer, - Deserializer as JsonDeserializer, - Value, - error::Error as JsonError, - value::RawValue as RawValue, - }; - pub fn from_str<'a, T>(s: &'a mut str) -> serde_json::Result - where - T: Deserialize<'a> { - serde_json_from_str(s) - } - pub fn from_slice<'a, T>(s: &'a mut [u8]) -> serde_json::Result - where - T: Deserialize<'a> { - serde_json_from_slice(s) - } + use serde::Deserialize; + pub use serde_json::{ + self, error::Error as JsonError, from_reader, from_slice, from_str, from_value, json, to_string, + to_string_pretty, to_value, to_writer, value::RawValue, Deserializer as JsonDeserializer, Value, + }; + pub fn from_str_mut<'a, T>(s: &'a mut str) -> serde_json::Result + where + T: Deserialize<'a>, + { + from_str(s) + } + pub fn from_slice_mut<'a, T>(s: &'a mut [u8]) -> serde_json::Result + where + T: Deserialize<'a>, + { + from_slice(s) + } } #[cfg(feature = "simd")] mod simd { - use serde::Deserialize; - use simd_json::serde::from_str as unsafe_from_str; //THIS is mutable and is unsafe! - pub use simd_json::{ - self, - serde::{ - from_reader, - from_slice, //THIS is mutable! - from_owned_value as from_value, - to_string_pretty, - to_string, - to_owned_value as to_value, - to_writer, - }, - Deserializer as JsonDeserializer, - json, - owned::Value, - Error as JsonError, - tape::Value as RawValue, //THIS is gonna be the fun one! - }; + use serde::Deserialize; + use simd_json::serde::from_str as unsafe_from_str; //THIS is mutable and is unsafe! + pub use simd_json::{ + self, + json, + owned::Value, + serde::{ + from_owned_value as from_value, + from_reader, + from_slice as from_slice_mut, //THIS is mutable! + to_owned_value as to_value, + to_string, + to_string_pretty, + to_writer, + }, + tape::Value as RawValue, //THIS is gonna be the fun one! + Deserializer as JsonDeserializer, + Error as JsonError, + }; - pub fn from_str<'a, T>(s: &'a mut str) -> simd_json::Result - where - T: Deserialize<'a> { - unsafe { unsafe_from_str(s) } - } + /// BEWARE this ISN'T safe - but is marked so for compatibility at the + /// moment. + pub fn from_str_mut<'a, T>(s: &'a mut str) -> simd_json::Result + where + T: Deserialize<'a>, + { + unsafe { unsafe_from_str(s) } + } } diff --git a/lambda-events/src/encodings/time.rs b/lambda-events/src/encodings/time.rs index f4a87e2b..24856416 100644 --- a/lambda-events/src/encodings/time.rs +++ b/lambda-events/src/encodings/time.rs @@ -215,6 +215,10 @@ where #[cfg(test)] #[allow(deprecated)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; use chrono::TimeZone; diff --git a/lambda-events/src/event/activemq/mod.rs b/lambda-events/src/event/activemq/mod.rs index a13a64d5..de2b0752 100644 --- a/lambda-events/src/event/activemq/mod.rs +++ b/lambda-events/src/event/activemq/mod.rs @@ -52,13 +52,16 @@ pub struct ActiveMqDestination { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. use super::*; #[test] #[cfg(feature = "activemq")] fn example_activemq_event() { - let mut data = include_bytes!("../../fixtures/example-activemq-event.json").to_vec(); - let mut data = data.to_vec(); + let data = include_bytes!("../../fixtures/example-activemq-event.json").to_vec(); + let mut data = data.to_vec(); let parsed: ActiveMqEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: ActiveMqEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); diff --git a/lambda-events/src/event/alb/mod.rs b/lambda-events/src/event/alb/mod.rs index 97643657..67644a5a 100644 --- a/lambda-events/src/event/alb/mod.rs +++ b/lambda-events/src/event/alb/mod.rs @@ -69,6 +69,10 @@ pub struct AlbTargetGroupResponse { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] @@ -84,7 +88,8 @@ mod test { #[test] #[cfg(feature = "alb")] fn example_alb_lambda_target_request_multivalue_headers() { - let mut data = include_bytes!("../../fixtures/example-alb-lambda-target-request-multivalue-headers.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-alb-lambda-target-request-multivalue-headers.json").to_vec(); let parsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); diff --git a/lambda-events/src/event/apigw/mod.rs b/lambda-events/src/event/apigw/mod.rs index 6839e0a2..7e907200 100644 --- a/lambda-events/src/event/apigw/mod.rs +++ b/lambda-events/src/event/apigw/mod.rs @@ -6,10 +6,10 @@ use crate::{ encodings::Body, iam::IamPolicyStatement, }; +use aws_lambda_json_impl::Value; use http::{HeaderMap, Method}; use query_map::QueryMap; use serde::{de::DeserializeOwned, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; -use aws_lambda_json_impl::Value; use std::collections::HashMap; /// `ApiGatewayProxyRequest` contains data coming from the API Gateway proxy @@ -779,25 +779,33 @@ pub fn serialize_authorizer_fields( #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. use super::*; #[test] #[cfg(feature = "apigw")] fn example_apigw_custom_auth_request_type_request() { let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-request-type-request.json").to_vec(); - let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_custom_auth_request_type_request_websocket() { - let mut data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-websocket-request.json").to_vec(); - let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut data = + include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-websocket-request.json").to_vec(); + let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -807,7 +815,8 @@ mod test { let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-request.json").to_vec(); let parsed: ApiGatewayCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerRequest = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -817,27 +826,33 @@ mod test { let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-response.json").to_vec(); let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerResponse = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_custom_auth_response_with_single_value_action() { - let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-action.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-action.json").to_vec(); let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerResponse = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_custom_auth_response_with_single_value_resource() { - let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-resource.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-resource.json") + .to_vec(); let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerResponse = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -876,7 +891,6 @@ mod test { let mut output = output.into_bytes(); let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); - } #[test] @@ -924,7 +938,7 @@ mod test { fn example_apigw_v2_request_multi_value_parameters() { let mut data = include_bytes!("../../fixtures/example-apigw-v2-request-multi-value-parameters.json").to_vec(); let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); - let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap(); + let output = aws_lambda_json_impl::to_string(&parsed).unwrap(); assert!(output.contains(r#""header2":"value1,value2""#)); assert!(output.contains(r#""queryStringParameters":{"Parameter1":"value1,value2"}"#)); @@ -932,7 +946,6 @@ mod test { let mut output = output.into_bytes(); let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); - } #[test] @@ -951,7 +964,8 @@ mod test { let mut data = include_bytes!("../../fixtures/example-apigw-websocket-request.json").to_vec(); let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayWebsocketProxyRequest = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -971,7 +985,8 @@ mod test { let mut data = include_bytes!("../../fixtures/example-apigw-websocket-request-without-method.json").to_vec(); let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayWebsocketProxyRequest = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -981,7 +996,8 @@ mod test { let mut data = include_bytes!("../../fixtures/example-apigw-websocket-request-disconnect-route.json").to_vec(); let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayWebsocketProxyRequest = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -1001,29 +1017,39 @@ mod test { #[cfg(feature = "apigw")] fn example_apigw_v2_custom_authorizer_v2_request() { let mut data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request.json").to_vec(); - let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let parsed: ApiGatewayV2CustomAuthorizerV2Request = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayV2CustomAuthorizerV2Request = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_v2_custom_authorizer_v2_request_without_cookies() { - let mut data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-cookies.json").to_vec(); - let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut data = + include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-cookies.json") + .to_vec(); + let parsed: ApiGatewayV2CustomAuthorizerV2Request = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayV2CustomAuthorizerV2Request = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "apigw")] fn example_apigw_v2_custom_authorizer_v2_request_without_identity_source() { - let mut data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-identity-source.json").to_vec(); - let parsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut data = + include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-identity-source.json") + .to_vec(); + let parsed: ApiGatewayV2CustomAuthorizerV2Request = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayV2CustomAuthorizerV2Request = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayV2CustomAuthorizerV2Request = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -1040,7 +1066,6 @@ mod test { #[test] #[cfg(feature = "apigw")] fn example_apigw_request_authorizer_fields() { - #[cfg(feature = "simd_json")] use aws_lambda_json_impl::simd_json::base::ValueAsScalar; @@ -1062,7 +1087,8 @@ mod test { let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-condition.json").to_vec(); let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ApiGatewayCustomAuthorizerResponse = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); let statement = parsed.policy_document.statement.first().unwrap(); diff --git a/lambda-events/src/event/appsync/mod.rs b/lambda-events/src/event/appsync/mod.rs index 0e0e3dcd..52eaee26 100644 --- a/lambda-events/src/event/appsync/mod.rs +++ b/lambda-events/src/event/appsync/mod.rs @@ -1,5 +1,5 @@ -use serde::{de::DeserializeOwned, Deserialize, Serialize}; use aws_lambda_json_impl::Value; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; @@ -119,6 +119,10 @@ where #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] @@ -157,7 +161,8 @@ mod test { let mut data = include_bytes!("../../fixtures/example-appsync-lambda-auth-response.json").to_vec(); let parsed: AppSyncLambdaAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: AppSyncLambdaAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: AppSyncLambdaAuthorizerResponse = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/autoscaling/mod.rs b/lambda-events/src/event/autoscaling/mod.rs index d0e074d9..b354aa5a 100644 --- a/lambda-events/src/event/autoscaling/mod.rs +++ b/lambda-events/src/event/autoscaling/mod.rs @@ -1,6 +1,6 @@ +use aws_lambda_json_impl::Value; use chrono::{DateTime, Utc}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use aws_lambda_json_impl::Value; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; @@ -45,6 +45,10 @@ where #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/bedrock_agent_runtime/mod.rs b/lambda-events/src/event/bedrock_agent_runtime/mod.rs index d9075e59..2c19b2d6 100644 --- a/lambda-events/src/event/bedrock_agent_runtime/mod.rs +++ b/lambda-events/src/event/bedrock_agent_runtime/mod.rs @@ -82,6 +82,9 @@ pub struct Agent { #[cfg(test)] mod tests { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. use crate::event::bedrock_agent_runtime::AgentEvent; @@ -97,7 +100,8 @@ mod tests { #[test] #[cfg(feature = "bedrock_agent_runtime")] fn example_bedrock_agent_runtime_event_without_parameters() { - let mut data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-parameters.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-parameters.json").to_vec(); let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); @@ -106,7 +110,8 @@ mod tests { #[test] #[cfg(feature = "bedrock_agent_runtime")] fn example_bedrock_agent_runtime_event_without_request_body() { - let mut data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-request-body.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-request-body.json").to_vec(); let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); diff --git a/lambda-events/src/event/clientvpn/mod.rs b/lambda-events/src/event/clientvpn/mod.rs index c9c2306c..9a1eda6a 100644 --- a/lambda-events/src/event/clientvpn/mod.rs +++ b/lambda-events/src/event/clientvpn/mod.rs @@ -47,6 +47,10 @@ pub struct ClientVpnConnectionHandlerResponse { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] @@ -55,7 +59,8 @@ mod test { let mut data = include_bytes!("../../fixtures/example-clientvpn-connectionhandler-request.json").to_vec(); let parsed: ClientVpnConnectionHandlerRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: ClientVpnConnectionHandlerRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: ClientVpnConnectionHandlerRequest = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudformation/mod.rs b/lambda-events/src/event/cloudformation/mod.rs index 32112201..97184806 100644 --- a/lambda-events/src/event/cloudformation/mod.rs +++ b/lambda-events/src/event/cloudformation/mod.rs @@ -1,5 +1,5 @@ -use serde::{de::DeserializeOwned, Deserialize, Serialize}; use aws_lambda_json_impl::Value; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::collections::HashMap; pub mod provider; @@ -100,6 +100,10 @@ pub enum CloudFormationCustomResourceResponseStatus { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use std::collections::HashMap; use super::{CloudFormationCustomResourceRequest::*, *}; @@ -116,7 +120,8 @@ mod test { #[test] fn example_cloudformation_custom_resource_create_request() { - let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-create-request.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-cloudformation-custom-resource-create-request.json").to_vec(); let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { @@ -131,7 +136,8 @@ mod test { #[test] fn example_cloudformation_custom_resource_update_request() { - let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-update-request.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-cloudformation-custom-resource-update-request.json").to_vec(); let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { @@ -146,7 +152,8 @@ mod test { #[test] fn example_cloudformation_custom_resource_delete_request() { - let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-delete-request.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-cloudformation-custom-resource-delete-request.json").to_vec(); let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { @@ -162,9 +169,11 @@ mod test { #[test] fn example_cloudformation_custom_resource_response() { let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-response.json").to_vec(); - let parsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let parsed: CloudFormationCustomResourceResponse = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CloudFormationCustomResourceResponse = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudformation/provider.rs b/lambda-events/src/event/cloudformation/provider.rs index ae7bb10c..a5bd2107 100644 --- a/lambda-events/src/event/cloudformation/provider.rs +++ b/lambda-events/src/event/cloudformation/provider.rs @@ -4,8 +4,8 @@ //! //! See https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.custom_resources-readme.html for details. -use serde::{de::DeserializeOwned, Deserialize, Serialize}; use aws_lambda_json_impl::Value; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(tag = "RequestType")] @@ -88,6 +88,10 @@ where #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use std::collections::HashMap; use super::{CloudFormationCustomResourceRequest::*, *}; @@ -104,7 +108,9 @@ mod test { #[test] fn example_create_request() { - let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-create-request.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-create-request.json") + .to_vec(); let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { @@ -119,7 +125,9 @@ mod test { #[test] fn example_update_request() { - let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-update-request.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-update-request.json") + .to_vec(); let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { @@ -134,7 +142,9 @@ mod test { #[test] fn example_delete_request() { - let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-delete-request.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-delete-request.json") + .to_vec(); let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); match parsed { @@ -149,10 +159,13 @@ mod test { #[test] fn example_response() { - let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-response.json").to_vec(); - let parsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut data = + include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-response.json").to_vec(); + let parsed: CloudFormationCustomResourceResponse = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CloudFormationCustomResourceResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CloudFormationCustomResourceResponse = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/cloudwatch_alarms/mod.rs b/lambda-events/src/event/cloudwatch_alarms/mod.rs index 175e4e94..1e6b220d 100644 --- a/lambda-events/src/event/cloudwatch_alarms/mod.rs +++ b/lambda-events/src/event/cloudwatch_alarms/mod.rs @@ -1,12 +1,12 @@ use std::collections::HashMap; +use aws_lambda_json_impl::Value; use chrono::{DateTime, Utc}; use serde::{ de::{DeserializeOwned, Visitor}, ser::Error as SerError, Deserialize, Serialize, }; -use aws_lambda_json_impl::Value; /// `CloudWatchAlarm` is the generic outer structure of an event triggered by a CloudWatch Alarm. /// You probably want to use `CloudWatchMetricAlarm` or `CloudWatchCompositeAlarm` if you know which kind of alarm your function is receiving. @@ -244,10 +244,14 @@ impl<'de> Visitor<'de> for ReasonDataVisitor { E: serde::de::Error, { let mut v_mut = v.to_owned().into_bytes(); - if let Ok(metric) = aws_lambda_json_impl::from_slice::(&mut v_mut) { + if let Ok(metric) = + aws_lambda_json_impl::from_slice::(v_mut.as_mut_slice()) + { return Ok(CloudWatchAlarmStateReasonData::Metric(metric)); } - if let Ok(aggregate) = aws_lambda_json_impl::from_slice::(&mut v_mut) { + if let Ok(aggregate) = + aws_lambda_json_impl::from_slice::(v_mut.as_mut_slice()) + { return Ok(CloudWatchAlarmStateReasonData::Composite(aggregate)); } Ok(CloudWatchAlarmStateReasonData::Generic(Value::String(v.to_owned()))) @@ -256,6 +260,10 @@ impl<'de> Visitor<'de> for ReasonDataVisitor { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] @@ -305,7 +313,8 @@ mod test { #[test] #[cfg(feature = "cloudwatch_alarms")] fn example_cloudwatch_alarm_composite_with_suppressor_alarm() { - let mut data = include_bytes!("../../fixtures/example-cloudwatch-alarm-composite-with-suppressor-alarm.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-cloudwatch-alarm-composite-with-suppressor-alarm.json").to_vec(); let parsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let state = parsed.alarm_data.state.clone().unwrap(); assert_eq!("WaitPeriod", state.actions_suppressed_by.unwrap()); diff --git a/lambda-events/src/event/cloudwatch_events/cloudtrail.rs b/lambda-events/src/event/cloudwatch_events/cloudtrail.rs index 7497e686..45c65474 100644 --- a/lambda-events/src/event/cloudwatch_events/cloudtrail.rs +++ b/lambda-events/src/event/cloudwatch_events/cloudtrail.rs @@ -1,6 +1,6 @@ +use aws_lambda_json_impl::Value; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use aws_lambda_json_impl::Value; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] @@ -83,6 +83,10 @@ pub struct UserIdentity { #[cfg(test)] mod tests { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::AWSAPICall; #[test] diff --git a/lambda-events/src/event/cloudwatch_events/mod.rs b/lambda-events/src/event/cloudwatch_events/mod.rs index 923765b7..dd88e313 100644 --- a/lambda-events/src/event/cloudwatch_events/mod.rs +++ b/lambda-events/src/event/cloudwatch_events/mod.rs @@ -1,6 +1,6 @@ +use aws_lambda_json_impl::Value; use chrono::{DateTime, Utc}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use aws_lambda_json_impl::Value; pub mod cloudtrail; pub mod codedeploy; diff --git a/lambda-events/src/event/cloudwatch_events/signin.rs b/lambda-events/src/event/cloudwatch_events/signin.rs index 65e1a013..82090e0f 100644 --- a/lambda-events/src/event/cloudwatch_events/signin.rs +++ b/lambda-events/src/event/cloudwatch_events/signin.rs @@ -1,5 +1,5 @@ -use serde::{Deserialize, Serialize}; use aws_lambda_json_impl::Value; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/cloudwatch_logs/mod.rs b/lambda-events/src/event/cloudwatch_logs/mod.rs index 813df9e9..c3d53fd3 100644 --- a/lambda-events/src/event/cloudwatch_logs/mod.rs +++ b/lambda-events/src/event/cloudwatch_logs/mod.rs @@ -118,6 +118,10 @@ impl Serialize for AwsLogs { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] @@ -145,8 +149,9 @@ mod test { assert_eq!(1552518348220, data.log_events[0].timestamp); assert_eq!("REPORT RequestId: 6234bffe-149a-b642-81ff-2e8e376d8aff\tDuration: 46.84 ms\tBilled Duration: 47 ms \tMemory Size: 192 MB\tMax Memory Used: 72 MB\t\n", data.log_events[0].message); - let mut new_json: String = aws_lambda_json_impl::to_string_pretty(&event).unwrap(); - let new_event: LogsEvent = aws_lambda_json_impl::from_str(&mut new_json).expect("failed to deserialize"); + let mut new_json = aws_lambda_json_impl::to_string_pretty(&event).unwrap().into_bytes(); + let new_event: LogsEvent = + aws_lambda_json_impl::from_slice(new_json.as_mut_slice()).expect("failed to deserialize"); assert_eq!(new_event, event); } diff --git a/lambda-events/src/event/code_commit/mod.rs b/lambda-events/src/event/code_commit/mod.rs index 769ee854..29ad37da 100644 --- a/lambda-events/src/event/code_commit/mod.rs +++ b/lambda-events/src/event/code_commit/mod.rs @@ -67,6 +67,10 @@ pub struct CodeCommitReference { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/codebuild/mod.rs b/lambda-events/src/event/codebuild/mod.rs index 333690f1..8ec86456 100644 --- a/lambda-events/src/event/codebuild/mod.rs +++ b/lambda-events/src/event/codebuild/mod.rs @@ -2,9 +2,9 @@ use crate::{ custom_serde::{codebuild_time, CodeBuildNumber}, encodings::{MinuteDuration, SecondDuration}, }; +use aws_lambda_json_impl::Value; use chrono::{DateTime, Utc}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use aws_lambda_json_impl::Value; pub type CodeBuildPhaseStatus = String; @@ -212,6 +212,10 @@ pub type CodeBuildTime = DateTime; #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/codedeploy/mod.rs b/lambda-events/src/event/codedeploy/mod.rs index 72ef1713..cffd5939 100644 --- a/lambda-events/src/event/codedeploy/mod.rs +++ b/lambda-events/src/event/codedeploy/mod.rs @@ -74,6 +74,10 @@ pub struct CodeDeployLifecycleEvent { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/codepipeline_cloudwatch/mod.rs b/lambda-events/src/event/codepipeline_cloudwatch/mod.rs index c66c9e8b..618809fa 100644 --- a/lambda-events/src/event/codepipeline_cloudwatch/mod.rs +++ b/lambda-events/src/event/codepipeline_cloudwatch/mod.rs @@ -79,12 +79,17 @@ pub struct CodePipelineEventDetailType { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] #[cfg(feature = "codepipeline_cloudwatch")] fn example_codepipeline_action_execution_stage_change_event() { - let mut data = include_bytes!("../../fixtures/example-codepipeline-action-execution-stage-change-event.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-codepipeline-action-execution-stage-change-event.json").to_vec(); let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); diff --git a/lambda-events/src/event/codepipeline_job/mod.rs b/lambda-events/src/event/codepipeline_job/mod.rs index 69f0510d..644c8b8d 100644 --- a/lambda-events/src/event/codepipeline_job/mod.rs +++ b/lambda-events/src/event/codepipeline_job/mod.rs @@ -115,6 +115,10 @@ pub struct CodePipelineArtifactCredentials { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/cognito/mod.rs b/lambda-events/src/event/cognito/mod.rs index 67449789..fa02eccb 100644 --- a/lambda-events/src/event/cognito/mod.rs +++ b/lambda-events/src/event/cognito/mod.rs @@ -1,5 +1,5 @@ -use serde::{de::DeserializeOwned, Deserialize, Serialize}; use aws_lambda_json_impl::Value; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::collections::HashMap; use crate::custom_serde::{deserialize_lambda_map, deserialize_nullish_boolean}; @@ -630,6 +630,10 @@ pub struct CognitoEventUserPoolsCustomMessageResponse { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] @@ -645,23 +649,30 @@ mod test { #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_create_auth_challenge() { - let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge.json").to_vec(); - let parsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut data = + include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge.json").to_vec(); + let parsed: CognitoEventUserPoolsCreateAuthChallenge = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsCreateAuthChallenge = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_create_auth_challenge_user_not_found() { - let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge-user-not-found.json").to_vec(); - let parsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut data = + include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge-user-not-found.json") + .to_vec(); + let parsed: CognitoEventUserPoolsCreateAuthChallenge = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(parsed.request.user_not_found); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsCreateAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsCreateAuthChallenge = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -671,17 +682,21 @@ mod test { let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-custommessage.json").to_vec(); let parsed: CognitoEventUserPoolsCustomMessage = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsCustomMessage = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsCustomMessage = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_define_auth_challenge() { - let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge.json").to_vec(); - let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut data = + include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge.json").to_vec(); + let parsed: CognitoEventUserPoolsDefineAuthChallenge = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsDefineAuthChallenge = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -690,27 +705,34 @@ mod test { fn example_cognito_event_userpools_define_auth_challenge_optional_response_fields() { let mut data = include_bytes!( "../../fixtures/example-cognito-event-userpools-define-auth-challenge-optional-response-fields.json" - ).to_vec(); - let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + ) + .to_vec(); + let parsed: CognitoEventUserPoolsDefineAuthChallenge = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(!parsed.response.fail_authentication); assert!(!parsed.response.issue_tokens); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsDefineAuthChallenge = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_define_auth_challenge_user_not_found() { - let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge-user-not-found.json").to_vec(); - let parsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut data = + include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge-user-not-found.json") + .to_vec(); + let parsed: CognitoEventUserPoolsDefineAuthChallenge = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(parsed.request.user_not_found); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsDefineAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsDefineAuthChallenge = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -720,17 +742,21 @@ mod test { let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-migrateuser.json").to_vec(); let parsed: CognitoEventUserPoolsMigrateUser = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsMigrateUser = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsMigrateUser = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_postauthentication() { - let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-postauthentication.json").to_vec(); - let parsed: CognitoEventUserPoolsPostAuthentication = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut data = + include_bytes!("../../fixtures/example-cognito-event-userpools-postauthentication.json").to_vec(); + let parsed: CognitoEventUserPoolsPostAuthentication = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsPostAuthentication = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsPostAuthentication = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -738,9 +764,11 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_postconfirmation() { let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-postconfirmation.json").to_vec(); - let parsed: CognitoEventUserPoolsPostConfirmation = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let parsed: CognitoEventUserPoolsPostConfirmation = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsPostConfirmation = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsPostConfirmation = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -748,9 +776,11 @@ mod test { #[cfg(feature = "cognito")] fn example_cognito_event_userpools_preauthentication() { let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-preauthentication.json").to_vec(); - let parsed: CognitoEventUserPoolsPreAuthentication = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let parsed: CognitoEventUserPoolsPreAuthentication = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsPreAuthentication = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsPreAuthentication = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -767,20 +797,24 @@ mod test { #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_pretokengen_incoming() { - let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-incoming.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-incoming.json").to_vec(); let parsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsPreTokenGen = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_pretokengen_v2_incoming() { - let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json").to_vec(); let parsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsPreTokenGenV2 = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -790,7 +824,8 @@ mod test { let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen.json").to_vec(); let parsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsPreTokenGen = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -800,17 +835,21 @@ mod test { let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2.json").to_vec(); let parsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsPreTokenGenV2 = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_verify_auth_challenge() { - let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge.json").to_vec(); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut data = + include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge.json").to_vec(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -819,13 +858,16 @@ mod test { fn example_cognito_event_userpools_verify_auth_challenge_optional_answer_correct() { let mut data = include_bytes!( "../../fixtures/example-cognito-event-userpools-verify-auth-challenge-optional-answer-correct.json" - ).to_vec(); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + ) + .to_vec(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(!parsed.response.answer_correct); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } @@ -834,26 +876,33 @@ mod test { fn example_cognito_event_userpools_verify_auth_challenge_null_answer_correct() { let mut data = include_bytes!( "../../fixtures/example-cognito-event-userpools-verify-auth-challenge-null-answer-correct.json" - ).to_vec(); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + ) + .to_vec(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(!parsed.response.answer_correct); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_verify_auth_challenge_user_not_found() { - let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge-user-not-found.json").to_vec(); - let parsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); + let mut data = + include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge-user-not-found.json") + .to_vec(); + let parsed: CognitoEventUserPoolsVerifyAuthChallenge = + aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert!(parsed.request.user_not_found); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } @@ -892,7 +941,8 @@ mod trigger_source_tests { let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_str(&mut header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -905,7 +955,8 @@ mod trigger_source_tests { let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_str(&mut header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -921,7 +972,8 @@ mod trigger_source_tests { let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_str(&mut header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -934,7 +986,8 @@ mod trigger_source_tests { let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_str(&mut header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -947,7 +1000,8 @@ mod trigger_source_tests { let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_str(&mut header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -961,7 +1015,8 @@ mod trigger_source_tests { let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_str(&mut header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -974,7 +1029,8 @@ mod trigger_source_tests { let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_str(&mut header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -993,7 +1049,8 @@ mod trigger_source_tests { let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_str(&mut header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -1006,7 +1063,8 @@ mod trigger_source_tests { let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_str(&mut header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } @@ -1027,7 +1085,8 @@ mod trigger_source_tests { let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_str(&mut header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: CognitoEventUserPoolsHeader<_> = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); }); } diff --git a/lambda-events/src/event/config/mod.rs b/lambda-events/src/event/config/mod.rs index 5eca5462..10ea4f3d 100644 --- a/lambda-events/src/event/config/mod.rs +++ b/lambda-events/src/event/config/mod.rs @@ -38,6 +38,10 @@ pub struct ConfigEvent { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/connect/mod.rs b/lambda-events/src/event/connect/mod.rs index 1eaffe38..91e8e3be 100644 --- a/lambda-events/src/event/connect/mod.rs +++ b/lambda-events/src/event/connect/mod.rs @@ -92,6 +92,10 @@ pub type ConnectResponse = HashMap; #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/documentdb/events/commom_types.rs b/lambda-events/src/event/documentdb/events/commom_types.rs index 5479f34b..2488d333 100644 --- a/lambda-events/src/event/documentdb/events/commom_types.rs +++ b/lambda-events/src/event/documentdb/events/commom_types.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; -use serde::{Deserialize, Serialize}; use aws_lambda_json_impl::Value; +use serde::{Deserialize, Serialize}; pub type AnyDocument = HashMap; diff --git a/lambda-events/src/event/documentdb/mod.rs b/lambda-events/src/event/documentdb/mod.rs index f91d03e9..a973f984 100644 --- a/lambda-events/src/event/documentdb/mod.rs +++ b/lambda-events/src/event/documentdb/mod.rs @@ -38,6 +38,10 @@ pub struct DocumentDbEvent { #[cfg(test)] #[cfg(feature = "documentdb")] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; pub type Event = DocumentDbEvent; diff --git a/lambda-events/src/event/dynamodb/mod.rs b/lambda-events/src/event/dynamodb/mod.rs index 89028363..834ef44a 100644 --- a/lambda-events/src/event/dynamodb/mod.rs +++ b/lambda-events/src/event/dynamodb/mod.rs @@ -253,6 +253,10 @@ pub struct StreamRecord { #[cfg(test)] #[allow(deprecated)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; use chrono::TimeZone; @@ -273,7 +277,8 @@ mod test { #[test] #[cfg(feature = "dynamodb")] fn example_dynamodb_event_with_optional_fields() { - let mut data = include_bytes!("../../fixtures/example-dynamodb-event-record-with-optional-fields.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-dynamodb-event-record-with-optional-fields.json").to_vec(); let parsed: EventRecord = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: EventRecord = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); diff --git a/lambda-events/src/event/ecr_scan/mod.rs b/lambda-events/src/event/ecr_scan/mod.rs index 247ecc0f..0cb02937 100644 --- a/lambda-events/src/event/ecr_scan/mod.rs +++ b/lambda-events/src/event/ecr_scan/mod.rs @@ -65,6 +65,10 @@ pub struct EcrScanEventFindingSeverityCounts { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] @@ -80,7 +84,8 @@ mod test { #[test] #[cfg(feature = "ecr_scan")] fn example_ecr_image_scan_event_with_missing_severities() { - let mut data = include_bytes!("../../fixtures/example-ecr-image-scan-event-with-missing-severities.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-ecr-image-scan-event-with-missing-severities.json").to_vec(); let parsed: EcrScanEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: EcrScanEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); diff --git a/lambda-events/src/event/eventbridge/mod.rs b/lambda-events/src/event/eventbridge/mod.rs index e754ecbb..3287d3db 100644 --- a/lambda-events/src/event/eventbridge/mod.rs +++ b/lambda-events/src/event/eventbridge/mod.rs @@ -1,6 +1,6 @@ +use aws_lambda_json_impl::Value; use chrono::{DateTime, Utc}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use aws_lambda_json_impl::Value; /// Parse EventBridge events. /// Deserialize the event detail into a structure that's `DeserializeOwned`. @@ -35,6 +35,10 @@ where #[cfg(test)] #[cfg(feature = "eventbridge")] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] @@ -54,7 +58,8 @@ mod test { assert_eq!("pending", parsed.detail.state); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: EventBridgeEvent = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } diff --git a/lambda-events/src/event/firehose/mod.rs b/lambda-events/src/event/firehose/mod.rs index 5e7ee6a0..c557e598 100644 --- a/lambda-events/src/event/firehose/mod.rs +++ b/lambda-events/src/event/firehose/mod.rs @@ -74,6 +74,10 @@ pub struct KinesisFirehoseRecordMetadata { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/iot/mod.rs b/lambda-events/src/event/iot/mod.rs index 9c419899..9c9b41e7 100644 --- a/lambda-events/src/event/iot/mod.rs +++ b/lambda-events/src/event/iot/mod.rs @@ -72,6 +72,10 @@ pub struct IoTCoreCustomAuthorizerResponse { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] @@ -90,7 +94,8 @@ mod test { let mut data = include_bytes!("../../fixtures/example-iot-custom-auth-response.json").to_vec(); let parsed: IoTCoreCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: IoTCoreCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: IoTCoreCustomAuthorizerResponse = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/iot_1_click/mod.rs b/lambda-events/src/event/iot_1_click/mod.rs index c7fde657..e7965316 100644 --- a/lambda-events/src/event/iot_1_click/mod.rs +++ b/lambda-events/src/event/iot_1_click/mod.rs @@ -58,6 +58,10 @@ pub struct IoTOneClickPlacementInfo { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/iot_button/mod.rs b/lambda-events/src/event/iot_button/mod.rs index 9c010fd2..5c80e386 100644 --- a/lambda-events/src/event/iot_button/mod.rs +++ b/lambda-events/src/event/iot_button/mod.rs @@ -13,6 +13,10 @@ pub struct IoTButtonEvent { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/kafka/mod.rs b/lambda-events/src/event/kafka/mod.rs index d19b51fb..b3dc2138 100644 --- a/lambda-events/src/event/kafka/mod.rs +++ b/lambda-events/src/event/kafka/mod.rs @@ -33,6 +33,10 @@ pub struct KafkaRecord { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/kinesis/event.rs b/lambda-events/src/event/kinesis/event.rs index e35aa0eb..080039e8 100644 --- a/lambda-events/src/event/kinesis/event.rs +++ b/lambda-events/src/event/kinesis/event.rs @@ -84,6 +84,10 @@ pub enum KinesisEncryptionType { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/lex/mod.rs b/lambda-events/src/event/lex/mod.rs index bae58bd9..7f5e0901 100644 --- a/lambda-events/src/event/lex/mod.rs +++ b/lambda-events/src/event/lex/mod.rs @@ -106,6 +106,10 @@ pub struct Attachment { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/rabbitmq/mod.rs b/lambda-events/src/event/rabbitmq/mod.rs index 3fa043cc..aea63631 100644 --- a/lambda-events/src/event/rabbitmq/mod.rs +++ b/lambda-events/src/event/rabbitmq/mod.rs @@ -1,5 +1,5 @@ -use serde::{de::DeserializeOwned, Deserialize, Serialize}; use aws_lambda_json_impl::Value; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; @@ -60,6 +60,10 @@ where #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/s3/event.rs b/lambda-events/src/event/s3/event.rs index d72ea579..1aaff157 100644 --- a/lambda-events/src/event/s3/event.rs +++ b/lambda-events/src/event/s3/event.rs @@ -90,6 +90,10 @@ pub struct S3Object { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/s3/object_lambda.rs b/lambda-events/src/event/s3/object_lambda.rs index 598e6658..04a83c4c 100644 --- a/lambda-events/src/event/s3/object_lambda.rs +++ b/lambda-events/src/event/s3/object_lambda.rs @@ -1,6 +1,6 @@ +use aws_lambda_json_impl::Value; use http::HeaderMap; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use aws_lambda_json_impl::Value; use std::collections::HashMap; use crate::custom_serde::{deserialize_headers, serialize_headers}; @@ -117,12 +117,17 @@ pub struct SessionIssuer { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] #[cfg(feature = "s3")] fn example_object_lambda_event_get_object_assumed_role() { - let mut data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-assumed-role.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-assumed-role.json").to_vec(); let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); @@ -162,7 +167,8 @@ mod test { #[test] #[cfg(feature = "s3")] fn example_object_lambda_event_list_objects_v2_iam() { - let mut data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-v2-iam.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-v2-iam.json").to_vec(); let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); diff --git a/lambda-events/src/event/secretsmanager/mod.rs b/lambda-events/src/event/secretsmanager/mod.rs index 8f685538..9a28abec 100644 --- a/lambda-events/src/event/secretsmanager/mod.rs +++ b/lambda-events/src/event/secretsmanager/mod.rs @@ -10,6 +10,10 @@ pub struct SecretsManagerSecretRotationEvent { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] @@ -18,7 +22,8 @@ mod test { let mut data = include_bytes!("../../fixtures/example-secretsmanager-secret-rotation-event.json").to_vec(); let parsed: SecretsManagerSecretRotationEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); - let reparsed: SecretsManagerSecretRotationEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); + let reparsed: SecretsManagerSecretRotationEvent = + aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); } } diff --git a/lambda-events/src/event/ses/mod.rs b/lambda-events/src/event/ses/mod.rs index badfdd41..f98f149d 100644 --- a/lambda-events/src/event/ses/mod.rs +++ b/lambda-events/src/event/ses/mod.rs @@ -120,6 +120,10 @@ pub struct SimpleEmailDisposition { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-events/src/event/sns/mod.rs b/lambda-events/src/event/sns/mod.rs index 537eb166..b4d1e734 100644 --- a/lambda-events/src/event/sns/mod.rs +++ b/lambda-events/src/event/sns/mod.rs @@ -248,6 +248,10 @@ pub struct CloudWatchDimension { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] @@ -273,7 +277,8 @@ mod test { #[test] #[cfg(feature = "sns")] fn my_example_sns_event_cloudwatch_single_metric() { - let mut data = include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-single-metric.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-single-metric.json").to_vec(); let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!(1, parsed.records.len()); @@ -291,7 +296,8 @@ mod test { #[test] #[cfg(feature = "sns")] fn my_example_sns_event_cloudwatch_multiple_metrics() { - let mut data = include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-multiple-metrics.json").to_vec(); + let mut data = + include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-multiple-metrics.json").to_vec(); let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!(2, parsed.records.len()); diff --git a/lambda-events/src/event/sqs/mod.rs b/lambda-events/src/event/sqs/mod.rs index 633decb9..90929bc5 100644 --- a/lambda-events/src/event/sqs/mod.rs +++ b/lambda-events/src/event/sqs/mod.rs @@ -180,6 +180,10 @@ pub struct SqsApiMessage { #[cfg(test)] mod test { + // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated + // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice + // once it has been deserialized. + use super::*; #[test] diff --git a/lambda-http/src/deserializer.rs b/lambda-http/src/deserializer.rs index 11991f52..8a357328 100644 --- a/lambda-http/src/deserializer.rs +++ b/lambda-http/src/deserializer.rs @@ -7,8 +7,8 @@ use aws_lambda_events::apigw::ApiGatewayProxyRequest; use aws_lambda_events::apigw::ApiGatewayV2httpRequest; #[cfg(feature = "apigw_websockets")] use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest; -use serde::{de::Error, Deserialize}; use aws_lambda_json_impl::RawValue; +use serde::{de::Error, Deserialize}; const ERROR_CONTEXT: &str = "this function expects a JSON payload from Amazon API Gateway, Amazon Elastic Load Balancer, or AWS Lambda Function URLs, but the data doesn't match any of those services' events"; @@ -54,7 +54,7 @@ mod tests { #[test] fn test_deserialize_apigw_rest() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-request.json"); + let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-request.json").to_owned(); let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw rest data"); match req { @@ -127,7 +127,8 @@ mod tests { let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json"); - let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw websocket data"); + let req: LambdaRequest = + aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw websocket data"); match req { LambdaRequest::WebSocket(req) => { assert_eq!("CONNECT", req.request_context.event_type.unwrap()); diff --git a/lambda-http/src/request.rs b/lambda-http/src/request.rs index 974329aa..b193bdd5 100644 --- a/lambda-http/src/request.rs +++ b/lambda-http/src/request.rs @@ -28,8 +28,8 @@ use aws_lambda_events::apigw::{ApiGatewayWebsocketProxyRequest, ApiGatewayWebsoc use aws_lambda_events::{encodings::Body, query_map::QueryMap}; use http::{header::HeaderName, HeaderMap, HeaderValue}; -use serde::{Deserialize, Serialize}; use aws_lambda_json_impl::JsonError; +use serde::{Deserialize, Serialize}; use std::{env, future::Future, io::Read, pin::Pin}; use url::Url; diff --git a/lambda-http/src/response.rs b/lambda-http/src/response.rs index 0a68566a..5e60a621 100644 --- a/lambda-http/src/response.rs +++ b/lambda-http/src/response.rs @@ -373,12 +373,12 @@ pub type BodyFuture = Pin + Send>>; #[cfg(test)] mod tests { use super::{Body, IntoResponse, LambdaResponse, RequestOrigin, X_LAMBDA_HTTP_CONTENT_ENCODING}; + use aws_lambda_json_impl::json; use http::{ header::{CONTENT_ENCODING, CONTENT_TYPE}, Response, StatusCode, }; use lambda_runtime_api_client::body::Body as HyperBody; - use aws_lambda_json_impl::json; const SVG_LOGO: &str = include_str!("../tests/data/svg_logo.svg"); diff --git a/lambda-integration-tests/src/authorizer.rs b/lambda-integration-tests/src/authorizer.rs index 24e9f4e1..42de319a 100644 --- a/lambda-integration-tests/src/authorizer.rs +++ b/lambda-integration-tests/src/authorizer.rs @@ -4,9 +4,9 @@ use aws_lambda_events::{ apigw::{ApiGatewayCustomAuthorizerPolicy, ApiGatewayCustomAuthorizerResponse}, event::iam::IamPolicyStatement, }; +use aws_lambda_json_impl::json; use lambda_runtime::{service_fn, tracing, Error, LambdaEvent}; use serde::Deserialize; -use aws_lambda_json_impl::json; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] From 6f8ba9ec7b4754348529af3190b882ae9e2f3086 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Tue, 22 Oct 2024 18:25:22 +0200 Subject: [PATCH 09/44] Revert to live simd_json crate - supports Eq values now --- json-impl/Cargo.toml | 3 +-- lambda-http/src/deserializer.rs | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 7ef68028..7ba08979 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -19,8 +19,7 @@ simd = [ "simd-json/ordered-float" ] [dependencies] serde_json = { version = "^1", features = ["raw_value"] } -#simd-json = { version = "^0", optional = true, features = ["ordered-float"] } -simd-json = { git = 'https://github.com/bassmanitram/simd-json', branch = "feature/ordered-float", optional = true} +simd-json = { version = "^0", optional = true } serde = { version = "^1", no-default-features = true } diff --git a/lambda-http/src/deserializer.rs b/lambda-http/src/deserializer.rs index 8a357328..11991f52 100644 --- a/lambda-http/src/deserializer.rs +++ b/lambda-http/src/deserializer.rs @@ -7,8 +7,8 @@ use aws_lambda_events::apigw::ApiGatewayProxyRequest; use aws_lambda_events::apigw::ApiGatewayV2httpRequest; #[cfg(feature = "apigw_websockets")] use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest; -use aws_lambda_json_impl::RawValue; use serde::{de::Error, Deserialize}; +use aws_lambda_json_impl::RawValue; const ERROR_CONTEXT: &str = "this function expects a JSON payload from Amazon API Gateway, Amazon Elastic Load Balancer, or AWS Lambda Function URLs, but the data doesn't match any of those services' events"; @@ -54,7 +54,7 @@ mod tests { #[test] fn test_deserialize_apigw_rest() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-request.json").to_owned(); + let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-request.json"); let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw rest data"); match req { @@ -127,8 +127,7 @@ mod tests { let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json"); - let req: LambdaRequest = - aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw websocket data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw websocket data"); match req { LambdaRequest::WebSocket(req) => { assert_eq!("CONNECT", req.request_context.event_type.unwrap()); From 79c9d6ebac18e77f5ed4ce5ba3401e6f3b89346b Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Wed, 23 Oct 2024 11:02:16 +0200 Subject: [PATCH 10/44] Complete replacement of serde_json reference by aws_lambda_json_impl references And add a very useful "from_bytes" combinator to aid in parsing from stuff like HTTP bodies (though from_reader is probably cheaper). --- json-impl/Cargo.toml | 1 + json-impl/src/lib.rs | 29 +++++++++++++++++++++++++++-- lambda-extension/Cargo.toml | 3 ++- lambda-extension/src/extension.rs | 6 ++++-- lambda-extension/src/logs.rs | 6 +++--- lambda-extension/src/requests.rs | 10 +++++----- lambda-extension/src/telemetry.rs | 10 +++++++--- lambda-runtime/Cargo.toml | 3 ++- lambda-runtime/src/deserializer.rs | 16 ++++++++++++++-- lambda-runtime/src/diagnostic.rs | 4 ++-- lambda-runtime/src/requests.rs | 6 +++--- lambda-runtime/src/runtime.rs | 6 +++--- lambda-runtime/src/types.rs | 8 ++++---- 13 files changed, 77 insertions(+), 31 deletions(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 7ba08979..1f747a55 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -20,6 +20,7 @@ simd = [ "simd-json/ordered-float" ] [dependencies] serde_json = { version = "^1", features = ["raw_value"] } simd-json = { version = "^0", optional = true } +bytes = { workspace = true } serde = { version = "^1", no-default-features = true } diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index 88c5fc72..4125312d 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -9,10 +9,12 @@ pub use simd::*; #[cfg(not(feature = "simd"))] mod serde { - use serde::Deserialize; + use bytes::Bytes; + use serde::{de::DeserializeOwned, Deserialize}; pub use serde_json::{ self, error::Error as JsonError, from_reader, from_slice, from_str, from_value, json, to_string, to_string_pretty, to_value, to_writer, value::RawValue, Deserializer as JsonDeserializer, Value, + to_vec, }; pub fn from_str_mut<'a, T>(s: &'a mut str) -> serde_json::Result where @@ -20,17 +22,25 @@ mod serde { { from_str(s) } + pub fn from_slice_mut<'a, T>(s: &'a mut [u8]) -> serde_json::Result where T: Deserialize<'a>, { from_slice(s) } + + pub fn from_bytes<'a, T>(b: Bytes) -> serde_json::Result + where + T: DeserializeOwned, + { + from_slice(&b) + } } #[cfg(feature = "simd")] mod simd { - use serde::Deserialize; + use serde::{de::DeserializeOwned, Deserialize}; use simd_json::serde::from_str as unsafe_from_str; //THIS is mutable and is unsafe! pub use simd_json::{ self, @@ -44,6 +54,7 @@ mod simd { to_string, to_string_pretty, to_writer, + to_vec, }, tape::Value as RawValue, //THIS is gonna be the fun one! Deserializer as JsonDeserializer, @@ -58,4 +69,18 @@ mod simd { { unsafe { unsafe_from_str(s) } } + + pub fn from_bytes<'a, T>(b: Bytes) -> serde_json::Result + where + T: DeserializeOwned, + { + match b.try_into_mut() { + Ok(b) => from_slice(b), + Err(b) => { + let mut v = b.into_vec(); + from_slice(&mut v) + } + } + } } + diff --git a/lambda-extension/Cargo.toml b/lambda-extension/Cargo.toml index 16b6dace..09d7c878 100644 --- a/lambda-extension/Cargo.toml +++ b/lambda-extension/Cargo.toml @@ -16,6 +16,7 @@ readme = "README.md" [features] default = ["tracing"] tracing = ["lambda_runtime_api_client/tracing"] +simd_json = [ "aws_lambda_json_impl/simd" ] [dependencies] async-stream = "0.3" @@ -27,7 +28,7 @@ hyper = { workspace = true, features = ["http1", "client", "server"] } hyper-util = { workspace = true } lambda_runtime_api_client = { version = "0.11", path = "../lambda-runtime-api-client" } serde = { version = "1", features = ["derive"] } -serde_json = "^1" +aws_lambda_json_impl = { path = "../json-impl" } tokio = { version = "1.0", features = [ "macros", "io-util", diff --git a/lambda-extension/src/extension.rs b/lambda-extension/src/extension.rs index d9717243..b23b5d9a 100644 --- a/lambda-extension/src/extension.rs +++ b/lambda-extension/src/extension.rs @@ -1,6 +1,8 @@ use http::Request; use http_body_util::BodyExt; use hyper::{body::Incoming, server::conn::http1, service::service_fn}; +use bytes::Bytes; +use aws_lambda_json_impl::{from_bytes, JsonError}; use hyper_util::rt::tokio::TokioIo; use lambda_runtime_api_client::Client; @@ -396,7 +398,7 @@ where let body = body.collect().await?.to_bytes(); trace!("{}", std::str::from_utf8(&body)?); // this may be very verbose - let event: NextEvent = serde_json::from_slice(&body)?; + let event: NextEvent = from_bytes(body)?; let is_invoke = event.is_invoke(); let event = LambdaEvent::new(event); @@ -541,7 +543,7 @@ async fn register<'a>( let (_, body) = res.into_parts(); let body = body.collect().await?.to_bytes(); - let response: RegisterResponseBody = serde_json::from_slice(&body)?; + let response: RegisterResponseBody = from_bytes(body)?; Ok(RegisterResponse { extension_id, diff --git a/lambda-extension/src/logs.rs b/lambda-extension/src/logs.rs index c3b0cda2..89e503a3 100644 --- a/lambda-extension/src/logs.rs +++ b/lambda-extension/src/logs.rs @@ -208,7 +208,7 @@ where .unwrap()); } }; - let logs: Vec = match serde_json::from_slice(&body.to_bytes()) { + let logs: Vec = match aws_lambda_json_impl::from_bytes(body.to_bytes()) { Ok(logs) => logs, Err(e) => { error!("Error parsing logs: {}", e); @@ -247,7 +247,7 @@ mod tests { record: LambdaLogRecord::Function("hello world".to_string()), }; - let actual = serde_json::from_str::(data).unwrap(); + let actual = aws_lambda_json_impl::from_str::(data).unwrap(); assert_eq!(expected, actual); } @@ -258,7 +258,7 @@ mod tests { #[test] fn $name() { let (input, expected) = $value; - let actual = serde_json::from_str::(&input).expect("unable to deserialize"); + let actual = aws_lambda_json_impl::from_str::(&input).expect("unable to deserialize"); assert!(actual.record == expected); } diff --git a/lambda-extension/src/requests.rs b/lambda-extension/src/requests.rs index 522b8402..42d48d4f 100644 --- a/lambda-extension/src/requests.rs +++ b/lambda-extension/src/requests.rs @@ -24,7 +24,7 @@ pub(crate) fn next_event_request(extension_id: &str) -> Result, Er } pub(crate) fn register_request(extension_name: &str, events: &[&str]) -> Result, Error> { - let events = serde_json::json!({ "events": events }); + let events = aws_lambda_json_impl::json!({ "events": events }); let req = build_request() .method(Method::POST) @@ -32,7 +32,7 @@ pub(crate) fn register_request(extension_name: &str, events: &[&str]) -> Result< .header(EXTENSION_NAME_HEADER, extension_name) .header(EXTENSION_ACCEPT_FEATURE, EXTENSION_ACCEPT_FEATURE_VALUE) .header(CONTENT_TYPE_HEADER_NAME, CONTENT_TYPE_HEADER_VALUE) - .body(Body::from(serde_json::to_string(&events)?))?; + .body(Body::from(aws_lambda_json_impl::to_string(&events)?))?; Ok(req) } @@ -67,7 +67,7 @@ pub(crate) fn subscribe_request( ) -> Result, Error> { let types = types.unwrap_or(&["platform", "function"]); - let data = serde_json::json!({ + let data = aws_lambda_json_impl::json!({ "schemaVersion": api.schema_version(), "types": types, "buffering": buffering.unwrap_or_default(), @@ -82,7 +82,7 @@ pub(crate) fn subscribe_request( .uri(api.uri()) .header(EXTENSION_ID_HEADER, extension_id) .header(CONTENT_TYPE_HEADER_NAME, CONTENT_TYPE_HEADER_VALUE) - .body(Body::from(serde_json::to_string(&data)?))?; + .body(Body::from(aws_lambda_json_impl::to_string(&data)?))?; Ok(req) } @@ -127,7 +127,7 @@ fn error_request( let body = match request { None => Body::empty(), - Some(err) => Body::from(serde_json::to_string(&err)?), + Some(err) => Body::from(aws_lambda_json_impl::to_string(&err)?), }; let req = build_request() diff --git a/lambda-extension/src/telemetry.rs b/lambda-extension/src/telemetry.rs index a7760892..e84c4b0b 100644 --- a/lambda-extension/src/telemetry.rs +++ b/lambda-extension/src/telemetry.rs @@ -291,7 +291,7 @@ where } }; - let telemetry: Vec = match serde_json::from_slice(&body.to_bytes()) { + let telemetry: Vec = match aws_lambda_json_impl::from_bytes(body.to_bytes()) { Ok(telemetry) => telemetry, Err(e) => { error!("Error parsing telemetry: {}", e); @@ -324,7 +324,11 @@ mod deserialization_tests { #[test] fn $name() { let (input, expected) = $value; - let actual = serde_json::from_str::(&input).expect("unable to deserialize"); + // To avoid lots of complex boilerplate, we use a mutable bytes slice in the parse + // with serde_json the slice is not actually mutated + // with simd_json it is + let mut input = input.as_bytes().to_vec(); + let actual = aws_lambda_json_impl::from_slice::(input.as_mut_slice()).expect("unable to deserialize"); assert!(actual.record == expected); } @@ -482,7 +486,7 @@ mod serialization_tests { #[test] fn $name() { let (input, expected) = $value; - let actual = serde_json::to_string(&input).expect("unable to serialize"); + let actual = aws_lambda_json_impl::to_string(&input).expect("unable to serialize"); println!("Input: {:?}\n", input); println!("Expected:\n {:?}\n", expected); println!("Actual:\n {:?}\n", actual); diff --git a/lambda-runtime/Cargo.toml b/lambda-runtime/Cargo.toml index 0f63cd47..e380b20c 100644 --- a/lambda-runtime/Cargo.toml +++ b/lambda-runtime/Cargo.toml @@ -20,6 +20,7 @@ opentelemetry = ["opentelemetry-semantic-conventions"] # enables access to the O anyhow = ["dep:anyhow"] # enables From for Diagnostic for anyhow error types, see README.md for more info eyre = ["dep:eyre"] # enables From for Diagnostic for eyre error types, see README.md for more info miette = ["dep:miette"] # enables From for Diagnostic for miette error types, see README.md for more info +simd_json = [ "aws_lambda_json_impl/simd" ] [dependencies] anyhow = { version = "1.0.86", optional = true } @@ -44,7 +45,7 @@ miette = { version = "7.2.0", optional = true } opentelemetry-semantic-conventions = { version = "0.14", optional = true } pin-project = "1" serde = { version = "1", features = ["derive", "rc"] } -serde_json = "^1" +aws_lambda_json_impl = { path = "../json-impl" } serde_path_to_error = "0.1.11" tokio = { version = "1.0", features = [ "macros", diff --git a/lambda-runtime/src/deserializer.rs b/lambda-runtime/src/deserializer.rs index 1841c050..90cd896f 100644 --- a/lambda-runtime/src/deserializer.rs +++ b/lambda-runtime/src/deserializer.rs @@ -11,7 +11,7 @@ const ERROR_CONTEXT: &str = "failed to deserialize the incoming data into the fu /// into the type that the function receives. #[derive(Debug)] pub(crate) struct DeserializeError { - inner: serde_path_to_error::Error, + inner: serde_path_to_error::Error, } impl fmt::Display for DeserializeError { @@ -32,11 +32,23 @@ impl Error for DeserializeError { } /// Deserialize the data sent to the function into the type that the function receives. +#[cfg(not(feature = "simd_json"))] pub(crate) fn deserialize(body: &[u8], context: Context) -> Result, DeserializeError> where T: for<'de> Deserialize<'de>, { - let jd = &mut serde_json::Deserializer::from_slice(body); + let jd = &mut aws_lambda_json_impl::JsonDeserializer::from_slice(body); + serde_path_to_error::deserialize(jd) + .map(|payload| LambdaEvent::new(payload, context)) + .map_err(|inner| DeserializeError { inner }) +} + +#[cfg(feature = "simd_json")] +pub(crate) fn deserialize(body: &mut [u8], context: Context) -> Result, DeserializeError> +where + T: for<'de> Deserialize<'de>, +{ + let jd = &mut aws_lambda_json_impl::JsonDeserializer::from_slice(body); serde_path_to_error::deserialize(jd) .map(|payload| LambdaEvent::new(payload, context)) .map_err(|inner| DeserializeError { inner }) diff --git a/lambda-runtime/src/diagnostic.rs b/lambda-runtime/src/diagnostic.rs index c03ce284..d4742639 100644 --- a/lambda-runtime/src/diagnostic.rs +++ b/lambda-runtime/src/diagnostic.rs @@ -158,7 +158,7 @@ mod test { #[test] fn round_trip_lambda_error() { - use serde_json::{json, Value}; + use aws_lambda_json_impl::{json, Value}; let expected = json!({ "errorType": "InvalidEventDataError", "errorMessage": "Error parsing event data.", @@ -168,7 +168,7 @@ mod test { error_type: "InvalidEventDataError".into(), error_message: "Error parsing event data.".into(), }; - let actual: Value = serde_json::to_value(actual).expect("failed to serialize diagnostic"); + let actual: Value = aws_lambda_json_impl::to_value(actual).expect("failed to serialize diagnostic"); assert_eq!(expected, actual); } diff --git a/lambda-runtime/src/requests.rs b/lambda-runtime/src/requests.rs index 729272f2..96e8ad8e 100644 --- a/lambda-runtime/src/requests.rs +++ b/lambda-runtime/src/requests.rs @@ -86,7 +86,7 @@ where let uri = format!("/2018-06-01/runtime/invocation/{}/response", self.request_id); let uri = Uri::from_str(&uri)?; - let body = serde_json::to_vec(&body)?; + let body = aws_lambda_json_impl::to_vec(&body)?; let body = Body::from(body); let req = build_request().method(Method::POST).uri(uri).body(body)?; @@ -116,7 +116,7 @@ where .entry(CONTENT_TYPE) .or_insert("application/octet-stream".parse()?); - let metadata_prelude = serde_json::to_string(&response.metadata_prelude)?; + let metadata_prelude = aws_lambda_json_impl::to_string(&response.metadata_prelude)?; tracing::trace!(?metadata_prelude); @@ -174,7 +174,7 @@ impl<'a> IntoRequest for EventErrorRequest<'a> { fn into_req(self) -> Result, Error> { let uri = format!("/2018-06-01/runtime/invocation/{}/error", self.request_id); let uri = Uri::from_str(&uri)?; - let body = serde_json::to_vec(&self.diagnostic)?; + let body = aws_lambda_json_impl::to_vec(&self.diagnostic)?; let body = Body::from(body); let req = build_request() diff --git a/lambda-runtime/src/runtime.rs b/lambda-runtime/src/runtime.rs index 1c676480..818b82c1 100644 --- a/lambda-runtime/src/runtime.rs +++ b/lambda-runtime/src/runtime.rs @@ -327,7 +327,7 @@ mod endpoint_tests { error_type: "InvalidEventDataError".into(), error_message: "Error parsing event data".into(), }; - let body = serde_json::to_string(&diagnostic)?; + let body = aws_lambda_json_impl::to_string(&diagnostic)?; let server = MockServer::start(); let mock = server.mock(|when, then| { @@ -377,7 +377,7 @@ mod endpoint_tests { let base = server.base_url().parse().expect("Invalid mock server Uri"); let client = Client::builder().with_endpoint(base).build()?; - async fn func(event: crate::LambdaEvent) -> Result { + async fn func(event: crate::LambdaEvent) -> Result { let (event, _) = event.into_parts(); Ok(event) } @@ -421,7 +421,7 @@ mod endpoint_tests { async fn run_panicking_handler(func: F) -> Result<(), Error> where - F: FnMut(crate::LambdaEvent) -> BoxFuture<'static, Result> + F: FnMut(crate::LambdaEvent) -> BoxFuture<'static, Result> + Send + 'static, { diff --git a/lambda-runtime/src/types.rs b/lambda-runtime/src/types.rs index ee09978f..768414f6 100644 --- a/lambda-runtime/src/types.rs +++ b/lambda-runtime/src/types.rs @@ -104,13 +104,13 @@ impl Context { /// and the incoming request data. pub fn new(request_id: &str, env_config: RefConfig, headers: &HeaderMap) -> Result { let client_context: Option = if let Some(value) = headers.get("lambda-runtime-client-context") { - serde_json::from_str(value.to_str()?)? + aws_lambda_json_impl::from_str(value.to_str()?)? } else { None }; let identity: Option = if let Some(value) = headers.get("lambda-runtime-cognito-identity") { - serde_json::from_str(value.to_str()?)? + aws_lambda_json_impl::from_str(value.to_str()?)? } else { None }; @@ -323,7 +323,7 @@ mod test { custom, environment, }; - let client_context_str = serde_json::to_string(&client_context).unwrap(); + let client_context_str = aws_lambda_json_impl::to_string(&client_context).unwrap(); let mut headers = HeaderMap::new(); headers.insert("lambda-runtime-aws-request-id", HeaderValue::from_static("my-id")); headers.insert("lambda-runtime-deadline-ms", HeaderValue::from_static("123")); @@ -360,7 +360,7 @@ mod test { identity_id: String::new(), identity_pool_id: String::new(), }; - let cognito_identity_str = serde_json::to_string(&cognito_identity).unwrap(); + let cognito_identity_str = aws_lambda_json_impl::to_string(&cognito_identity).unwrap(); let mut headers = HeaderMap::new(); headers.insert("lambda-runtime-aws-request-id", HeaderValue::from_static("my-id")); headers.insert("lambda-runtime-deadline-ms", HeaderValue::from_static("123")); From 0940f12438ac88869c81733b9941c539ddc45236 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Wed, 23 Oct 2024 11:04:27 +0200 Subject: [PATCH 11/44] cleanup --- lambda-extension/src/extension.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lambda-extension/src/extension.rs b/lambda-extension/src/extension.rs index b23b5d9a..9170658c 100644 --- a/lambda-extension/src/extension.rs +++ b/lambda-extension/src/extension.rs @@ -1,8 +1,6 @@ use http::Request; use http_body_util::BodyExt; use hyper::{body::Incoming, server::conn::http1, service::service_fn}; -use bytes::Bytes; -use aws_lambda_json_impl::{from_bytes, JsonError}; use hyper_util::rt::tokio::TokioIo; use lambda_runtime_api_client::Client; @@ -398,7 +396,7 @@ where let body = body.collect().await?.to_bytes(); trace!("{}", std::str::from_utf8(&body)?); // this may be very verbose - let event: NextEvent = from_bytes(body)?; + let event: NextEvent = aws_lambda_json_impl::from_bytes(body)?; let is_invoke = event.is_invoke(); let event = LambdaEvent::new(event); @@ -543,7 +541,7 @@ async fn register<'a>( let (_, body) = res.into_parts(); let body = body.collect().await?.to_bytes(); - let response: RegisterResponseBody = from_bytes(body)?; + let response: RegisterResponseBody = aws_lambda_json_impl::from_bytes(body)?; Ok(RegisterResponse { extension_id, From 5ec7dbad1645decc197caba2eb7be37b252bf8b0 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Wed, 23 Oct 2024 11:44:31 +0200 Subject: [PATCH 12/44] fix dependencies --- lambda-http/Cargo.toml | 2 +- lambda-integration-tests/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lambda-http/Cargo.toml b/lambda-http/Cargo.toml index 889bacde..fb2583ff 100644 --- a/lambda-http/Cargo.toml +++ b/lambda-http/Cargo.toml @@ -27,7 +27,7 @@ opentelemetry = ["lambda_runtime/opentelemetry"] # enables access to the OpenTel anyhow = ["lambda_runtime/anyhow"] # enables From for Diagnostic for anyhow error types, see README.md for more info eyre = ["lambda_runtime/eyre"] # enables From for Diagnostic for eyre error types, see README.md for more info miette = ["lambda_runtime/miette"] # enables From for Diagnostic for miette error types, see README.md for more info -simd_json = [ "aws_lambda_json_impl/simd", "aws_lambda_events/simd_json" ] +simd_json = [ "aws_lambda_json_impl/simd", "aws_lambda_events/simd_json", "lambda_runtime/simd_json" ] [dependencies] base64 = { workspace = true } diff --git a/lambda-integration-tests/Cargo.toml b/lambda-integration-tests/Cargo.toml index 6ecea0ad..b46feeff 100644 --- a/lambda-integration-tests/Cargo.toml +++ b/lambda-integration-tests/Cargo.toml @@ -18,7 +18,7 @@ tokio = { version = "1", features = ["full"] } serde = { version = "1.0.204", features = ["derive"] } [features] -simd_json = [ "aws_lambda_json_impl/simd" ] +simd_json = [ "aws_lambda_json_impl/simd", "lambda_runtime/simd_json", "aws_lambda_events/simd_json" ] [dev-dependencies] reqwest = { version = "0.12.5", features = ["blocking"] } From 8344c12015a69db14c4a23c5ce744441d9b188af Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Wed, 23 Oct 2024 11:50:13 +0200 Subject: [PATCH 13/44] Fix simd-related imports --- json-impl/src/lib.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index 4125312d..4fe59895 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -40,6 +40,7 @@ mod serde { #[cfg(feature = "simd")] mod simd { + use bytes::Bytes; use serde::{de::DeserializeOwned, Deserialize}; use simd_json::serde::from_str as unsafe_from_str; //THIS is mutable and is unsafe! pub use simd_json::{ @@ -70,15 +71,15 @@ mod simd { unsafe { unsafe_from_str(s) } } - pub fn from_bytes<'a, T>(b: Bytes) -> serde_json::Result + pub fn from_bytes<'a, T>(b: Bytes) -> simd_json::Result where T: DeserializeOwned, { match b.try_into_mut() { - Ok(b) => from_slice(b), + Ok(mut b) => from_slice_mut(&mut b), Err(b) => { - let mut v = b.into_vec(); - from_slice(&mut v) + let mut v = b.to_vec(); + from_slice_mut(&mut v) } } } From f2b146e5285d888f182088c07671d49e8c8320b4 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Wed, 23 Oct 2024 11:57:36 +0200 Subject: [PATCH 14/44] Don't rename from_slice --- json-impl/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index 4fe59895..f719987c 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -50,7 +50,7 @@ mod simd { serde::{ from_owned_value as from_value, from_reader, - from_slice as from_slice_mut, //THIS is mutable! + from_slice, //THIS requires a mutable slice! to_owned_value as to_value, to_string, to_string_pretty, @@ -76,10 +76,10 @@ mod simd { T: DeserializeOwned, { match b.try_into_mut() { - Ok(mut b) => from_slice_mut(&mut b), + Ok(mut b) => from_slice(&mut b), Err(b) => { let mut v = b.to_vec(); - from_slice_mut(&mut v) + from_slice(&mut v) } } } From d24f7bda84dc0cec748b7976c251807d829baa63 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Wed, 23 Oct 2024 11:58:00 +0200 Subject: [PATCH 15/44] Generalize tests --- lambda-extension/src/logs.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lambda-extension/src/logs.rs b/lambda-extension/src/logs.rs index 89e503a3..3c1c5025 100644 --- a/lambda-extension/src/logs.rs +++ b/lambda-extension/src/logs.rs @@ -237,7 +237,10 @@ mod tests { #[test] fn deserialize_full() { - let data = r#"{"time": "2020-08-20T12:31:32.123Z","type": "function", "record": "hello world"}"#; + // To avoid lots of complex boilerplate, we use a mutable bytes slice in the parse + // with serde_json the slice is not actually mutated + // with simd_json it is + let mut data = r#"{"time": "2020-08-20T12:31:32.123Z","type": "function", "record": "hello world"}"#.as_bytes().to_vec(); let expected = LambdaLog { time: Utc .with_ymd_and_hms(2020, 8, 20, 12, 31, 32) @@ -247,7 +250,7 @@ mod tests { record: LambdaLogRecord::Function("hello world".to_string()), }; - let actual = aws_lambda_json_impl::from_str::(data).unwrap(); + let actual = aws_lambda_json_impl::from_slice::(data.as_mut_slice()).unwrap(); assert_eq!(expected, actual); } @@ -258,7 +261,11 @@ mod tests { #[test] fn $name() { let (input, expected) = $value; - let actual = aws_lambda_json_impl::from_str::(&input).expect("unable to deserialize"); + // To avoid lots of complex boilerplate, we use a mutable bytes slice in the parse + // with serde_json the slice is not actually mutated + // with simd_json it is + let mut input = input.as_bytes().to_vec(); + let actual = aws_lambda_json_impl::from_slice::(input.as_mut_slice()).expect("unable to deserialize"); assert!(actual.record == expected); } From 137a2109b3c39622fe90068d15b3d59dc0690636 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Wed, 23 Oct 2024 11:59:27 +0200 Subject: [PATCH 16/44] Don't rename from_slice --- json-impl/src/lib.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index f719987c..dcc1098f 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -22,20 +22,6 @@ mod serde { { from_str(s) } - - pub fn from_slice_mut<'a, T>(s: &'a mut [u8]) -> serde_json::Result - where - T: Deserialize<'a>, - { - from_slice(s) - } - - pub fn from_bytes<'a, T>(b: Bytes) -> serde_json::Result - where - T: DeserializeOwned, - { - from_slice(&b) - } } #[cfg(feature = "simd")] From f38e25083286acdb00cceadf5bed393dd46f3158 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Wed, 23 Oct 2024 12:43:49 +0200 Subject: [PATCH 17/44] A better approach to intended use Plus the from_vec using an owned vec gets us around some awkward lifetime issues when trying to write "generic" code for both simd_json and serde_json --- json-impl/src/lib.rs | 47 +++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index dcc1098f..046ae1a6 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -16,19 +16,32 @@ mod serde { to_string_pretty, to_value, to_writer, value::RawValue, Deserializer as JsonDeserializer, Value, to_vec, }; - pub fn from_str_mut<'a, T>(s: &'a mut str) -> serde_json::Result + pub fn from_bytes<'a, T>(b: Bytes) -> simd_json::Result where - T: Deserialize<'a>, + T: DeserializeOwned, + { + from_slice(&mut b) + } + + pub fn from_string<'a, T>(s: String) -> simd_json::Result + where + T: DeserializeOwned, { - from_str(s) + from_str(s.as_str()) + } + + pub fn from_vec<'a, T>(mut v: Vec) -> simd_json::Result + where + T: DeserializeOwned, + { + from_slice(&mut v) } } #[cfg(feature = "simd")] mod simd { use bytes::Bytes; - use serde::{de::DeserializeOwned, Deserialize}; - use simd_json::serde::from_str as unsafe_from_str; //THIS is mutable and is unsafe! + use serde::de::DeserializeOwned; pub use simd_json::{ self, json, @@ -36,6 +49,7 @@ mod simd { serde::{ from_owned_value as from_value, from_reader, + from_str, //THIS requires a mutable string slice AND is unsafe from_slice, //THIS requires a mutable slice! to_owned_value as to_value, to_string, @@ -48,15 +62,6 @@ mod simd { Error as JsonError, }; - /// BEWARE this ISN'T safe - but is marked so for compatibility at the - /// moment. - pub fn from_str_mut<'a, T>(s: &'a mut str) -> simd_json::Result - where - T: Deserialize<'a>, - { - unsafe { unsafe_from_str(s) } - } - pub fn from_bytes<'a, T>(b: Bytes) -> simd_json::Result where T: DeserializeOwned, @@ -69,5 +74,19 @@ mod simd { } } } + + pub fn from_string<'a, T>(mut s: String) -> simd_json::Result + where + T: DeserializeOwned, + { + unsafe{ from_str(s.as_mut_str()) } + } + + pub fn from_vec<'a, T>(mut v: Vec) -> simd_json::Result + where + T: DeserializeOwned, + { + from_slice(&mut v) + } } From 3c1d23e14fa6ab121bdac93acec287329b70444b Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Wed, 23 Oct 2024 14:52:19 +0200 Subject: [PATCH 18/44] One error left in this round - missing trait on simd_json deserializer --- lambda-events/src/custom_serde/mod.rs | 46 ++++++++-- .../src/event/cloudwatch_logs/mod.rs | 4 +- lambda-events/src/event/cognito/mod.rs | 20 ++--- lambda-runtime/src/deserializer.rs | 84 ++++++++++++++----- lambda-runtime/src/layers/api_response.rs | 2 +- lambda-runtime/src/types.rs | 20 ++++- 6 files changed, 130 insertions(+), 46 deletions(-) diff --git a/lambda-events/src/custom_serde/mod.rs b/lambda-events/src/custom_serde/mod.rs index ffd51385..63352af2 100644 --- a/lambda-events/src/custom_serde/mod.rs +++ b/lambda-events/src/custom_serde/mod.rs @@ -171,6 +171,7 @@ mod test { assert_eq!(serde_dynamo::Item::from(HashMap::new()), decoded.v); } + #[cfg(not(feature = "simd_json"))] #[test] fn test_deserialize_nullish_boolean() { #[derive(Deserialize)] @@ -179,20 +180,49 @@ mod test { v: bool, } - let mut test = String::from_str(r#"{"v": null}"#).unwrap(); - let decoded: Test = aws_lambda_json_impl::from_str(test.as_mut()).unwrap(); + let test = r#"{"v": null}"#; + let decoded: Test = aws_lambda_json_impl::from_str(&test).unwrap(); assert!(!decoded.v); - let mut test = String::from_str(r#"{}"#).unwrap(); - let decoded: Test = aws_lambda_json_impl::from_str(test.as_mut()).unwrap(); + let test = r#"{}"#; + let decoded: Test = aws_lambda_json_impl::from_str(&test).unwrap(); assert!(!decoded.v); - let mut test = String::from_str(r#"{"v": true}"#).unwrap(); - let decoded: Test = aws_lambda_json_impl::from_str(test.as_mut()).unwrap(); + let test = r#"{"v": true}"#; + let decoded: Test = aws_lambda_json_impl::from_str(&test).unwrap(); assert!(decoded.v); - let mut test = String::from_str(r#"{"v": false}"#).unwrap(); - let decoded: Test = aws_lambda_json_impl::from_str(test.as_mut()).unwrap(); + let test = r#"{"v": false}"#; + let decoded: Test = aws_lambda_json_impl::from_str(&test).unwrap(); + assert!(!decoded.v); + } + #[cfg(feature = "simd_json")] + #[test] + fn test_deserialize_nullish_boolean() { + // + // Let's have some fun! This is how to do SAFE from_str with simd_json + // + + #[derive(Deserialize)] + struct Test { + #[serde(default, deserialize_with = "deserialize_nullish_boolean")] + v: bool, + } + + let test = String::from_str(r#"{"v": null}"#).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap(); + assert!(!decoded.v); + + let test = String::from_str(r#"{}"#).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap(); + assert!(!decoded.v); + + let test = String::from_str(r#"{"v": true}"#).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap(); + assert!(decoded.v); + + let test = String::from_str(r#"{"v": false}"#).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap(); assert!(!decoded.v); } } diff --git a/lambda-events/src/event/cloudwatch_logs/mod.rs b/lambda-events/src/event/cloudwatch_logs/mod.rs index c3d53fd3..68bc96cf 100644 --- a/lambda-events/src/event/cloudwatch_logs/mod.rs +++ b/lambda-events/src/event/cloudwatch_logs/mod.rs @@ -127,12 +127,12 @@ mod test { #[test] #[cfg(feature = "cloudwatch_logs")] fn test_deserialize_example() { - let mut json = r#"{ + let json = r#"{ "awslogs": { "data": "H4sIAFETomIAA12Ry27bMBBF9/4KQuiyqsQ36Z2DqEGBGC0sdRUHAS0NExV6uCJVNw3y76Fkx03CFTH3cubwztMChRO14Jy5h+JxD9ESRZerYnW3zvJ8dZVFn4+W/tDBMImYUMaFVDrF5FVs+vuroR/3k56Yg0sa0+4qk0D50MddX8Ev98aa+wFMO3lJinWS0gTT5ObT9arI8uJWM2uUkMCpZIxiorGRtsQMiOXCgHxt5MadK4d67+u++1o3HgYXWt7M4my4nhmOw+7Kph+rg/HlQwBwM1M0W2//c2V/oPPvmzydb7OpriZqygQhFItUa6GlUkymgrNUS5EKpQhRfMpGCEzC/xgWjCpNOBMn8nM3X4fcvWmn2DDnhGNFWXiffvCdtjON3mQ/vm8KtIHfY3j6rVoiEdaxsxZizLSJd4KRWGFrYwIKqBSVMtZu/eU4mCmoJWLii2KodVt/UTcNVOiNJEMdbf0a2n54RHn9DwKYJmh9EYrmLzoJPx2EwfJY33bRmfb5mOjiefECiB5LsVgCAAA=" } }"#.to_owned(); - let event: LogsEvent = aws_lambda_json_impl::from_str(&mut json).expect("failed to deserialize"); + let event: LogsEvent = aws_lambda_json_impl::from_string(json).expect("failed to deserialize"); let data = event.clone().aws_logs.data; assert_eq!("DATA_MESSAGE", data.message_type); diff --git a/lambda-events/src/event/cognito/mod.rs b/lambda-events/src/event/cognito/mod.rs index fa02eccb..61ec415e 100644 --- a/lambda-events/src/event/cognito/mod.rs +++ b/lambda-events/src/event/cognito/mod.rs @@ -939,7 +939,7 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&mut header).unwrap(); + aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); @@ -953,7 +953,7 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&mut header).unwrap(); + aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); @@ -970,7 +970,7 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&mut header).unwrap(); + aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); @@ -984,7 +984,7 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&mut header).unwrap(); + aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); @@ -998,7 +998,7 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&mut header).unwrap(); + aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); @@ -1013,7 +1013,7 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&mut header).unwrap(); + aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); @@ -1027,7 +1027,7 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&mut header).unwrap(); + aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); @@ -1047,7 +1047,7 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&mut header).unwrap(); + aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); @@ -1061,7 +1061,7 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&mut header).unwrap(); + aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); @@ -1083,7 +1083,7 @@ mod trigger_source_tests { possible_triggers.into_iter().for_each(|trigger| { let mut header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = - aws_lambda_json_impl::from_str(&mut header).unwrap(); + aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); let reparsed: CognitoEventUserPoolsHeader<_> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); diff --git a/lambda-runtime/src/deserializer.rs b/lambda-runtime/src/deserializer.rs index 90cd896f..771fb88e 100644 --- a/lambda-runtime/src/deserializer.rs +++ b/lambda-runtime/src/deserializer.rs @@ -6,50 +6,90 @@ use crate::{Context, LambdaEvent}; const ERROR_CONTEXT: &str = "failed to deserialize the incoming data into the function's payload type"; -/// Event payload deserialization error. -/// Returned when the data sent to the function cannot be deserialized -/// into the type that the function receives. -#[derive(Debug)] -pub(crate) struct DeserializeError { - inner: serde_path_to_error::Error, -} +use bytes::Bytes; + +#[cfg(not(feature = "simd_json"))] +mod deser_error { + use super::*; -impl fmt::Display for DeserializeError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let path = self.inner.path().to_string(); - if path == "." { - writeln!(f, "{ERROR_CONTEXT}: {}", self.inner) - } else { - writeln!(f, "{ERROR_CONTEXT}: [{path}] {}", self.inner) + /// Event payload deserialization error. + /// Returned when the data sent to the function cannot be deserialized + /// into the type that the function receives. + #[derive(Debug)] + #[cfg(not(feature = "simd_json"))] + pub(crate) struct DeserializeError { + pub(super) inner: serde_path_to_error::Error, + } + impl fmt::Display for DeserializeError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let path = self.inner.to_string(); + if path == "." { + writeln!(f, "{ERROR_CONTEXT}: {}", self.inner) + } else { + writeln!(f, "{ERROR_CONTEXT}: [{path}] {}", self.inner) + } + } + } + + impl Error for DeserializeError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + Some(&self.inner) } } } -impl Error for DeserializeError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - Some(&self.inner) +#[cfg(feature = "simd_json")] +mod deser_error { + use super::*; + + /// Event payload deserialization error. + /// Returned when the data sent to the function cannot be deserialized + /// into the type that the function receives. + /// For simd_json, we can't get serde_path_to_error to work at the moment + + #[derive(Debug)] + pub(crate) struct DeserializeError { + pub(super) inner: aws_lambda_json_impl::JsonError + } + + impl fmt::Display for DeserializeError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let path = self.inner.to_string(); + if path == "." { + writeln!(f, "{ERROR_CONTEXT}: {}", self.inner) + } else { + writeln!(f, "{ERROR_CONTEXT}: [{path}] {}", self.inner) + } + } + } + + impl Error for DeserializeError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + Some(&self.inner) + } } } +pub(crate) use deser_error::*; + /// Deserialize the data sent to the function into the type that the function receives. #[cfg(not(feature = "simd_json"))] -pub(crate) fn deserialize(body: &[u8], context: Context) -> Result, DeserializeError> +pub(crate) fn deserialize(body: Bytes, context: Context) -> Result, DeserializeError> where T: for<'de> Deserialize<'de>, { - let jd = &mut aws_lambda_json_impl::JsonDeserializer::from_slice(body); + let jd = &mut aws_lambda_json_impl::from_bytes(body); serde_path_to_error::deserialize(jd) .map(|payload| LambdaEvent::new(payload, context)) .map_err(|inner| DeserializeError { inner }) } #[cfg(feature = "simd_json")] -pub(crate) fn deserialize(body: &mut [u8], context: Context) -> Result, DeserializeError> +pub(crate) fn deserialize(body: Bytes, context: Context) -> Result, DeserializeError> where T: for<'de> Deserialize<'de>, { - let jd = &mut aws_lambda_json_impl::JsonDeserializer::from_slice(body); - serde_path_to_error::deserialize(jd) + aws_lambda_json_impl::from_bytes(body) .map(|payload| LambdaEvent::new(payload, context)) .map_err(|inner| DeserializeError { inner }) } diff --git a/lambda-runtime/src/layers/api_response.rs b/lambda-runtime/src/layers/api_response.rs index e744cde1..59e24fc0 100644 --- a/lambda-runtime/src/layers/api_response.rs +++ b/lambda-runtime/src/layers/api_response.rs @@ -102,7 +102,7 @@ where }; let request_id = req.context.request_id.clone(); - let lambda_event = match deserializer::deserialize::(&req.body, req.context) { + let lambda_event = match deserializer::deserialize::(req.body, req.context) { Ok(lambda_event) => lambda_event, Err(err) => match build_event_error_request(&request_id, err) { Ok(request) => return RuntimeApiResponseFuture::Ready(Some(Ok(request))), diff --git a/lambda-runtime/src/types.rs b/lambda-runtime/src/types.rs index 768414f6..b5511cec 100644 --- a/lambda-runtime/src/types.rs +++ b/lambda-runtime/src/types.rs @@ -3,13 +3,14 @@ use base64::prelude::*; use bytes::Bytes; use http::{header::ToStrError, HeaderMap, HeaderValue, StatusCode}; use lambda_runtime_api_client::body::Body; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize, de::DeserializeOwned}; use std::{ collections::HashMap, fmt::Debug, time::{Duration, SystemTime}, }; use tokio_stream::Stream; +use aws_lambda_json_impl::JsonError; /// Client context sent by the AWS Mobile SDK. #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)] @@ -99,18 +100,31 @@ impl Default for Context { } } +#[cfg(not(feature = "simd_json"))] +fn parse_header<'a,T>(h: &'a HeaderValue) -> Result +where T: Deserialize<'a> { + aws_lambda_json_impl::from_str(h.to_str()?)? +} + +#[cfg(feature = "simd_json")] +fn parse_header(h: &HeaderValue) -> Result +where T: DeserializeOwned { + let v = h.as_bytes().to_vec(); + aws_lambda_json_impl::from_vec(v) +} + impl Context { /// Create a new [Context] struct based on the function configuration /// and the incoming request data. pub fn new(request_id: &str, env_config: RefConfig, headers: &HeaderMap) -> Result { let client_context: Option = if let Some(value) = headers.get("lambda-runtime-client-context") { - aws_lambda_json_impl::from_str(value.to_str()?)? + parse_header(value)? } else { None }; let identity: Option = if let Some(value) = headers.get("lambda-runtime-cognito-identity") { - aws_lambda_json_impl::from_str(value.to_str()?)? + parse_header(value)? } else { None }; From 334246e459a1103b4fd76aa171cd2b2a6693badd Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Wed, 23 Oct 2024 16:04:54 +0200 Subject: [PATCH 19/44] Fix need for 'from_reader' on deserializer THAT is NOT easy to create for simd_json. --- lambda-events/src/event/cloudwatch_logs/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lambda-events/src/event/cloudwatch_logs/mod.rs b/lambda-events/src/event/cloudwatch_logs/mod.rs index 68bc96cf..73c22343 100644 --- a/lambda-events/src/event/cloudwatch_logs/mod.rs +++ b/lambda-events/src/event/cloudwatch_logs/mod.rs @@ -80,8 +80,7 @@ impl<'de> Deserialize<'de> for AwsLogs { })?; let bytes = flate2::read::GzDecoder::new(&bytes[..]); - let mut de = aws_lambda_json_impl::JsonDeserializer::from_reader(BufReader::new(bytes)); - data = Some(LogData::deserialize(&mut de).map_err(Error::custom)?); + data = aws_lambda_json_impl::from_reader(BufReader::new(bytes)).map_err(Error::custom)?; } _ => return Err(Error::unknown_field(key, FIELDS)), } From e0317b2bc523a3413e16c40cfe4d9a9ed98447e2 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Thu, 24 Oct 2024 10:41:55 +0200 Subject: [PATCH 20/44] We're down to the core of the issue We've removed Deserialize from of lambda_http::request::LambdaRequest ... that makes EVERYTHING compile in the simd_json context ... with the exception of th calls to lambda_runtime::run which require the expected request type to be serde::Deserialize. So now it's back to that issue - which, if I recall well, was the blocker back when I first started this! --- lambda-http/src/deserializer.rs | 178 ++--------------- .../deserializer/deserializer_serde_json.rs | 167 ++++++++++++++++ .../deserializer/deserializer_simd_json.rs | 180 ++++++++++++++++++ lambda-http/src/ext/request.rs | 15 ++ lambda-http/src/request.rs | 125 ++++++++++-- 5 files changed, 478 insertions(+), 187 deletions(-) create mode 100644 lambda-http/src/deserializer/deserializer_serde_json.rs create mode 100644 lambda-http/src/deserializer/deserializer_simd_json.rs diff --git a/lambda-http/src/deserializer.rs b/lambda-http/src/deserializer.rs index 11991f52..64f0cd0a 100644 --- a/lambda-http/src/deserializer.rs +++ b/lambda-http/src/deserializer.rs @@ -1,167 +1,11 @@ -use crate::request::LambdaRequest; -#[cfg(feature = "alb")] -use aws_lambda_events::alb::AlbTargetGroupRequest; -#[cfg(feature = "apigw_rest")] -use aws_lambda_events::apigw::ApiGatewayProxyRequest; -#[cfg(feature = "apigw_http")] -use aws_lambda_events::apigw::ApiGatewayV2httpRequest; -#[cfg(feature = "apigw_websockets")] -use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest; -use serde::{de::Error, Deserialize}; -use aws_lambda_json_impl::RawValue; - -const ERROR_CONTEXT: &str = "this function expects a JSON payload from Amazon API Gateway, Amazon Elastic Load Balancer, or AWS Lambda Function URLs, but the data doesn't match any of those services' events"; - -#[cfg(feature = "pass_through")] -const PASS_THROUGH_ENABLED: bool = true; - -impl<'de> Deserialize<'de> for LambdaRequest { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let raw_value: Box = Box::deserialize(deserializer)?; - let data = raw_value.get(); - - #[cfg(feature = "apigw_rest")] - if let Ok(res) = aws_lambda_json_impl::from_str::(data) { - return Ok(LambdaRequest::ApiGatewayV1(res)); - } - #[cfg(feature = "apigw_http")] - if let Ok(res) = aws_lambda_json_impl::from_str::(data) { - return Ok(LambdaRequest::ApiGatewayV2(res)); - } - #[cfg(feature = "alb")] - if let Ok(res) = aws_lambda_json_impl::from_str::(data) { - return Ok(LambdaRequest::Alb(res)); - } - #[cfg(feature = "apigw_websockets")] - if let Ok(res) = aws_lambda_json_impl::from_str::(data) { - return Ok(LambdaRequest::WebSocket(res)); - } - #[cfg(feature = "pass_through")] - if PASS_THROUGH_ENABLED { - return Ok(LambdaRequest::PassThrough(data.to_string())); - } - - Err(Error::custom(ERROR_CONTEXT)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_deserialize_apigw_rest() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-request.json"); - - let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw rest data"); - match req { - LambdaRequest::ApiGatewayV1(req) => { - assert_eq!("12345678912", req.request_context.account_id.unwrap()); - } - other => panic!("unexpected request variant: {:?}", other), - } - } - - #[test] - fn test_deserialize_apigw_http() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-v2-request-iam.json"); - - let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw http data"); - match req { - LambdaRequest::ApiGatewayV2(req) => { - assert_eq!("123456789012", req.request_context.account_id.unwrap()); - } - other => panic!("unexpected request variant: {:?}", other), - } - } - - #[test] - fn test_deserialize_sam_rest() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-sam-rest-request.json"); - - let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize SAM rest data"); - match req { - LambdaRequest::ApiGatewayV1(req) => { - assert_eq!("123456789012", req.request_context.account_id.unwrap()); - } - other => panic!("unexpected request variant: {:?}", other), - } - } - - #[test] - fn test_deserialize_sam_http() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-sam-http-request.json"); - - let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize SAM http data"); - match req { - LambdaRequest::ApiGatewayV2(req) => { - assert_eq!("123456789012", req.request_context.account_id.unwrap()); - } - other => panic!("unexpected request variant: {:?}", other), - } - } - - #[test] - fn test_deserialize_alb() { - let data = include_bytes!( - "../../lambda-events/src/fixtures/example-alb-lambda-target-request-multivalue-headers.json" - ); - - let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize alb rest data"); - match req { - LambdaRequest::Alb(req) => { - assert_eq!( - "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/lambda-target/abcdefgh", - req.request_context.elb.target_group_arn.unwrap() - ); - } - other => panic!("unexpected request variant: {:?}", other), - } - } - - #[test] - fn test_deserialize_apigw_websocket() { - let data = - include_bytes!("../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json"); - - let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw websocket data"); - match req { - LambdaRequest::WebSocket(req) => { - assert_eq!("CONNECT", req.request_context.event_type.unwrap()); - } - other => panic!("unexpected request variant: {:?}", other), - } - } - - #[test] - #[cfg(feature = "pass_through")] - fn test_deserialize_bedrock_agent() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-bedrock-agent-runtime-event.json"); - - let req: LambdaRequest = - aws_lambda_json_impl::from_slice(data).expect("failed to deserialize bedrock agent request data"); - match req { - LambdaRequest::PassThrough(req) => { - assert_eq!(String::from_utf8_lossy(data), req); - } - other => panic!("unexpected request variant: {:?}", other), - } - } - - #[test] - #[cfg(feature = "pass_through")] - fn test_deserialize_sqs() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-sqs-event.json"); - - let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize sqs event data"); - match req { - LambdaRequest::PassThrough(req) => { - assert_eq!(String::from_utf8_lossy(data), req); - } - other => panic!("unexpected request variant: {:?}", other), - } - } -} +#[cfg(feature = "simd_json")] +mod deserializer_simd_json; +#[cfg(feature = "simd_json")] +#[allow(unused_imports)] +pub use deserializer_simd_json::*; + +#[cfg(not(feature = "simd_json"))] +mod deserializer_serde_json; +#[cfg(not(feature = "simd_json"))] +#[allow(unused_imports)] +pub use deserializer_serde_json::*; \ No newline at end of file diff --git a/lambda-http/src/deserializer/deserializer_serde_json.rs b/lambda-http/src/deserializer/deserializer_serde_json.rs new file mode 100644 index 00000000..11991f52 --- /dev/null +++ b/lambda-http/src/deserializer/deserializer_serde_json.rs @@ -0,0 +1,167 @@ +use crate::request::LambdaRequest; +#[cfg(feature = "alb")] +use aws_lambda_events::alb::AlbTargetGroupRequest; +#[cfg(feature = "apigw_rest")] +use aws_lambda_events::apigw::ApiGatewayProxyRequest; +#[cfg(feature = "apigw_http")] +use aws_lambda_events::apigw::ApiGatewayV2httpRequest; +#[cfg(feature = "apigw_websockets")] +use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest; +use serde::{de::Error, Deserialize}; +use aws_lambda_json_impl::RawValue; + +const ERROR_CONTEXT: &str = "this function expects a JSON payload from Amazon API Gateway, Amazon Elastic Load Balancer, or AWS Lambda Function URLs, but the data doesn't match any of those services' events"; + +#[cfg(feature = "pass_through")] +const PASS_THROUGH_ENABLED: bool = true; + +impl<'de> Deserialize<'de> for LambdaRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let raw_value: Box = Box::deserialize(deserializer)?; + let data = raw_value.get(); + + #[cfg(feature = "apigw_rest")] + if let Ok(res) = aws_lambda_json_impl::from_str::(data) { + return Ok(LambdaRequest::ApiGatewayV1(res)); + } + #[cfg(feature = "apigw_http")] + if let Ok(res) = aws_lambda_json_impl::from_str::(data) { + return Ok(LambdaRequest::ApiGatewayV2(res)); + } + #[cfg(feature = "alb")] + if let Ok(res) = aws_lambda_json_impl::from_str::(data) { + return Ok(LambdaRequest::Alb(res)); + } + #[cfg(feature = "apigw_websockets")] + if let Ok(res) = aws_lambda_json_impl::from_str::(data) { + return Ok(LambdaRequest::WebSocket(res)); + } + #[cfg(feature = "pass_through")] + if PASS_THROUGH_ENABLED { + return Ok(LambdaRequest::PassThrough(data.to_string())); + } + + Err(Error::custom(ERROR_CONTEXT)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_deserialize_apigw_rest() { + let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-request.json"); + + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw rest data"); + match req { + LambdaRequest::ApiGatewayV1(req) => { + assert_eq!("12345678912", req.request_context.account_id.unwrap()); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + fn test_deserialize_apigw_http() { + let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-v2-request-iam.json"); + + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw http data"); + match req { + LambdaRequest::ApiGatewayV2(req) => { + assert_eq!("123456789012", req.request_context.account_id.unwrap()); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + fn test_deserialize_sam_rest() { + let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-sam-rest-request.json"); + + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize SAM rest data"); + match req { + LambdaRequest::ApiGatewayV1(req) => { + assert_eq!("123456789012", req.request_context.account_id.unwrap()); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + fn test_deserialize_sam_http() { + let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-sam-http-request.json"); + + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize SAM http data"); + match req { + LambdaRequest::ApiGatewayV2(req) => { + assert_eq!("123456789012", req.request_context.account_id.unwrap()); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + fn test_deserialize_alb() { + let data = include_bytes!( + "../../lambda-events/src/fixtures/example-alb-lambda-target-request-multivalue-headers.json" + ); + + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize alb rest data"); + match req { + LambdaRequest::Alb(req) => { + assert_eq!( + "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/lambda-target/abcdefgh", + req.request_context.elb.target_group_arn.unwrap() + ); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + fn test_deserialize_apigw_websocket() { + let data = + include_bytes!("../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json"); + + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw websocket data"); + match req { + LambdaRequest::WebSocket(req) => { + assert_eq!("CONNECT", req.request_context.event_type.unwrap()); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + #[cfg(feature = "pass_through")] + fn test_deserialize_bedrock_agent() { + let data = include_bytes!("../../lambda-events/src/fixtures/example-bedrock-agent-runtime-event.json"); + + let req: LambdaRequest = + aws_lambda_json_impl::from_slice(data).expect("failed to deserialize bedrock agent request data"); + match req { + LambdaRequest::PassThrough(req) => { + assert_eq!(String::from_utf8_lossy(data), req); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + #[cfg(feature = "pass_through")] + fn test_deserialize_sqs() { + let data = include_bytes!("../../lambda-events/src/fixtures/example-sqs-event.json"); + + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize sqs event data"); + match req { + LambdaRequest::PassThrough(req) => { + assert_eq!(String::from_utf8_lossy(data), req); + } + other => panic!("unexpected request variant: {:?}", other), + } + } +} diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs new file mode 100644 index 00000000..018d0f98 --- /dev/null +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -0,0 +1,180 @@ +use crate::request::LambdaRequest; +#[cfg(feature = "alb")] +use aws_lambda_events::alb::AlbTargetGroupRequest; +#[cfg(feature = "apigw_rest")] +use aws_lambda_events::apigw::ApiGatewayProxyRequest; +#[cfg(feature = "apigw_http")] +use aws_lambda_events::apigw::ApiGatewayV2httpRequest; +#[cfg(feature = "apigw_websockets")] +use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest; +use aws_lambda_json_impl::JsonError; +use serde::de::Error; + +const ERROR_CONTEXT: &str = "this function expects a JSON payload from Amazon API Gateway, Amazon Elastic Load Balancer, or AWS Lambda Function URLs, but the data doesn't match any of those services' events"; + +#[cfg(feature = "pass_through")] +const PASS_THROUGH_ENABLED: bool = true; + +// simd_json and LambdaRequest don't sit well together due to how the request variant is discovered +// simd can't use a real serde deserializer and RawValue technique because simd_json doesn't have a RawValue like that ... wellll... +// if we accept that and do a custom function, we COULD do something similar - but that's a bit time consuming if you support all variants +// but with simd we CAN attempt to look for "marker required properties" in the incoming JSON 'Tape' - what characteristics identify them... + +pub fn deserialize(b: &mut [u8]) -> Result { + let d = aws_lambda_json_impl::JsonDeserializer::from_slice(b)?; + let t = d.into_tape(); + let v = t.as_value(); + + #[cfg(feature = "apigw_rest")] + if let (Some(rc), true) = (v.get_object("request_context"),v.contains_key("http_method")) { + if rc.get("http").is_none() { + let res: ApiGatewayProxyRequest = t.deserialize()?; + return Ok(LambdaRequest::ApiGatewayV1(res)); + } + } + #[cfg(feature = "apigw_http")] + if let Some(rc) = v.get_object("request_context") { + if rc.get("http").is_some() { + let res: ApiGatewayV2httpRequest = t.deserialize()?; + return Ok(LambdaRequest::ApiGatewayV2(res)); + } + } + #[cfg(feature = "alb")] + if let Some(rc) = v.get_object("request_context") { + if let Some(_) = rc.get("elb") { + let res: AlbTargetGroupRequest = t.deserialize()?; + return Ok(LambdaRequest::Alb(res)); + } + } + #[cfg(feature = "apigw_websockets")] + if v.contains_key("connected_at") { + let res: ApiGatewayWebsocketProxyRequest = t.deserialize()?; + return Ok(LambdaRequest::WebSocket(res)); + } + + #[cfg(feature = "pass_through")] + if PASS_THROUGH_ENABLED { + return Ok(LambdaRequest::PassThrough(data.to_string())); + } + + Err(Error::custom(ERROR_CONTEXT)) + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_deserialize_apigw_rest() { + let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-request.json").to_vec(); + + let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize apigw rest data"); + match req { + LambdaRequest::ApiGatewayV1(req) => { + assert_eq!("12345678912", req.request_context.account_id.unwrap()); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + fn test_deserialize_apigw_http() { + let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-v2-request-iam.json").to_vec(); + + let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize apigw http data"); + match req { + LambdaRequest::ApiGatewayV2(req) => { + assert_eq!("123456789012", req.request_context.account_id.unwrap()); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + fn test_deserialize_sam_rest() { + let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-sam-rest-request.json").to_vec(); + + let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize SAM rest data"); + match req { + LambdaRequest::ApiGatewayV1(req) => { + assert_eq!("123456789012", req.request_context.account_id.unwrap()); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + fn test_deserialize_sam_http() { + let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-sam-http-request.json").to_vec(); + + let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize SAM http data"); + match req { + LambdaRequest::ApiGatewayV2(req) => { + assert_eq!("123456789012", req.request_context.account_id.unwrap()); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + fn test_deserialize_alb() { + let mut data = include_bytes!( + "../../../lambda-events/src/fixtures/example-alb-lambda-target-request-multivalue-headers.json" + ).to_vec(); + + let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize alb rest data"); + match req { + LambdaRequest::Alb(req) => { + assert_eq!( + "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/lambda-target/abcdefgh", + req.request_context.elb.target_group_arn.unwrap() + ); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + fn test_deserialize_apigw_websocket() { + let mut data = + include_bytes!("../../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json").to_vec(); + + let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize apigw websocket data"); + match req { + LambdaRequest::WebSocket(req) => { + assert_eq!("CONNECT", req.request_context.event_type.unwrap()); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + #[cfg(feature = "pass_through")] + fn test_deserialize_bedrock_agent() { + let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-bedrock-agent-runtime-event.json").to_vec(); + + let req: LambdaRequest = + deserialize(data.as_mut_slice()).expect("failed to deserialize bedrock agent request data"); + match req { + LambdaRequest::PassThrough(req) => { + assert_eq!(String::from_utf8_lossy(data), req); + } + other => panic!("unexpected request variant: {:?}", other), + } + } + + #[test] + #[cfg(feature = "pass_through")] + fn test_deserialize_sqs() { + let data = include_bytes!("../../../lambda-events/src/fixtures/example-sqs-event.json"); + + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize sqs event data"); + match req { + LambdaRequest::PassThrough(req) => { + assert_eq!(String::from_utf8_lossy(data), req); + } + other => panic!("unexpected request variant: {:?}", other), + } + } +} diff --git a/lambda-http/src/ext/request.rs b/lambda-http/src/ext/request.rs index 66a5f5cf..706335ed 100644 --- a/lambda-http/src/ext/request.rs +++ b/lambda-http/src/ext/request.rs @@ -244,6 +244,7 @@ impl RequestPayloadExt for http::Request { .unwrap_or_else(|| Ok(None)) } + #[cfg(not(feature = "simd_json"))] fn json(&self) -> Result, JsonPayloadError> where D: DeserializeOwned, @@ -256,6 +257,20 @@ impl RequestPayloadExt for http::Request { .map_err(JsonPayloadError::Parsing) } + #[cfg(feature = "simd_json")] + fn json(&self) -> Result, JsonPayloadError> + where + D: DeserializeOwned, + { + if self.body().is_empty() { + return Ok(None); + } + let mut body = self.body().to_vec(); + aws_lambda_json_impl::from_slice::(body.as_mut_slice()) + .map(Some) + .map_err(JsonPayloadError::Parsing) + } + fn form_url_encoded(&self) -> Result, FormUrlEncodedPayloadError> where D: DeserializeOwned, diff --git a/lambda-http/src/request.rs b/lambda-http/src/request.rs index b193bdd5..b5f37e8c 100644 --- a/lambda-http/src/request.rs +++ b/lambda-http/src/request.rs @@ -28,9 +28,13 @@ use aws_lambda_events::apigw::{ApiGatewayWebsocketProxyRequest, ApiGatewayWebsoc use aws_lambda_events::{encodings::Body, query_map::QueryMap}; use http::{header::HeaderName, HeaderMap, HeaderValue}; -use aws_lambda_json_impl::JsonError; +use aws_lambda_json_impl::{simd_json::ErrorType, JsonError}; use serde::{Deserialize, Serialize}; +#[cfg(feature = "simd_json")] +use crate::deserializer::deserialize; + + use std::{env, future::Future, io::Read, pin::Pin}; use url::Url; @@ -459,11 +463,15 @@ impl RequestContext { /// Ok(println!("{:#?}", request)) /// } /// ``` -pub fn from_reader(rdr: R) -> Result +pub fn from_reader(mut rdr: R) -> Result where R: Read, { - aws_lambda_json_impl::from_reader(rdr).map(LambdaRequest::into) + let mut data = Vec::new(); + if let Err(e) = rdr.read_to_end(&mut data) { + return Err(JsonError::generic(ErrorType::Io(e))); + }; + Ok(deserialize(data.as_mut_slice())?.into()) } /// Deserializes a `Request` from a string of JSON text. @@ -482,10 +490,55 @@ where /// Ok(println!("{:#?}", request)) /// } /// ``` +#[cfg(not(feature = "simd_json"))] pub fn from_str(s: &str) -> Result { aws_lambda_json_impl::from_str(s).map(LambdaRequest::into) } +/// Deserializes a `Request` from a string of JSON text using simd_json +/// +/// # Example +/// +/// ```rust,no_run +/// use lambda_http::request::from_str; +/// use std::fs::File; +/// use std::error::Error; +/// +/// fn main() -> Result<(), Box> { +/// let mut json = r#"{ ...raw json here... }"#.to_owned(); +/// let request = from_str(&mut json)?; +/// Ok(println!("{:#?}", request)) +/// } +/// +/// # SAFETY +/// simd_json requires mutable access to the string slice and may +/// leave the slice with invalid UTF8 data +/// ``` +#[cfg(feature = "simd_json")] +pub unsafe fn from_str(s: &mut str) -> Result { + Ok(deserialize(s.as_bytes_mut())?.into()) +} + +/// Deserializes a `Request` from an owned String of JSON text. +/// +/// # Example +/// +/// ```rust,no_run +/// use lambda_http::request::from_string; +/// use std::fs::File; +/// use std::error::Error; +/// +/// fn main() -> Result<(), Box> { +/// let mut json = r#"{ ...raw json here... }"#.to_owned(); +/// let request = from_str(json); +/// Ok(println!("{:#?}", request)) +/// } +/// ``` +pub fn from_string(s: String) -> Result { + let mut v = s.into_bytes(); + Ok(deserialize(v.as_mut_slice())?.into()) +} + fn x_forwarded_proto() -> HeaderName { HeaderName::from_static("x-forwarded-proto") } @@ -529,6 +582,8 @@ mod tests { use super::*; use crate::ext::RequestExt; use std::fs::File; + #[cfg(feature = "simd_json")] + use aws_lambda_json_impl::simd_json::prelude::ValueAsScalar; #[test] fn deserializes_apigw_request_events_from_readables() { @@ -539,6 +594,7 @@ mod tests { assert!(result.is_ok(), "event was not parsed as expected {result:?}"); } + #[cfg(not(feature = "simd_json"))] #[test] fn deserializes_minimal_apigw_http_request_events() { // from the docs @@ -561,12 +617,41 @@ mod tests { ); } + #[cfg(feature = "simd_json")] + #[test] + fn deserializes_minimal_apigw_http_request_events_with_simd() { + // from the docs + // https://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-api-gateway-request + let mut input = include_str!("../tests/data/apigw_v2_proxy_request_minimal.json").to_owned(); + let result = unsafe{ from_str(&mut input) }; + assert!( + result.is_ok(), + "event was not parsed as expected {result:?} given {input}" //SO not safe to do! + ); + let req = result.expect("failed to parse request"); + assert_eq!(req.method(), "GET"); + assert_eq!(req.uri(), "https://xxx.execute-api.us-east-1.amazonaws.com/"); + + // Ensure this is an APIGWv2 request + let req_context = req.request_context_ref().expect("Request is missing RequestContext"); + assert!( + matches!(req_context, &RequestContext::ApiGatewayV2(_)), + "expected ApiGatewayV2 context, got {req_context:?}" + ); + } + + // + // From here on, for testing, we use the from_string function in order top avoid + // duplicating test sources and having to deal with safety and mutability differences + // between the two JSON parsers we support + // + #[test] fn deserializes_apigw_http_request_events() { // from the docs // https://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-api-gateway-request let input = include_str!("../tests/data/apigw_v2_proxy_request.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event was not parsed as expected {result:?} given {input}" @@ -599,7 +684,7 @@ mod tests { // https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format // https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html let input = include_str!("../tests/data/apigw_proxy_request.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event was not parsed as expected {result:?} given {input}" @@ -624,7 +709,7 @@ mod tests { // from the docs // https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html#urls-payloads let input = include_str!("../tests/data/lambda_function_url_request.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event was not parsed as expected {result:?} given {input}" @@ -657,7 +742,7 @@ mod tests { // from the docs // https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers let input = include_str!("../tests/data/alb_request.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event was not parsed as expected {result:?} given {input}" @@ -682,7 +767,7 @@ mod tests { // from the docs // https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers let input = include_str!("../tests/data/alb_request_encoded_query_parameters.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event was not parsed as expected {result:?} given {input}" @@ -707,7 +792,7 @@ mod tests { // from docs // https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format let input = include_str!("../tests/data/apigw_multi_value_proxy_request.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event is was not parsed as expected {result:?} given {input}" @@ -737,7 +822,7 @@ mod tests { // from docs // https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format let input = include_str!("../tests/data/alb_multi_value_request.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event is was not parsed as expected {result:?} given {input}" @@ -763,7 +848,7 @@ mod tests { // from docs // https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format let input = include_str!("../tests/data/alb_multi_value_request_encoded_query_parameters.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event is was not parsed as expected {result:?} given {input}" @@ -794,7 +879,7 @@ mod tests { // * sam local start-api // * Invoke the API let input = include_str!("../tests/data/apigw_v2_sam_local.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event was not parsed as expected {result:?} given {input}" @@ -808,7 +893,7 @@ mod tests { fn deserialize_apigw_no_host() { // generated from the 'apigateway-aws-proxy' test event template in the Lambda console let input = include_str!("../tests/data/apigw_no_host.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event was not parsed as expected {result:?} given {input}" @@ -822,7 +907,7 @@ mod tests { fn deserialize_alb_no_host() { // generated from ALB health checks let input = include_str!("../tests/data/alb_no_host.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event was not parsed as expected {result:?} given {input}" @@ -836,7 +921,7 @@ mod tests { fn deserialize_apigw_path_with_space() { // generated from ALB health checks let input = include_str!("../tests/data/apigw_request_path_with_space.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event was not parsed as expected {result:?} given {input}" @@ -854,7 +939,7 @@ mod tests { #[test] fn deserializes_apigw_http_request_with_stage_in_path() { let input = include_str!("../tests/data/apigw_v2_proxy_request_with_stage_in_path.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event was not parsed as expected {result:?} given {input}" @@ -880,7 +965,7 @@ mod tests { // from docs // https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format let input = include_str!("../tests/data/apigw_multi_value_proxy_request.json"); - let request = from_str(input).expect("failed to parse request"); + let request = from_string(input.to_owned()).expect("failed to parse request"); let (mut parts, _) = request.into_parts(); #[derive(Deserialize)] @@ -902,7 +987,7 @@ mod tests { use axum_core::extract::FromRequestParts; use axum_extra::extract::Query; let input = include_str!("../tests/data/apigw_v2_proxy_request.json"); - let request = from_str(input).expect("failed to parse request"); + let request = from_string(input.to_owned()).expect("failed to parse request"); let (mut parts, _) = request.into_parts(); #[derive(Deserialize)] @@ -923,7 +1008,7 @@ mod tests { use axum_core::extract::FromRequestParts; use axum_extra::extract::Query; let input = include_str!("../tests/data/alb_multi_value_request.json"); - let request = from_str(input).expect("failed to parse request"); + let request = from_string(input.to_owned()).expect("failed to parse request"); let (mut parts, _) = request.into_parts(); #[derive(Deserialize)] @@ -943,7 +1028,7 @@ mod tests { #[cfg(feature = "apigw_rest")] fn deserializes_request_authorizer() { let input = include_str!("../../lambda-events/src/fixtures/example-apigw-request.json"); - let result = from_str(input); + let result = from_string(input.to_owned()); assert!( result.is_ok(), "event was not parsed as expected {result:?} given {input}" From fbe48028e8d41a3ccaf1641e9012c3afa66e1971 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Thu, 24 Oct 2024 18:38:34 +0200 Subject: [PATCH 21/44] All compile errors "fixed" ... but SERIOUSLY unsafe at the moment At the moment the only way around the deserializer-must-be-simd issue is an unsafe "cast" ... and even the type equivalence check that I tried before that cast will itself not compile, so that is currently commented out. --- .../deserializer/deserializer_simd_json.rs | 106 ++++++++++-------- lambda-http/src/request.rs | 14 +-- lambda-runtime/src/deserializer.rs | 3 + 3 files changed, 68 insertions(+), 55 deletions(-) diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index 018d0f98..aa53b7b8 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -1,3 +1,5 @@ +use std::any::TypeId; + use crate::request::LambdaRequest; #[cfg(feature = "alb")] use aws_lambda_events::alb::AlbTargetGroupRequest; @@ -7,58 +9,72 @@ use aws_lambda_events::apigw::ApiGatewayProxyRequest; use aws_lambda_events::apigw::ApiGatewayV2httpRequest; #[cfg(feature = "apigw_websockets")] use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest; -use aws_lambda_json_impl::JsonError; -use serde::de::Error; +use aws_lambda_json_impl::JsonDeserializer; +use serde::{de::Error, Deserialize}; const ERROR_CONTEXT: &str = "this function expects a JSON payload from Amazon API Gateway, Amazon Elastic Load Balancer, or AWS Lambda Function URLs, but the data doesn't match any of those services' events"; #[cfg(feature = "pass_through")] const PASS_THROUGH_ENABLED: bool = true; + // simd_json and LambdaRequest don't sit well together due to how the request variant is discovered -// simd can't use a real serde deserializer and RawValue technique because simd_json doesn't have a RawValue like that ... wellll... -// if we accept that and do a custom function, we COULD do something similar - but that's a bit time consuming if you support all variants -// but with simd we CAN attempt to look for "marker required properties" in the incoming JSON 'Tape' - what characteristics identify them... - -pub fn deserialize(b: &mut [u8]) -> Result { - let d = aws_lambda_json_impl::JsonDeserializer::from_slice(b)?; - let t = d.into_tape(); - let v = t.as_value(); - - #[cfg(feature = "apigw_rest")] - if let (Some(rc), true) = (v.get_object("request_context"),v.contains_key("http_method")) { - if rc.get("http").is_none() { - let res: ApiGatewayProxyRequest = t.deserialize()?; - return Ok(LambdaRequest::ApiGatewayV1(res)); +// +// To get there, we have to get a bit hacky - we panic if the deserializer we have been offered is not +// a simd_json::Deserializer (please someone show me a better way if there is one!) because we need the +// the Tape from it - THEN we can do some peeking to see what's there and try to deduce the type we are +// looking for. +// +impl<'de> Deserialize<'de> for LambdaRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de> + { + // Firstly we can say 'this is a programming error if this isn't a simd_json::Deserializer. + //if TypeId::of::() != TypeId::of::>() {panic!("Deserializer must be simd_json::Deserializer")}; + + // And now, like a lot of simd_json, we have to venture into the unsafe! + let d = unsafe { std::ptr::read(&deserializer as *const _ as *const JsonDeserializer<'de>) }; + std::mem::forget(deserializer); + + let t = d.into_tape(); + let v = t.as_value(); + + #[cfg(feature = "apigw_rest")] + if let (Some(rc), true) = (v.get_object("request_context"),v.contains_key("http_method")) { + if rc.get("http").is_none() { + let res: ApiGatewayProxyRequest = t.deserialize().map_err(|e|Error::custom(e))?; + return Ok(LambdaRequest::ApiGatewayV1(res)); + } } - } - #[cfg(feature = "apigw_http")] - if let Some(rc) = v.get_object("request_context") { - if rc.get("http").is_some() { - let res: ApiGatewayV2httpRequest = t.deserialize()?; - return Ok(LambdaRequest::ApiGatewayV2(res)); + #[cfg(feature = "apigw_http")] + if let Some(rc) = v.get_object("request_context") { + if rc.get("http").is_some() { + let res: ApiGatewayV2httpRequest = t.deserialize().map_err(|e|Error::custom(e))?; + return Ok(LambdaRequest::ApiGatewayV2(res)); + } } - } - #[cfg(feature = "alb")] - if let Some(rc) = v.get_object("request_context") { - if let Some(_) = rc.get("elb") { - let res: AlbTargetGroupRequest = t.deserialize()?; - return Ok(LambdaRequest::Alb(res)); + #[cfg(feature = "alb")] + if let Some(rc) = v.get_object("request_context") { + if let Some(_) = rc.get("elb") { + let res: AlbTargetGroupRequest = t.deserialize().map_err(|e|Error::custom(e))?; + return Ok(LambdaRequest::Alb(res)); + } + } + #[cfg(feature = "apigw_websockets")] + if v.contains_key("connected_at") { + let res: ApiGatewayWebsocketProxyRequest = t.deserialize().map_err(|e|Error::custom(e))?; + return Ok(LambdaRequest::WebSocket(res)); } - } - #[cfg(feature = "apigw_websockets")] - if v.contains_key("connected_at") { - let res: ApiGatewayWebsocketProxyRequest = t.deserialize()?; - return Ok(LambdaRequest::WebSocket(res)); - } - #[cfg(feature = "pass_through")] - if PASS_THROUGH_ENABLED { - return Ok(LambdaRequest::PassThrough(data.to_string())); - } + #[cfg(feature = "pass_through")] + if PASS_THROUGH_ENABLED { + return Ok(LambdaRequest::PassThrough(data.to_string())); + } - Err(Error::custom(ERROR_CONTEXT)) + Err(Error::custom(ERROR_CONTEXT)) + } } #[cfg(test)] @@ -69,7 +85,7 @@ mod tests { fn test_deserialize_apigw_rest() { let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-request.json").to_vec(); - let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize apigw rest data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize apigw rest data"); match req { LambdaRequest::ApiGatewayV1(req) => { assert_eq!("12345678912", req.request_context.account_id.unwrap()); @@ -82,7 +98,7 @@ mod tests { fn test_deserialize_apigw_http() { let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-v2-request-iam.json").to_vec(); - let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize apigw http data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize apigw http data"); match req { LambdaRequest::ApiGatewayV2(req) => { assert_eq!("123456789012", req.request_context.account_id.unwrap()); @@ -95,7 +111,7 @@ mod tests { fn test_deserialize_sam_rest() { let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-sam-rest-request.json").to_vec(); - let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize SAM rest data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize SAM rest data"); match req { LambdaRequest::ApiGatewayV1(req) => { assert_eq!("123456789012", req.request_context.account_id.unwrap()); @@ -108,7 +124,7 @@ mod tests { fn test_deserialize_sam_http() { let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-sam-http-request.json").to_vec(); - let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize SAM http data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize SAM http data"); match req { LambdaRequest::ApiGatewayV2(req) => { assert_eq!("123456789012", req.request_context.account_id.unwrap()); @@ -123,7 +139,7 @@ mod tests { "../../../lambda-events/src/fixtures/example-alb-lambda-target-request-multivalue-headers.json" ).to_vec(); - let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize alb rest data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize alb rest data"); match req { LambdaRequest::Alb(req) => { assert_eq!( @@ -140,7 +156,7 @@ mod tests { let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json").to_vec(); - let req: LambdaRequest = deserialize(data.as_mut_slice()).expect("failed to deserialize apigw websocket data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize apigw websocket data"); match req { LambdaRequest::WebSocket(req) => { assert_eq!("CONNECT", req.request_context.event_type.unwrap()); diff --git a/lambda-http/src/request.rs b/lambda-http/src/request.rs index b5f37e8c..e3b8625e 100644 --- a/lambda-http/src/request.rs +++ b/lambda-http/src/request.rs @@ -32,8 +32,6 @@ use aws_lambda_json_impl::{simd_json::ErrorType, JsonError}; use serde::{Deserialize, Serialize}; #[cfg(feature = "simd_json")] -use crate::deserializer::deserialize; - use std::{env, future::Future, io::Read, pin::Pin}; use url::Url; @@ -463,15 +461,11 @@ impl RequestContext { /// Ok(println!("{:#?}", request)) /// } /// ``` -pub fn from_reader(mut rdr: R) -> Result +pub fn from_reader(rdr: R) -> Result where R: Read, { - let mut data = Vec::new(); - if let Err(e) = rdr.read_to_end(&mut data) { - return Err(JsonError::generic(ErrorType::Io(e))); - }; - Ok(deserialize(data.as_mut_slice())?.into()) + aws_lambda_json_impl::from_reader(rdr).map(LambdaRequest::into) } /// Deserializes a `Request` from a string of JSON text. @@ -516,7 +510,7 @@ pub fn from_str(s: &str) -> Result { /// ``` #[cfg(feature = "simd_json")] pub unsafe fn from_str(s: &mut str) -> Result { - Ok(deserialize(s.as_bytes_mut())?.into()) + aws_lambda_json_impl::from_str(s).map(LambdaRequest::into) } /// Deserializes a `Request` from an owned String of JSON text. @@ -536,7 +530,7 @@ pub unsafe fn from_str(s: &mut str) -> Result { /// ``` pub fn from_string(s: String) -> Result { let mut v = s.into_bytes(); - Ok(deserialize(v.as_mut_slice())?.into()) + aws_lambda_json_impl::from_slice(v.as_mut_slice()).map(LambdaRequest::into) } fn x_forwarded_proto() -> HeaderName { diff --git a/lambda-runtime/src/deserializer.rs b/lambda-runtime/src/deserializer.rs index 771fb88e..f5f8d284 100644 --- a/lambda-runtime/src/deserializer.rs +++ b/lambda-runtime/src/deserializer.rs @@ -89,7 +89,10 @@ pub(crate) fn deserialize(body: Bytes, context: Context) -> Result Deserialize<'de>, { + //THIS is where we can decide what type of serializer we actually want! aws_lambda_json_impl::from_bytes(body) .map(|payload| LambdaEvent::new(payload, context)) .map_err(|inner| DeserializeError { inner }) } + + From 1893e6a934852f207240136e6b6ef8963b67b62f Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 25 Oct 2024 10:08:44 +0200 Subject: [PATCH 22/44] Explain the unsafe code and the constraints that make it 'safe' --- .../src/deserializer/deserializer_simd_json.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index aa53b7b8..bd9df27c 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -30,10 +30,17 @@ impl<'de> Deserialize<'de> for LambdaRequest { where D: serde::Deserializer<'de> { - // Firstly we can say 'this is a programming error if this isn't a simd_json::Deserializer. + // We can't do this because D is not enforced to be 'static //if TypeId::of::() != TypeId::of::>() {panic!("Deserializer must be simd_json::Deserializer")}; - - // And now, like a lot of simd_json, we have to venture into the unsafe! + + // + // OK, what comes now is as blatant "crash and burn" moment ... IF the deserializer is NOT a simd_json::Deserializer. + // At the moment, I can't find a type-safe way to do this (without a million lines of code that obfuscate the + // intent beyond all comprehension) - HOWEVER... IF we are here, then someone has built us with the feature + // simd_json enabled - which means that all KNOWN invokers have ALSO been built with simd_json enabled - which means + // that this is safe... IF callers ONLY use the standard invokers (i.e. the Lambda Runtime or the standard entry-point + // functions in aws_lambda_json_impl). If not ... well, then you are on your own! + // let d = unsafe { std::ptr::read(&deserializer as *const _ as *const JsonDeserializer<'de>) }; std::mem::forget(deserializer); From 2c26efd21efb347d6944439be433421d0530183b Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 25 Oct 2024 10:32:54 +0200 Subject: [PATCH 23/44] Fixes for when using serde_json --- json-impl/src/lib.rs | 12 ++++++------ .../src/deserializer/deserializer_serde_json.rs | 16 ++++++++-------- lambda-http/src/request.rs | 9 ++++----- lambda-runtime/src/deserializer.rs | 3 ++- lambda-runtime/src/types.rs | 7 +++++-- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index 046ae1a6..c8b2ab47 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -10,31 +10,31 @@ pub use simd::*; #[cfg(not(feature = "simd"))] mod serde { use bytes::Bytes; - use serde::{de::DeserializeOwned, Deserialize}; + use serde::de::DeserializeOwned; pub use serde_json::{ self, error::Error as JsonError, from_reader, from_slice, from_str, from_value, json, to_string, to_string_pretty, to_value, to_writer, value::RawValue, Deserializer as JsonDeserializer, Value, to_vec, }; - pub fn from_bytes<'a, T>(b: Bytes) -> simd_json::Result + pub fn from_bytes(b: Bytes) -> serde_json::Result where T: DeserializeOwned, { - from_slice(&mut b) + from_slice(&b) } - pub fn from_string<'a, T>(s: String) -> simd_json::Result + pub fn from_string(s: String) -> serde_json::Result where T: DeserializeOwned, { from_str(s.as_str()) } - pub fn from_vec<'a, T>(mut v: Vec) -> simd_json::Result + pub fn from_vec(v: Vec) -> serde_json::Result where T: DeserializeOwned, { - from_slice(&mut v) + from_slice(&v) } } diff --git a/lambda-http/src/deserializer/deserializer_serde_json.rs b/lambda-http/src/deserializer/deserializer_serde_json.rs index 11991f52..158e2344 100644 --- a/lambda-http/src/deserializer/deserializer_serde_json.rs +++ b/lambda-http/src/deserializer/deserializer_serde_json.rs @@ -54,7 +54,7 @@ mod tests { #[test] fn test_deserialize_apigw_rest() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-request.json"); + let data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-request.json"); let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw rest data"); match req { @@ -67,7 +67,7 @@ mod tests { #[test] fn test_deserialize_apigw_http() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-v2-request-iam.json"); + let data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-v2-request-iam.json"); let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw http data"); match req { @@ -80,7 +80,7 @@ mod tests { #[test] fn test_deserialize_sam_rest() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-sam-rest-request.json"); + let data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-sam-rest-request.json"); let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize SAM rest data"); match req { @@ -93,7 +93,7 @@ mod tests { #[test] fn test_deserialize_sam_http() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-sam-http-request.json"); + let data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-sam-http-request.json"); let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize SAM http data"); match req { @@ -107,7 +107,7 @@ mod tests { #[test] fn test_deserialize_alb() { let data = include_bytes!( - "../../lambda-events/src/fixtures/example-alb-lambda-target-request-multivalue-headers.json" + "../../../lambda-events/src/fixtures/example-alb-lambda-target-request-multivalue-headers.json" ); let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize alb rest data"); @@ -125,7 +125,7 @@ mod tests { #[test] fn test_deserialize_apigw_websocket() { let data = - include_bytes!("../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json"); + include_bytes!("../../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json"); let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw websocket data"); match req { @@ -139,7 +139,7 @@ mod tests { #[test] #[cfg(feature = "pass_through")] fn test_deserialize_bedrock_agent() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-bedrock-agent-runtime-event.json"); + let data = include_bytes!("../../../lambda-events/src/fixtures/example-bedrock-agent-runtime-event.json"); let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize bedrock agent request data"); @@ -154,7 +154,7 @@ mod tests { #[test] #[cfg(feature = "pass_through")] fn test_deserialize_sqs() { - let data = include_bytes!("../../lambda-events/src/fixtures/example-sqs-event.json"); + let data = include_bytes!("../../../lambda-events/src/fixtures/example-sqs-event.json"); let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize sqs event data"); match req { diff --git a/lambda-http/src/request.rs b/lambda-http/src/request.rs index e3b8625e..b8fd7126 100644 --- a/lambda-http/src/request.rs +++ b/lambda-http/src/request.rs @@ -27,14 +27,13 @@ use aws_lambda_events::apigw::{ApiGatewayV2httpRequest, ApiGatewayV2httpRequestC use aws_lambda_events::apigw::{ApiGatewayWebsocketProxyRequest, ApiGatewayWebsocketProxyRequestContext}; use aws_lambda_events::{encodings::Body, query_map::QueryMap}; use http::{header::HeaderName, HeaderMap, HeaderValue}; - -use aws_lambda_json_impl::{simd_json::ErrorType, JsonError}; use serde::{Deserialize, Serialize}; - -#[cfg(feature = "simd_json")] - use std::{env, future::Future, io::Read, pin::Pin}; use url::Url; +use aws_lambda_json_impl::JsonError; + +#[cfg(feature = "simd_json")] +use aws_lambda_json_impl::simd_json::ErrorType; /// Internal representation of an Lambda http event from /// ALB, API Gateway REST and HTTP API proxy event perspectives diff --git a/lambda-runtime/src/deserializer.rs b/lambda-runtime/src/deserializer.rs index f5f8d284..4cdb0457 100644 --- a/lambda-runtime/src/deserializer.rs +++ b/lambda-runtime/src/deserializer.rs @@ -78,7 +78,8 @@ pub(crate) fn deserialize(body: Bytes, context: Context) -> Result Deserialize<'de>, { - let jd = &mut aws_lambda_json_impl::from_bytes(body); + use aws_lambda_json_impl::JsonDeserializer; + let jd = &mut JsonDeserializer::from_slice(&body); serde_path_to_error::deserialize(jd) .map(|payload| LambdaEvent::new(payload, context)) .map_err(|inner| DeserializeError { inner }) diff --git a/lambda-runtime/src/types.rs b/lambda-runtime/src/types.rs index b5511cec..f01c412a 100644 --- a/lambda-runtime/src/types.rs +++ b/lambda-runtime/src/types.rs @@ -3,7 +3,10 @@ use base64::prelude::*; use bytes::Bytes; use http::{header::ToStrError, HeaderMap, HeaderValue, StatusCode}; use lambda_runtime_api_client::body::Body; -use serde::{Deserialize, Serialize, de::DeserializeOwned}; +use serde::{Deserialize, Serialize}; +#[cfg(feature = "simd_json")] +use serde::de::DeserializeOwned; + use std::{ collections::HashMap, fmt::Debug, @@ -103,7 +106,7 @@ impl Default for Context { #[cfg(not(feature = "simd_json"))] fn parse_header<'a,T>(h: &'a HeaderValue) -> Result where T: Deserialize<'a> { - aws_lambda_json_impl::from_str(h.to_str()?)? + aws_lambda_json_impl::from_slice(h.as_bytes()) } #[cfg(feature = "simd_json")] From 4c0a2ee818737909d415782796687393a657d8ab Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 25 Oct 2024 10:50:03 +0200 Subject: [PATCH 24/44] Clippy lints for simd_json code --- json-impl/Cargo.toml | 5 ++--- json-impl/src/lib.rs | 6 +++--- .../src/deserializer/deserializer_simd_json.rs | 12 +++++------- lambda-http/src/request.rs | 11 +++++------ 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 1f747a55..18cb3132 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -19,8 +19,7 @@ simd = [ "simd-json/ordered-float" ] [dependencies] serde_json = { version = "^1", features = ["raw_value"] } -simd-json = { version = "^0", optional = true } +#simd-json = { version = "^0", optional = true } +simd-json = { git = "https://github.com/bassmanitram/simd-json", branch = "serde-json-error-checks", optional = true } bytes = { workspace = true } serde = { version = "^1", no-default-features = true } - - diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index c8b2ab47..30603914 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -62,7 +62,7 @@ mod simd { Error as JsonError, }; - pub fn from_bytes<'a, T>(b: Bytes) -> simd_json::Result + pub fn from_bytes(b: Bytes) -> simd_json::Result where T: DeserializeOwned, { @@ -75,14 +75,14 @@ mod simd { } } - pub fn from_string<'a, T>(mut s: String) -> simd_json::Result + pub fn from_string(mut s: String) -> simd_json::Result where T: DeserializeOwned, { unsafe{ from_str(s.as_mut_str()) } } - pub fn from_vec<'a, T>(mut v: Vec) -> simd_json::Result + pub fn from_vec(mut v: Vec) -> simd_json::Result where T: DeserializeOwned, { diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index bd9df27c..975627de 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -1,5 +1,3 @@ -use std::any::TypeId; - use crate::request::LambdaRequest; #[cfg(feature = "alb")] use aws_lambda_events::alb::AlbTargetGroupRequest; @@ -50,27 +48,27 @@ impl<'de> Deserialize<'de> for LambdaRequest { #[cfg(feature = "apigw_rest")] if let (Some(rc), true) = (v.get_object("request_context"),v.contains_key("http_method")) { if rc.get("http").is_none() { - let res: ApiGatewayProxyRequest = t.deserialize().map_err(|e|Error::custom(e))?; + let res: ApiGatewayProxyRequest = t.deserialize().map_err(Error::custom)?; return Ok(LambdaRequest::ApiGatewayV1(res)); } } #[cfg(feature = "apigw_http")] if let Some(rc) = v.get_object("request_context") { if rc.get("http").is_some() { - let res: ApiGatewayV2httpRequest = t.deserialize().map_err(|e|Error::custom(e))?; + let res: ApiGatewayV2httpRequest = t.deserialize().map_err(Error::custom)?; return Ok(LambdaRequest::ApiGatewayV2(res)); } } #[cfg(feature = "alb")] if let Some(rc) = v.get_object("request_context") { - if let Some(_) = rc.get("elb") { - let res: AlbTargetGroupRequest = t.deserialize().map_err(|e|Error::custom(e))?; + if rc.get("elb").is_some() { + let res: AlbTargetGroupRequest = t.deserialize().map_err(Error::custom)?; return Ok(LambdaRequest::Alb(res)); } } #[cfg(feature = "apigw_websockets")] if v.contains_key("connected_at") { - let res: ApiGatewayWebsocketProxyRequest = t.deserialize().map_err(|e|Error::custom(e))?; + let res: ApiGatewayWebsocketProxyRequest = t.deserialize().map_err(Error::custom)?; return Ok(LambdaRequest::WebSocket(res)); } diff --git a/lambda-http/src/request.rs b/lambda-http/src/request.rs index b8fd7126..5cc56969 100644 --- a/lambda-http/src/request.rs +++ b/lambda-http/src/request.rs @@ -32,9 +32,6 @@ use std::{env, future::Future, io::Read, pin::Pin}; use url::Url; use aws_lambda_json_impl::JsonError; -#[cfg(feature = "simd_json")] -use aws_lambda_json_impl::simd_json::ErrorType; - /// Internal representation of an Lambda http event from /// ALB, API Gateway REST and HTTP API proxy event perspectives /// @@ -502,11 +499,13 @@ pub fn from_str(s: &str) -> Result { /// let request = from_str(&mut json)?; /// Ok(println!("{:#?}", request)) /// } +/// ``` +/// +/// # Safety /// -/// # SAFETY /// simd_json requires mutable access to the string slice and may -/// leave the slice with invalid UTF8 data -/// ``` +/// leave the slice with invalid UTF8 data. +/// #[cfg(feature = "simd_json")] pub unsafe fn from_str(s: &mut str) -> Result { aws_lambda_json_impl::from_str(s).map(LambdaRequest::into) From bd6a3d87ba771a4af6cb69d7c55e06c14b4ce721 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 25 Oct 2024 10:58:26 +0200 Subject: [PATCH 25/44] Test fixes and clippy lints --- lambda-events/src/custom_serde/mod.rs | 18 ++++++++---------- lambda-events/src/event/cognito/mod.rs | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/lambda-events/src/custom_serde/mod.rs b/lambda-events/src/custom_serde/mod.rs index 63352af2..98ed8a81 100644 --- a/lambda-events/src/custom_serde/mod.rs +++ b/lambda-events/src/custom_serde/mod.rs @@ -97,8 +97,6 @@ where #[cfg(test)] #[allow(deprecated)] mod test { - use std::str::FromStr; - use super::*; use serde::{Deserialize, Serialize}; @@ -181,19 +179,19 @@ mod test { } let test = r#"{"v": null}"#; - let decoded: Test = aws_lambda_json_impl::from_str(&test).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); assert!(!decoded.v); let test = r#"{}"#; - let decoded: Test = aws_lambda_json_impl::from_str(&test).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); assert!(!decoded.v); let test = r#"{"v": true}"#; - let decoded: Test = aws_lambda_json_impl::from_str(&test).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); assert!(decoded.v); let test = r#"{"v": false}"#; - let decoded: Test = aws_lambda_json_impl::from_str(&test).unwrap(); + let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap(); assert!(!decoded.v); } #[cfg(feature = "simd_json")] @@ -209,19 +207,19 @@ mod test { v: bool, } - let test = String::from_str(r#"{"v": null}"#).unwrap(); + let test = r#"{"v": null}"#.to_owned(); let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap(); assert!(!decoded.v); - let test = String::from_str(r#"{}"#).unwrap(); + let test = r#"{}"#.to_owned(); let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap(); assert!(!decoded.v); - let test = String::from_str(r#"{"v": true}"#).unwrap(); + let test = r#"{"v": true}"#.to_owned(); let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap(); assert!(decoded.v); - let test = String::from_str(r#"{"v": false}"#).unwrap(); + let test = r#"{"v": false}"#.to_owned(); let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap(); assert!(!decoded.v); } diff --git a/lambda-events/src/event/cognito/mod.rs b/lambda-events/src/event/cognito/mod.rs index 61ec415e..aae7dd9e 100644 --- a/lambda-events/src/event/cognito/mod.rs +++ b/lambda-events/src/event/cognito/mod.rs @@ -937,7 +937,7 @@ mod trigger_source_tests { "PreSignUp_ExternalProvider", ]; possible_triggers.into_iter().for_each(|trigger| { - let mut header = gen_header(trigger); + let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); @@ -951,7 +951,7 @@ mod trigger_source_tests { fn pre_authentication() { let possible_triggers = ["PreAuthentication_Authentication"]; possible_triggers.into_iter().for_each(|trigger| { - let mut header = gen_header(trigger); + let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); @@ -968,7 +968,7 @@ mod trigger_source_tests { ]; possible_triggers.into_iter().for_each(|trigger| { - let mut header = gen_header(trigger); + let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); @@ -982,7 +982,7 @@ mod trigger_source_tests { let possible_triggers = ["PostAuthentication_Authentication"]; possible_triggers.into_iter().for_each(|trigger| { - let mut header = gen_header(trigger); + let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); @@ -996,7 +996,7 @@ mod trigger_source_tests { let possible_triggers = ["DefineAuthChallenge_Authentication"]; possible_triggers.into_iter().for_each(|trigger| { - let mut header = gen_header(trigger); + let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); @@ -1011,7 +1011,7 @@ mod trigger_source_tests { let possible_triggers = ["CreateAuthChallenge_Authentication"]; possible_triggers.into_iter().for_each(|trigger| { - let mut header = gen_header(trigger); + let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); @@ -1025,7 +1025,7 @@ mod trigger_source_tests { let possible_triggers = ["VerifyAuthChallengeResponse_Authentication"]; possible_triggers.into_iter().for_each(|trigger| { - let mut header = gen_header(trigger); + let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); @@ -1045,7 +1045,7 @@ mod trigger_source_tests { ]; possible_triggers.into_iter().for_each(|trigger| { - let mut header = gen_header(trigger); + let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); @@ -1059,7 +1059,7 @@ mod trigger_source_tests { let possible_triggers = ["UserMigration_Authentication", "UserMigration_ForgotPassword"]; possible_triggers.into_iter().for_each(|trigger| { - let mut header = gen_header(trigger); + let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); @@ -1081,7 +1081,7 @@ mod trigger_source_tests { ]; possible_triggers.into_iter().for_each(|trigger| { - let mut header = gen_header(trigger); + let header = gen_header(trigger); let parsed: CognitoEventUserPoolsHeader = aws_lambda_json_impl::from_string(header).unwrap(); let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes(); From 05483172ca686f4dadf03caddc5c9ffbcf53c520 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 25 Oct 2024 11:06:50 +0200 Subject: [PATCH 26/44] MARKER: All original tests work in serde_json mode From 72e3636f99520f7164d846b4f5047b68af506d2e Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 25 Oct 2024 12:36:15 +0200 Subject: [PATCH 27/44] Doc and change simd_json provenance --- json-impl/Cargo.toml | 2 +- .../src/deserializer/deserializer_simd_json.rs | 18 ++++++++++++------ lambda-runtime/src/deserializer.rs | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 18cb3132..7582c86c 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -20,6 +20,6 @@ simd = [ "simd-json/ordered-float" ] [dependencies] serde_json = { version = "^1", features = ["raw_value"] } #simd-json = { version = "^0", optional = true } -simd-json = { git = "https://github.com/bassmanitram/simd-json", branch = "serde-json-error-checks", optional = true } +simd-json = { git = "https://github.com/simd-lite/simd-json", branch = "main", optional = true } bytes = { workspace = true } serde = { version = "^1", no-default-features = true } diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index 975627de..1e2b293a 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -32,12 +32,18 @@ impl<'de> Deserialize<'de> for LambdaRequest { //if TypeId::of::() != TypeId::of::>() {panic!("Deserializer must be simd_json::Deserializer")}; // - // OK, what comes now is as blatant "crash and burn" moment ... IF the deserializer is NOT a simd_json::Deserializer. - // At the moment, I can't find a type-safe way to do this (without a million lines of code that obfuscate the - // intent beyond all comprehension) - HOWEVER... IF we are here, then someone has built us with the feature - // simd_json enabled - which means that all KNOWN invokers have ALSO been built with simd_json enabled - which means - // that this is safe... IF callers ONLY use the standard invokers (i.e. the Lambda Runtime or the standard entry-point - // functions in aws_lambda_json_impl). If not ... well, then you are on your own! + // OK, what comes next is a blatant "THIS is gonna crash" moment ... IF the deserializer is NOT a simd_json::Deserializer. + // At the moment, I can't find a type-safe way to check the Deserializer implementation (without a million lines of code + // that obfuscate the simple intent beyond all comprehension). + // + // HOWEVER... IF we are here, then someone has built us with the simd_json feature enabled - which means that all KNOWN + // invokers have ALSO been built with simd_json enabled - which means that this is safe... IF users ONLY exploit the standard + // invokers (i.e. the Lambda Runtime or the standard entry-point functions in aws_lambda_json_impl). + // + // If not ... well, then they are on their own! + // + // TODO: Find an economical way to safely type-check and "cast" the deserializer because, while + // this works, because Deserializer is not object safe, the "cast" requires a move. // let d = unsafe { std::ptr::read(&deserializer as *const _ as *const JsonDeserializer<'de>) }; std::mem::forget(deserializer); diff --git a/lambda-runtime/src/deserializer.rs b/lambda-runtime/src/deserializer.rs index 4cdb0457..41c0e5c4 100644 --- a/lambda-runtime/src/deserializer.rs +++ b/lambda-runtime/src/deserializer.rs @@ -90,7 +90,7 @@ pub(crate) fn deserialize(body: Bytes, context: Context) -> Result Deserialize<'de>, { - //THIS is where we can decide what type of serializer we actually want! + //TODO: Find a way to make serde_path_to_json work aws_lambda_json_impl::from_bytes(body) .map(|payload| LambdaEvent::new(payload, context)) .map_err(|inner| DeserializeError { inner }) From bcf29ef60c665fbfb601b5669818835797059fc3 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 25 Oct 2024 12:38:53 +0200 Subject: [PATCH 28/44] MARKER: All but one test passed in simd_json mode! From ebf675fe88b51778356676aec561bb4e9202b614 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 25 Oct 2024 12:53:33 +0200 Subject: [PATCH 29/44] All tests work... And this mod was proof that simd_json does, indeed, mess with the source slice! Docs on switching to simd_json will need to make that very clear. --- lambda-events/src/event/sns/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lambda-events/src/event/sns/mod.rs b/lambda-events/src/event/sns/mod.rs index b4d1e734..36bc2e6b 100644 --- a/lambda-events/src/event/sns/mod.rs +++ b/lambda-events/src/event/sns/mod.rs @@ -279,6 +279,7 @@ mod test { fn my_example_sns_event_cloudwatch_single_metric() { let mut data = include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-single-metric.json").to_vec(); + let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap(); assert_eq!(1, parsed.records.len()); @@ -286,6 +287,13 @@ mod test { let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap(); assert_eq!(parsed, reparsed); + // + // Without this, the test fails when using simd_json - precisely because simd_json needs a + // MUTABLE reference and it WILL modify the slice! + // + let mut data = + include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-single-metric.json").to_vec(); + let parsed: SnsEventObj = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to parse CloudWatch Alarm payload"); From 353d14eb2548162cf873830e354403dfe9e341e3 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 25 Oct 2024 18:19:27 +0200 Subject: [PATCH 30/44] MARKER: serde_json mode works with no adverse affect on performance From bbc41da30e01c554c75a396d374f066036db2026 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 25 Oct 2024 18:29:54 +0200 Subject: [PATCH 31/44] Add debugging simd_json http request deserialization isn't working from external caller --- lambda-http/Cargo.toml | 1 + .../src/deserializer/deserializer_simd_json.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/lambda-http/Cargo.toml b/lambda-http/Cargo.toml index fb2583ff..6a2d48a0 100644 --- a/lambda-http/Cargo.toml +++ b/lambda-http/Cargo.toml @@ -48,6 +48,7 @@ aws_lambda_json_impl = { path = "../json-impl" } serde_urlencoded = "0.7" tokio-stream = "0.1.2" url = "2.2" +tracing = "0" [dependencies.aws_lambda_events] path = "../lambda-events" diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index 1e2b293a..6ff08768 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -9,6 +9,7 @@ use aws_lambda_events::apigw::ApiGatewayV2httpRequest; use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest; use aws_lambda_json_impl::JsonDeserializer; use serde::{de::Error, Deserialize}; +use tracing::debug; const ERROR_CONTEXT: &str = "this function expects a JSON payload from Amazon API Gateway, Amazon Elastic Load Balancer, or AWS Lambda Function URLs, but the data doesn't match any of those services' events"; @@ -28,6 +29,7 @@ impl<'de> Deserialize<'de> for LambdaRequest { where D: serde::Deserializer<'de> { + // We can't do this because D is not enforced to be 'static //if TypeId::of::() != TypeId::of::>() {panic!("Deserializer must be simd_json::Deserializer")}; @@ -45,15 +47,20 @@ impl<'de> Deserialize<'de> for LambdaRequest { // TODO: Find an economical way to safely type-check and "cast" the deserializer because, while // this works, because Deserializer is not object safe, the "cast" requires a move. // + debug!("Deserializing event into some sort of HTTP event - going unsafe..."); let d = unsafe { std::ptr::read(&deserializer as *const _ as *const JsonDeserializer<'de>) }; std::mem::forget(deserializer); + debug!("Back from unsafe..."); + debug!("Getting the tape"); let t = d.into_tape(); + debug!("Getting the value"); let v = t.as_value(); #[cfg(feature = "apigw_rest")] if let (Some(rc), true) = (v.get_object("request_context"),v.contains_key("http_method")) { if rc.get("http").is_none() { + debug!("Parsing REST API request"); let res: ApiGatewayProxyRequest = t.deserialize().map_err(Error::custom)?; return Ok(LambdaRequest::ApiGatewayV1(res)); } @@ -61,6 +68,7 @@ impl<'de> Deserialize<'de> for LambdaRequest { #[cfg(feature = "apigw_http")] if let Some(rc) = v.get_object("request_context") { if rc.get("http").is_some() { + debug!("Parsing HTTP API request"); let res: ApiGatewayV2httpRequest = t.deserialize().map_err(Error::custom)?; return Ok(LambdaRequest::ApiGatewayV2(res)); } @@ -68,21 +76,25 @@ impl<'de> Deserialize<'de> for LambdaRequest { #[cfg(feature = "alb")] if let Some(rc) = v.get_object("request_context") { if rc.get("elb").is_some() { + debug!("Parsing ALB request"); let res: AlbTargetGroupRequest = t.deserialize().map_err(Error::custom)?; return Ok(LambdaRequest::Alb(res)); } } #[cfg(feature = "apigw_websockets")] if v.contains_key("connected_at") { + debug!("Parsing WebSocket request"); let res: ApiGatewayWebsocketProxyRequest = t.deserialize().map_err(Error::custom)?; return Ok(LambdaRequest::WebSocket(res)); } #[cfg(feature = "pass_through")] if PASS_THROUGH_ENABLED { + debug!("Defaulting to pass_through"); return Ok(LambdaRequest::PassThrough(data.to_string())); } + debug!("Failed to find a candidate request type"); Err(Error::custom(ERROR_CONTEXT)) } From 2935c9f9ac565cf413facc761a8f23f66d73b2bd Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Fri, 25 Oct 2024 18:32:34 +0200 Subject: [PATCH 32/44] More debug --- lambda-http/src/deserializer/deserializer_simd_json.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index 6ff08768..9a4a9eeb 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -56,6 +56,7 @@ impl<'de> Deserialize<'de> for LambdaRequest { let t = d.into_tape(); debug!("Getting the value"); let v = t.as_value(); + debug!("Establishing the event type"); #[cfg(feature = "apigw_rest")] if let (Some(rc), true) = (v.get_object("request_context"),v.contains_key("http_method")) { From 4e0c417a531256c25b4fcbdd6a74894eced2af2f Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Sat, 26 Oct 2024 20:25:59 +0200 Subject: [PATCH 33/44] Yeah, that didn't work AT ALL - literal crash! --- .../deserializer/deserializer_simd_json.rs | 28 +------------------ 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index 9a4a9eeb..f78192e2 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -30,32 +30,6 @@ impl<'de> Deserialize<'de> for LambdaRequest { D: serde::Deserializer<'de> { - // We can't do this because D is not enforced to be 'static - //if TypeId::of::() != TypeId::of::>() {panic!("Deserializer must be simd_json::Deserializer")}; - - // - // OK, what comes next is a blatant "THIS is gonna crash" moment ... IF the deserializer is NOT a simd_json::Deserializer. - // At the moment, I can't find a type-safe way to check the Deserializer implementation (without a million lines of code - // that obfuscate the simple intent beyond all comprehension). - // - // HOWEVER... IF we are here, then someone has built us with the simd_json feature enabled - which means that all KNOWN - // invokers have ALSO been built with simd_json enabled - which means that this is safe... IF users ONLY exploit the standard - // invokers (i.e. the Lambda Runtime or the standard entry-point functions in aws_lambda_json_impl). - // - // If not ... well, then they are on their own! - // - // TODO: Find an economical way to safely type-check and "cast" the deserializer because, while - // this works, because Deserializer is not object safe, the "cast" requires a move. - // - debug!("Deserializing event into some sort of HTTP event - going unsafe..."); - let d = unsafe { std::ptr::read(&deserializer as *const _ as *const JsonDeserializer<'de>) }; - std::mem::forget(deserializer); - debug!("Back from unsafe..."); - - debug!("Getting the tape"); - let t = d.into_tape(); - debug!("Getting the value"); - let v = t.as_value(); debug!("Establishing the event type"); #[cfg(feature = "apigw_rest")] @@ -162,7 +136,7 @@ mod tests { let mut data = include_bytes!( "../../../lambda-events/src/fixtures/example-alb-lambda-target-request-multivalue-headers.json" ).to_vec(); - + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize alb rest data"); match req { LambdaRequest::Alb(req) => { From 4ab9c3ccdcee85a5d7b01a379cec944321af3922 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Mon, 28 Oct 2024 10:28:33 +0100 Subject: [PATCH 34/44] The unsafe cast that works (using proposed features of simd_json) Turns out I was casting to the wrong thing --- json-impl/Cargo.toml | 2 +- .../deserializer/deserializer_simd_json.rs | 67 ++++++++++++------- lambda-http/src/ext/request.rs | 4 +- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 7582c86c..4977c1b1 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -20,6 +20,6 @@ simd = [ "simd-json/ordered-float" ] [dependencies] serde_json = { version = "^1", features = ["raw_value"] } #simd-json = { version = "^0", optional = true } -simd-json = { git = "https://github.com/simd-lite/simd-json", branch = "main", optional = true } +simd-json = { git = "https://github.com/bassmanitram/simd-json", branch = "deser-as-value", optional = true } bytes = { workspace = true } serde = { version = "^1", no-default-features = true } diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index f78192e2..7c685edc 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -30,48 +30,69 @@ impl<'de> Deserialize<'de> for LambdaRequest { D: serde::Deserializer<'de> { + // We can't do this because D is not enforced to be 'static + //if TypeId::of::() != TypeId::of::>() {panic!("Deserializer must be simd_json::Deserializer")}; + + // + // There is a future feature of simd_json being considered that is very similar to serde_json's RawValue - effectively a + // Deserializer-implementation-specific way of introspecting/peeking at the parsed JSON before continuing with deserialization. + // That's what the serde_json implementation of this uses, but, for now we have to resort to some wildly unsafe code in order + // to cast the incoming D to &mut simd_json::Deserializer. AND we don't "forget" the incoming value either because we need THAT + // to pass to our sub-deserialize attempts! + // + // HOWEVER... IF we are here, then someone has built this code with the simd_json feature enabled - which means that all KNOWN + // invokers have ALSO been built with simd_json enabled - which means that this is, in fact, "safe"... IF users ONLY exploit the + // standard invokers (i.e. the Lambda Runtime or the standard entry-point functions in aws_lambda_json_impl). + // + // If not ... well, expect bad things to happen! + // + debug!("Deserializing event into some sort of HTTP event - going unsafe..."); + let d = unsafe { std::ptr::read_unaligned(&deserializer as *const _ as *mut &mut JsonDeserializer<'de>) }; +// std::mem::forget(deserializer); We need deserializer - otherwise we have to Box the Deserialize dyn when casting back and using for deserialize calls + debug!("Getting the value"); + let v = d.as_value(); debug!("Establishing the event type"); + let (http_context, alb_context, websocket_context) = if let Some(rc) = v.get("requestContext") { + (rc.contains_key("http"), rc.contains_key("elb"), rc.contains_key("connectedAt")) + } else { + (false, false, false) + }; + d.restart(); + #[cfg(feature = "apigw_rest")] - if let (Some(rc), true) = (v.get_object("request_context"),v.contains_key("http_method")) { - if rc.get("http").is_none() { - debug!("Parsing REST API request"); - let res: ApiGatewayProxyRequest = t.deserialize().map_err(Error::custom)?; - return Ok(LambdaRequest::ApiGatewayV1(res)); - } + if !(http_context || alb_context || websocket_context) { + debug!("Parsing REST API request"); + return ApiGatewayProxyRequest::deserialize(deserializer).map_err(Error::custom).map(LambdaRequest::ApiGatewayV1); } + #[cfg(feature = "apigw_http")] - if let Some(rc) = v.get_object("request_context") { - if rc.get("http").is_some() { - debug!("Parsing HTTP API request"); - let res: ApiGatewayV2httpRequest = t.deserialize().map_err(Error::custom)?; - return Ok(LambdaRequest::ApiGatewayV2(res)); - } + if http_context { + debug!("Parsing HTTP API request"); + return ApiGatewayV2httpRequest::deserialize(deserializer).map_err(Error::custom).map(LambdaRequest::ApiGatewayV2); } + #[cfg(feature = "alb")] - if let Some(rc) = v.get_object("request_context") { - if rc.get("elb").is_some() { - debug!("Parsing ALB request"); - let res: AlbTargetGroupRequest = t.deserialize().map_err(Error::custom)?; - return Ok(LambdaRequest::Alb(res)); - } + if alb_context { + debug!("Parsing ALB request"); + return AlbTargetGroupRequest::deserialize(deserializer).map_err(Error::custom).map(LambdaRequest::Alb); } + #[cfg(feature = "apigw_websockets")] - if v.contains_key("connected_at") { + if websocket_context { debug!("Parsing WebSocket request"); - let res: ApiGatewayWebsocketProxyRequest = t.deserialize().map_err(Error::custom)?; - return Ok(LambdaRequest::WebSocket(res)); + return ApiGatewayWebsocketProxyRequest::deserialize(deserializer).map_err(Error::custom).map(LambdaRequest::WebSocket); } +/* Can't support this yet #[cfg(feature = "pass_through")] if PASS_THROUGH_ENABLED { debug!("Defaulting to pass_through"); return Ok(LambdaRequest::PassThrough(data.to_string())); } - + */ debug!("Failed to find a candidate request type"); Err(Error::custom(ERROR_CONTEXT)) - } } diff --git a/lambda-http/src/ext/request.rs b/lambda-http/src/ext/request.rs index 706335ed..ac27caba 100644 --- a/lambda-http/src/ext/request.rs +++ b/lambda-http/src/ext/request.rs @@ -527,7 +527,7 @@ mod tests { assert!(payload.is_err()); if let Err(JsonPayloadError::Parsing(err)) = payload { - assert!(err.is_syntax()) + assert!(err.is_syntax(), "Error should be syntax: {:?}", err) } else { panic!( "{}", @@ -544,7 +544,7 @@ mod tests { let result = request.json::(); if let Err(JsonPayloadError::Parsing(err)) = result { - assert!(err.is_data()) + assert!(err.is_data(), "Error should be data: {:?}", err) } else { panic!( "{}", From 23e59509a410282b56abae7e34dc7962dbb922e0 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Mon, 28 Oct 2024 10:31:06 +0100 Subject: [PATCH 35/44] MARKER: Tests work for HTTP request deserialization via simd_json From 08dd1b012248c958b8ac9697fe9d57d699676f85 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Mon, 28 Oct 2024 11:34:00 +0100 Subject: [PATCH 36/44] Remove explicit simd_json source Using local patch instead --- json-impl/Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 4977c1b1..9f7a0e79 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -19,7 +19,6 @@ simd = [ "simd-json/ordered-float" ] [dependencies] serde_json = { version = "^1", features = ["raw_value"] } -#simd-json = { version = "^0", optional = true } -simd-json = { git = "https://github.com/bassmanitram/simd-json", branch = "deser-as-value", optional = true } +simd-json = { version = "^0", optional = true } bytes = { workspace = true } serde = { version = "^1", no-default-features = true } From 49506998874c1d4cdcd7ae9d9636c438164e03e3 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Mon, 28 Oct 2024 11:34:48 +0100 Subject: [PATCH 37/44] MARKER: Local integration tests work From 614b8a3445ebd721ee3c882e8f588a2e6d3c73a0 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Mon, 28 Oct 2024 11:47:07 +0100 Subject: [PATCH 38/44] fix doc tests --- lambda-http/src/request.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lambda-http/src/request.rs b/lambda-http/src/request.rs index 5cc56969..58ca664d 100644 --- a/lambda-http/src/request.rs +++ b/lambda-http/src/request.rs @@ -496,7 +496,7 @@ pub fn from_str(s: &str) -> Result { /// /// fn main() -> Result<(), Box> { /// let mut json = r#"{ ...raw json here... }"#.to_owned(); -/// let request = from_str(&mut json)?; +/// let request = unsafe{ from_str(&mut json) }?; /// Ok(println!("{:#?}", request)) /// } /// ``` @@ -522,7 +522,7 @@ pub unsafe fn from_str(s: &mut str) -> Result { /// /// fn main() -> Result<(), Box> { /// let mut json = r#"{ ...raw json here... }"#.to_owned(); -/// let request = from_str(json); +/// let request = from_string(json); /// Ok(println!("{:#?}", request)) /// } /// ``` From 7b2f0bb5e1b9ebccdb148d55be18df339b022c6c Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Mon, 28 Oct 2024 14:28:25 +0100 Subject: [PATCH 39/44] A bit more debugging --- json-impl/Cargo.toml | 3 ++- lambda-http/src/deserializer/deserializer_simd_json.rs | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 9f7a0e79..44b34c8a 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -19,6 +19,7 @@ simd = [ "simd-json/ordered-float" ] [dependencies] serde_json = { version = "^1", features = ["raw_value"] } -simd-json = { version = "^0", optional = true } +#simd-json = { version = "^0", optional = true } +simd-json = { git = "https://github.com/bassmanitram/simd-json.git", branch = "deser-as-value", optional = true } bytes = { workspace = true } serde = { version = "^1", no-default-features = true } diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index 7c685edc..e5c2e0e2 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -49,7 +49,9 @@ impl<'de> Deserialize<'de> for LambdaRequest { debug!("Deserializing event into some sort of HTTP event - going unsafe..."); let d = unsafe { std::ptr::read_unaligned(&deserializer as *const _ as *mut &mut JsonDeserializer<'de>) }; // std::mem::forget(deserializer); We need deserializer - otherwise we have to Box the Deserialize dyn when casting back and using for deserialize calls - debug!("Getting the value"); + + + debug!("Getting the value from d: {:?}", d); let v = d.as_value(); debug!("Establishing the event type"); @@ -58,7 +60,9 @@ impl<'de> Deserialize<'de> for LambdaRequest { } else { (false, false, false) }; + debug!("State of d before restart: {:?}", d); d.restart(); + debug!("State of d after restart: {:?}", d); #[cfg(feature = "apigw_rest")] if !(http_context || alb_context || websocket_context) { From 1f3f984ada274bbd0c9285d00bdccbc15f1b39c9 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Mon, 28 Oct 2024 14:37:46 +0100 Subject: [PATCH 40/44] Comment out restart - it seems it's not required --- lambda-http/src/deserializer/deserializer_simd_json.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index e5c2e0e2..a77de00d 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -60,9 +60,9 @@ impl<'de> Deserialize<'de> for LambdaRequest { } else { (false, false, false) }; - debug!("State of d before restart: {:?}", d); - d.restart(); - debug!("State of d after restart: {:?}", d); +// debug!("State of d before restart: {:?}", d); +// d.restart(); +// debug!("State of d after restart: {:?}", d); #[cfg(feature = "apigw_rest")] if !(http_context || alb_context || websocket_context) { From 05c0a0b83c13207d35f8f40078e2eddc3a393346 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Mon, 28 Oct 2024 14:42:10 +0100 Subject: [PATCH 41/44] Tests without restart work - not net needed in this implementation --- lambda-http/src/deserializer/deserializer_simd_json.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index a77de00d..a3861de9 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -60,9 +60,6 @@ impl<'de> Deserialize<'de> for LambdaRequest { } else { (false, false, false) }; -// debug!("State of d before restart: {:?}", d); -// d.restart(); -// debug!("State of d after restart: {:?}", d); #[cfg(feature = "apigw_rest")] if !(http_context || alb_context || websocket_context) { From a939b8fc93565e8e039d34b5b9cbee54bd1d5bb7 Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Mon, 28 Oct 2024 17:29:12 +0100 Subject: [PATCH 42/44] Use simd-json main --- json-impl/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index 44b34c8a..d8b92bac 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -20,6 +20,6 @@ simd = [ "simd-json/ordered-float" ] [dependencies] serde_json = { version = "^1", features = ["raw_value"] } #simd-json = { version = "^0", optional = true } -simd-json = { git = "https://github.com/bassmanitram/simd-json.git", branch = "deser-as-value", optional = true } +simd-json = { git = "https://github.com/simd-lite/simd-json.git", branch = "main", optional = true } bytes = { workspace = true } serde = { version = "^1", no-default-features = true } From 825e343300c84d1f5719bdc976cb93276b072a3c Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Tue, 29 Oct 2024 11:27:55 +0100 Subject: [PATCH 43/44] Simplify the cast and adjust the doc --- .../src/deserializer/deserializer_simd_json.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index a3861de9..1efa3280 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -36,9 +36,8 @@ impl<'de> Deserialize<'de> for LambdaRequest { // // There is a future feature of simd_json being considered that is very similar to serde_json's RawValue - effectively a // Deserializer-implementation-specific way of introspecting/peeking at the parsed JSON before continuing with deserialization. - // That's what the serde_json implementation of this uses, but, for now we have to resort to some wildly unsafe code in order - // to cast the incoming D to &mut simd_json::Deserializer. AND we don't "forget" the incoming value either because we need THAT - // to pass to our sub-deserialize attempts! + // That's what the serde_json implementation of this uses, but, for now we have to resort to this wildly unsafe cast of the + // the incoming D to &mut simd_json::Deserializer. // // HOWEVER... IF we are here, then someone has built this code with the simd_json feature enabled - which means that all KNOWN // invokers have ALSO been built with simd_json enabled - which means that this is, in fact, "safe"... IF users ONLY exploit the @@ -46,15 +45,12 @@ impl<'de> Deserialize<'de> for LambdaRequest { // // If not ... well, expect bad things to happen! // - debug!("Deserializing event into some sort of HTTP event - going unsafe..."); - let d = unsafe { std::ptr::read_unaligned(&deserializer as *const _ as *mut &mut JsonDeserializer<'de>) }; -// std::mem::forget(deserializer); We need deserializer - otherwise we have to Box the Deserialize dyn when casting back and using for deserialize calls + let d = unsafe { &*(&deserializer as *const _ as *mut &mut JsonDeserializer<'de>) }; - - debug!("Getting the value from d: {:?}", d); + // Get a simd_json "raw" Value representing what is in the deserializer; let v = d.as_value(); - debug!("Establishing the event type"); + // Introspect for the type markers on V2 payloads let (http_context, alb_context, websocket_context) = if let Some(rc) = v.get("requestContext") { (rc.contains_key("http"), rc.contains_key("elb"), rc.contains_key("connectedAt")) } else { @@ -62,6 +58,7 @@ impl<'de> Deserialize<'de> for LambdaRequest { }; #[cfg(feature = "apigw_rest")] + // If it's not a V2 payload, then we try to deserialize a V1 payload if !(http_context || alb_context || websocket_context) { debug!("Parsing REST API request"); return ApiGatewayProxyRequest::deserialize(deserializer).map_err(Error::custom).map(LambdaRequest::ApiGatewayV1); From a853fb98892316cd73d716d511e50a874bc1914b Mon Sep 17 00:00:00 2001 From: Martin Bartlett Date: Tue, 29 Oct 2024 12:33:52 +0100 Subject: [PATCH 44/44] Support feature pass_through --- json-impl/Cargo.toml | 3 +- json-impl/src/lib.rs | 1 + .../deserializer/deserializer_simd_json.rs | 34 +++++++++++-------- lambda-http/src/response.rs | 6 ++++ 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml index d8b92bac..56ee590d 100644 --- a/json-impl/Cargo.toml +++ b/json-impl/Cargo.toml @@ -15,11 +15,12 @@ edition = "2021" [features] default = [ ] -simd = [ "simd-json/ordered-float" ] +simd = [ "simd-json/ordered-float", "value-trait/ordered-float" ] [dependencies] serde_json = { version = "^1", features = ["raw_value"] } #simd-json = { version = "^0", optional = true } simd-json = { git = "https://github.com/simd-lite/simd-json.git", branch = "main", optional = true } +value-trait = { version = "^0", optional = true } bytes = { workspace = true } serde = { version = "^1", no-default-features = true } diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs index 30603914..bc3e09c2 100644 --- a/json-impl/src/lib.rs +++ b/json-impl/src/lib.rs @@ -61,6 +61,7 @@ mod simd { Deserializer as JsonDeserializer, Error as JsonError, }; + pub use value_trait::prelude::*; pub fn from_bytes(b: Bytes) -> simd_json::Result where diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs index 1efa3280..e15deab7 100644 --- a/lambda-http/src/deserializer/deserializer_simd_json.rs +++ b/lambda-http/src/deserializer/deserializer_simd_json.rs @@ -7,7 +7,7 @@ use aws_lambda_events::apigw::ApiGatewayProxyRequest; use aws_lambda_events::apigw::ApiGatewayV2httpRequest; #[cfg(feature = "apigw_websockets")] use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest; -use aws_lambda_json_impl::JsonDeserializer; +use aws_lambda_json_impl::{JsonDeserializer,Writable}; use serde::{de::Error, Deserialize}; use tracing::debug; @@ -51,15 +51,15 @@ impl<'de> Deserialize<'de> for LambdaRequest { let v = d.as_value(); // Introspect for the type markers on V2 payloads - let (http_context, alb_context, websocket_context) = if let Some(rc) = v.get("requestContext") { - (rc.contains_key("http"), rc.contains_key("elb"), rc.contains_key("connectedAt")) + let (rc_present, http_context, alb_context, websocket_context) = if let Some(rc) = v.get("requestContext") { + (true, rc.contains_key("http"), rc.contains_key("elb"), rc.contains_key("connectedAt")) } else { - (false, false, false) + (false, false, false, false) }; - + #[cfg(feature = "apigw_rest")] // If it's not a V2 payload, then we try to deserialize a V1 payload - if !(http_context || alb_context || websocket_context) { + if rc_present && !(http_context || alb_context || websocket_context) { debug!("Parsing REST API request"); return ApiGatewayProxyRequest::deserialize(deserializer).map_err(Error::custom).map(LambdaRequest::ApiGatewayV1); } @@ -82,13 +82,15 @@ impl<'de> Deserialize<'de> for LambdaRequest { return ApiGatewayWebsocketProxyRequest::deserialize(deserializer).map_err(Error::custom).map(LambdaRequest::WebSocket); } -/* Can't support this yet #[cfg(feature = "pass_through")] if PASS_THROUGH_ENABLED { + let mut buf = Vec::new(); + v.write(&mut buf).map_err(D::Error::custom)?; + let s = String::from_utf8_lossy(&buf); debug!("Defaulting to pass_through"); - return Ok(LambdaRequest::PassThrough(data.to_string())); + return Ok(LambdaRequest::PassThrough(s.into_owned())); } - */ + debug!("Failed to find a candidate request type"); Err(Error::custom(ERROR_CONTEXT)) } @@ -185,13 +187,14 @@ mod tests { #[test] #[cfg(feature = "pass_through")] fn test_deserialize_bedrock_agent() { - let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-bedrock-agent-runtime-event.json").to_vec(); + let data = include_bytes!("../../../lambda-events/src/fixtures/example-bedrock-agent-runtime-event.json"); + let mut data_vec = data.to_vec(); let req: LambdaRequest = - deserialize(data.as_mut_slice()).expect("failed to deserialize bedrock agent request data"); + aws_lambda_json_impl::from_slice(data_vec.as_mut_slice()).expect("failed to deserialize bedrock agent request data"); match req { LambdaRequest::PassThrough(req) => { - assert_eq!(String::from_utf8_lossy(data), req); + assert_eq!(String::from_utf8_lossy(data).replace(|c: char| c.is_ascii_whitespace(), ""), req); } other => panic!("unexpected request variant: {:?}", other), } @@ -201,11 +204,14 @@ mod tests { #[cfg(feature = "pass_through")] fn test_deserialize_sqs() { let data = include_bytes!("../../../lambda-events/src/fixtures/example-sqs-event.json"); + let mut data_vec = data.to_vec(); - let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize sqs event data"); + let req: LambdaRequest = aws_lambda_json_impl::from_slice(data_vec.as_mut_slice()).expect("failed to deserialize sqs event data"); match req { LambdaRequest::PassThrough(req) => { - assert_eq!(String::from_utf8_lossy(data), req); + //We have to hack a bit + + assert_eq!(String::from_utf8_lossy(data).replace(|c: char| c.is_ascii_whitespace(), ""), req.replace("Message Body","MessageBody")); } other => panic!("unexpected request variant: {:?}", other), } diff --git a/lambda-http/src/response.rs b/lambda-http/src/response.rs index 5e60a621..60ed5bf9 100644 --- a/lambda-http/src/response.rs +++ b/lambda-http/src/response.rs @@ -133,9 +133,15 @@ impl LambdaResponse { RequestOrigin::PassThrough => { match body { // text body must be a valid json string + #[cfg(not(feature = "simd_json"))] Some(Body::Text(body)) => {LambdaResponse::PassThrough(aws_lambda_json_impl::from_str(&body).unwrap_or_default())}, + #[cfg(feature = "simd_json")] + Some(Body::Text(body)) => {LambdaResponse::PassThrough(aws_lambda_json_impl::from_string(body).unwrap_or_default())}, // binary body and other cases return Value::Null + #[cfg(not(feature = "simd_json"))] _ => LambdaResponse::PassThrough(aws_lambda_json_impl::Value::Null), + #[cfg(feature = "simd_json")] + _ => LambdaResponse::PassThrough(aws_lambda_json_impl::Value::Static(aws_lambda_json_impl::StaticNode::Null)), } } #[cfg(not(any(