-
Notifications
You must be signed in to change notification settings - Fork 133
/
optional.dart
133 lines (114 loc) · 4.21 KB
/
optional.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2013 Google Inc. 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.
// ignore_for_file: null_check_on_nullable_type_parameter
import 'dart:collection';
/// A value that might be absent.
///
/// Use Optional as an alternative to allowing fields, parameters or return
/// values to be null. It signals that a value is not required and provides
/// convenience methods for dealing with the absent case.
///
/// With the introduction of non-null by default in Dart SDK 2.12, developers
/// should avoid adding more uses of this type. Existing users should migrate
/// away from the `Optional` type to types marked nullable: `T?`. This type
/// will be removed in Quiver 4.0.0.
// TODO(kevmoo): re-deprecate this once usage is removed from Flutter plugins
//@Deprecated('Migrate to a non-nullable type. Will be removed in 4.0.0')
class Optional<T> extends IterableBase<T> {
/// Constructs an empty Optional.
const Optional.absent() : _value = null;
/// Constructs an Optional of the given [value].
///
/// Throws [ArgumentError] if [value] is null.
Optional.of(T value) : _value = value {
// TODO(cbracken): Delete and make this ctor const once mixed-mode
// execution is no longer around.
ArgumentError.checkNotNull(value);
}
/// Constructs an Optional of the given [value].
///
/// If [value] is null, returns [absent()].
const Optional.fromNullable(T? value) : _value = value;
final T? _value;
/// True when this optional contains a value.
bool get isPresent => _value != null;
/// True when this optional contains no value.
bool get isNotPresent => _value == null;
/// Gets the Optional value.
///
/// Throws [StateError] if [value] is null.
T get value {
if (_value == null) {
throw StateError('value called on absent Optional.');
}
return _value!;
}
/// Executes a function if the Optional value is present.
void ifPresent(void Function(T value) ifPresent) {
if (isPresent) {
ifPresent(_value!);
}
}
/// Execution a function if the Optional value is absent.
void ifAbsent(void Function() ifAbsent) {
if (!isPresent) {
ifAbsent();
}
}
/// Gets the Optional value with a default.
///
/// The default is returned if the Optional is [absent()].
///
/// Throws [ArgumentError] if [defaultValue] is null.
T or(T defaultValue) {
return _value ?? defaultValue;
}
/// Gets the Optional value, or [null] if there is none.
T? get orNull => _value;
/// Transforms the Optional value.
///
/// If the Optional is [absent()], returns [absent()] without applying the transformer.
///
/// The transformer must not return [null]. If it does, an [ArgumentError] is thrown.
Optional<S> transform<S>(S Function(T value) transformer) {
return _value == null
? Optional<S>.absent()
: Optional<S>.of(transformer(_value!));
}
/// Transforms the Optional value.
///
/// If the Optional is [absent()], returns [absent()] without applying the transformer.
///
/// Returns [absent()] if the transformer returns [null].
Optional<S> transformNullable<S>(S? Function(T value) transformer) {
return _value == null
? Optional<S>.absent()
: Optional<S>.fromNullable(transformer(_value!));
}
@override
Iterator<T> get iterator =>
isPresent ? <T>[_value!].iterator : Iterable<T>.empty().iterator;
/// Delegates to the underlying [value] hashCode.
@override
int get hashCode => _value.hashCode;
/// Delegates to the underlying [value] operator==.
@override
bool operator ==(Object o) => o is Optional<T> && o._value == _value;
@override
String toString() {
return _value == null
? 'Optional { absent }'
: 'Optional { value: $_value }';
}
}