Skip to content

Instantly share code, notes, and snippets.

@priezz
Last active January 5, 2023 10:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save priezz/59853d90dab5c4382a6bfa86d6f8fff7 to your computer and use it in GitHub Desktop.
Save priezz/59853d90dab5c4382a6bfa86d6f8fff7 to your computer and use it in GitHub Desktop.
Sealed classes for Dart

Sealed classes for Dart

Created with <3 with dartpad.dev.

// --------------------------------------------------------------------------------- //
/// GENERATED ---> ///
class _ResultBaseModel<T> {
_ResultBaseModel({required this.value});
T value;
}
abstract class Result<T> implements ISerializable {
final _ResultBaseModel<T> _model = _ResultBaseModel<T>();
T get value => _model.value;
@override
Json toJson() => {
'value': value,
};
/// >>> SEALED SPECIFIC
factory Result.failure({required T value, required String message}) =>
ResultFailure<T>(value: value, message: message);
factory Result.success({required T value}) => ResultSuccess<T>(value: value);
Result._();
factory Result.fromJson(Json json) {
switch (json['@class']) {
case 'ResultFailure':
return ResultFailure<T>.fromJson(json);
case 'ResultSuccess':
return ResultSuccess<T>.fromJson(json);
default:
throw Exception('Could not deserialize Result from $json');
}
}
R? maybe<R>({
R Function(ResultFailure<T>)? failure,
R Function(ResultSuccess<T>)? success,
R Function()? $else,
}) {
final self = this;
if (success != null && self is ResultSuccess<T>) {
return success(self);
} else if (failure != null && self is ResultFailure<T>) {
return failure(self);
} else if ($else != null) {
return $else();
} else {
return null;
}
}
R? whenOrNull<R>({
R Function(ResultFailure<T>)? failure,
R Function(ResultSuccess<T>)? success,
}) {
final self = this;
if (self is ResultSuccess<T>) {
return success?.call(self);
} else if (self is ResultFailure<T>) {
return failure?.call(self);
} else {
throw Exception('Unexpected subclass of Result.');
}
}
R when<R>({
required R Function(ResultFailure<T>) failure,
required R Function(ResultSuccess<T>) success,
}) => whenOrNull(
failure: failure,
success: success,
)!;
R? whenFailure<R>(R Function(ResultFailure<T>) f) => this is ResultFailure<T> ? f(this as ResultFailure<T>) : null;
R? whenSuccess<R>(R Function(ResultSuccess<T>) f) => this is ResultSuccess<T> ? f(this as ResultSuccess<T>) : null;
ResultFailure<T>? get asFailureOrNull => castOrNull(this);
ResultFailure<T>? get asSuccessOrNull => castOrNull(this);
/// <<< SEALED SPECIFIC
}
/// SEALED SPECIFIC
class _ResultFailureModel<T> extends _ResultBaseModel<T> {
late String message;
}
class ResultFailure<T> extends Result<T> {
factory ResultFailure({required T value, required String message}) =>
ResultFailure._build(
(b) => b
..message = message
..value = value,
);
ResultFailure._build(
void Function(_ResultFailureModel<T>) builder,
/// >>> SEALED SPECIFIC
): super._() {
/// <<< SEALED SPECIFIC
builder.call(_model);
}
factory ResultFailure.fromJson(Json json) {
/// >>> SEALED SPECIFIC
if (json['@class'] != 'ResultFailure') {
throw Exception('Invalid json data for ResultSuccess. $json');
}
/// <<< SEALED SPECIFIC
return ResultFailure._fromModel(_modelFromJson<T>(json));
}
factory ResultFailure._fromModel(
_ResultFailureModel<T> source,
) =>
ResultFailure<T>._build((dest) => _modelCopy<T>(source, dest));
static void _modelCopy<T>(
_ResultFailureModel<T> source,
_ResultFailureModel<T> dest,
) {
dest.message = source.message;
dest.value = source.value;
}
static _ResultFailureModel<T> _modelFromJson<T>(
Json json,
) => _ResultFailureModel()
..message = json['message'] as String
..value = json['value'];
@override
// ignore: overridden_fields
final _ResultFailureModel<T> _model = _ResultFailureModel();
String get message => _model.message;
@override
Json toJson() => {
/// >>> SEALED SPECIFIC
'@class': 'ResultFailure',
...super.toJson(),
/// <<< SEALED SPECIFIC
'message': _model.message,
};
}
/// SEALED SPECIFIC
class _ResultSuccessModel<T> extends _ResultBaseModel<T> {
}
class ResultSuccess<T> extends Result<T> {
factory ResultSuccess({required T value}) =>
ResultSuccess._build(
(b) => b
..value = value,
);
ResultSuccess._build(
void Function(_ResultSuccessModel<T>) builder,
/// >>> SEALED SPECIFIC
): super._() {
/// <<< SEALED SPECIFIC
builder.call(_model);
}
factory ResultSuccess.fromJson(Json json) {
/// >>> SEALED SPECIFIC
if (json['@class'] != 'ResultSuccess') {
throw Exception('Invalid json data for ResultSuccess. $json');
}
/// <<< SEALED SPECIFIC
return ResultSuccess._fromModel(_modelFromJson<T>(json));
}
factory ResultSuccess._fromModel(
_ResultSuccessModel<T> source,
) =>
ResultSuccess<T>._build((dest) => _modelCopy<T>(source, dest));
static void _modelCopy<T>(
_ResultSuccessModel<T> source,
_ResultSuccessModel<T> dest,
) {
dest.value = source.value;
}
static _ResultSuccessModel<T> _modelFromJson<T>(
Json json,
) => _ResultSuccessModel()
..value = json['value'];
@override
// ignore: overridden_fields
final _ResultSuccessModel<T> _model = _ResultSuccessModel();
@override
Json toJson() => {
/// >>> SEALED SPECIFIC
'@class': 'ResultSuccess',
...super.toJson(),
/// <<< SEALED SPECIFIC
};
}
/// <--- GENERATED ///
// --------------------------------------------------------------------------------- //
// @sealed
// ignore: unused_element
abstract class _ResultModel<T> {
Class failure(String message);
Class success();
late T value;
}
// @sealed
// ignore: unused_element
abstract class _RustResultModel<Success, Failure> {
Class failure(Failure error);
Class success(Success value);
}
extension ResultX<T> on Result<T> {
display() {
final String result = when(
failure: (f) => '${f.value}: ${f.message}',
success: (s) => '${s.value}',
);
print(result);
}
}
void main() {
try {
final Result<int> result = Result.failure(value: 404, message: 'Not found');
print(result.runtimeType);
result.display();
final Map json = result.toJson();
final Result otherResult = Result.fromJson(json);
print(otherResult.runtimeType);
otherResult.display();
final Result<int> otherResult2 = Result.fromJson(json);
print(otherResult2.runtimeType);
otherResult2.display();
final Result<int> otherResult3 = ResultSuccess.fromJson(json);
print(otherResult3.runtimeType);
otherResult3.display();
} catch(e) {
print('\n$e');
}
}
// --------------------------------------------------------------------------------- //
/// From data_classes.dart
T? castOrNull<T>(dynamic x) => x != null && x is T ? x : null;
abstract class ISerializable {}
typedef Class = void;
typedef Json = Map<dynamic, dynamic>;
/// GENERATED START ///
abstract class Result<T> extends _ResultSealed<T> {
Result._({this.value});
factory Result.Failure() => _ResultFailure<T>();
factory Result.Success(T value) => _ResultSuccess<T>(value);
T? value;
R when<R>({
required R Function() Failure,
required R Function() Success,
}) {
if (this is _ResultSuccess<T>) {
return Success();
} else if (this is _ResultFailure) {
return Failure();
} else {
throw Exception('[Result] class cannot be instantiated directly.');
}
}
}
class _ResultSuccess<T> extends Result<T> {
_ResultSuccess(T value): super._(value: value) {Success(value);}
}
class _ResultFailure<T> extends Result<T> {
_ResultFailure(): super._() {Failure();}
}
/// GENERATED END ///
// ---------------------------------------------------------------------- //
//
@sealed
class _ResultSealed<T> {
Failure() {}
Success(T value) {score = 10;}
int score = 0;
}
extension ResultX<T> on Result<T> {
display<T>() {
final int score = when<(
Success: (s) => f.value ? s.score : 0,
Failure: (f) => f.score,
);
print('$str: $score');
}
}
Result<bool> getResult() => Result.Success(true);
void main() {
getResult().display();
test(a: null);
final n = null;
// _defaultNull.p();
// null.p();
}
extension on int? {
p() => print('int, ${this.runtimeType}');
}
extension on Null {
p() => print('null');
}
const _defaultNull = null;
// class Ii implements int {}
test({int? a = _defaultNull, int? b = _defaultNull}) {
final bool withA = a != _defaultNull;
final bool withB = b != _defaultNull;
// final bool withA = a is Null;
// final bool withB = b is Null;
print('a provided: $withA');
print('b provided: $withB');
// _defaultNull.p();
// if (a == null) (a as Null).p();
a.p();
b.p();
// if (b == null) (b as Null).p();
}
// copyWith({int? value}) --> copyWith({V<int?>? value} = const V<int?>()) (edited)
// white_check_mark
// +1
// heavy_check_mark
// 10:02
// copyWith();.
// copyWith(value: V(10));
// copyWith(value: V(null)); (edited)
// 10:04
// copy((b) => b.value = 10); (edited)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment