From 5e7609dfc02869e6ae8b9f912bfcd947aeea8ef0 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Thu, 25 May 2023 21:34:54 -0700 Subject: [PATCH 1/5] Make compiling chrono conditional It's not necessary for all event types. Signed-off-by: David Calavera --- lambda-events/Cargo.toml | 24 +- lambda-events/src/custom_serde/mod.rs | 264 ------------- .../src/{encodings.rs => encodings/mod.rs} | 94 +---- lambda-events/src/encodings/time.rs | 360 ++++++++++++++++++ lambda-events/src/lib.rs | 2 + 5 files changed, 379 insertions(+), 365 deletions(-) rename lambda-events/src/{encodings.rs => encodings/mod.rs} (81%) create mode 100644 lambda-events/src/encodings/time.rs diff --git a/lambda-events/Cargo.toml b/lambda-events/Cargo.toml index 57be6bde..daefffa8 100644 --- a/lambda-events/Cargo.toml +++ b/lambda-events/Cargo.toml @@ -29,7 +29,7 @@ chrono = { version = "0.4.23", default-features = false, features = [ "clock", "serde", "std", -] } +], optional = true } query_map = { version = "^0.6", features = ["serde", "url-query"] } flate2 = { version = "1.0.24", optional = true } @@ -81,21 +81,21 @@ activemq = [] alb = [] apigw = [] appsync = [] -autoscaling = [] -chime_bot = [] +autoscaling = ["chrono"] +chime_bot = ["chrono"] clientvpn = [] -cloudwatch_events = [] +cloudwatch_events = ["chrono"] cloudwatch_logs = ["flate2"] -code_commit = [] -codebuild = [] -codedeploy = [] +code_commit = ["chrono"] +codebuild = ["chrono"] +codedeploy = ["chrono"] codepipeline = [] -codepipeline_cloudwatch = [] +codepipeline_cloudwatch = ["chrono"] codepipeline_job = [] cognito = [] config = [] connect = [] -dynamodb = ["streams", "serde_dynamo"] +dynamodb = ["chrono", "serde_dynamo", "streams"] ecr_scan = [] firehose = [] iam = [] @@ -109,9 +109,9 @@ kinesis_analytics = ["kinesis"] lambda_function_urls = [] lex = [] rabbitmq = [] -s3 = [] +s3 = ["chrono"] s3_batch_job = ["s3"] -ses = [] -sns = ["serde_with"] +ses = ["chrono"] +sns = ["chrono", "serde_with"] sqs = ["serde_with"] streams = [] diff --git a/lambda-events/src/custom_serde/mod.rs b/lambda-events/src/custom_serde/mod.rs index e2c44af9..57aa20c3 100644 --- a/lambda-events/src/custom_serde/mod.rs +++ b/lambda-events/src/custom_serde/mod.rs @@ -1,6 +1,4 @@ -#[allow(unused)] use base64::Engine; -use chrono::{DateTime, Duration, TimeZone, Utc}; use serde; use serde::de::{Deserialize, Deserializer, Error as DeError}; use serde::ser::Serializer; @@ -34,89 +32,6 @@ pub(crate) mod float_unix_epoch; #[cfg(any(feature = "alb", feature = "apigw"))] pub(crate) mod http_method; -fn normalize_timestamp<'de, D>(deserializer: D) -> Result<(u64, u64), D::Error> -where - D: Deserializer<'de>, -{ - #[derive(Deserialize)] - #[serde(untagged)] - enum StringOrNumber { - String(String), - Float(f64), - Int(u64), - } - - let input: f64 = match StringOrNumber::deserialize(deserializer)? { - StringOrNumber::String(s) => s.parse::().map_err(DeError::custom)?, - StringOrNumber::Float(f) => f, - StringOrNumber::Int(i) => i as f64, - }; - - // We need to do this due to floating point issues. - let input_as_string = format!("{}", input); - let parts: Result, _> = input_as_string - .split('.') - .map(|x| x.parse::().map_err(DeError::custom)) - .collect(); - let parts = parts?; - if parts.len() > 1 { - Ok((parts[0], parts[1])) - } else { - Ok((parts[0], 0)) - } -} - -pub(crate) fn serialize_milliseconds(date: &DateTime, serializer: S) -> Result -where - S: Serializer, -{ - let ts_with_millis = date.timestamp_millis(); - serializer.serialize_str(&ts_with_millis.to_string()) -} - -pub(crate) fn deserialize_milliseconds<'de, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - let (whole, frac) = normalize_timestamp(deserializer)?; - assert_eq!(frac, 0); - let seconds: f64 = whole as f64 / 1000.0; - let milliseconds: u32 = (seconds.fract() * 1000f64) as u32; - let nanos = milliseconds * 1_000_000; - Utc.timestamp_opt(seconds as i64, nanos) - .latest() - .ok_or_else(|| D::Error::custom("invalid timestamp")) -} - -pub(crate) fn serialize_seconds(date: &DateTime, serializer: S) -> Result -where - S: Serializer, -{ - let seconds = date.timestamp(); - let milliseconds = date.timestamp_subsec_millis(); - let whole_seconds = seconds + (milliseconds as i64 / 1000); - let subsec_millis = milliseconds % 1000; - if milliseconds > 0 { - let combined = format!("{}.{:03}", whole_seconds, subsec_millis); - serializer.serialize_str(&combined) - } else { - serializer.serialize_str(&whole_seconds.to_string()) - } -} - -#[allow(dead_code)] -pub(crate) fn deserialize_seconds<'de, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - let (whole, frac) = normalize_timestamp(deserializer)?; - let seconds = whole; - let nanos = frac * 1_000_000; - Utc.timestamp_opt(seconds as i64, nanos as u32) - .latest() - .ok_or_else(|| D::Error::custom("invalid timestamp")) -} - pub(crate) fn deserialize_base64<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, @@ -159,40 +74,6 @@ where Ok(opt.unwrap_or_default()) } -pub(crate) fn serialize_duration_seconds(duration: &Duration, serializer: S) -> Result -where - S: Serializer, -{ - let seconds = duration.num_seconds(); - - serializer.serialize_i64(seconds) -} - -pub(crate) fn deserialize_duration_seconds<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let seconds = f64::deserialize(deserializer)?; - Ok(Duration::seconds(seconds as i64)) -} - -pub(crate) fn serialize_duration_minutes(duration: &Duration, serializer: S) -> Result -where - S: Serializer, -{ - let minutes = duration.num_minutes(); - - serializer.serialize_i64(minutes) -} - -pub(crate) fn deserialize_duration_minutes<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let minutes = f64::deserialize(deserializer)?; - Ok(Duration::minutes(minutes as i64)) -} - /// Deserializes `HashMap<_>`, mapping JSON `null` to an empty map. #[cfg(any( feature = "alb", @@ -214,7 +95,6 @@ where #[allow(deprecated)] mod test { use super::*; - use chrono::TimeZone; use serde_json; #[test] @@ -245,76 +125,6 @@ mod test { assert_eq!(encoded, r#"{"v":"SGVsbG8gV29ybGQ="}"#.to_string()); } - #[test] - fn test_deserialize_milliseconds() { - #[derive(Deserialize)] - struct Test { - #[serde(deserialize_with = "deserialize_milliseconds")] - v: DateTime, - } - let expected = Utc.ymd(2017, 10, 5).and_hms_nano(15, 33, 44, 302_000_000); - - // Test parsing strings. - let data = json!({ - "v": "1507217624302", - }); - let decoded: Test = serde_json::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(); - assert_eq!(expected, decoded.v,); - // Test parsing floats. - let data = json!({ - "v": 1507217624302.0, - }); - let decoded: Test = serde_json::from_value(data).unwrap(); - assert_eq!(expected, decoded.v,); - } - - #[test] - fn test_serialize_milliseconds() { - #[derive(Serialize)] - struct Test { - #[serde(serialize_with = "serialize_milliseconds")] - v: DateTime, - } - 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(); - assert_eq!(encoded, String::from(r#"{"v":"427683600099"}"#)); - } - - #[test] - fn test_serialize_seconds() { - #[derive(Serialize)] - struct Test { - #[serde(serialize_with = "serialize_seconds")] - v: DateTime, - } - - // Make sure nanoseconds are chopped off. - let instance = Test { - v: Utc.ymd(1983, 7, 22).and_hms_nano(1, 0, 0, 99), - }; - let encoded = serde_json::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(); - assert_eq!(encoded, String::from(r#"{"v":"427683600.002"}"#)); - - // Make sure milliseconds are included. - let instance = Test { - v: Utc.ymd(1983, 7, 22).and_hms_nano(1, 0, 0, 1_234_000_000), - }; - let encoded = serde_json::to_string(&instance).unwrap(); - assert_eq!(encoded, String::from(r#"{"v":"427683601.234"}"#)); - } - #[test] fn test_deserialize_map() { #[derive(Deserialize)] @@ -356,80 +166,6 @@ mod test { assert_eq!(serde_dynamo::Item::from(HashMap::new()), decoded.v); } - #[test] - fn test_deserialize_duration_seconds() { - #[derive(Deserialize)] - struct Test { - #[serde(deserialize_with = "deserialize_duration_seconds")] - v: Duration, - } - - let expected = Duration::seconds(36); - - let data = json!({ - "v": 36, - }); - let decoded: Test = serde_json::from_value(data).unwrap(); - assert_eq!(expected, decoded.v,); - - let data = json!({ - "v": 36.1, - }); - let decoded: Test = serde_json::from_value(data).unwrap(); - assert_eq!(expected, decoded.v,); - } - - #[test] - fn test_serialize_duration_seconds() { - #[derive(Serialize)] - struct Test { - #[serde(serialize_with = "serialize_duration_seconds")] - v: Duration, - } - let instance = Test { - v: Duration::seconds(36), - }; - let encoded = serde_json::to_string(&instance).unwrap(); - assert_eq!(encoded, String::from(r#"{"v":36}"#)); - } - - #[test] - fn test_deserialize_duration_minutes() { - #[derive(Deserialize)] - struct Test { - #[serde(deserialize_with = "deserialize_duration_minutes")] - v: Duration, - } - - let expected = Duration::minutes(36); - - let data = json!({ - "v": 36, - }); - let decoded: Test = serde_json::from_value(data).unwrap(); - assert_eq!(expected, decoded.v,); - - let data = json!({ - "v": 36.1, - }); - let decoded: Test = serde_json::from_value(data).unwrap(); - assert_eq!(expected, decoded.v,); - } - - #[test] - fn test_serialize_duration_minutes() { - #[derive(Serialize)] - struct Test { - #[serde(serialize_with = "serialize_duration_minutes")] - v: Duration, - } - let instance = Test { - v: Duration::minutes(36), - }; - let encoded = serde_json::to_string(&instance).unwrap(); - assert_eq!(encoded, String::from(r#"{"v":36}"#)); - } - #[test] fn test_deserialize_nullish_boolean() { #[derive(Deserialize)] diff --git a/lambda-events/src/encodings.rs b/lambda-events/src/encodings/mod.rs similarity index 81% rename from lambda-events/src/encodings.rs rename to lambda-events/src/encodings/mod.rs index 42dd15a7..5b8e947c 100644 --- a/lambda-events/src/encodings.rs +++ b/lambda-events/src/encodings/mod.rs @@ -1,5 +1,4 @@ use super::custom_serde::*; -use chrono::{DateTime, Duration, Utc}; use std::{borrow::Cow, mem::take, ops::Deref, ops::DerefMut, pin::Pin, task::Poll}; use base64::display::Base64Display; @@ -10,6 +9,11 @@ use serde::ser::{Error as SerError, Serialize, Serializer}; pub type Error = Box; +#[cfg(feature = "chrono")] +mod time; +#[cfg(feature = "chrono")] +pub use self::time::*; + /// Binary data encoded in base64. #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub struct Base64Data( @@ -32,94 +36,6 @@ impl DerefMut for Base64Data { } } -/// Timestamp with millisecond precision. -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -pub struct MillisecondTimestamp( - #[serde(deserialize_with = "deserialize_milliseconds")] - #[serde(serialize_with = "serialize_milliseconds")] - pub DateTime, -); - -impl Deref for MillisecondTimestamp { - type Target = DateTime; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for MillisecondTimestamp { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -/// Timestamp with second precision. -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -pub struct SecondTimestamp( - #[serde(deserialize_with = "deserialize_seconds")] - #[serde(serialize_with = "serialize_seconds")] - pub DateTime, -); - -impl Deref for SecondTimestamp { - type Target = DateTime; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for SecondTimestamp { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -/// Duration with second precision. -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -pub struct SecondDuration( - #[serde(deserialize_with = "deserialize_duration_seconds")] - #[serde(serialize_with = "serialize_duration_seconds")] - pub Duration, -); - -impl Deref for SecondDuration { - type Target = Duration; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for SecondDuration { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -/// Duration with minute precision. -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -pub struct MinuteDuration( - #[serde(deserialize_with = "deserialize_duration_minutes")] - #[serde(serialize_with = "serialize_duration_minutes")] - pub Duration, -); - -impl Deref for MinuteDuration { - type Target = Duration; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for MinuteDuration { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - /// Representation of http request and response bodies as supported /// by API Gateway and ALBs. /// diff --git a/lambda-events/src/encodings/time.rs b/lambda-events/src/encodings/time.rs new file mode 100644 index 00000000..f2147328 --- /dev/null +++ b/lambda-events/src/encodings/time.rs @@ -0,0 +1,360 @@ +use chrono::{DateTime, Duration, TimeZone, Utc}; +use serde::de::{Deserialize, Deserializer, Error as DeError}; +use serde::ser::Serializer; +use std::ops::{Deref, DerefMut}; + +/// Timestamp with millisecond precision. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct MillisecondTimestamp( + #[serde(deserialize_with = "deserialize_milliseconds")] + #[serde(serialize_with = "serialize_milliseconds")] + pub DateTime, +); + +impl Deref for MillisecondTimestamp { + type Target = DateTime; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for MillisecondTimestamp { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +/// Timestamp with second precision. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct SecondTimestamp( + #[serde(deserialize_with = "deserialize_seconds")] + #[serde(serialize_with = "serialize_seconds")] + pub DateTime, +); + +impl Deref for SecondTimestamp { + type Target = DateTime; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for SecondTimestamp { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +/// Duration with second precision. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct SecondDuration( + #[serde(deserialize_with = "deserialize_duration_seconds")] + #[serde(serialize_with = "serialize_duration_seconds")] + pub Duration, +); + +impl Deref for SecondDuration { + type Target = Duration; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for SecondDuration { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +/// Duration with minute precision. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct MinuteDuration( + #[serde(deserialize_with = "deserialize_duration_minutes")] + #[serde(serialize_with = "serialize_duration_minutes")] + pub Duration, +); + +impl Deref for MinuteDuration { + type Target = Duration; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for MinuteDuration { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +fn serialize_milliseconds(date: &DateTime, serializer: S) -> Result +where + S: Serializer, +{ + let ts_with_millis = date.timestamp_millis(); + serializer.serialize_str(&ts_with_millis.to_string()) +} + +fn deserialize_milliseconds<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let (whole, frac) = normalize_timestamp(deserializer)?; + assert_eq!(frac, 0); + let seconds: f64 = whole as f64 / 1000.0; + let milliseconds: u32 = (seconds.fract() * 1000f64) as u32; + let nanos = milliseconds * 1_000_000; + Utc.timestamp_opt(seconds as i64, nanos) + .latest() + .ok_or_else(|| D::Error::custom("invalid timestamp")) +} + +fn serialize_seconds(date: &DateTime, serializer: S) -> Result +where + S: Serializer, +{ + let seconds = date.timestamp(); + let milliseconds = date.timestamp_subsec_millis(); + let whole_seconds = seconds + (milliseconds as i64 / 1000); + let subsec_millis = milliseconds % 1000; + if milliseconds > 0 { + let combined = format!("{}.{:03}", whole_seconds, subsec_millis); + serializer.serialize_str(&combined) + } else { + serializer.serialize_str(&whole_seconds.to_string()) + } +} + +fn deserialize_seconds<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let (whole, frac) = normalize_timestamp(deserializer)?; + let seconds = whole; + let nanos = frac * 1_000_000; + Utc.timestamp_opt(seconds as i64, nanos as u32) + .latest() + .ok_or_else(|| D::Error::custom("invalid timestamp")) +} + +fn serialize_duration_seconds(duration: &Duration, serializer: S) -> Result +where + S: Serializer, +{ + let seconds = duration.num_seconds(); + + serializer.serialize_i64(seconds) +} + +fn deserialize_duration_seconds<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let seconds = f64::deserialize(deserializer)?; + Ok(Duration::seconds(seconds as i64)) +} + +fn serialize_duration_minutes(duration: &Duration, serializer: S) -> Result +where + S: Serializer, +{ + let minutes = duration.num_minutes(); + + serializer.serialize_i64(minutes) +} + +fn deserialize_duration_minutes<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let minutes = f64::deserialize(deserializer)?; + Ok(Duration::minutes(minutes as i64)) +} + +fn normalize_timestamp<'de, D>(deserializer: D) -> Result<(u64, u64), D::Error> +where + D: Deserializer<'de>, +{ + #[derive(Deserialize)] + #[serde(untagged)] + enum StringOrNumber { + String(String), + Float(f64), + Int(u64), + } + + let input: f64 = match StringOrNumber::deserialize(deserializer)? { + StringOrNumber::String(s) => s.parse::().map_err(DeError::custom)?, + StringOrNumber::Float(f) => f, + StringOrNumber::Int(i) => i as f64, + }; + + // We need to do this due to floating point issues. + let input_as_string = format!("{}", input); + let parts: Result, _> = input_as_string + .split('.') + .map(|x| x.parse::().map_err(DeError::custom)) + .collect(); + let parts = parts?; + if parts.len() > 1 { + Ok((parts[0], parts[1])) + } else { + Ok((parts[0], 0)) + } +} + +#[cfg(test)] +#[allow(deprecated)] +mod test { + use super::*; + use chrono::TimeZone; + use serde_json; + + #[test] + fn test_deserialize_milliseconds() { + #[derive(Deserialize)] + struct Test { + #[serde(deserialize_with = "deserialize_milliseconds")] + v: DateTime, + } + let expected = Utc.ymd(2017, 10, 5).and_hms_nano(15, 33, 44, 302_000_000); + + // Test parsing strings. + let data = json!({ + "v": "1507217624302", + }); + let decoded: Test = serde_json::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(); + assert_eq!(expected, decoded.v,); + // Test parsing floats. + let data = json!({ + "v": 1507217624302.0, + }); + let decoded: Test = serde_json::from_value(data).unwrap(); + assert_eq!(expected, decoded.v,); + } + + #[test] + fn test_serialize_milliseconds() { + #[derive(Serialize)] + struct Test { + #[serde(serialize_with = "serialize_milliseconds")] + v: DateTime, + } + 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(); + assert_eq!(encoded, String::from(r#"{"v":"427683600099"}"#)); + } + + #[test] + fn test_serialize_seconds() { + #[derive(Serialize)] + struct Test { + #[serde(serialize_with = "serialize_seconds")] + v: DateTime, + } + + // Make sure nanoseconds are chopped off. + let instance = Test { + v: Utc.ymd(1983, 7, 22).and_hms_nano(1, 0, 0, 99), + }; + let encoded = serde_json::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(); + assert_eq!(encoded, String::from(r#"{"v":"427683600.002"}"#)); + + // Make sure milliseconds are included. + let instance = Test { + v: Utc.ymd(1983, 7, 22).and_hms_nano(1, 0, 0, 1_234_000_000), + }; + let encoded = serde_json::to_string(&instance).unwrap(); + assert_eq!(encoded, String::from(r#"{"v":"427683601.234"}"#)); + } + + #[test] + fn test_deserialize_duration_seconds() { + #[derive(Deserialize)] + struct Test { + #[serde(deserialize_with = "deserialize_duration_seconds")] + v: Duration, + } + + let expected = Duration::seconds(36); + + let data = json!({ + "v": 36, + }); + let decoded: Test = serde_json::from_value(data).unwrap(); + assert_eq!(expected, decoded.v,); + + let data = json!({ + "v": 36.1, + }); + let decoded: Test = serde_json::from_value(data).unwrap(); + assert_eq!(expected, decoded.v,); + } + + #[test] + fn test_serialize_duration_seconds() { + #[derive(Serialize)] + struct Test { + #[serde(serialize_with = "serialize_duration_seconds")] + v: Duration, + } + let instance = Test { + v: Duration::seconds(36), + }; + let encoded = serde_json::to_string(&instance).unwrap(); + assert_eq!(encoded, String::from(r#"{"v":36}"#)); + } + + #[test] + fn test_deserialize_duration_minutes() { + #[derive(Deserialize)] + struct Test { + #[serde(deserialize_with = "deserialize_duration_minutes")] + v: Duration, + } + + let expected = Duration::minutes(36); + + let data = json!({ + "v": 36, + }); + let decoded: Test = serde_json::from_value(data).unwrap(); + assert_eq!(expected, decoded.v,); + + let data = json!({ + "v": 36.1, + }); + let decoded: Test = serde_json::from_value(data).unwrap(); + assert_eq!(expected, decoded.v,); + } + + #[test] + fn test_serialize_duration_minutes() { + #[derive(Serialize)] + struct Test { + #[serde(serialize_with = "serialize_duration_minutes")] + v: Duration, + } + let instance = Test { + v: Duration::minutes(36), + }; + let encoded = serde_json::to_string(&instance).unwrap(); + assert_eq!(encoded, String::from(r#"{"v":36}"#)); + } +} diff --git a/lambda-events/src/lib.rs b/lambda-events/src/lib.rs index fa6cce05..3647096d 100644 --- a/lambda-events/src/lib.rs +++ b/lambda-events/src/lib.rs @@ -11,6 +11,7 @@ extern crate serde_json; // Crates with types that we use publicly. Reexported for ease of interoperability. pub extern crate bytes; +#[cfg(feature = "chrono")] pub extern crate chrono; pub extern crate http; pub extern crate http_body; @@ -22,6 +23,7 @@ pub extern crate serde_json; mod custom_serde; /// Encodings used in AWS Lambda json event values. pub mod encodings; +#[cfg(feature = "chrono")] pub mod time_window; /// AWS Lambda event definitions. From e55d79f1f893d59144b9c964506b9ad52e1d60f0 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Thu, 25 May 2023 21:36:41 -0700 Subject: [PATCH 2/5] Make compiling query_map conditional. It's not used in all events. Signed-off-by: David Calavera --- lambda-events/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lambda-events/Cargo.toml b/lambda-events/Cargo.toml index daefffa8..94ace808 100644 --- a/lambda-events/Cargo.toml +++ b/lambda-events/Cargo.toml @@ -30,7 +30,7 @@ chrono = { version = "0.4.23", default-features = false, features = [ "serde", "std", ], optional = true } -query_map = { version = "^0.6", features = ["serde", "url-query"] } +query_map = { version = "^0.6", features = ["serde", "url-query"], optional = true } flate2 = { version = "1.0.24", optional = true } [dev-dependencies] @@ -78,8 +78,8 @@ default = [ ] activemq = [] -alb = [] -apigw = [] +alb = ["query_map"] +apigw = ["query_map"] appsync = [] autoscaling = ["chrono"] chime_bot = ["chrono"] From e7b229a3f228e097a92f72a4877feec35faac4be Mon Sep 17 00:00:00 2001 From: David Calavera Date: Sat, 27 May 2023 17:33:22 -0700 Subject: [PATCH 3/5] Test individual features - Convert package to 2021 edition. - Format imports. Signed-off-by: David Calavera --- .github/workflows/build-events.yml | 9 + Makefile | 41 ++ lambda-events/Cargo.toml | 25 +- lambda-events/src/custom_serde/mod.rs | 2 +- lambda-events/src/encodings/http.rs | 342 +++++++++++++++++ lambda-events/src/encodings/mod.rs | 351 +----------------- lambda-events/src/event/activemq/mod.rs | 3 +- lambda-events/src/event/alb/mod.rs | 10 +- lambda-events/src/event/appsync/mod.rs | 3 +- lambda-events/src/event/autoscaling/mod.rs | 3 +- lambda-events/src/event/codebuild/mod.rs | 2 +- lambda-events/src/event/cognito/mod.rs | 3 +- lambda-events/src/event/connect/mod.rs | 3 +- .../src/event/dynamodb/attributes.rs | 2 +- lambda-events/src/event/dynamodb/mod.rs | 5 +- lambda-events/src/event/firehose/mod.rs | 6 +- lambda-events/src/event/iot/mod.rs | 2 +- lambda-events/src/event/iot_1_click/mod.rs | 6 +- lambda-events/src/event/kafka/mod.rs | 3 +- .../src/event/lambda_function_urls/mod.rs | 3 +- lambda-events/src/event/lex/mod.rs | 3 +- lambda-events/src/event/rabbitmq/mod.rs | 3 +- lambda-events/src/event/s3/event.rs | 3 +- lambda-events/src/event/s3/object_lambda.rs | 3 +- lambda-events/src/event/sns/mod.rs | 3 +- lambda-events/src/event/sqs/mod.rs | 3 +- lambda-events/src/lib.rs | 19 +- lambda-http/Cargo.toml | 2 +- 28 files changed, 462 insertions(+), 401 deletions(-) create mode 100644 lambda-events/src/encodings/http.rs diff --git a/.github/workflows/build-events.yml b/.github/workflows/build-events.yml index dbf9a0ae..3a56e597 100644 --- a/.github/workflows/build-events.yml +++ b/.github/workflows/build-events.yml @@ -26,3 +26,12 @@ jobs: with: package: aws_lambda_events toolchain: ${{ matrix.toolchain}} + check-event-features: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + + - name: Test individual event features + run: make check-event-features diff --git a/Makefile b/Makefile index cb00545c..e85010e8 100644 --- a/Makefile +++ b/Makefile @@ -60,3 +60,44 @@ invoke-integration-api-%: curl -X POST -d '{"command": "hello"}' $(API_URL)/trait/post curl -X POST -d '{"command": "hello"}' $(API_URL)/al2/post curl -X POST -d '{"command": "hello"}' $(API_URL)/al2-trait/post + +# Test individual event features to ensure optional dependencies +# are correctly loaded when all default features are disabled. +check-event-features: + cargo test --package aws_lambda_events --no-default-features --features activemq + cargo test --package aws_lambda_events --no-default-features --features alb + cargo test --package aws_lambda_events --no-default-features --features apigw + cargo test --package aws_lambda_events --no-default-features --features appsync + cargo test --package aws_lambda_events --no-default-features --features autoscaling + cargo test --package aws_lambda_events --no-default-features --features chime_bot + cargo test --package aws_lambda_events --no-default-features --features clientvpn + cargo test --package aws_lambda_events --no-default-features --features cloudwatch_events + cargo test --package aws_lambda_events --no-default-features --features cloudwatch_logs + cargo test --package aws_lambda_events --no-default-features --features code_commit + cargo test --package aws_lambda_events --no-default-features --features codebuild + cargo test --package aws_lambda_events --no-default-features --features codedeploy + cargo test --package aws_lambda_events --no-default-features --features codepipeline_cloudwatch + cargo test --package aws_lambda_events --no-default-features --features codepipeline_job + cargo test --package aws_lambda_events --no-default-features --features cognito + cargo test --package aws_lambda_events --no-default-features --features config + cargo test --package aws_lambda_events --no-default-features --features connect + cargo test --package aws_lambda_events --no-default-features --features dynamodb + cargo test --package aws_lambda_events --no-default-features --features ecr_scan + cargo test --package aws_lambda_events --no-default-features --features firehose + cargo test --package aws_lambda_events --no-default-features --features iam + cargo test --package aws_lambda_events --no-default-features --features iot + cargo test --package aws_lambda_events --no-default-features --features iot_1_click + cargo test --package aws_lambda_events --no-default-features --features iot_button + cargo test --package aws_lambda_events --no-default-features --features iot_deprecated + cargo test --package aws_lambda_events --no-default-features --features kafka + cargo test --package aws_lambda_events --no-default-features --features kinesis + cargo test --package aws_lambda_events --no-default-features --features kinesis_analytics + cargo test --package aws_lambda_events --no-default-features --features lambda_function_urls + cargo test --package aws_lambda_events --no-default-features --features lex + cargo test --package aws_lambda_events --no-default-features --features rabbitmq + cargo test --package aws_lambda_events --no-default-features --features s3 + cargo test --package aws_lambda_events --no-default-features --features s3_batch_job + cargo test --package aws_lambda_events --no-default-features --features ses + cargo test --package aws_lambda_events --no-default-features --features sns + cargo test --package aws_lambda_events --no-default-features --features sqs + cargo test --package aws_lambda_events --no-default-features --features streams \ No newline at end of file diff --git a/lambda-events/Cargo.toml b/lambda-events/Cargo.toml index 94ace808..930ee039 100644 --- a/lambda-events/Cargo.toml +++ b/lambda-events/Cargo.toml @@ -13,18 +13,19 @@ repository = "https://github.com/awslabs/aws-lambda-rust-runtime" readme = "README.md" keywords = ["lambda", "aws", "amazon", "events", "S3"] categories = ["api-bindings", "encoding", "web-programming"] +edition = "2021" [dependencies] base64 = "0.21" -http = "0.2" -http-body = "0.4" -http-serde = "^1" +http = { version = "0.2", optional = true } +http-body = { version = "0.4", optional = true } +http-serde = { version = "^1", optional = true } serde = "^1" serde_derive = "^1" serde_with = { version = "^3", features = ["json"], optional = true } serde_json = "^1" serde_dynamo = { version = "^4.1", optional = true } -bytes = { version = "1", features = ["serde"] } +bytes = { version = "1", features = ["serde"], optional = true } chrono = { version = "0.4.23", default-features = false, features = [ "clock", "serde", @@ -78,8 +79,8 @@ default = [ ] activemq = [] -alb = ["query_map"] -apigw = ["query_map"] +alb = ["bytes", "http", "http-body", "http-serde", "query_map"] +apigw = ["bytes", "http", "http-body", "http-serde", "query_map"] appsync = [] autoscaling = ["chrono"] chime_bot = ["chrono"] @@ -97,19 +98,19 @@ config = [] connect = [] dynamodb = ["chrono", "serde_dynamo", "streams"] ecr_scan = [] -firehose = [] +firehose = ["chrono"] iam = [] -iot = ["iam"] +iot = ["bytes", "http", "http-body", "http-serde", "iam"] iot_1_click = [] iot_button = [] iot_deprecated = ["iot"] -kafka = [] -kinesis = [] +kafka = ["chrono"] +kinesis = ["chrono"] kinesis_analytics = ["kinesis"] -lambda_function_urls = [] +lambda_function_urls = ["bytes", "http", "http-body", "http-serde"] lex = [] rabbitmq = [] -s3 = ["chrono"] +s3 = ["bytes", "chrono", "http", "http-body", "http-serde"] s3_batch_job = ["s3"] ses = ["chrono"] sns = ["chrono", "serde_with"] diff --git a/lambda-events/src/custom_serde/mod.rs b/lambda-events/src/custom_serde/mod.rs index 57aa20c3..2a8dd88e 100644 --- a/lambda-events/src/custom_serde/mod.rs +++ b/lambda-events/src/custom_serde/mod.rs @@ -1,5 +1,4 @@ use base64::Engine; -use serde; use serde::de::{Deserialize, Deserializer, Error as DeError}; use serde::ser::Serializer; use std::collections::HashMap; @@ -80,6 +79,7 @@ where feature = "apigw", feature = "cloudwatch_events", feature = "code_commit", + feature = "cognito", test ))] pub(crate) fn deserialize_nullish_boolean<'de, D>(deserializer: D) -> Result diff --git a/lambda-events/src/encodings/http.rs b/lambda-events/src/encodings/http.rs new file mode 100644 index 00000000..c090b653 --- /dev/null +++ b/lambda-events/src/encodings/http.rs @@ -0,0 +1,342 @@ +use base64::display::Base64Display; +use bytes::Bytes; +use http_body::{Body as HttpBody, SizeHint}; +use serde::de::{Deserialize, Deserializer, Error as DeError, Visitor}; +use serde::ser::{Error as SerError, Serialize, Serializer}; +use std::{borrow::Cow, mem::take, ops::Deref, pin::Pin, task::Poll}; + +/// Representation of http request and response bodies as supported +/// by API Gateway and ALBs. +/// +/// These come in three flavors +/// * `Empty` ( no body ) +/// * `Text` ( text data ) +/// * `Binary` ( binary data ) +/// +/// Body types can be `Deref` and `AsRef`'d into `[u8]` types much like the [hyper crate](https://crates.io/crates/hyper) +/// +/// # Examples +/// +/// Body types are inferred with `From` implementations. +/// +/// ## Text +/// +/// Types like `String`, `str` whose type reflects +/// text produce `Body::Text` variants +/// +/// ``` +/// assert!(match aws_lambda_events::encodings::Body::from("text") { +/// aws_lambda_events::encodings::Body::Text(_) => true, +/// _ => false +/// }) +/// ``` +/// +/// ## Binary +/// +/// Types like `Vec` and `&[u8]` whose types reflect raw bytes produce `Body::Binary` variants +/// +/// ``` +/// assert!(match aws_lambda_events::encodings::Body::from("text".as_bytes()) { +/// aws_lambda_events::encodings::Body::Binary(_) => true, +/// _ => false +/// }) +/// ``` +/// +/// `Binary` responses bodies will automatically get based64 encoded to meet API Gateway's response expectations. +/// +/// ## Empty +/// +/// The unit type ( `()` ) whose type represents an empty value produces `Body::Empty` variants +/// +/// ``` +/// assert!(match aws_lambda_events::encodings::Body::from(()) { +/// aws_lambda_events::encodings::Body::Empty => true, +/// _ => false +/// }) +/// ``` +/// +/// +/// For more information about API Gateway's body types, +/// refer to [this documentation](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html). +#[derive(Debug, Default, Eq, PartialEq)] +pub enum Body { + /// An empty body + #[default] + Empty, + /// A body containing string data + Text(String), + /// A body containing binary data + Binary(Vec), +} + +impl Body { + /// Decodes body, if needed. + /// + /// # Panics + /// + /// Panics when aws communicates to handler that request is base64 encoded but + /// it can not be base64 decoded + pub fn from_maybe_encoded(is_base64_encoded: bool, body: &str) -> Body { + use base64::Engine; + + if is_base64_encoded { + Body::from( + ::base64::engine::general_purpose::STANDARD + .decode(body) + .expect("failed to decode aws base64 encoded body"), + ) + } else { + Body::from(body) + } + } +} + +impl From<()> for Body { + fn from(_: ()) -> Self { + Body::Empty + } +} + +impl<'a> From<&'a str> for Body { + fn from(s: &'a str) -> Self { + Body::Text(s.into()) + } +} + +impl From for Body { + fn from(b: String) -> Self { + Body::Text(b) + } +} + +impl From> for Body { + #[inline] + fn from(cow: Cow<'static, str>) -> Body { + match cow { + Cow::Borrowed(b) => Body::from(b.to_owned()), + Cow::Owned(o) => Body::from(o), + } + } +} + +impl From> for Body { + #[inline] + fn from(cow: Cow<'static, [u8]>) -> Body { + match cow { + Cow::Borrowed(b) => Body::from(b), + Cow::Owned(o) => Body::from(o), + } + } +} + +impl From> for Body { + fn from(b: Vec) -> Self { + Body::Binary(b) + } +} + +impl<'a> From<&'a [u8]> for Body { + fn from(b: &'a [u8]) -> Self { + Body::Binary(b.to_vec()) + } +} + +impl Deref for Body { + type Target = [u8]; + + #[inline] + fn deref(&self) -> &Self::Target { + self.as_ref() + } +} + +impl AsRef<[u8]> for Body { + #[inline] + fn as_ref(&self) -> &[u8] { + match self { + Body::Empty => &[], + Body::Text(ref bytes) => bytes.as_ref(), + Body::Binary(ref bytes) => bytes.as_ref(), + } + } +} + +impl Clone for Body { + fn clone(&self) -> Self { + match self { + Body::Empty => Body::Empty, + Body::Text(ref bytes) => Body::Text(bytes.clone()), + Body::Binary(ref bytes) => Body::Binary(bytes.clone()), + } + } +} + +impl Serialize for Body { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Body::Text(data) => { + serializer.serialize_str(::std::str::from_utf8(data.as_ref()).map_err(S::Error::custom)?) + } + Body::Binary(data) => { + serializer.collect_str(&Base64Display::new(data, &base64::engine::general_purpose::STANDARD)) + } + Body::Empty => serializer.serialize_unit(), + } + } +} + +impl<'de> Deserialize<'de> for Body { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct BodyVisitor; + + impl<'de> Visitor<'de> for BodyVisitor { + type Value = Body; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("string") + } + + fn visit_str(self, value: &str) -> Result + where + E: DeError, + { + Ok(Body::from(value)) + } + } + + deserializer.deserialize_str(BodyVisitor) + } +} + +impl HttpBody for Body { + type Data = Bytes; + type Error = super::Error; + + fn poll_data( + self: Pin<&mut Self>, + _cx: &mut std::task::Context<'_>, + ) -> Poll>> { + let body = take(self.get_mut()); + Poll::Ready(match body { + Body::Empty => None, + Body::Text(s) => Some(Ok(s.into())), + Body::Binary(b) => Some(Ok(b.into())), + }) + } + + fn poll_trailers( + self: Pin<&mut Self>, + _cx: &mut std::task::Context<'_>, + ) -> Poll, Self::Error>> { + Poll::Ready(Ok(None)) + } + + fn is_end_stream(&self) -> bool { + matches!(self, Body::Empty) + } + + fn size_hint(&self) -> SizeHint { + match self { + Body::Empty => SizeHint::default(), + Body::Text(ref s) => SizeHint::with_exact(s.len() as u64), + Body::Binary(ref b) => SizeHint::with_exact(b.len() as u64), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use serde_json; + use std::collections::HashMap; + + #[test] + fn body_has_default() { + assert_eq!(Body::default(), Body::Empty); + } + + #[test] + fn from_unit() { + assert_eq!(Body::from(()), Body::Empty); + } + + #[test] + fn from_str() { + match Body::from(String::from("foo").as_str()) { + Body::Text(_) => (), + not => panic!("expected Body::Text(...) got {:?}", not), + } + } + + #[test] + fn from_string() { + match Body::from(String::from("foo")) { + Body::Text(_) => (), + not => panic!("expected Body::Text(...) got {:?}", not), + } + } + + #[test] + fn from_cow_str() { + match Body::from(Cow::from("foo")) { + Body::Text(_) => (), + not => panic!("expected Body::Text(...) got {:?}", not), + } + } + + #[test] + fn from_cow_bytes() { + match Body::from(Cow::from("foo".as_bytes())) { + Body::Binary(_) => (), + not => panic!("expected Body::Binary(...) got {:?}", not), + } + } + + #[test] + fn from_bytes() { + match Body::from("foo".as_bytes()) { + Body::Binary(_) => (), + not => panic!("expected Body::Binary(...) got {:?}", not), + } + } + + #[test] + 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"}"#); + } + + #[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"}"#); + } + + #[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}"#); + } + + #[test] + fn serialize_from_maybe_encoded() { + match Body::from_maybe_encoded(false, "foo") { + Body::Text(_) => (), + not => panic!("expected Body::Text(...) got {:?}", not), + } + + match Body::from_maybe_encoded(true, "Zm9v") { + Body::Binary(b) => assert_eq!(&[102, 111, 111], b.as_slice()), + not => panic!("expected Body::Text(...) got {:?}", not), + } + } +} diff --git a/lambda-events/src/encodings/mod.rs b/lambda-events/src/encodings/mod.rs index 5b8e947c..30472ce6 100644 --- a/lambda-events/src/encodings/mod.rs +++ b/lambda-events/src/encodings/mod.rs @@ -1,18 +1,17 @@ -use super::custom_serde::*; -use std::{borrow::Cow, mem::take, ops::Deref, ops::DerefMut, pin::Pin, task::Poll}; - -use base64::display::Base64Display; -use bytes::Bytes; -use http_body::{Body as HttpBody, SizeHint}; -use serde::de::{Deserialize, Deserializer, Error as DeError, Visitor}; -use serde::ser::{Error as SerError, Serialize, Serializer}; +use std::{ops::Deref, ops::DerefMut}; pub type Error = Box; #[cfg(feature = "chrono")] mod time; +use crate::custom_serde::{deserialize_base64, serialize_base64}; + #[cfg(feature = "chrono")] pub use self::time::*; +#[cfg(feature = "http")] +mod http; +#[cfg(feature = "http")] +pub use self::http::*; /// Binary data encoded in base64. #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] @@ -35,339 +34,3 @@ impl DerefMut for Base64Data { &mut self.0 } } - -/// Representation of http request and response bodies as supported -/// by API Gateway and ALBs. -/// -/// These come in three flavors -/// * `Empty` ( no body ) -/// * `Text` ( text data ) -/// * `Binary` ( binary data ) -/// -/// Body types can be `Deref` and `AsRef`'d into `[u8]` types much like the [hyper crate](https://crates.io/crates/hyper) -/// -/// # Examples -/// -/// Body types are inferred with `From` implementations. -/// -/// ## Text -/// -/// Types like `String`, `str` whose type reflects -/// text produce `Body::Text` variants -/// -/// ``` -/// assert!(match aws_lambda_events::encodings::Body::from("text") { -/// aws_lambda_events::encodings::Body::Text(_) => true, -/// _ => false -/// }) -/// ``` -/// -/// ## Binary -/// -/// Types like `Vec` and `&[u8]` whose types reflect raw bytes produce `Body::Binary` variants -/// -/// ``` -/// assert!(match aws_lambda_events::encodings::Body::from("text".as_bytes()) { -/// aws_lambda_events::encodings::Body::Binary(_) => true, -/// _ => false -/// }) -/// ``` -/// -/// `Binary` responses bodies will automatically get based64 encoded to meet API Gateway's response expectations. -/// -/// ## Empty -/// -/// The unit type ( `()` ) whose type represents an empty value produces `Body::Empty` variants -/// -/// ``` -/// assert!(match aws_lambda_events::encodings::Body::from(()) { -/// aws_lambda_events::encodings::Body::Empty => true, -/// _ => false -/// }) -/// ``` -/// -/// -/// For more information about API Gateway's body types, -/// refer to [this documentation](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html). -#[derive(Debug, Default, Eq, PartialEq)] -pub enum Body { - /// An empty body - #[default] - Empty, - /// A body containing string data - Text(String), - /// A body containing binary data - Binary(Vec), -} - -impl Body { - /// Decodes body, if needed. - /// - /// # Panics - /// - /// Panics when aws communicates to handler that request is base64 encoded but - /// it can not be base64 decoded - pub fn from_maybe_encoded(is_base64_encoded: bool, body: &str) -> Body { - use base64::Engine; - - if is_base64_encoded { - Body::from( - ::base64::engine::general_purpose::STANDARD - .decode(body) - .expect("failed to decode aws base64 encoded body"), - ) - } else { - Body::from(body) - } - } -} - -impl From<()> for Body { - fn from(_: ()) -> Self { - Body::Empty - } -} - -impl<'a> From<&'a str> for Body { - fn from(s: &'a str) -> Self { - Body::Text(s.into()) - } -} - -impl From for Body { - fn from(b: String) -> Self { - Body::Text(b) - } -} - -impl From> for Body { - #[inline] - fn from(cow: Cow<'static, str>) -> Body { - match cow { - Cow::Borrowed(b) => Body::from(b.to_owned()), - Cow::Owned(o) => Body::from(o), - } - } -} - -impl From> for Body { - #[inline] - fn from(cow: Cow<'static, [u8]>) -> Body { - match cow { - Cow::Borrowed(b) => Body::from(b), - Cow::Owned(o) => Body::from(o), - } - } -} - -impl From> for Body { - fn from(b: Vec) -> Self { - Body::Binary(b) - } -} - -impl<'a> From<&'a [u8]> for Body { - fn from(b: &'a [u8]) -> Self { - Body::Binary(b.to_vec()) - } -} - -impl Deref for Body { - type Target = [u8]; - - #[inline] - fn deref(&self) -> &Self::Target { - self.as_ref() - } -} - -impl AsRef<[u8]> for Body { - #[inline] - fn as_ref(&self) -> &[u8] { - match self { - Body::Empty => &[], - Body::Text(ref bytes) => bytes.as_ref(), - Body::Binary(ref bytes) => bytes.as_ref(), - } - } -} - -impl Clone for Body { - fn clone(&self) -> Self { - match self { - Body::Empty => Body::Empty, - Body::Text(ref bytes) => Body::Text(bytes.clone()), - Body::Binary(ref bytes) => Body::Binary(bytes.clone()), - } - } -} - -impl Serialize for Body { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - match self { - Body::Text(data) => { - serializer.serialize_str(::std::str::from_utf8(data.as_ref()).map_err(S::Error::custom)?) - } - Body::Binary(data) => { - serializer.collect_str(&Base64Display::new(data, &base64::engine::general_purpose::STANDARD)) - } - Body::Empty => serializer.serialize_unit(), - } - } -} - -impl<'de> Deserialize<'de> for Body { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct BodyVisitor; - - impl<'de> Visitor<'de> for BodyVisitor { - type Value = Body; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("string") - } - - fn visit_str(self, value: &str) -> Result - where - E: DeError, - { - Ok(Body::from(value)) - } - } - - deserializer.deserialize_str(BodyVisitor) - } -} - -impl HttpBody for Body { - type Data = Bytes; - type Error = Error; - - fn poll_data( - self: Pin<&mut Self>, - _cx: &mut std::task::Context<'_>, - ) -> Poll>> { - let body = take(self.get_mut()); - Poll::Ready(match body { - Body::Empty => None, - Body::Text(s) => Some(Ok(s.into())), - Body::Binary(b) => Some(Ok(b.into())), - }) - } - - fn poll_trailers( - self: Pin<&mut Self>, - _cx: &mut std::task::Context<'_>, - ) -> Poll, Self::Error>> { - Poll::Ready(Ok(None)) - } - - fn is_end_stream(&self) -> bool { - matches!(self, Body::Empty) - } - - fn size_hint(&self) -> SizeHint { - match self { - Body::Empty => SizeHint::default(), - Body::Text(ref s) => SizeHint::with_exact(s.len() as u64), - Body::Binary(ref b) => SizeHint::with_exact(b.len() as u64), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use serde_json; - use std::collections::HashMap; - - #[test] - fn body_has_default() { - assert_eq!(Body::default(), Body::Empty); - } - - #[test] - fn from_unit() { - assert_eq!(Body::from(()), Body::Empty); - } - - #[test] - fn from_str() { - match Body::from(String::from("foo").as_str()) { - Body::Text(_) => (), - not => panic!("expected Body::Text(...) got {:?}", not), - } - } - - #[test] - fn from_string() { - match Body::from(String::from("foo")) { - Body::Text(_) => (), - not => panic!("expected Body::Text(...) got {:?}", not), - } - } - - #[test] - fn from_cow_str() { - match Body::from(Cow::from("foo")) { - Body::Text(_) => (), - not => panic!("expected Body::Text(...) got {:?}", not), - } - } - - #[test] - fn from_cow_bytes() { - match Body::from(Cow::from("foo".as_bytes())) { - Body::Binary(_) => (), - not => panic!("expected Body::Binary(...) got {:?}", not), - } - } - - #[test] - fn from_bytes() { - match Body::from("foo".as_bytes()) { - Body::Binary(_) => (), - not => panic!("expected Body::Binary(...) got {:?}", not), - } - } - - #[test] - 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"}"#); - } - - #[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"}"#); - } - - #[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}"#); - } - - #[test] - fn serialize_from_maybe_encoded() { - match Body::from_maybe_encoded(false, "foo") { - Body::Text(_) => (), - not => panic!("expected Body::Text(...) got {:?}", not), - } - - match Body::from_maybe_encoded(true, "Zm9v") { - Body::Binary(b) => assert_eq!(&[102, 111, 111], b.as_slice()), - not => panic!("expected Body::Text(...) got {:?}", not), - } - } -} diff --git a/lambda-events/src/event/activemq/mod.rs b/lambda-events/src/event/activemq/mod.rs index fcb490ec..afa16a0d 100644 --- a/lambda-events/src/event/activemq/mod.rs +++ b/lambda-events/src/event/activemq/mod.rs @@ -1,6 +1,7 @@ -use crate::custom_serde::*; use std::collections::HashMap; +use crate::custom_serde::deserialize_lambda_map; + #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct ActiveMqEvent { diff --git a/lambda-events/src/event/alb/mod.rs b/lambda-events/src/event/alb/mod.rs index b9a69ce5..dd9c86c9 100644 --- a/lambda-events/src/event/alb/mod.rs +++ b/lambda-events/src/event/alb/mod.rs @@ -1,4 +1,6 @@ -use crate::custom_serde::{http_method, serialize_headers, serialize_multi_value_headers}; +use crate::custom_serde::{ + deserialize_headers, deserialize_nullish_boolean, http_method, serialize_headers, serialize_multi_value_headers, +}; use crate::encodings::Body; use http::{HeaderMap, Method}; use query_map::QueryMap; @@ -15,13 +17,14 @@ pub struct AlbTargetGroupRequest { pub query_string_parameters: QueryMap, #[serde(default)] pub multi_value_query_string_parameters: QueryMap, - #[serde(deserialize_with = "http_serde::header_map::deserialize", default)] + #[serde(deserialize_with = "deserialize_headers", default)] #[serde(serialize_with = "serialize_headers")] pub headers: HeaderMap, - #[serde(deserialize_with = "http_serde::header_map::deserialize", default)] + #[serde(deserialize_with = "deserialize_headers", default)] #[serde(serialize_with = "serialize_multi_value_headers")] pub multi_value_headers: HeaderMap, pub request_context: AlbTargetGroupRequestContext, + #[serde(default, deserialize_with = "deserialize_nullish_boolean")] pub is_base64_encoded: bool, pub body: Option, } @@ -57,6 +60,7 @@ pub struct AlbTargetGroupResponse { pub multi_value_headers: HeaderMap, #[serde(skip_serializing_if = "Option::is_none")] pub body: Option, + #[serde(default, deserialize_with = "deserialize_nullish_boolean")] pub is_base64_encoded: bool, } diff --git a/lambda-events/src/event/appsync/mod.rs b/lambda-events/src/event/appsync/mod.rs index 0ef67b7b..336041a0 100644 --- a/lambda-events/src/event/appsync/mod.rs +++ b/lambda-events/src/event/appsync/mod.rs @@ -1,9 +1,10 @@ -use crate::custom_serde::*; use serde::de::DeserializeOwned; use serde::ser::Serialize; use serde_json::Value; use std::collections::HashMap; +use crate::custom_serde::deserialize_lambda_map; + /// Deprecated: `AppSyncResolverTemplate` does not represent resolver events sent by AppSync. Instead directly model your input schema, or use map[string]string, json.RawMessage, interface{}, etc.. #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/autoscaling/mod.rs b/lambda-events/src/event/autoscaling/mod.rs index ce0128c2..d3d28e9d 100644 --- a/lambda-events/src/event/autoscaling/mod.rs +++ b/lambda-events/src/event/autoscaling/mod.rs @@ -1,10 +1,11 @@ -use crate::custom_serde::*; use chrono::{DateTime, Utc}; use serde::de::DeserializeOwned; use serde::ser::Serialize; use serde_json::Value; use std::collections::HashMap; +use crate::custom_serde::deserialize_lambda_map; + /// `AutoScalingEvent` struct is used to parse the json for auto scaling event types // #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/codebuild/mod.rs b/lambda-events/src/event/codebuild/mod.rs index 2c6ddf39..93a0de90 100644 --- a/lambda-events/src/event/codebuild/mod.rs +++ b/lambda-events/src/event/codebuild/mod.rs @@ -1,4 +1,4 @@ -use crate::custom_serde::*; +use crate::custom_serde::{codebuild_time, CodeBuildNumber}; use crate::encodings::{MinuteDuration, SecondDuration}; use chrono::{DateTime, Utc}; use serde::de::DeserializeOwned; diff --git a/lambda-events/src/event/cognito/mod.rs b/lambda-events/src/event/cognito/mod.rs index 99bc682b..9a57f965 100644 --- a/lambda-events/src/event/cognito/mod.rs +++ b/lambda-events/src/event/cognito/mod.rs @@ -1,9 +1,10 @@ -use crate::custom_serde::*; use serde::de::DeserializeOwned; use serde::ser::Serialize; use serde_json::Value; use std::collections::HashMap; +use crate::custom_serde::{deserialize_lambda_map, deserialize_nullish_boolean}; + /// `CognitoEvent` contains data from an event sent from AWS Cognito Sync #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/connect/mod.rs b/lambda-events/src/event/connect/mod.rs index 62e86b52..c48ed49f 100644 --- a/lambda-events/src/event/connect/mod.rs +++ b/lambda-events/src/event/connect/mod.rs @@ -1,6 +1,7 @@ -use crate::custom_serde::*; use std::collections::HashMap; +use crate::custom_serde::deserialize_lambda_map; + /// `ConnectEvent` contains the data structure for a Connect event. #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/dynamodb/attributes.rs b/lambda-events/src/event/dynamodb/attributes.rs index d2f32caf..aad2cd4b 100644 --- a/lambda-events/src/event/dynamodb/attributes.rs +++ b/lambda-events/src/event/dynamodb/attributes.rs @@ -1,5 +1,5 @@ use base64::Engine; -use event::serde_dynamo::AttributeValue; +use serde_dynamo::AttributeValue; use std::collections::HashMap; #[cfg(test)] diff --git a/lambda-events/src/event/dynamodb/mod.rs b/lambda-events/src/event/dynamodb/mod.rs index 00ff08e4..cec6c608 100644 --- a/lambda-events/src/event/dynamodb/mod.rs +++ b/lambda-events/src/event/dynamodb/mod.rs @@ -1,8 +1,7 @@ -use crate::custom_serde::*; -use crate::streams::DynamoDbBatchItemFailure; +use crate::custom_serde::deserialize_lambda_dynamodb_item; use crate::time_window::*; +use crate::{custom_serde::float_unix_epoch, streams::DynamoDbBatchItemFailure}; use chrono::{DateTime, Utc}; -use serde::{Deserialize, Serialize}; use std::fmt; #[cfg(test)] diff --git a/lambda-events/src/event/firehose/mod.rs b/lambda-events/src/event/firehose/mod.rs index 63ef3e1f..20d95259 100644 --- a/lambda-events/src/event/firehose/mod.rs +++ b/lambda-events/src/event/firehose/mod.rs @@ -1,5 +1,7 @@ -use crate::custom_serde::*; -use crate::encodings::{Base64Data, MillisecondTimestamp}; +use crate::{ + custom_serde::deserialize_lambda_map, + encodings::{Base64Data, MillisecondTimestamp}, +}; use std::collections::HashMap; /// `KinesisFirehoseEvent` represents the input event from Amazon Kinesis Firehose. It is used as the input parameter. diff --git a/lambda-events/src/event/iot/mod.rs b/lambda-events/src/event/iot/mod.rs index 9f45899f..f91eaae5 100644 --- a/lambda-events/src/event/iot/mod.rs +++ b/lambda-events/src/event/iot/mod.rs @@ -1,4 +1,4 @@ -use crate::custom_serde::*; +use crate::custom_serde::serialize_headers; use crate::encodings::Base64Data; use crate::iam::IamPolicyDocument; use http::HeaderMap; diff --git a/lambda-events/src/event/iot_1_click/mod.rs b/lambda-events/src/event/iot_1_click/mod.rs index 0e1c11b6..5189463e 100644 --- a/lambda-events/src/event/iot_1_click/mod.rs +++ b/lambda-events/src/event/iot_1_click/mod.rs @@ -1,6 +1,7 @@ -use crate::custom_serde::*; use std::collections::HashMap; +use crate::custom_serde::deserialize_lambda_map; + /// `IoTOneClickEvent` represents a click event published by clicking button type /// device. #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] @@ -57,8 +58,7 @@ pub struct IoTOneClickPlacementInfo { #[cfg(test)] mod test { use super::*; - - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "iot_1_click")] diff --git a/lambda-events/src/event/kafka/mod.rs b/lambda-events/src/event/kafka/mod.rs index 6c4d78fa..a72735b4 100644 --- a/lambda-events/src/event/kafka/mod.rs +++ b/lambda-events/src/event/kafka/mod.rs @@ -1,5 +1,4 @@ -use crate::custom_serde::*; -use crate::encodings::MillisecondTimestamp; +use crate::{custom_serde::deserialize_lambda_map, encodings::MillisecondTimestamp}; use std::collections::HashMap; #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] diff --git a/lambda-events/src/event/lambda_function_urls/mod.rs b/lambda-events/src/event/lambda_function_urls/mod.rs index d1567b56..d7f8884f 100644 --- a/lambda-events/src/event/lambda_function_urls/mod.rs +++ b/lambda-events/src/event/lambda_function_urls/mod.rs @@ -1,7 +1,8 @@ -use crate::custom_serde::*; use http::HeaderMap; use std::collections::HashMap; +use crate::custom_serde::{deserialize_lambda_map, serialize_headers}; + /// `LambdaFunctionUrlRequest` contains data coming from the HTTP request to a Lambda Function URL. #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/lex/mod.rs b/lambda-events/src/event/lex/mod.rs index a3593dfd..3fb67699 100644 --- a/lambda-events/src/event/lex/mod.rs +++ b/lambda-events/src/event/lex/mod.rs @@ -1,6 +1,7 @@ -use crate::custom_serde::*; use std::collections::HashMap; +use crate::custom_serde::deserialize_lambda_map; + #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct LexEvent { diff --git a/lambda-events/src/event/rabbitmq/mod.rs b/lambda-events/src/event/rabbitmq/mod.rs index c8af802f..98eb83dc 100644 --- a/lambda-events/src/event/rabbitmq/mod.rs +++ b/lambda-events/src/event/rabbitmq/mod.rs @@ -1,9 +1,10 @@ -use crate::custom_serde::*; use serde::de::DeserializeOwned; use serde::ser::Serialize; use serde_json::Value; use std::collections::HashMap; +use crate::custom_serde::deserialize_lambda_map; + #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct RabbitMqEvent { diff --git a/lambda-events/src/event/s3/event.rs b/lambda-events/src/event/s3/event.rs index b25cfdd2..ea3b05e6 100644 --- a/lambda-events/src/event/s3/event.rs +++ b/lambda-events/src/event/s3/event.rs @@ -1,7 +1,8 @@ -use crate::custom_serde::*; use chrono::{DateTime, Utc}; use std::collections::HashMap; +use crate::custom_serde::deserialize_lambda_map; + /// `S3Event` which wrap an array of `S3Event`Record #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/s3/object_lambda.rs b/lambda-events/src/event/s3/object_lambda.rs index e31a751e..a0d898a0 100644 --- a/lambda-events/src/event/s3/object_lambda.rs +++ b/lambda-events/src/event/s3/object_lambda.rs @@ -1,10 +1,11 @@ -use crate::custom_serde::*; use http::HeaderMap; use serde::de::DeserializeOwned; use serde::ser::Serialize; use serde_json::Value; use std::collections::HashMap; +use crate::custom_serde::{deserialize_headers, serialize_headers}; + /// `S3ObjectLambdaEvent` contains data coming from S3 object lambdas /// See: https://docs.aws.amazon.com/AmazonS3/latest/userguide/olap-writing-lambda.html #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] diff --git a/lambda-events/src/event/sns/mod.rs b/lambda-events/src/event/sns/mod.rs index 78193fcf..6a8ba50a 100644 --- a/lambda-events/src/event/sns/mod.rs +++ b/lambda-events/src/event/sns/mod.rs @@ -1,9 +1,10 @@ -use crate::custom_serde::*; use chrono::{DateTime, Utc}; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use std::collections::HashMap; +use crate::custom_serde::deserialize_lambda_map; + /// The `Event` notification event handled by Lambda /// /// [https://docs.aws.amazon.com/lambda/latest/dg/with-sns.html](https://docs.aws.amazon.com/lambda/latest/dg/with-sns.html) diff --git a/lambda-events/src/event/sqs/mod.rs b/lambda-events/src/event/sqs/mod.rs index 5dc178b2..c1bc14d8 100644 --- a/lambda-events/src/event/sqs/mod.rs +++ b/lambda-events/src/event/sqs/mod.rs @@ -1,4 +1,5 @@ -use crate::{custom_serde::*, encodings::Base64Data}; +use crate::custom_serde::deserialize_lambda_map; +use crate::encodings::Base64Data; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use std::collections::HashMap; diff --git a/lambda-events/src/lib.rs b/lambda-events/src/lib.rs index 3647096d..4ea05820 100644 --- a/lambda-events/src/lib.rs +++ b/lambda-events/src/lib.rs @@ -1,24 +1,13 @@ -extern crate base64; -extern crate http_serde; -#[cfg(test)] -#[macro_use] -extern crate pretty_assertions; #[macro_use] extern crate serde_derive; #[cfg(test)] #[macro_use] extern crate serde_json; -// Crates with types that we use publicly. Reexported for ease of interoperability. -pub extern crate bytes; -#[cfg(feature = "chrono")] -pub extern crate chrono; -pub extern crate http; -pub extern crate http_body; -pub extern crate query_map; -pub extern crate serde; -#[cfg(not(test))] -pub extern crate serde_json; +#[cfg(feature = "http")] +pub use http; +#[cfg(feature = "query_map")] +pub use query_map; mod custom_serde; /// Encodings used in AWS Lambda json event values. diff --git a/lambda-http/Cargo.toml b/lambda-http/Cargo.toml index 289aec17..e2ec0e83 100644 --- a/lambda-http/Cargo.toml +++ b/lambda-http/Cargo.toml @@ -42,7 +42,7 @@ percent-encoding = "2.2" path = "../lambda-events" version = "0.9.0" default-features = false -features = ["alb", "apigw"] +features = ["alb", "apigw", "query_map"] [dev-dependencies] log = "^0.4" From 7d57ad4a859b27d4638f1afb36564a88939551fc Mon Sep 17 00:00:00 2001 From: David Calavera Date: Sat, 27 May 2023 18:56:59 -0700 Subject: [PATCH 4/5] Remove old idioms So people don't have to learn 2015 idioms like `extern crate` and implicit macro imports. Signed-off-by: David Calavera --- Makefile | 5 ++++- lambda-events/Cargo.toml | 6 +----- .../src/custom_serde/codebuild_time.rs | 11 +++++++---- .../src/custom_serde/float_unix_epoch.rs | 6 +++--- lambda-events/src/custom_serde/headers.rs | 13 +++++++------ lambda-events/src/custom_serde/http_method.rs | 11 ++++++----- lambda-events/src/custom_serde/mod.rs | 11 ++++++----- lambda-events/src/encodings/http.rs | 2 +- lambda-events/src/encodings/mod.rs | 5 +++-- lambda-events/src/encodings/time.rs | 17 ++++++++++------- lambda-events/src/event/activemq/mod.rs | 3 ++- lambda-events/src/event/alb/mod.rs | 3 ++- lambda-events/src/event/apigw/mod.rs | 4 ++-- lambda-events/src/event/appsync/mod.rs | 4 ++-- lambda-events/src/event/autoscaling/mod.rs | 4 ++-- lambda-events/src/event/chime_bot/mod.rs | 1 + lambda-events/src/event/clientvpn/mod.rs | 4 +++- .../src/event/cloudwatch_events/cloudtrail.rs | 3 +-- .../src/event/cloudwatch_events/codedeploy.rs | 3 +-- .../src/event/cloudwatch_events/codepipeline.rs | 3 +-- .../src/event/cloudwatch_events/ec2.rs | 3 +-- .../src/event/cloudwatch_events/emr.rs | 3 +-- .../src/event/cloudwatch_events/gamelift.rs | 3 +-- .../src/event/cloudwatch_events/glue.rs | 3 +-- .../src/event/cloudwatch_events/health.rs | 4 +--- .../src/event/cloudwatch_events/kms.rs | 3 +-- .../src/event/cloudwatch_events/macie.rs | 4 +--- .../src/event/cloudwatch_events/mod.rs | 2 +- .../src/event/cloudwatch_events/opsworks.rs | 3 +-- .../src/event/cloudwatch_events/signin.rs | 3 +-- .../src/event/cloudwatch_events/sms.rs | 3 +-- .../src/event/cloudwatch_events/ssm.rs | 4 +--- .../src/event/cloudwatch_events/tag.rs | 3 +-- .../event/cloudwatch_events/trustedadvisor.rs | 4 +--- lambda-events/src/event/cloudwatch_logs/mod.rs | 2 +- lambda-events/src/event/code_commit/mod.rs | 3 ++- lambda-events/src/event/codebuild/mod.rs | 4 ++-- lambda-events/src/event/codedeploy/mod.rs | 3 ++- .../src/event/codepipeline_cloudwatch/mod.rs | 3 ++- lambda-events/src/event/codepipeline_job/mod.rs | 4 +++- lambda-events/src/event/cognito/mod.rs | 4 ++-- lambda-events/src/event/config/mod.rs | 4 +++- lambda-events/src/event/connect/mod.rs | 3 ++- lambda-events/src/event/dynamodb/mod.rs | 3 ++- lambda-events/src/event/ecr_scan/mod.rs | 4 +++- lambda-events/src/event/firehose/mod.rs | 3 ++- lambda-events/src/event/iam/mod.rs | 2 ++ lambda-events/src/event/iot/mod.rs | 3 ++- lambda-events/src/event/iot_1_click/mod.rs | 1 + lambda-events/src/event/iot_button/mod.rs | 4 +++- lambda-events/src/event/iot_deprecated/mod.rs | 1 + lambda-events/src/event/kafka/mod.rs | 3 ++- lambda-events/src/event/kinesis/analytics.rs | 1 + lambda-events/src/event/kinesis/event.rs | 3 ++- .../src/event/lambda_function_urls/mod.rs | 1 + lambda-events/src/event/lex/mod.rs | 3 ++- lambda-events/src/event/mod.rs | 2 -- lambda-events/src/event/rabbitmq/mod.rs | 4 ++-- lambda-events/src/event/s3/batch_job.rs | 2 ++ lambda-events/src/event/s3/event.rs | 3 ++- lambda-events/src/event/s3/object_lambda.rs | 4 ++-- lambda-events/src/event/ses/mod.rs | 3 ++- lambda-events/src/event/sns/mod.rs | 2 +- lambda-events/src/event/sqs/mod.rs | 2 +- lambda-events/src/event/streams/mod.rs | 2 ++ lambda-events/src/lib.rs | 7 +------ lambda-events/src/time_window.rs | 3 ++- 67 files changed, 139 insertions(+), 121 deletions(-) diff --git a/Makefile b/Makefile index e85010e8..544d08b7 100644 --- a/Makefile +++ b/Makefile @@ -100,4 +100,7 @@ check-event-features: cargo test --package aws_lambda_events --no-default-features --features ses cargo test --package aws_lambda_events --no-default-features --features sns cargo test --package aws_lambda_events --no-default-features --features sqs - cargo test --package aws_lambda_events --no-default-features --features streams \ No newline at end of file + cargo test --package aws_lambda_events --no-default-features --features streams + +fmt: + cargo +nightly fmt --all \ No newline at end of file diff --git a/lambda-events/Cargo.toml b/lambda-events/Cargo.toml index 930ee039..fc6f7c61 100644 --- a/lambda-events/Cargo.toml +++ b/lambda-events/Cargo.toml @@ -20,8 +20,7 @@ base64 = "0.21" http = { version = "0.2", optional = true } http-body = { version = "0.4", optional = true } http-serde = { version = "^1", optional = true } -serde = "^1" -serde_derive = "^1" +serde = { version = "^1", features = ["derive"] } serde_with = { version = "^3", features = ["json"], optional = true } serde_json = "^1" serde_dynamo = { version = "^4.1", optional = true } @@ -34,9 +33,6 @@ chrono = { version = "0.4.23", default-features = false, features = [ query_map = { version = "^0.6", features = ["serde", "url-query"], optional = true } flate2 = { version = "1.0.24", optional = true } -[dev-dependencies] -pretty_assertions = "1.3" - [features] default = [ "activemq", diff --git a/lambda-events/src/custom_serde/codebuild_time.rs b/lambda-events/src/custom_serde/codebuild_time.rs index c57ccd6a..94d0e2f5 100644 --- a/lambda-events/src/custom_serde/codebuild_time.rs +++ b/lambda-events/src/custom_serde/codebuild_time.rs @@ -1,6 +1,9 @@ use chrono::{DateTime, TimeZone, Utc}; -use serde::de::{Deserialize, Deserializer, Error as DeError, Visitor}; use serde::ser::Serializer; +use serde::{ + de::{Deserializer, Error as DeError, Visitor}, + Deserialize, +}; use std::fmt; // Jan 2, 2006 3:04:05 PM @@ -10,7 +13,7 @@ struct TimeVisitor; impl<'de> Visitor<'de> for TimeVisitor { type Value = DateTime; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { write!(formatter, "valid codebuild time: {}", CODEBUILD_TIME_FORMAT) } @@ -74,7 +77,7 @@ mod tests { #[serde(with = "str_time")] pub date: TestTime, } - let data = json!({ + let data = serde_json::json!({ "date": "Sep 1, 2017 4:12:29 PM" }); @@ -92,7 +95,7 @@ mod tests { #[serde(with = "optional_time")] pub date: Option, } - let data = json!({ + let data = serde_json::json!({ "date": "Sep 1, 2017 4:12:29 PM" }); diff --git a/lambda-events/src/custom_serde/float_unix_epoch.rs b/lambda-events/src/custom_serde/float_unix_epoch.rs index 54fc64e4..82fd51df 100644 --- a/lambda-events/src/custom_serde/float_unix_epoch.rs +++ b/lambda-events/src/custom_serde/float_unix_epoch.rs @@ -14,13 +14,13 @@ fn ne_timestamp(ts: T) -> SerdeError { } impl fmt::Debug for SerdeError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ChronoSerdeError({})", self) } } impl fmt::Display for SerdeError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { SerdeError::NonExistent { ref timestamp } => { write!(f, "value is not a legal timestamp: {}", timestamp) @@ -77,7 +77,7 @@ where impl<'de> de::Visitor<'de> for SecondsFloatTimestampVisitor { type Value = DateTime; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a unix timestamp as a float") } diff --git a/lambda-events/src/custom_serde/headers.rs b/lambda-events/src/custom_serde/headers.rs index 904ccd9b..9cb89e40 100644 --- a/lambda-events/src/custom_serde/headers.rs +++ b/lambda-events/src/custom_serde/headers.rs @@ -49,7 +49,7 @@ impl<'de> Visitor<'de> for HeaderMapVisitor { type Value = HeaderMap; // Format a message stating what data this Visitor expects to receive. - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("lots of things can go wrong with HeaderMap") } @@ -81,7 +81,7 @@ impl<'de> Visitor<'de> for HeaderMapVisitor { let mut map = HeaderMap::with_capacity(access.size_hint().unwrap_or(0)); if !self.is_human_readable { - while let Some((key, arr)) = access.next_entry::, Vec>>()? { + while let Some((key, arr)) = access.next_entry::, Vec>>()? { let key = HeaderName::from_bytes(key.as_bytes()) .map_err(|_| de::Error::invalid_value(Unexpected::Str(&key), &self))?; for val in arr { @@ -91,7 +91,7 @@ impl<'de> Visitor<'de> for HeaderMapVisitor { } } } else { - while let Some((key, val)) = access.next_entry::, OneOrMore>()? { + while let Some((key, val)) = access.next_entry::, OneOrMore<'_>>()? { let key = HeaderName::from_bytes(key.as_bytes()) .map_err(|_| de::Error::invalid_value(Unexpected::Str(&key), &self))?; match val { @@ -135,6 +135,7 @@ where #[cfg(test)] mod tests { use super::*; + use serde::{Deserialize, Serialize}; #[test] fn test_deserialize_missing_http_headers() { @@ -143,7 +144,7 @@ mod tests { #[serde(deserialize_with = "deserialize_headers", default)] pub headers: HeaderMap, } - let data = json!({ + let data = serde_json::json!({ "not_headers": {} }); @@ -161,7 +162,7 @@ mod tests { #[serde(serialize_with = "serialize_multi_value_headers")] headers: HeaderMap, } - let data = json!({ + let data = serde_json::json!({ "headers": { "Accept": ["*/*"] } @@ -181,7 +182,7 @@ mod tests { #[serde(deserialize_with = "deserialize_headers")] headers: HeaderMap, } - let data = json!({ "headers": null }); + let data = serde_json::json!({ "headers": null }); let decoded: Test = serde_json::from_value(data).unwrap(); assert!(decoded.headers.is_empty()); diff --git a/lambda-events/src/custom_serde/http_method.rs b/lambda-events/src/custom_serde/http_method.rs index 6060a429..63a98eb4 100644 --- a/lambda-events/src/custom_serde/http_method.rs +++ b/lambda-events/src/custom_serde/http_method.rs @@ -11,7 +11,7 @@ struct MethodVisitor; impl<'de> Visitor<'de> for MethodVisitor { type Value = Method; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { write!(formatter, "valid method name") } @@ -56,6 +56,7 @@ pub fn serialize_optional(method: &Option, ser: S) -> Res #[cfg(test)] mod tests { use super::*; + use serde::{Deserialize, Serialize}; #[test] fn test_http_method_serializer() { @@ -64,7 +65,7 @@ mod tests { #[serde(with = "crate::custom_serde::http_method")] pub method: http::Method, } - let data = json!({ + let data = serde_json::json!({ "method": "DELETE" }); let decoded: Test = serde_json::from_value(data.clone()).unwrap(); @@ -83,7 +84,7 @@ mod tests { #[serde(default)] pub method: Option, } - let data = json!({ + let data = serde_json::json!({ "method": "DELETE" }); let decoded: Test = serde_json::from_value(data.clone()).unwrap(); @@ -92,11 +93,11 @@ mod tests { let recoded = serde_json::to_value(decoded).unwrap(); assert_eq!(data, recoded); - let data = json!({ "method": null }); + let data = serde_json::json!({ "method": null }); let decoded: Test = serde_json::from_value(data).unwrap(); assert_eq!(None, decoded.method); - let data = json!({}); + let data = serde_json::json!({}); let decoded: Test = serde_json::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 2a8dd88e..65f0f89a 100644 --- a/lambda-events/src/custom_serde/mod.rs +++ b/lambda-events/src/custom_serde/mod.rs @@ -95,6 +95,7 @@ where #[allow(deprecated)] mod test { use super::*; + use serde::{Deserialize, Serialize}; use serde_json; #[test] @@ -104,7 +105,7 @@ mod test { #[serde(deserialize_with = "deserialize_base64")] v: Vec, } - let data = json!({ + let data = serde_json::json!({ "v": "SGVsbG8gV29ybGQ=", }); let decoded: Test = serde_json::from_value(data).unwrap(); @@ -132,13 +133,13 @@ mod test { #[serde(deserialize_with = "deserialize_lambda_map")] v: HashMap, } - let input = json!({ + let input = serde_json::json!({ "v": {}, }); let decoded: Test = serde_json::from_value(input).unwrap(); assert_eq!(HashMap::new(), decoded.v); - let input = json!({ + let input = serde_json::json!({ "v": null, }); let decoded: Test = serde_json::from_value(input).unwrap(); @@ -153,13 +154,13 @@ mod test { #[serde(deserialize_with = "deserialize_lambda_dynamodb_item")] v: serde_dynamo::Item, } - let input = json!({ + let input = serde_json::json!({ "v": {}, }); let decoded: Test = serde_json::from_value(input).unwrap(); assert_eq!(serde_dynamo::Item::from(HashMap::new()), decoded.v); - let input = json!({ + let input = serde_json::json!({ "v": null, }); let decoded: Test = serde_json::from_value(input).unwrap(); diff --git a/lambda-events/src/encodings/http.rs b/lambda-events/src/encodings/http.rs index c090b653..effb48f4 100644 --- a/lambda-events/src/encodings/http.rs +++ b/lambda-events/src/encodings/http.rs @@ -198,7 +198,7 @@ impl<'de> Deserialize<'de> for Body { impl<'de> Visitor<'de> for BodyVisitor { type Value = Body; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { formatter.write_str("string") } diff --git a/lambda-events/src/encodings/mod.rs b/lambda-events/src/encodings/mod.rs index 30472ce6..ccc92684 100644 --- a/lambda-events/src/encodings/mod.rs +++ b/lambda-events/src/encodings/mod.rs @@ -1,7 +1,6 @@ +use serde::{Deserialize, Serialize}; use std::{ops::Deref, ops::DerefMut}; -pub type Error = Box; - #[cfg(feature = "chrono")] mod time; use crate::custom_serde::{deserialize_base64, serialize_base64}; @@ -13,6 +12,8 @@ mod http; #[cfg(feature = "http")] pub use self::http::*; +pub type Error = Box; + /// Binary data encoded in base64. #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub struct Base64Data( diff --git a/lambda-events/src/encodings/time.rs b/lambda-events/src/encodings/time.rs index f2147328..390927ca 100644 --- a/lambda-events/src/encodings/time.rs +++ b/lambda-events/src/encodings/time.rs @@ -1,6 +1,9 @@ use chrono::{DateTime, Duration, TimeZone, Utc}; -use serde::de::{Deserialize, Deserializer, Error as DeError}; use serde::ser::Serializer; +use serde::{ + de::{Deserializer, Error as DeError}, + Deserialize, Serialize, +}; use std::ops::{Deref, DerefMut}; /// Timestamp with millisecond precision. @@ -224,7 +227,7 @@ mod test { let expected = Utc.ymd(2017, 10, 5).and_hms_nano(15, 33, 44, 302_000_000); // Test parsing strings. - let data = json!({ + let data = serde_json::json!({ "v": "1507217624302", }); let decoded: Test = serde_json::from_value(data).unwrap(); @@ -233,7 +236,7 @@ mod test { let decoded: Test = serde_json::from_slice(r#"{"v":1507217624302}"#.as_bytes()).unwrap(); assert_eq!(expected, decoded.v,); // Test parsing floats. - let data = json!({ + let data = serde_json::json!({ "v": 1507217624302.0, }); let decoded: Test = serde_json::from_value(data).unwrap(); @@ -294,13 +297,13 @@ mod test { let expected = Duration::seconds(36); - let data = json!({ + let data = serde_json::json!({ "v": 36, }); let decoded: Test = serde_json::from_value(data).unwrap(); assert_eq!(expected, decoded.v,); - let data = json!({ + let data = serde_json::json!({ "v": 36.1, }); let decoded: Test = serde_json::from_value(data).unwrap(); @@ -331,13 +334,13 @@ mod test { let expected = Duration::minutes(36); - let data = json!({ + let data = serde_json::json!({ "v": 36, }); let decoded: Test = serde_json::from_value(data).unwrap(); assert_eq!(expected, decoded.v,); - let data = json!({ + let data = serde_json::json!({ "v": 36.1, }); let decoded: Test = serde_json::from_value(data).unwrap(); diff --git a/lambda-events/src/event/activemq/mod.rs b/lambda-events/src/event/activemq/mod.rs index afa16a0d..9469ece4 100644 --- a/lambda-events/src/event/activemq/mod.rs +++ b/lambda-events/src/event/activemq/mod.rs @@ -1,3 +1,4 @@ +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; @@ -53,7 +54,7 @@ pub struct ActiveMqDestination { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "activemq")] diff --git a/lambda-events/src/event/alb/mod.rs b/lambda-events/src/event/alb/mod.rs index dd9c86c9..259dce23 100644 --- a/lambda-events/src/event/alb/mod.rs +++ b/lambda-events/src/event/alb/mod.rs @@ -4,6 +4,7 @@ use crate::custom_serde::{ use crate::encodings::Body; use http::{HeaderMap, Method}; use query_map::QueryMap; +use serde::{Deserialize, Serialize}; /// `AlbTargetGroupRequest` contains data originating from the ALB Lambda target group integration #[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)] @@ -68,7 +69,7 @@ pub struct AlbTargetGroupResponse { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "alb")] diff --git a/lambda-events/src/event/apigw/mod.rs b/lambda-events/src/event/apigw/mod.rs index 196bff86..917f06aa 100644 --- a/lambda-events/src/event/apigw/mod.rs +++ b/lambda-events/src/event/apigw/mod.rs @@ -6,7 +6,7 @@ use crate::encodings::Body; use http::{HeaderMap, Method}; use query_map::QueryMap; use serde::de::DeserializeOwned; -use serde::ser::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::HashMap; @@ -751,7 +751,7 @@ pub struct IamPolicyStatement { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "apigw")] diff --git a/lambda-events/src/event/appsync/mod.rs b/lambda-events/src/event/appsync/mod.rs index 336041a0..120fc9e3 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; -use serde::ser::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::HashMap; @@ -122,7 +122,7 @@ where mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "appsync")] diff --git a/lambda-events/src/event/autoscaling/mod.rs b/lambda-events/src/event/autoscaling/mod.rs index d3d28e9d..cc003daf 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; -use serde::ser::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::HashMap; @@ -48,7 +48,7 @@ where mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "autoscaling")] diff --git a/lambda-events/src/event/chime_bot/mod.rs b/lambda-events/src/event/chime_bot/mod.rs index ef57c6f9..6581ed2c 100644 --- a/lambda-events/src/event/chime_bot/mod.rs +++ b/lambda-events/src/event/chime_bot/mod.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/clientvpn/mod.rs b/lambda-events/src/event/clientvpn/mod.rs index f0e61dda..0e188704 100644 --- a/lambda-events/src/event/clientvpn/mod.rs +++ b/lambda-events/src/event/clientvpn/mod.rs @@ -1,3 +1,5 @@ +use serde::{Deserialize, Serialize}; + #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct ClientVpnConnectionHandlerRequest { @@ -47,7 +49,7 @@ pub struct ClientVpnConnectionHandlerResponse { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "clientvpn")] diff --git a/lambda-events/src/event/cloudwatch_events/cloudtrail.rs b/lambda-events/src/event/cloudwatch_events/cloudtrail.rs index aefa7f4a..36d071ea 100644 --- a/lambda-events/src/event/cloudwatch_events/cloudtrail.rs +++ b/lambda-events/src/event/cloudwatch_events/cloudtrail.rs @@ -1,5 +1,4 @@ -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] diff --git a/lambda-events/src/event/cloudwatch_events/codedeploy.rs b/lambda-events/src/event/cloudwatch_events/codedeploy.rs index 0dd2b540..1bd44297 100644 --- a/lambda-events/src/event/cloudwatch_events/codedeploy.rs +++ b/lambda-events/src/event/cloudwatch_events/codedeploy.rs @@ -1,5 +1,4 @@ -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/cloudwatch_events/codepipeline.rs b/lambda-events/src/event/cloudwatch_events/codepipeline.rs index 86a1de15..ce5fa47c 100644 --- a/lambda-events/src/event/cloudwatch_events/codepipeline.rs +++ b/lambda-events/src/event/cloudwatch_events/codepipeline.rs @@ -1,5 +1,4 @@ -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/cloudwatch_events/ec2.rs b/lambda-events/src/event/cloudwatch_events/ec2.rs index c4e26b4e..c8eb7834 100644 --- a/lambda-events/src/event/cloudwatch_events/ec2.rs +++ b/lambda-events/src/event/cloudwatch_events/ec2.rs @@ -1,5 +1,4 @@ -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/cloudwatch_events/emr.rs b/lambda-events/src/event/cloudwatch_events/emr.rs index 942e5984..87fb8085 100644 --- a/lambda-events/src/event/cloudwatch_events/emr.rs +++ b/lambda-events/src/event/cloudwatch_events/emr.rs @@ -1,5 +1,4 @@ -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/cloudwatch_events/gamelift.rs b/lambda-events/src/event/cloudwatch_events/gamelift.rs index 1369a793..fb5c50a7 100644 --- a/lambda-events/src/event/cloudwatch_events/gamelift.rs +++ b/lambda-events/src/event/cloudwatch_events/gamelift.rs @@ -1,5 +1,4 @@ -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; use crate::custom_serde::deserialize_nullish_boolean; diff --git a/lambda-events/src/event/cloudwatch_events/glue.rs b/lambda-events/src/event/cloudwatch_events/glue.rs index f752f53e..08f05929 100644 --- a/lambda-events/src/event/cloudwatch_events/glue.rs +++ b/lambda-events/src/event/cloudwatch_events/glue.rs @@ -1,5 +1,4 @@ -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/cloudwatch_events/health.rs b/lambda-events/src/event/cloudwatch_events/health.rs index 3c8acbf9..2a6a82e3 100644 --- a/lambda-events/src/event/cloudwatch_events/health.rs +++ b/lambda-events/src/event/cloudwatch_events/health.rs @@ -1,8 +1,6 @@ +use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use serde_derive::Deserialize; -use serde_derive::Serialize; - #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct Event { diff --git a/lambda-events/src/event/cloudwatch_events/kms.rs b/lambda-events/src/event/cloudwatch_events/kms.rs index ac6f8926..74a76e70 100644 --- a/lambda-events/src/event/cloudwatch_events/kms.rs +++ b/lambda-events/src/event/cloudwatch_events/kms.rs @@ -1,5 +1,4 @@ -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/cloudwatch_events/macie.rs b/lambda-events/src/event/cloudwatch_events/macie.rs index 4ce78b71..37d18d7a 100644 --- a/lambda-events/src/event/cloudwatch_events/macie.rs +++ b/lambda-events/src/event/cloudwatch_events/macie.rs @@ -1,8 +1,6 @@ +use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use serde_derive::Deserialize; -use serde_derive::Serialize; - #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct Alert { diff --git a/lambda-events/src/event/cloudwatch_events/mod.rs b/lambda-events/src/event/cloudwatch_events/mod.rs index 3c39e3d3..425de865 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; -use serde::ser::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; pub mod cloudtrail; diff --git a/lambda-events/src/event/cloudwatch_events/opsworks.rs b/lambda-events/src/event/cloudwatch_events/opsworks.rs index c75f1b5e..d1c192e5 100644 --- a/lambda-events/src/event/cloudwatch_events/opsworks.rs +++ b/lambda-events/src/event/cloudwatch_events/opsworks.rs @@ -1,5 +1,4 @@ -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/cloudwatch_events/signin.rs b/lambda-events/src/event/cloudwatch_events/signin.rs index 4d256e3b..1cd73e6e 100644 --- a/lambda-events/src/event/cloudwatch_events/signin.rs +++ b/lambda-events/src/event/cloudwatch_events/signin.rs @@ -1,5 +1,4 @@ -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] diff --git a/lambda-events/src/event/cloudwatch_events/sms.rs b/lambda-events/src/event/cloudwatch_events/sms.rs index 33092b76..7d161822 100644 --- a/lambda-events/src/event/cloudwatch_events/sms.rs +++ b/lambda-events/src/event/cloudwatch_events/sms.rs @@ -1,5 +1,4 @@ -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/cloudwatch_events/ssm.rs b/lambda-events/src/event/cloudwatch_events/ssm.rs index a826ed07..fa6ffc3b 100644 --- a/lambda-events/src/event/cloudwatch_events/ssm.rs +++ b/lambda-events/src/event/cloudwatch_events/ssm.rs @@ -1,8 +1,6 @@ +use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use serde_derive::Deserialize; -use serde_derive::Serialize; - #[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct EC2AutomationStepStatusChange { diff --git a/lambda-events/src/event/cloudwatch_events/tag.rs b/lambda-events/src/event/cloudwatch_events/tag.rs index 573a99ea..d5bc9681 100644 --- a/lambda-events/src/event/cloudwatch_events/tag.rs +++ b/lambda-events/src/event/cloudwatch_events/tag.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; -use serde_derive::Deserialize; -use serde_derive::Serialize; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/cloudwatch_events/trustedadvisor.rs b/lambda-events/src/event/cloudwatch_events/trustedadvisor.rs index ce6cf79f..6a7e25d3 100644 --- a/lambda-events/src/event/cloudwatch_events/trustedadvisor.rs +++ b/lambda-events/src/event/cloudwatch_events/trustedadvisor.rs @@ -1,8 +1,6 @@ +use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use serde_derive::Deserialize; -use serde_derive::Serialize; - #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct CheckItemRefreshNotification { diff --git a/lambda-events/src/event/cloudwatch_logs/mod.rs b/lambda-events/src/event/cloudwatch_logs/mod.rs index 053974ec..0c9ad4a8 100644 --- a/lambda-events/src/event/cloudwatch_logs/mod.rs +++ b/lambda-events/src/event/cloudwatch_logs/mod.rs @@ -59,7 +59,7 @@ impl<'de> Deserialize<'de> for AwsLogs { impl<'de> Visitor<'de> for AwsLogsVisitor { type Value = AwsLogs; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a base64 gzipped string") } diff --git a/lambda-events/src/event/code_commit/mod.rs b/lambda-events/src/event/code_commit/mod.rs index 8b2e617f..87687cfd 100644 --- a/lambda-events/src/event/code_commit/mod.rs +++ b/lambda-events/src/event/code_commit/mod.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; use crate::custom_serde::deserialize_nullish_boolean; @@ -68,7 +69,7 @@ pub struct CodeCommitReference { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "code_commit")] diff --git a/lambda-events/src/event/codebuild/mod.rs b/lambda-events/src/event/codebuild/mod.rs index 93a0de90..a3839f92 100644 --- a/lambda-events/src/event/codebuild/mod.rs +++ b/lambda-events/src/event/codebuild/mod.rs @@ -2,7 +2,7 @@ use crate::custom_serde::{codebuild_time, CodeBuildNumber}; use crate::encodings::{MinuteDuration, SecondDuration}; use chrono::{DateTime, Utc}; use serde::de::DeserializeOwned; -use serde::ser::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; pub type CodeBuildPhaseStatus = String; @@ -213,7 +213,7 @@ pub type CodeBuildTime = DateTime; mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "codebuild")] diff --git a/lambda-events/src/event/codedeploy/mod.rs b/lambda-events/src/event/codedeploy/mod.rs index 61bfc665..2ab37a82 100644 --- a/lambda-events/src/event/codedeploy/mod.rs +++ b/lambda-events/src/event/codedeploy/mod.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; pub type CodeDeployDeploymentState = String; @@ -68,7 +69,7 @@ pub struct CodeDeployEventDetail { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "codedeploy")] diff --git a/lambda-events/src/event/codepipeline_cloudwatch/mod.rs b/lambda-events/src/event/codepipeline_cloudwatch/mod.rs index d4d3477b..f26aa54f 100644 --- a/lambda-events/src/event/codepipeline_cloudwatch/mod.rs +++ b/lambda-events/src/event/codepipeline_cloudwatch/mod.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; pub type CodePipelineStageState = String; @@ -80,7 +81,7 @@ pub struct CodePipelineEventDetailType { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "codepipeline_cloudwatch")] diff --git a/lambda-events/src/event/codepipeline_job/mod.rs b/lambda-events/src/event/codepipeline_job/mod.rs index 0767b272..6c5d75f6 100644 --- a/lambda-events/src/event/codepipeline_job/mod.rs +++ b/lambda-events/src/event/codepipeline_job/mod.rs @@ -1,3 +1,5 @@ +use serde::{Deserialize, Serialize}; + /// `CodePipelineJobEvent` contains data from an event sent from AWS CodePipeline #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] @@ -115,7 +117,7 @@ pub struct CodePipelineArtifactCredentials { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "codepipeline_job")] diff --git a/lambda-events/src/event/cognito/mod.rs b/lambda-events/src/event/cognito/mod.rs index 9a57f965..6874ee24 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; -use serde::ser::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::HashMap; @@ -458,7 +458,7 @@ pub struct CognitoEventUserPoolsCustomMessageResponse { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "cognito")] diff --git a/lambda-events/src/event/config/mod.rs b/lambda-events/src/event/config/mod.rs index bb5d0c11..0b03ecc5 100644 --- a/lambda-events/src/event/config/mod.rs +++ b/lambda-events/src/event/config/mod.rs @@ -1,3 +1,5 @@ +use serde::{Deserialize, Serialize}; + /// `ConfigEvent` contains data from an event sent from AWS Config #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] @@ -38,7 +40,7 @@ pub struct ConfigEvent { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "config")] diff --git a/lambda-events/src/event/connect/mod.rs b/lambda-events/src/event/connect/mod.rs index c48ed49f..bc640930 100644 --- a/lambda-events/src/event/connect/mod.rs +++ b/lambda-events/src/event/connect/mod.rs @@ -1,3 +1,4 @@ +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; @@ -93,7 +94,7 @@ pub type ConnectResponse = HashMap; mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "connect")] diff --git a/lambda-events/src/event/dynamodb/mod.rs b/lambda-events/src/event/dynamodb/mod.rs index cec6c608..398f2dd5 100644 --- a/lambda-events/src/event/dynamodb/mod.rs +++ b/lambda-events/src/event/dynamodb/mod.rs @@ -2,6 +2,7 @@ use crate::custom_serde::deserialize_lambda_dynamodb_item; use crate::time_window::*; use crate::{custom_serde::float_unix_epoch, streams::DynamoDbBatchItemFailure}; use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; use std::fmt; #[cfg(test)] @@ -251,7 +252,7 @@ mod test { use super::*; use chrono::TimeZone; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "dynamodb")] diff --git a/lambda-events/src/event/ecr_scan/mod.rs b/lambda-events/src/event/ecr_scan/mod.rs index 87dede6f..1ed91896 100644 --- a/lambda-events/src/event/ecr_scan/mod.rs +++ b/lambda-events/src/event/ecr_scan/mod.rs @@ -1,3 +1,5 @@ +use serde::{Deserialize, Serialize}; + #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct EcrScanEvent { @@ -59,7 +61,7 @@ pub struct EcrScanEventFindingSeverityCounts { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "ecr_scan")] diff --git a/lambda-events/src/event/firehose/mod.rs b/lambda-events/src/event/firehose/mod.rs index 20d95259..352342ec 100644 --- a/lambda-events/src/event/firehose/mod.rs +++ b/lambda-events/src/event/firehose/mod.rs @@ -2,6 +2,7 @@ use crate::{ custom_serde::deserialize_lambda_map, encodings::{Base64Data, MillisecondTimestamp}, }; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; /// `KinesisFirehoseEvent` represents the input event from Amazon Kinesis Firehose. It is used as the input parameter. @@ -75,7 +76,7 @@ pub struct KinesisFirehoseRecordMetadata { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "firehose")] diff --git a/lambda-events/src/event/iam/mod.rs b/lambda-events/src/event/iam/mod.rs index 1b73e44b..12bf7ba9 100644 --- a/lambda-events/src/event/iam/mod.rs +++ b/lambda-events/src/event/iam/mod.rs @@ -1,3 +1,5 @@ +use serde::{Deserialize, Serialize}; + /// `IamPolicyDocument` represents an IAM policy document. #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/iot/mod.rs b/lambda-events/src/event/iot/mod.rs index f91eaae5..31220b17 100644 --- a/lambda-events/src/event/iot/mod.rs +++ b/lambda-events/src/event/iot/mod.rs @@ -2,6 +2,7 @@ use crate::custom_serde::serialize_headers; use crate::encodings::Base64Data; use crate::iam::IamPolicyDocument; use http::HeaderMap; +use serde::{Deserialize, Serialize}; /// `IoTCoreCustomAuthorizerRequest` represents the request to an IoT Core custom authorizer. /// See https://docs.aws.amazon.com/iot/latest/developerguide/config-custom-auth.html @@ -75,7 +76,7 @@ pub struct IoTCoreCustomAuthorizerResponse { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "iot")] diff --git a/lambda-events/src/event/iot_1_click/mod.rs b/lambda-events/src/event/iot_1_click/mod.rs index 5189463e..4ec47d71 100644 --- a/lambda-events/src/event/iot_1_click/mod.rs +++ b/lambda-events/src/event/iot_1_click/mod.rs @@ -1,3 +1,4 @@ +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; diff --git a/lambda-events/src/event/iot_button/mod.rs b/lambda-events/src/event/iot_button/mod.rs index 32ba8d5a..ac79e34b 100644 --- a/lambda-events/src/event/iot_button/mod.rs +++ b/lambda-events/src/event/iot_button/mod.rs @@ -1,3 +1,5 @@ +use serde::{Deserialize, Serialize}; + #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct IoTButtonEvent { @@ -13,7 +15,7 @@ pub struct IoTButtonEvent { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "iot_button")] diff --git a/lambda-events/src/event/iot_deprecated/mod.rs b/lambda-events/src/event/iot_deprecated/mod.rs index 4304d7cd..12c1df99 100644 --- a/lambda-events/src/event/iot_deprecated/mod.rs +++ b/lambda-events/src/event/iot_deprecated/mod.rs @@ -1,4 +1,5 @@ use crate::iot::*; +use serde::{Deserialize, Serialize}; /// `IoTCustomAuthorizerRequest` contains data coming in to a custom IoT device gateway authorizer function. /// Deprecated: Use IoTCoreCustomAuthorizerRequest instead. `IoTCustomAuthorizerRequest` does not correctly model the request schema diff --git a/lambda-events/src/event/kafka/mod.rs b/lambda-events/src/event/kafka/mod.rs index a72735b4..07299859 100644 --- a/lambda-events/src/event/kafka/mod.rs +++ b/lambda-events/src/event/kafka/mod.rs @@ -1,4 +1,5 @@ use crate::{custom_serde::deserialize_lambda_map, encodings::MillisecondTimestamp}; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] @@ -34,7 +35,7 @@ pub struct KafkaRecord { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "kafka")] diff --git a/lambda-events/src/event/kinesis/analytics.rs b/lambda-events/src/event/kinesis/analytics.rs index 1704009e..74c95606 100644 --- a/lambda-events/src/event/kinesis/analytics.rs +++ b/lambda-events/src/event/kinesis/analytics.rs @@ -1,4 +1,5 @@ use crate::encodings::Base64Data; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/kinesis/event.rs b/lambda-events/src/event/kinesis/event.rs index c401fa72..0c43ae10 100644 --- a/lambda-events/src/event/kinesis/event.rs +++ b/lambda-events/src/event/kinesis/event.rs @@ -1,5 +1,6 @@ use crate::encodings::{Base64Data, SecondTimestamp}; use crate::time_window::{TimeWindowEventResponseProperties, TimeWindowProperties}; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] @@ -74,7 +75,7 @@ pub struct KinesisRecord { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "kinesis")] diff --git a/lambda-events/src/event/lambda_function_urls/mod.rs b/lambda-events/src/event/lambda_function_urls/mod.rs index d7f8884f..37ddfe39 100644 --- a/lambda-events/src/event/lambda_function_urls/mod.rs +++ b/lambda-events/src/event/lambda_function_urls/mod.rs @@ -1,4 +1,5 @@ use http::HeaderMap; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use crate::custom_serde::{deserialize_lambda_map, serialize_headers}; diff --git a/lambda-events/src/event/lex/mod.rs b/lambda-events/src/event/lex/mod.rs index 3fb67699..a058a249 100644 --- a/lambda-events/src/event/lex/mod.rs +++ b/lambda-events/src/event/lex/mod.rs @@ -1,3 +1,4 @@ +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; @@ -107,7 +108,7 @@ pub struct Attachment { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "lex")] diff --git a/lambda-events/src/event/mod.rs b/lambda-events/src/event/mod.rs index e7b8c7f7..1aa56697 100644 --- a/lambda-events/src/event/mod.rs +++ b/lambda-events/src/event/mod.rs @@ -67,8 +67,6 @@ pub mod connect; /// AWS Lambda event definitions for dynamodb. #[cfg(feature = "dynamodb")] -extern crate serde_dynamo; -#[cfg(feature = "dynamodb")] pub mod dynamodb; /// AWS Lambda event definitions for ecr_scan. diff --git a/lambda-events/src/event/rabbitmq/mod.rs b/lambda-events/src/event/rabbitmq/mod.rs index 98eb83dc..14a379a5 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; -use serde::ser::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::HashMap; @@ -63,7 +63,7 @@ where mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "rabbitmq")] diff --git a/lambda-events/src/event/s3/batch_job.rs b/lambda-events/src/event/s3/batch_job.rs index 8db71896..e3eb691e 100644 --- a/lambda-events/src/event/s3/batch_job.rs +++ b/lambda-events/src/event/s3/batch_job.rs @@ -1,3 +1,5 @@ +use serde::{Deserialize, Serialize}; + /// `S3BatchJobEvent` encapsulates the detail of a s3 batch job #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/event/s3/event.rs b/lambda-events/src/event/s3/event.rs index ea3b05e6..13d514ad 100644 --- a/lambda-events/src/event/s3/event.rs +++ b/lambda-events/src/event/s3/event.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; @@ -91,7 +92,7 @@ pub struct S3Object { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "s3")] diff --git a/lambda-events/src/event/s3/object_lambda.rs b/lambda-events/src/event/s3/object_lambda.rs index a0d898a0..1eec2c0d 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; -use serde::ser::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::HashMap; @@ -118,7 +118,7 @@ pub struct SessionIssuer { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "s3")] diff --git a/lambda-events/src/event/ses/mod.rs b/lambda-events/src/event/ses/mod.rs index 3570652f..a4a97039 100644 --- a/lambda-events/src/event/ses/mod.rs +++ b/lambda-events/src/event/ses/mod.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; /// `SimpleEmailEvent` is the outer structure of an event sent via SES. #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] @@ -121,7 +122,7 @@ pub struct SimpleEmailDisposition { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "ses")] diff --git a/lambda-events/src/event/sns/mod.rs b/lambda-events/src/event/sns/mod.rs index 6a8ba50a..3c859d3e 100644 --- a/lambda-events/src/event/sns/mod.rs +++ b/lambda-events/src/event/sns/mod.rs @@ -179,7 +179,7 @@ pub struct MessageAttribute { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "sns")] diff --git a/lambda-events/src/event/sqs/mod.rs b/lambda-events/src/event/sqs/mod.rs index c1bc14d8..af4d3f21 100644 --- a/lambda-events/src/event/sqs/mod.rs +++ b/lambda-events/src/event/sqs/mod.rs @@ -116,7 +116,7 @@ pub struct BatchItemFailure { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] #[cfg(feature = "sqs")] diff --git a/lambda-events/src/event/streams/mod.rs b/lambda-events/src/event/streams/mod.rs index 51a77121..9e0fd76f 100644 --- a/lambda-events/src/event/streams/mod.rs +++ b/lambda-events/src/event/streams/mod.rs @@ -1,3 +1,5 @@ +use serde::{Deserialize, Serialize}; + /// `KinesisEventResponse` is the outer structure to report batch item failures for KinesisEvent. #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/lambda-events/src/lib.rs b/lambda-events/src/lib.rs index 4ea05820..564debd7 100644 --- a/lambda-events/src/lib.rs +++ b/lambda-events/src/lib.rs @@ -1,9 +1,4 @@ -#[macro_use] -extern crate serde_derive; -#[cfg(test)] -#[macro_use] -extern crate serde_json; - +#![deny(rust_2018_idioms)] #[cfg(feature = "http")] pub use http; #[cfg(feature = "query_map")] diff --git a/lambda-events/src/time_window.rs b/lambda-events/src/time_window.rs index 9418dc8c..9f035995 100644 --- a/lambda-events/src/time_window.rs +++ b/lambda-events/src/time_window.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use crate::custom_serde::deserialize_lambda_map; @@ -65,7 +66,7 @@ pub struct TimeWindowEventResponseProperties { mod test { use super::*; - extern crate serde_json; + use serde_json; #[test] fn test_window_deserializer() { From 6be612ac0731bdee8a5c13b56adaaa01ea0bcd4c Mon Sep 17 00:00:00 2001 From: David Calavera Date: Sat, 27 May 2023 18:58:58 -0700 Subject: [PATCH 5/5] Bump crate version Signed-off-by: David Calavera --- lambda-events/Cargo.toml | 2 +- lambda-http/Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lambda-events/Cargo.toml b/lambda-events/Cargo.toml index fc6f7c61..b1108c63 100644 --- a/lambda-events/Cargo.toml +++ b/lambda-events/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws_lambda_events" -version = "0.9.0" +version = "0.10.0" description = "AWS Lambda event definitions" authors = [ "Christian Legnitto ", diff --git a/lambda-http/Cargo.toml b/lambda-http/Cargo.toml index e2ec0e83..1409555e 100644 --- a/lambda-http/Cargo.toml +++ b/lambda-http/Cargo.toml @@ -40,9 +40,9 @@ percent-encoding = "2.2" [dependencies.aws_lambda_events] path = "../lambda-events" -version = "0.9.0" +version = "0.10.0" default-features = false -features = ["alb", "apigw", "query_map"] +features = ["alb", "apigw"] [dev-dependencies] log = "^0.4"