Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library barback.utils; | 5 library barback.utils; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:typed_data'; | 8 import 'dart:typed_data'; |
| 9 | 9 |
| 10 import 'package:stack_trace/stack_trace.dart'; | 10 import 'package:stack_trace/stack_trace.dart'; |
| 11 | 11 |
| 12 /// A pair of values. | 12 /// A class that represents a value or an error. |
| 13 class Pair<E, F> { | 13 class FallibleValue<E> { |
|
Bob Nystrom
2014/01/08 00:47:40
What do you think of just calling this "Fallible"?
nweiz
2014/01/08 22:15:09
Done.
| |
| 14 E first; | 14 /// Whether [this] has a [value], as opposed to an [error]. |
| 15 F last; | 15 final bool hasValue; |
| 16 | 16 |
| 17 Pair(this.first, this.last); | 17 /// Whether [this] has an [error], as opposed to an[value]. |
|
Bob Nystrom
2014/01/08 00:47:40
"an[" -> "a ["
nweiz
2014/01/08 22:15:09
Done.
| |
| 18 bool get hasError => !hasValue; | |
| 18 | 19 |
| 19 String toString() => '($first, $last)'; | 20 /// The value. |
| 21 /// | |
| 22 /// This will be `null` if [this] has an [error]. | |
| 23 final E _value; | |
| 20 | 24 |
| 21 bool operator==(other) { | 25 /// The value. |
| 22 if (other is! Pair) return false; | 26 /// |
| 23 return other.first == first && other.last == last; | 27 /// This will throw a [StateError] if [this] has an [error]. |
| 28 E get value { | |
| 29 if (hasValue) return _value; | |
| 30 throw new StateError("FallibleValue has no value.\n" | |
| 31 "$_error$_stackTraceSuffix"); | |
| 24 } | 32 } |
| 25 | 33 |
| 26 int get hashCode => first.hashCode ^ last.hashCode; | 34 /// The error. |
| 27 } | 35 /// |
| 36 /// This will be `null` if [this] has a [value]. | |
| 37 final _error; | |
| 28 | 38 |
| 29 /// A class that represents one and only one of two types of values. | 39 /// The error. |
| 30 class Either<E, F> { | |
| 31 /// Whether this is a value of type `E`. | |
| 32 final bool isFirst; | |
| 33 | |
| 34 /// Whether this is a value of type `F`. | |
| 35 bool get isSecond => !isFirst; | |
| 36 | |
| 37 /// The value, either of type `E` or `F`. | |
| 38 final _value; | |
| 39 | |
| 40 /// The value of type `E`. | |
| 41 /// | 40 /// |
| 42 /// It's an error to access this is this is of type `F`. | 41 /// This will throw a [StateError] if [this] has a [value]. |
| 43 E get first { | 42 get error { |
| 44 assert(isFirst); | 43 if (hasError) return _error; |
| 45 return _value; | 44 throw new StateError("FallibleValue has no error."); |
| 46 } | 45 } |
| 47 | 46 |
| 48 /// The value of type `F`. | 47 /// The stack trace for [_error]. |
| 49 /// | 48 /// |
| 50 /// It's an error to access this is this is of type `E`. | 49 /// This will be `null` if [this] has a [value], or if no stack trace was |
| 51 F get second { | 50 /// provided. |
| 52 assert(isSecond); | 51 final StackTrace _stackTrace; |
| 53 return _value; | 52 |
| 53 /// The stack trace for [error]. | |
| 54 /// | |
| 55 /// This will throw a [StateError] if [this] has a [value]. | |
| 56 StackTrace get stackTrace { | |
| 57 if (hasError) return _stackTrace; | |
| 58 throw new StateError("FallibleValue has no error."); | |
| 54 } | 59 } |
| 55 | 60 |
| 56 /// Creates an [Either] with type `E`. | 61 FallibleValue.withValue(this._value) |
|
Bob Nystrom
2014/01/08 00:47:40
Maybe just:
new Fallible.value(...)
new Fallible.
nweiz
2014/01/08 22:15:09
That's what I had at first, but those apparently c
| |
| 57 Either.withFirst(this._value) | 62 : hasValue = true; |
| 58 : isFirst = true; | |
| 59 | 63 |
| 60 /// Creates an [Either] with type `F`. | 64 FallibleValue.withError(this._error, [this._stackTrace]) |
| 61 Either.withSecond(this._value) | 65 : hasValue = false; |
| 62 : isFirst = false; | |
| 63 | 66 |
| 64 /// Runs [whenFirst] or [whenSecond] depending on the type of [this]. | 67 String toString() { |
| 65 /// | 68 if (hasValue) return "FallibleValue value: $value"; |
| 66 /// Returns the result of whichvever function was run. | 69 return "FallibleValue error: $error$_stackTraceSuffix"; |
| 67 match(whenFirst(E value), whenSecond(F value)) { | |
| 68 if (isFirst) return whenFirst(first); | |
| 69 return whenSecond(second); | |
| 70 } | 70 } |
| 71 | 71 |
| 72 String toString() => "$_value (${isFirst? 'first' : 'second'})"; | 72 String get _stackTraceSuffix { |
| 73 if (stackTrace == null) return ""; | |
| 74 return "\nStack trace:\n${new Chain.from(_stackTrace).terse}"; | |
| 75 } | |
| 73 } | 76 } |
| 74 | 77 |
| 75 /// Converts a number in the range [0-255] to a two digit hex string. | 78 /// Converts a number in the range [0-255] to a two digit hex string. |
| 76 /// | 79 /// |
| 77 /// For example, given `255`, returns `ff`. | 80 /// For example, given `255`, returns `ff`. |
| 78 String byteToHex(int byte) { | 81 String byteToHex(int byte) { |
| 79 assert(byte >= 0 && byte <= 255); | 82 assert(byte >= 0 && byte <= 255); |
| 80 | 83 |
| 81 const DIGITS = "0123456789abcdef"; | 84 const DIGITS = "0123456789abcdef"; |
| 82 return DIGITS[(byte ~/ 16) % 16] + DIGITS[byte % 16]; | 85 return DIGITS[(byte ~/ 16) % 16] + DIGITS[byte % 16]; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 subscription = callback().listen(controller.add, | 259 subscription = callback().listen(controller.add, |
| 257 onError: controller.addError, | 260 onError: controller.addError, |
| 258 onDone: controller.close); | 261 onDone: controller.close); |
| 259 }, | 262 }, |
| 260 onCancel: () => subscription.cancel(), | 263 onCancel: () => subscription.cancel(), |
| 261 onPause: () => subscription.pause(), | 264 onPause: () => subscription.pause(), |
| 262 onResume: () => subscription.resume(), | 265 onResume: () => subscription.resume(), |
| 263 sync: true); | 266 sync: true); |
| 264 return controller.stream; | 267 return controller.stream; |
| 265 } | 268 } |
| OLD | NEW |