-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoptional.dart
More file actions
106 lines (77 loc) · 2.57 KB
/
optional.dart
File metadata and controls
106 lines (77 loc) · 2.57 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
/// A constant, absent Optional.
const Optional<dynamic> empty = _Absent<dynamic>();
/// A container object which may contain a non-null value.
///
/// Offers several methods which depend on the presence or absence of a contained value.
abstract class Optional<T> {
/// Creates a new Optional with the given non-null value.
///
/// Throws [ArgumentError] if value is null.
factory Optional.of(T value) {
if (value == null) {
throw ArgumentError('value must be non-null');
} else {
return _Present<T>(value);
}
}
/// Creates an empty Optional.
const factory Optional.empty() = _Absent<T>._internal;
/// The value associated with this Optional, if any.
///
/// Throws [NoValuePresentError] if no value is present.
T get value;
/// Whether the Optional has a value.
bool get isPresent;
/// Returns this Optional's value, if present, as nullable. Otherwise, returns null.
T? get orElseNull;
/// Invokes consume() with this Optional's value, if present. Otherwise, if orElse is passed, invokes it, otherwise does nothing.
void ifPresent(void Function(T) consume, {void Function() orElse});
/// The hashCode of this Optional's value, if present. Otherwise, 0.
@override
int get hashCode;
@override
bool operator ==(Object other);
}
class _Present<T> implements Optional<T> {
const _Present(this._value);
final T _value;
@override
T get value => _value;
@override
bool get isPresent => true;
@override
T? get orElseNull => _value;
@override
void ifPresent(void Function(T) consume, {void Function()? orElse}) =>
consume(_value);
@override
int get hashCode => _value.hashCode;
@override
bool operator ==(Object other) => other is _Present && other._value == _value;
@override
String toString() => 'Optional[value: $_value]';
}
class _Absent<T> implements Optional<T> {
const _Absent();
const _Absent._internal();
@override
T get value => throw NoValuePresentError();
@override
bool get isPresent => false;
@override
T? get orElseNull => null;
@override
void ifPresent(void Function(T) consume, {void Function()? orElse}) =>
orElse == null ? null : orElse();
@override
int get hashCode => 0;
@override
bool operator ==(Object other) => other is _Absent;
@override
String toString() => 'Optional[empty]';
}
/// Error thrown when attempting to operate on an empty Optional's value.
class NoValuePresentError extends StateError {
/// Creates a new NoValuePresentError with a message reading "no value present"
NoValuePresentError() : super('no value present');
}