diff --git a/rust-runtime/aws-smithy-eventstream/Cargo.toml b/rust-runtime/aws-smithy-eventstream/Cargo.toml index a77aff9e85..ba924539c9 100644 --- a/rust-runtime/aws-smithy-eventstream/Cargo.toml +++ b/rust-runtime/aws-smithy-eventstream/Cargo.toml @@ -9,6 +9,8 @@ repository = "https://github.com/awslabs/smithy-rs" [features] derive-arbitrary = ["arbitrary", "derive_arbitrary"] +serde-serialize = [] +serde-deserialize = [] [dependencies] derive_arbitrary = { version = "=1.1.6", optional = true } # 1.2.0 requires Rust 1.63 to compile diff --git a/rust-runtime/aws-smithy-eventstream/external-types.toml b/rust-runtime/aws-smithy-eventstream/external-types.toml index 2e54673ff5..987e8f46d9 100644 --- a/rust-runtime/aws-smithy-eventstream/external-types.toml +++ b/rust-runtime/aws-smithy-eventstream/external-types.toml @@ -1,4 +1,6 @@ allowed_external_types = [ + "serde::de::Deserialize", + "serde::ser::Serialize", "aws_smithy_types::*", "bytes::buf::buf_impl::Buf", "bytes::buf::buf_mut::BufMut", diff --git a/rust-runtime/aws-smithy-eventstream/src/error.rs b/rust-runtime/aws-smithy-eventstream/src/error.rs index bda5ff900d..fcd717683c 100644 --- a/rust-runtime/aws-smithy-eventstream/src/error.rs +++ b/rust-runtime/aws-smithy-eventstream/src/error.rs @@ -24,6 +24,7 @@ pub(crate) enum ErrorKind { TimestampValueTooLarge(DateTime), Marshalling(String), Unmarshalling(String), + DeserializedStream, } #[derive(Debug)] @@ -51,6 +52,12 @@ impl Error { kind: ErrorKind::Unmarshalling(message.into()), } } + + pub const fn deserialized_stream() -> Self { + Self { + kind: ErrorKind::DeserializedStream, + } + } } impl From for Error { @@ -92,6 +99,10 @@ impl fmt::Display for Error { ), Marshalling(error) => write!(f, "failed to marshall message: {}", error), Unmarshalling(error) => write!(f, "failed to unmarshall message: {}", error), + DeserializedStream => write!( + f, + "this is a deserialized stream. No message can be sent or be received." + ), } } } diff --git a/rust-runtime/aws-smithy-http/Cargo.toml b/rust-runtime/aws-smithy-http/Cargo.toml index 23bb28437d..33ecdb9635 100644 --- a/rust-runtime/aws-smithy-http/Cargo.toml +++ b/rust-runtime/aws-smithy-http/Cargo.toml @@ -13,6 +13,8 @@ repository = "https://github.com/awslabs/smithy-rs" [features] rt-tokio = ["tokio/rt", "tokio/fs", "tokio/io-util", "tokio-util/io"] event-stream = ["aws-smithy-eventstream"] +serde-serialize = ["aws-smithy-eventstream/serde-serialize"] +serde-deserialize = ["aws-smithy-eventstream/serde-deserialize"] [dependencies] aws-smithy-eventstream = { path = "../aws-smithy-eventstream", optional = true } diff --git a/rust-runtime/aws-smithy-http/external-types.toml b/rust-runtime/aws-smithy-http/external-types.toml index a3dbbce3c5..a36378a4ca 100644 --- a/rust-runtime/aws-smithy-http/external-types.toml +++ b/rust-runtime/aws-smithy-http/external-types.toml @@ -1,4 +1,7 @@ allowed_external_types = [ + "serde::de::Deserialize", + "serde::ser::Serialize", + "aws_smithy_types::*", "bytes::buf::buf_impl::Buf", "bytes::bytes::Bytes", diff --git a/rust-runtime/aws-smithy-http/src/event_stream.rs b/rust-runtime/aws-smithy-http/src/event_stream.rs index 8b09a5bb90..8c7e596df3 100644 --- a/rust-runtime/aws-smithy-http/src/event_stream.rs +++ b/rust-runtime/aws-smithy-http/src/event_stream.rs @@ -10,6 +10,9 @@ use std::error::Error as StdError; mod receiver; mod sender; +#[cfg(all(aws_sdk_unstable, feature = "serde-deserialized"))] +mod deserialized_stream; + pub type BoxError = Box; #[doc(inline)] @@ -17,3 +20,5 @@ pub use sender::{EventStreamSender, MessageStreamAdapter, MessageStreamError}; #[doc(inline)] pub use receiver::{RawMessage, Receiver, ReceiverError}; + +pub use deserialized_stream::*; diff --git a/rust-runtime/aws-smithy-http/src/event_stream/deserialized_stream.rs b/rust-runtime/aws-smithy-http/src/event_stream/deserialized_stream.rs new file mode 100644 index 0000000000..f8c2bca09c --- /dev/null +++ b/rust-runtime/aws-smithy-http/src/event_stream/deserialized_stream.rs @@ -0,0 +1,51 @@ +use receiver::{RawMessage, Receiver}; + +use super::*; +use aws_smithy_eventstream::frame::UnmarshallMessage; +use std::{fmt::Debug, marker::PhantomData}; +/// This data is used to fill a field when the users try to deserialize data that has a Receiver in one of the field. +pub struct DeserializedReceiverStream(PhantomData<(T, E)>); +impl Debug for DeserializedReceiverStream { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("DeserializedStream") + } +} +impl DeserializedReceiverStream +where + T: std::fmt::Debug, + E: std::fmt::Debug, +{ + /// default value + pub fn create() -> impl UnmarshallMessage { + Self(PhantomData::<(T, E)>) + } +} + +impl UnmarshallMessage for DeserializedReceiverStream +where + T: Debug, + E: Debug, +{ + type Error = E; + type Output = T; + fn unmarshall( + &self, + _: &aws_smithy_eventstream::frame::Message, + ) -> Result< + aws_smithy_eventstream::frame::UnmarshalledMessage, + aws_smithy_eventstream::error::Error, + > { + Err(aws_smithy_eventstream::error::Error::deserialized_stream()) + } +} + +/// Error returned from Deserialized Stream. +#[derive(Debug)] +pub struct DeserializedStreamError; + +impl StdError for DeserializedStreamError {} +impl std::fmt::Display for DeserializedStreamError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("Stream was deserialized") + } +}