Unverified Commit 29997665 authored by ysaito1001's avatar ysaito1001 Committed by GitHub
Browse files

Remove third party types from public APIs (#2845)



## Motivation and Context
Addresses item 1, 3, and 9 in #2413 

## Description
This PR removes the third party types as follows:
- removes `InvalidHeaderValue` from public API in `aws-http`
- removes `SendError` from public API in `aws-smithy-async`
- removes `xmlparser` from public API in `aws-smithy-xml`

Those types were exposed to public APIs primarily due to the
implementation of traits, e.g. `From` and `Iterator`. Those
implementations are used internally (such as XML deserialization and
converting an error type) so we should be able to hide them within
crates.

## Testing
- [x] Passed tests in CI

## Checklist
<!--- If a checkbox below is not applicable, then please DELETE it
rather than leaving it unchecked -->
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the
smithy-rs codegen or runtime crates
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the AWS
SDK, generated SDK code, or SDK runtime crates

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._

---------

Co-authored-by: default avatarysaito1001 <awsaito@amazon.com>
parent 26827f1a
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -628,3 +628,15 @@ message = "The naming `make_token` for fields and the API of `IdempotencyTokenPr
references = ["smithy-rs#2783"]
meta = { "breaking" = true, "tada" = false, "bug" = false }
author = "ysaito1001"

[[smithy-rs]]
message = "`aws_smithy_async::future::rendezvous::Sender::send` no longer exposes `tokio::sync::mpsc::error::SendError` for the error of its return type and instead exposes a new-type wrapper called `aws_smithy_async::future::rendezvous::error::SendError`. In addition, the `aws_smithy_xml` crate no longer exposes types from `xmlparser`."
references = ["smithy-rs#2845"]
meta = { "breaking" = true, "tada" = false, "bug" = false, "target" = "client" }
author = "ysaito1001"

[[aws-sdk-rust]]
message = "The implementation `From<http::header::value::InvalidHeaderValue>` for `aws_http::user_agent::UserAgentStageError` has been removed."
references = ["smithy-rs#2845"]
meta = { "breaking" = true, "tada" = false, "bug" = false }
author = "ysaito1001"
+0 −3
Original line number Diff line number Diff line
@@ -5,7 +5,4 @@ allowed_external_types = [
    "aws_types::*",
    "bytes::bytes::Bytes",
    "http_body::Body",

    # TODO(https://github.com/awslabs/smithy-rs/issues/1193): Decide if the following should be exposed
    "http::header::value::InvalidHeaderValue",
]
+20 −13
Original line number Diff line number Diff line
@@ -550,6 +550,16 @@ pub struct UserAgentStageError {
    kind: UserAgentStageErrorKind,
}

impl UserAgentStageError {
    // `pub(crate)` method instead of implementing `From<InvalidHeaderValue>` so that we
    // don't have to expose `InvalidHeaderValue` in public API.
    pub(crate) fn from_invalid_header(value: InvalidHeaderValue) -> Self {
        Self {
            kind: UserAgentStageErrorKind::InvalidHeader(value),
        }
    }
}

impl Error for UserAgentStageError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        use UserAgentStageErrorKind::*;
@@ -578,14 +588,6 @@ impl From<UserAgentStageErrorKind> for UserAgentStageError {
    }
}

impl From<InvalidHeaderValue> for UserAgentStageError {
    fn from(value: InvalidHeaderValue) -> Self {
        Self {
            kind: UserAgentStageErrorKind::InvalidHeader(value),
        }
    }
}

#[allow(clippy::declare_interior_mutable_const)] // we will never mutate this
const X_AMZ_USER_AGENT: HeaderName = HeaderName::from_static("x-amz-user-agent");

@@ -601,11 +603,16 @@ impl MapRequest for UserAgentStage {
            let ua = conf
                .get::<AwsUserAgent>()
                .ok_or(UserAgentStageErrorKind::UserAgentMissing)?;
            req.headers_mut()
                .append(USER_AGENT, HeaderValue::try_from(ua.ua_header())?);
            req.headers_mut()
                .append(X_AMZ_USER_AGENT, HeaderValue::try_from(ua.aws_ua_header())?);

            req.headers_mut().append(
                USER_AGENT,
                HeaderValue::try_from(ua.ua_header())
                    .map_err(UserAgentStageError::from_invalid_header)?,
            );
            req.headers_mut().append(
                X_AMZ_USER_AGENT,
                HeaderValue::try_from(ua.aws_ua_header())
                    .map_err(UserAgentStageError::from_invalid_header)?,
            );
            Ok(req)
        })
    }
+0 −3
Original line number Diff line number Diff line
@@ -5,7 +5,4 @@ allowed_external_types = [

    # TODO(https://github.com/awslabs/smithy-rs/issues/1193): Switch to AsyncIterator once standardized
    "futures_core::stream::Stream",

    # TODO(https://github.com/awslabs/smithy-rs/issues/1193): Don't expose `SendError`
    "tokio::sync::mpsc::error::SendError",
]
+32 −3
Original line number Diff line number Diff line
@@ -14,7 +14,6 @@

use std::sync::Arc;
use std::task::{Context, Poll};
use tokio::sync::mpsc::error::SendError;
use tokio::sync::Semaphore;

/// Create a new rendezvous channel
@@ -38,6 +37,36 @@ pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
    )
}

/// Errors for rendezvous channel
pub mod error {
    use std::fmt;
    use tokio::sync::mpsc::error::SendError as TokioSendError;

    /// Error when [crate::future::rendezvous::Sender] fails to send a value to the associated `Receiver`
    #[derive(Debug)]
    pub struct SendError<T> {
        source: TokioSendError<T>,
    }

    impl<T> SendError<T> {
        pub(crate) fn tokio_send_error(source: TokioSendError<T>) -> Self {
            Self { source }
        }
    }

    impl<T> fmt::Display for SendError<T> {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "failed to send value to the receiver")
        }
    }

    impl<T: fmt::Debug + 'static> std::error::Error for SendError<T> {
        fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
            Some(&self.source)
        }
    }
}

#[derive(Debug)]
/// Sender-half of a channel
pub struct Sender<T> {
@@ -50,7 +79,7 @@ impl<T> Sender<T> {
    ///
    /// Unlike something like `tokio::sync::mpsc::Channel` where sending a value will be buffered until
    /// demand exists, a rendezvous sender will wait until matching demand exists before this function will return.
    pub async fn send(&self, item: T) -> Result<(), SendError<T>> {
    pub async fn send(&self, item: T) -> Result<(), error::SendError<T>> {
        let result = self.chan.send(item).await;
        // If this is an error, the rx half has been dropped. We will never get demand.
        if result.is_ok() {
@@ -61,7 +90,7 @@ impl<T> Sender<T> {
                .expect("semaphore is never closed")
                .forget();
        }
        result
        result.map_err(error::SendError::tokio_send_error)
    }
}

Loading