2
2
// SPDX-License-Identifier: Apache-2.0
3
3
4
4
import 'dart:convert' ;
5
+ import 'dart:typed_data' ;
5
6
6
7
import 'package:async/async.dart' ;
7
8
import 'package:aws_common/aws_common.dart' ;
@@ -12,7 +13,7 @@ import 'package:smithy/smithy.dart';
12
13
/// A protocol for sending requests over HTTP.
13
14
@optionalTypeArgs
14
15
abstract class HttpProtocol <InputPayload , Input , OutputPayload , Output >
15
- implements Protocol <Input , Output , Stream < List < int >> > {
16
+ implements Protocol <Input , OutputPayload > {
16
17
const HttpProtocol ();
17
18
18
19
/// The content type of the request payload, added to the `Content-Type`
@@ -21,7 +22,7 @@ abstract class HttpProtocol<InputPayload, Input, OutputPayload, Output>
21
22
22
23
/// Protocol headers
23
24
Map <String , String > get headers => {
24
- 'Content-Type' : contentType,
25
+ AWSHeaders .contentType : contentType,
25
26
};
26
27
27
28
Serializers get serializers;
@@ -45,45 +46,49 @@ abstract class HttpProtocol<InputPayload, Input, OutputPayload, Output>
45
46
return AWSHttpClient ()..supportedProtocols = SupportedProtocols .http1;
46
47
}
47
48
48
- @override
49
- Stream <List <int >> serialize (Object ? input, {FullType ? specifiedType}) {
50
- final Object ? payload = input is HasPayload ? input.getPayload () : input;
49
+ /// Serializes [input] to an HTTP body.
50
+ Stream <List <int >> serialize (Input input) {
51
+ final payload = switch (input) {
52
+ InputPayload _ => input,
53
+ _ as HasPayload <InputPayload > => input.getPayload (),
54
+ };
51
55
return switch (payload) {
56
+ null => const Stream .empty (),
52
57
String _ => Stream .value (utf8.encode (payload)),
53
58
List <int > _ => Stream .value (payload),
54
59
Stream <List <int >> _ => payload,
55
60
_ => Stream .fromFuture (
56
61
Future .value (
57
62
wireSerializer.serialize (
58
- input,
59
- specifiedType:
60
- specifiedType ?? FullType (Input , [FullType (InputPayload )]),
63
+ payload,
64
+ // Even though we're serializing the payload, specify the
65
+ // [Input] type since the semantics of serializing [Input]
66
+ // vs [InputPayload] vary. For example, some traits
67
+ // may only apply to the payload when serializing it as part
68
+ // of an [Input] struct vs. when directly serialized.
69
+ //
70
+ // We further pass the [InputPayloas] so that our built_value plugins
71
+ // have both types which is helpful when making determinations
72
+ // about how to, for example, process a List<Object?> which
73
+ // could represent either a Map or a List.
74
+ specifiedType: FullType (Input , [FullType (InputPayload )]),
61
75
),
62
76
),
63
77
),
64
78
};
65
79
}
66
80
67
- @override
68
- Future <Object ?> deserialize (
69
- Stream <List <int >> response, {
70
- FullType ? specifiedType,
71
- }) async {
72
- specifiedType ?? = FullType (OutputPayload );
73
- if (specifiedType.root == OutputPayload &&
74
- OutputPayload == Stream <List <int >>) {
75
- return response;
76
- }
77
-
78
- final body = await collectBytes (response);
79
- if (specifiedType.root == OutputPayload ) {
80
- if (OutputPayload == List <int >) {
81
- return body;
82
- } else if (OutputPayload == String ) {
83
- return body.isEmpty ? '' : utf8.decode (body);
84
- }
85
- }
86
- return await wireSerializer.deserialize (body, specifiedType: specifiedType);
81
+ /// Deserializes an HTTP [response] body to an [OutputPayload] .
82
+ Future <OutputPayload > deserialize (Stream <List <int >> response) async {
83
+ return switch (OutputPayload ) {
84
+ const (Stream <List <int >>) => response,
85
+ const (List <int >) || const (Uint8List ) => await collectBytes (response),
86
+ const (String ) => await utf8.decodeStream (response),
87
+ _ => await wireSerializer.deserialize (
88
+ await collectBytes (response),
89
+ specifiedType: FullType (OutputPayload ),
90
+ ),
91
+ } as OutputPayload ;
87
92
}
88
93
}
89
94
@@ -101,7 +106,7 @@ mixin HasLabel {
101
106
String labelFor (String key);
102
107
}
103
108
104
- abstract interface class HasPayload <Payload > {
109
+ abstract interface class HasPayload <Payload extends Object ? > {
105
110
Payload ? getPayload ();
106
111
}
107
112
0 commit comments