OLD | NEW |
1 // Copyright 2013 Google Inc. All Rights Reserved. | 1 // Copyright 2013 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 part of quiver.core; | 15 part of quiver.core; |
16 | 16 |
17 /** | 17 /// A value that might be absent. |
18 * A value that might be absent. | 18 /// |
19 * | 19 /// Use Optional as an alternative to allowing fields, parameters or return |
20 * Use Optional as an alternative to allowing fields, parameters or return | 20 /// values to be null. It signals that a value is not required and provides |
21 * values to be null. It signals that a value is not required and provides | 21 /// convenience methods for dealing with the absent case. |
22 * convenience methods for dealing with the absent case. | 22 class Optional<T> extends IterableBase<T> { |
23 */ | |
24 class Optional<T> { | |
25 final T _value; | 23 final T _value; |
26 | 24 |
27 /** | 25 /// Constructs an empty Optional. |
28 * Constructs an empty Optional. | |
29 */ | |
30 const Optional.absent() : _value = null; | 26 const Optional.absent() : _value = null; |
31 | 27 |
32 /** | 28 /// Constructs an Optional of the given [value]. |
33 * Constructs an Optional of the given [value]. | 29 /// |
34 * | 30 /// Throws [ArgumentError] if [value] is null. |
35 * Throws [ArgumentError] if [value] is null. | |
36 */ | |
37 Optional.of(T value) : this._value = value { | 31 Optional.of(T value) : this._value = value { |
38 if (this._value == null) throw new ArgumentError('Must not be null.'); | 32 if (this._value == null) throw new ArgumentError('Must not be null.'); |
39 } | 33 } |
40 | 34 |
41 /** | 35 /// Constructs an Optional of the given [value]. |
42 * Constructs an Optional of the given [value]. | 36 /// |
43 * | 37 /// If [value] is null, returns [absent()]. |
44 * If [value] is null, returns [absent()]. | |
45 */ | |
46 const Optional.fromNullable(T value) : this._value = value; | 38 const Optional.fromNullable(T value) : this._value = value; |
47 | 39 |
48 /** | 40 /// Whether the Optional contains a value. |
49 * Whether the Optional contains a value. | |
50 */ | |
51 bool get isPresent => _value != null; | 41 bool get isPresent => _value != null; |
52 | 42 |
53 /** | 43 /// Gets the Optional value. |
54 * Gets the Optional value. | 44 /// |
55 * | 45 /// Throws [StateError] if [value] is null. |
56 * Throws [StateError] if [value] is null. | |
57 */ | |
58 T get value { | 46 T get value { |
59 if (this._value == null) { | 47 if (this._value == null) { |
60 throw new StateError('value called on absent Optional.'); | 48 throw new StateError('value called on absent Optional.'); |
61 } | 49 } |
62 return _value; | 50 return _value; |
63 } | 51 } |
64 | 52 |
65 /** | 53 /// Executes a function if the Optional value is present. |
66 * Executes a function if the Optional value is present. | |
67 */ | |
68 void ifPresent(void ifPresent(T value)) { | 54 void ifPresent(void ifPresent(T value)) { |
69 if (isPresent) { | 55 if (isPresent) { |
70 ifPresent(_value); | 56 ifPresent(_value); |
71 } | 57 } |
72 } | 58 } |
73 | 59 |
74 /** | 60 /// Execution a function if the Optional value is absent. |
75 * Execution a function if the Optional value is absent. | |
76 */ | |
77 void ifAbsent(void ifAbsent()) { | 61 void ifAbsent(void ifAbsent()) { |
78 if (!isPresent) { | 62 if (!isPresent) { |
79 ifAbsent(); | 63 ifAbsent(); |
80 } | 64 } |
81 } | 65 } |
82 | 66 |
83 /** | 67 /// Gets the Optional value with a default. |
84 * Gets the Optional value with a default. | 68 /// |
85 * | 69 /// The default is returned if the Optional is [absent()]. |
86 * The default is returned if the Optional is [absent()]. | 70 /// |
87 * | 71 /// Throws [ArgumentError] if [defaultValue] is null. |
88 * Throws [ArgumentError] if [defaultValue] is null. | |
89 */ | |
90 T or(T defaultValue) { | 72 T or(T defaultValue) { |
91 if (defaultValue == null) { | 73 if (defaultValue == null) { |
92 throw new ArgumentError('defaultValue must not be null.'); | 74 throw new ArgumentError('defaultValue must not be null.'); |
93 } | 75 } |
94 return _value == null ? defaultValue : _value; | 76 return _value == null ? defaultValue : _value; |
95 } | 77 } |
96 | 78 |
97 /** | 79 /// Gets the Optional value, or [null] if there is none. |
98 * Gets the Optional value, or [null] if there is none. | |
99 */ | |
100 T get orNull => _value; | 80 T get orNull => _value; |
101 | 81 |
102 /** | 82 /// Transforms the Optional value. |
103 * Transforms the Optional value. | 83 /// |
104 * | 84 /// If the Optional is [absent()], returns [absent()] without applying the tra
nsformer. |
105 * If the Optional is [absent()], returns [absent()] without applying the tran
sformer. | 85 /// |
106 * | 86 /// The transformer must not return [null]. If it does, an [ArgumentError] is
thrown. |
107 * The transformer must not return [null]. If it does, an [ArgumentError] is t
hrown. | 87 Optional<S> transform<S>(S transformer(T value)) { |
108 */ | |
109 Optional transform(dynamic transformer(T value)) { | |
110 return _value == null | 88 return _value == null |
111 ? new Optional.absent() | 89 ? new Optional.absent() |
112 : new Optional.of(transformer(_value)); | 90 : new Optional.of(transformer(_value)); |
113 } | 91 } |
114 | 92 |
115 /** | 93 @override |
116 * Delegates to the underlying [value] hashCode. | 94 Iterator<T> get iterator => |
117 */ | 95 isPresent ? <T>[_value].iterator : new Iterable<T>.empty().iterator; |
| 96 |
| 97 /// Delegates to the underlying [value] hashCode. |
118 int get hashCode => _value.hashCode; | 98 int get hashCode => _value.hashCode; |
119 | 99 |
120 /** | 100 /// Delegates to the underlying [value] operator==. |
121 * Delegates to the underlying [value] operator==. | |
122 */ | |
123 bool operator ==(o) => o is Optional && o._value == _value; | 101 bool operator ==(o) => o is Optional && o._value == _value; |
124 | 102 |
125 String toString() { | 103 String toString() { |
126 return _value == null | 104 return _value == null |
127 ? 'Optional { absent }' | 105 ? 'Optional { absent }' |
128 : 'Optional { value: ${_value} }'; | 106 : 'Optional { value: ${_value} }'; |
129 } | 107 } |
130 } | 108 } |
OLD | NEW |