// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. class CancelableToken extends CancellationToken { bool _isCancelled = false; int? _cancellationCode; String? _cancellationReason; /// An optional code for why this request was cancelled. int? get cancellationCode => _cancellationCode; /// An description for why this request was cancelled. String? get cancellationReason => _cancellationReason; @override bool get isCancellationRequested => _isCancelled; void cancel({int? code, String? reason}) { _isCancelled = true; _cancellationCode = code; _cancellationReason = reason; } } /// A token used to signal cancellation of an operation. This allows computation /// to be skipped when a caller is no longer interested in the result, for example /// when a $/cancel request is received for an in-progress request. abstract class CancellationToken { bool get isCancellationRequested; } /// A [CancellationToken] that cannot be cancelled. class NotCancelableToken extends CancellationToken { @override bool get isCancellationRequested => false; } /// A cancellable wrapper over another cancellation token. /// /// This token will be considered cancelled if either it is itself cancelled, /// or if [_child] is cancelled. /// /// Cancelling this token will also cancel [_child] if it is a cancelable /// token. class _WrappedCancelableToken extends CancelableToken { final CancellationToken _child; _WrappedCancelableToken(this._child); @override bool get isCancellationRequested => super.isCancellationRequested || _child.isCancellationRequested; @override void cancel({int? code, String? reason}) { super.cancel(code: code, reason: reason); var child = _child; if (child is CancelableToken) { child.cancel(code: code, reason: reason); } } } extension CancellationTokenExtension on CancellationToken { /// Wraps this token to make it cancelable if it is not already. CancelableToken asCancelable() { var token = this; return token is CancelableToken ? token : _WrappedCancelableToken(token); } }