Skip to content

Commit

Permalink
feat!: Closure-based reader-writer serde for JSON, FormURL (#696)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbelkins authored May 10, 2024
1 parent 1f9b1e2 commit 4b045a4
Show file tree
Hide file tree
Showing 409 changed files with 5,937 additions and 10,578 deletions.
2 changes: 2 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ excluded:
- Tests/ClientRuntimeTests/*
- Tests/SmithyTestUtilTests/*
- Tests/SmithyXMLTests/*
- Tests/SmithyJSONTests/*
- Tests/SmithyFormURLTests/*
- Tests/SmithyTimestampsTests/*
- Tests/WeatherSDKTests/*
- smithy-swift-codegen-test/build/*
Expand Down
33 changes: 32 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ let package = Package(
.library(name: "ClientRuntime", targets: ["ClientRuntime"]),
.library(name: "SmithyReadWrite", targets: ["SmithyReadWrite"]),
.library(name: "SmithyXML", targets: ["SmithyXML"]),
.library(name: "SmithyJSON", targets: ["SmithyJSON"]),
.library(name: "SmithyFormURL", targets: ["SmithyFormURL"]),
.library(name: "SmithyTestUtil", targets: ["SmithyTestUtil"]),
],
dependencies: [
Expand All @@ -42,14 +44,21 @@ let package = Package(
name: "ClientRuntime",
dependencies: [
"SmithyXML",
"SmithyJSON",
"SmithyFormURL",
.product(name: "AwsCommonRuntimeKit", package: "aws-crt-swift"),
.product(name: "Logging", package: "swift-log"),
],
resources: [
.copy("PrivacyInfo.xcprivacy")
]
),
.target(name: "SmithyReadWrite"),
.target(
name: "SmithyReadWrite",
dependencies: [
"SmithyTimestamps"
]
),
.target(
name: "SmithyXML",
dependencies: [
Expand All @@ -58,6 +67,20 @@ let package = Package(
libXML2DependencyOrNil
].compactMap { $0 }
),
.target(
name: "SmithyJSON",
dependencies: [
"SmithyReadWrite",
"SmithyTimestamps"
]
),
.target(
name: "SmithyFormURL",
dependencies: [
"SmithyReadWrite",
"SmithyTimestamps"
]
),
libXML2TargetOrNil,
.target(
name: "SmithyTimestamps"
Expand All @@ -74,6 +97,14 @@ let package = Package(
name: "SmithyXMLTests",
dependencies: ["SmithyXML", "ClientRuntime"]
),
.testTarget(
name: "SmithyJSONTests",
dependencies: ["SmithyJSON", "ClientRuntime"]
),
.testTarget(
name: "SmithyFormURLTests",
dependencies: ["SmithyFormURL", "ClientRuntime"]
),
.testTarget(
name: "SmithyTimestampsTests",
dependencies: ["SmithyTimestamps"]
Expand Down
12 changes: 0 additions & 12 deletions Sources/ClientRuntime/Config/DefaultSDKRuntimeConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@ public struct DefaultSDKRuntimeConfiguration<DefaultSDKRuntimeRetryStrategy: Ret
/// The name of the client this config configures.
public var clientName: String

/// The encoder to be used for encoding models.
///
/// If none is provided, a default encoder will be used.
public var encoder: RequestEncoder?

/// The decoder to be used for decoding models.
///
/// If none is provided, a default decoder will be used.
public var decoder: ResponseDecoder?

/// The HTTP client to be used for HTTP connections.
///
/// If none is provided, the AWS CRT HTTP client will be used.
Expand Down Expand Up @@ -70,8 +60,6 @@ public struct DefaultSDKRuntimeConfiguration<DefaultSDKRuntimeRetryStrategy: Ret
) throws {
self.serviceName = clientName
self.clientName = clientName
self.encoder = nil
self.decoder = nil
self.httpClientConfiguration = Self.defaultHttpClientConfiguration
self.httpClientEngine = Self.makeClient(httpClientConfiguration: self.httpClientConfiguration)
self.idempotencyTokenGenerator = Self.defaultIdempotencyTokenGenerator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import struct Foundation.Data

extension EventStream {
/// Stream adapter that encodes input into `Data` objects.
public class DefaultMessageEncoderStream<Event: MessageMarshallable>: MessageEncoderStream, Stream {
public class DefaultMessageEncoderStream<Event>: MessageEncoderStream, Stream {
let stream: AsyncThrowingStream<Event, Error>
let messageEncoder: MessageEncoder
let messageSigner: MessageSigner
Expand Down
23 changes: 0 additions & 23 deletions Sources/ClientRuntime/EventStream/MessageMarshallable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,4 @@
// SPDX-License-Identifier: Apache-2.0
//

/// Marshals an event stream event into a `Message`.
/// Codgegen generates a conformance to this protocol for each event stream event input.
public protocol MessageMarshallable {
/// Marshals a event stream event into a `Message`.
/// - Parameters:
/// - encoder: RequestEncoder to use to encode the event stream event.
/// Note: event type may contain nested types that need to be encoded
/// using the same encoder.
/// - Returns: The marshalled `Message`.
func marshall(encoder: RequestEncoder) throws -> EventStream.Message
}

public typealias MarshalClosure<T> = (T) throws -> (EventStream.Message)

/// Provides a `MarshalClosure` for event payloads that are Swift `Encodable`.
/// - Parameter requestEncoder: The Swift `Encoder` to be used for encoding this event payload.
/// - Returns: A `MarshalClosure` that uses the provided encoder to encode event payloads.
public func jsonMarshalClosure<T: MessageMarshallable>(
requestEncoder: RequestEncoder
) -> MarshalClosure<T> {
return { eventStream in
try eventStream.marshall(encoder: requestEncoder)
}
}
21 changes: 0 additions & 21 deletions Sources/ClientRuntime/EventStream/MessageUnmarshallable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,4 @@
// SPDX-License-Identifier: Apache-2.0
//

/// Unmarshals a `Message` into a event stream event.
/// Codgegen generates a conformance to this protocol for each event stream event output.
public protocol MessageUnmarshallable {
/// Unmarshals a `Message` into a event stream event.
/// - Parameters:
/// - message: The message to unmarshal.
/// - decoder: ResponseDecoder to use to decode the event stream event.
/// Note: event type may contain nested types that need to be decoded
/// using the same decoder.
init(message: EventStream.Message, decoder: ResponseDecoder) throws
}

public typealias UnmarshalClosure<T> = (EventStream.Message) throws -> T

/// Provides an `UnmarshalClosure` for event payloads that are Swift `Decodable`.
/// - Parameter responseDecoder: The Swift `Decoder` to be used for decoding this event payload.
/// - Returns: An `UnmarshalClosure` that uses the provided decoder to decode event payloads.
public func jsonUnmarshalClosure<T: MessageUnmarshallable>(responseDecoder: ResponseDecoder) -> UnmarshalClosure<T> {
return { message in
try T(message: message, decoder: responseDecoder)
}
}
29 changes: 29 additions & 0 deletions Sources/ClientRuntime/Networking/BaseError/BaseError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

public protocol BaseError {
var httpResponse: HttpResponse { get }
var code: String { get }
var message: String? { get }
var requestID: String? { get }

func customError() -> Error?
}

public extension BaseError {

/// Returns a custom error from the error response, if any.
///
/// By default, a `BaseError` returns no custom error unless
/// the implementation provides its own implementation of this method.
/// - Returns: Some custom `Error` or `nil` if none.
func customError() -> Error? { nil }
}

public enum BaseErrorDecodeError: Error {
case missingRequiredData
}
38 changes: 0 additions & 38 deletions Sources/ClientRuntime/Networking/Http/HTTPResponseClosure.swift

This file was deleted.

This file was deleted.

This file was deleted.

22 changes: 0 additions & 22 deletions Sources/ClientRuntime/Networking/Http/HttpContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,6 @@ public class HttpContext: MiddlewareContext {
return attributes.get(key: AttributeKeys.isChunkedEligibleStream)
}

public func getDecoder() -> ResponseDecoder {
return attributes.get(key: AttributeKeys.decoder)!
}

public func getEncoder() -> RequestEncoder {
return attributes.get(key: AttributeKeys.encoder)!
}

public func getExpiration() -> TimeInterval {
return attributes.get(key: AttributeKeys.expiration) ?? 0
}
Expand Down Expand Up @@ -178,18 +170,6 @@ public class HttpContextBuilder {
return self
}

@discardableResult
public func withDecoder(value: ResponseDecoder) -> HttpContextBuilder {
self.attributes.set(key: AttributeKeys.decoder, value: value)
return self
}

@discardableResult
public func withEncoder(value: RequestEncoder) -> HttpContextBuilder {
self.attributes.set(key: AttributeKeys.encoder, value: value)
return self
}

@discardableResult
public func withExpiration(value: TimeInterval) -> HttpContextBuilder {
self.attributes.set(key: AttributeKeys.expiration, value: value)
Expand Down Expand Up @@ -329,8 +309,6 @@ public enum AttributeKeys {
public static let authSchemeResolver = AttributeKey<AuthSchemeResolver>(name: "AuthSchemeResolver")
public static let authSchemes = AttributeKey<Attributes>(name: "AuthSchemes")
public static let bidirectionalStreaming = AttributeKey<Bool>(name: "BidirectionalStreaming")
public static let decoder = AttributeKey<ResponseDecoder>(name: "Decoder")
public static let encoder = AttributeKey<RequestEncoder>(name: "Encoder")
public static let flowType = AttributeKey<FlowType>(name: "FlowType")
public static let host = AttributeKey<String>(name: "Host")
public static let hostPrefix = AttributeKey<String>(name: "HostPrefix")
Expand Down
21 changes: 17 additions & 4 deletions Sources/ClientRuntime/Networking/Http/HttpResponse.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import protocol SmithyReadWrite.WireDataProviding
import AwsCommonRuntimeKit

public class HttpResponse: HttpUrlResponse, ResponseMessage {
Expand Down Expand Up @@ -32,6 +36,15 @@ extension HttpResponse: CustomDebugStringConvertible {
}
}

extension HttpResponse: WireDataProviding {

public func data() async throws -> Data {
let data = try await body.readData()
body = .data(data)
return data ?? Data()
}
}

extension ByteStream {

// Convert the body stream to a ValidatingFileStream to check checksums
Expand Down
13 changes: 0 additions & 13 deletions Sources/ClientRuntime/Networking/Http/HttpResponseBinding.swift

This file was deleted.

Loading

0 comments on commit 4b045a4

Please sign in to comment.