Unverified Commit 93c4b09e authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Add `RestorableEnumN<T>` and `RestorableEnum<T>` to restorable primitive types (#115050)

* Add RestorableEnumN and RestorableEnum to restorable primitive types

* Review Changes

* Change to assert if not part of the valid set.

* Assert if default value isn't in the enum
parent 7d2b0113
...@@ -496,3 +496,177 @@ class RestorableTextEditingController extends RestorableChangeNotifier<TextEditi ...@@ -496,3 +496,177 @@ class RestorableTextEditingController extends RestorableChangeNotifier<TextEditi
return value.text; return value.text;
} }
} }
/// A [RestorableProperty] that knows how to store and restore a nullable [Enum]
/// type.
///
/// {@macro flutter.widgets.RestorableNum}
///
/// The values are serialized using the name of the enum, obtained using the
/// [EnumName.name] extension accessor.
///
/// The represented value is accessible via the [value] getter. The set of
/// values in the enum are accessible via the [values] getter. Since
/// [RestorableEnumN] allows null, this set will include null.
///
/// See also:
///
/// * [RestorableEnum], a class similar to this one that knows how to store and
/// restore non-nullable [Enum] types.
class RestorableEnumN<T extends Enum> extends RestorableValue<T?> {
/// Creates a [RestorableEnumN].
///
/// {@macro flutter.widgets.RestorableNum.constructor}
RestorableEnumN(T? defaultValue, { required Iterable<T> values })
: assert(defaultValue == null || values.contains(defaultValue),
'Default value $defaultValue not found in $T values: $values'),
_defaultValue = defaultValue,
values = values.toSet();
@override
T? createDefaultValue() => _defaultValue;
final T? _defaultValue;
@override
set value(T? newValue) {
assert(newValue == null || values.contains(newValue),
'Attempted to set an unknown enum value "$newValue" that is not null, or '
'in the valid set of enum values for the $T type: '
'${values.map<String>((T value) => value.name).toSet()}');
super.value = newValue;
}
/// The set of non-null values that this [RestorableEnumN] may represent.
///
/// This is a required field that supplies the enum values that are serialized
/// and restored.
///
/// If a value is encountered that is not null or a value in this set,
/// [fromPrimitives] will assert when restoring.
///
/// It is typically set to the `values` list of the enum type.
///
/// In addition to this set, because [RestorableEnumN] allows nullable values,
/// null is also a valid value, even though it doesn't appear in this set.
///
/// {@tool snippet} For example, to create a [RestorableEnumN] with an
/// [AxisDirection] enum value, with a default value of null, you would build
/// it like the code below:
///
/// ```dart
/// RestorableEnumN<AxisDirection> axis = RestorableEnumN<AxisDirection>(null, values: AxisDirection.values);
/// ```
/// {@end-tool}
Set<T> values;
@override
void didUpdateValue(T? oldValue) {
notifyListeners();
}
@override
T? fromPrimitives(Object? data) {
if (data == null) {
return null;
}
if (data is String) {
for (final T allowed in values) {
if (allowed.name == data) {
return allowed;
}
}
assert(false,
'Attempted to set an unknown enum value "$data" that is not null, or '
'in the valid set of enum values for the $T type: '
'${values.map<String>((T value) => value.name).toSet()}');
}
return _defaultValue;
}
@override
Object? toPrimitives() => value?.name;
}
/// A [RestorableProperty] that knows how to store and restore an [Enum]
/// type.
///
/// {@macro flutter.widgets.RestorableNum}
///
/// The values are serialized using the name of the enum, obtained using the
/// [EnumName.name] extension accessor.
///
/// The represented value is accessible via the [value] getter.
///
/// See also:
///
/// * [RestorableEnumN], a class similar to this one that knows how to store and
/// restore nullable [Enum] types.
class RestorableEnum<T extends Enum> extends RestorableValue<T> {
/// Creates a [RestorableEnum].
///
/// {@macro flutter.widgets.RestorableNum.constructor}
RestorableEnum(T defaultValue, { required Iterable<T> values })
: assert(values.contains(defaultValue),
'Default value $defaultValue not found in $T values: $values'),
_defaultValue = defaultValue,
values = values.toSet();
@override
T createDefaultValue() => _defaultValue;
final T _defaultValue;
@override
set value(T newValue) {
assert(values.contains(newValue),
'Attempted to set an unknown enum value "$newValue" that is not in the '
'valid set of enum values for the $T type: '
'${values.map<String>((T value) => value.name).toSet()}');
super.value = newValue;
}
/// The set of values that this [RestorableEnum] may represent.
///
/// This is a required field that supplies the possible enum values that can
/// be serialized and restored.
///
/// If a value is encountered that is not in this set, [fromPrimitives] will
/// assert when restoring.
///
/// It is typically set to the `values` list of the enum type.
///
/// {@tool snippet} For example, to create a [RestorableEnum] with an
/// [AxisDirection] enum value, with a default value of [AxisDirection.up],
/// you would build it like the code below:
///
/// ```dart
/// RestorableEnum<AxisDirection> axis = RestorableEnum<AxisDirection>(AxisDirection.up, values: AxisDirection.values);
/// ```
/// {@end-tool}
Set<T> values;
@override
void didUpdateValue(T? oldValue) {
notifyListeners();
}
@override
T fromPrimitives(Object? data) {
if (data != null && data is String) {
for (final T allowed in values) {
if (allowed.name == data) {
return allowed;
}
}
assert(false,
'Attempted to restore an unknown enum value "$data" that is not in the '
'valid set of enum values for the $T type: '
'${values.map<String>((T value) => value.name).toSet()}');
}
return _defaultValue;
}
@override
Object toPrimitives() => value.name;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment