blob: 87189a74d7befaba5ab236c8cc25fc419d31dceb [file] [log] [blame]
// Copyright (c) 2017, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'dart:async';
import 'package:async/async.dart';
import '../shared/status.dart';
import 'call.dart';
/// A gRPC response.
abstract class Response {
/// Header metadata returned from the server.
///
/// The [headers] future will complete before any response objects become
/// available. If [cancel] is called before the headers are available, the
/// returned future will complete with an error.
Future<Map<String, String>> get headers;
/// Trailer metadata returned from the server.
///
/// The [trailers] future will complete after all responses have been received
/// from the server. If [cancel] is called before the trailers are available,
/// the returned future will complete with an error.
Future<Map<String, String>> get trailers;
/// Cancel this gRPC call. Any remaining request objects will not be sent, and
/// no further responses will be received.
Future<void> cancel();
}
/// A gRPC response producing a single value.
class ResponseFuture<R> extends DelegatingFuture<R>
with _ResponseMixin<dynamic, R> {
final ClientCall<dynamic, R> _call;
static R _ensureOnlyOneResponse<R>(R previous, R element) {
if (previous != null) {
throw new GrpcError.unimplemented('More than one response received');
}
return element;
}
static R _ensureOneResponse<R>(R value) {
if (value == null)
throw new GrpcError.unimplemented('No responses received');
return value;
}
ResponseFuture(this._call)
: super(_call.response
.fold(null, _ensureOnlyOneResponse)
.then(_ensureOneResponse));
}
/// A gRPC response producing a stream of values.
class ResponseStream<R> extends DelegatingStream<R>
with _ResponseMixin<dynamic, R> {
final ClientCall<dynamic, R> _call;
ResponseStream(this._call) : super(_call.response);
}
abstract class _ResponseMixin<Q, R> implements Response {
ClientCall<Q, R> get _call;
@override
Future<Map<String, String>> get headers => _call.headers;
@override
Future<Map<String, String>> get trailers => _call.trailers;
@override
Future<void> cancel() => _call.cancel();
}