-
Notifications
You must be signed in to change notification settings - Fork 134
Expand file tree
/
Copy pathoptional.dart
More file actions
141 lines (122 loc) · 4.37 KB
/
Copy pathoptional.dart
File metadata and controls
141 lines (122 loc) · 4.37 KB
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
134
135
136
137
138
139
140
141
// 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.
///
/// This class was written before Dart SDK 2.12 added first class support for
/// non-nullable types. Where possible, it is strongly preferred to use those
/// language features and to not use this class at all.
///
/// Usually, `Optional<T>` should be migrated to `T?`.
///
/// However, code that already uses `Optional` can continue to use it if the
/// cost of migration is considered too high. The class will not be removed.
///
/// Valid new use cases:
///
/// - if an API only accepts non-null values, you can use `Optional` as a
/// general way to pass it values that mean "absent";
/// - for a general way to represent "nested levels" of absent, such as
/// `Optional<Optional<T>>`.
///
/// Both of these should be very rare.
@Deprecated('Generally, migrate to a nullable type.')
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 }';
}
}