| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library json_rpc_2.utils; | |
| 6 | |
| 7 import 'dart:async'; | |
| 8 | |
| 9 import 'package:stack_trace/stack_trace.dart'; | |
| 10 | |
| 11 typedef ZeroArgumentFunction(); | |
| 12 | |
| 13 /// Like [new Future.sync], but automatically wraps the future in a | |
| 14 /// [Chain.track] call. | |
| 15 Future syncFuture(callback()) => Chain.track(new Future.sync(callback)); | |
| 16 | |
| 17 /// Returns a sentence fragment listing the elements of [iter]. | |
| 18 /// | |
| 19 /// This converts each element of [iter] to a string and separates them with | |
| 20 /// commas and/or "and" where appropriate. | |
| 21 String toSentence(Iterable iter) { | |
| 22 if (iter.length == 1) return iter.first.toString(); | |
| 23 return iter.take(iter.length - 1).join(", ") + " and ${iter.last}"; | |
| 24 } | |
| 25 | |
| 26 /// Returns [name] if [number] is 1, or the plural of [name] otherwise. | |
| 27 /// | |
| 28 /// By default, this just adds "s" to the end of [name] to get the plural. If | |
| 29 /// [plural] is passed, that's used instead. | |
| 30 String pluralize(String name, int number, {String plural}) { | |
| 31 if (number == 1) return name; | |
| 32 if (plural != null) return plural; | |
| 33 return '${name}s'; | |
| 34 } | |
| 35 | |
| 36 /// A regular expression to match the exception prefix that some exceptions' | |
| 37 /// [Object.toString] values contain. | |
| 38 final _exceptionPrefix = new RegExp(r'^([A-Z][a-zA-Z]*)?(Exception|Error): '); | |
| 39 | |
| 40 /// Get a string description of an exception. | |
| 41 /// | |
| 42 /// Many exceptions include the exception class name at the beginning of their | |
| 43 /// [toString], so we remove that if it exists. | |
| 44 String getErrorMessage(error) => | |
| 45 error.toString().replaceFirst(_exceptionPrefix, ''); | |
| 46 | |
| 47 /// Like `try`/`finally`, run [body] and ensure that [whenComplete] runs | |
| 48 /// afterwards, regardless of whether [body] succeeded. | |
| 49 /// | |
| 50 /// This is synchronicity-agnostic relative to [body]. If [body] returns a | |
| 51 /// [Future], this wil run asynchronously; otherwise it will run synchronously. | |
| 52 tryFinally(body(), whenComplete()) { | |
| 53 var result; | |
| 54 try { | |
| 55 result = body(); | |
| 56 } catch (_) { | |
| 57 whenComplete(); | |
| 58 rethrow; | |
| 59 } | |
| 60 | |
| 61 if (result is! Future) { | |
| 62 whenComplete(); | |
| 63 return result; | |
| 64 } else { | |
| 65 return result.whenComplete(whenComplete); | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 /// Returns a [StreamSink] that wraps [sink] and maps each event added using | |
| 70 /// [callback]. | |
| 71 StreamSink mapStreamSink(StreamSink sink, callback(event)) => | |
| 72 new _MappedStreamSink(sink, callback); | |
| 73 | |
| 74 /// A [StreamSink] wrapper that maps each event added to the sink. | |
| 75 class _MappedStreamSink implements StreamSink { | |
| 76 final StreamSink _inner; | |
| 77 final Function _callback; | |
| 78 | |
| 79 Future get done => _inner.done; | |
| 80 | |
| 81 _MappedStreamSink(this._inner, this._callback); | |
| 82 | |
| 83 void add(event) => _inner.add(_callback(event)); | |
| 84 void addError(error, [StackTrace stackTrace]) => | |
| 85 _inner.addError(error, stackTrace); | |
| 86 Future addStream(Stream stream) => _inner.addStream(stream.map(_callback)); | |
| 87 Future close() => _inner.close(); | |
| 88 } | |
| OLD | NEW |