I have a sealed class for FailureOrSuccess, with subclasses for Success, and Failure.ch
The Failure subclass is also a sealed class, with multiple subclasses for the different types of failure.
I would like to have a switch statement that switches between failure and success, and within the failure code block, have another switch statement that allows me to switch between the different failure options?
Is it possible to do this with nested sealed-classes?
(here's an example of what I'm trying to do below, though this doesn't work).
switch (state.authFailureOrSuccessOption) {
case Success(): {
context.router.replace(const DailyRoute());
}
case Failure(): {
String text;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(switch (???) {
case CancelledByUser:
return 'Cancelled';
case ServerError:
return 'Server Error';
case EmailAlreadyInUse:
return 'Email already in use';
case InvalidEmailAndPasswordCombination:
return 'Invalid email and password combination';
case UnknownError:
return 'An unknown error occurred';
}),));
}
}
And here's a list of my sealed-classes for reference:
// Overall Class
sealed class FailureOrSuccess {
const FailureOrSuccess();
}
// Level 2 Subclass
class Success extends FailureOrSuccess {
const Success();
}
sealed class Failure extends FailureOrSuccess {
const Failure();
}
// Level 3 Subclass
sealed class AuthFailure extends Failure {
const AuthFailure();
}
// Leven 4 Subclasses of AuthFailure
class CancelledByUser extends AuthFailure {
const CancelledByUser();
}
class ServerError extends AuthFailure {
const ServerError();
}
class EmailAlreadyInUse extends AuthFailure {
const EmailAlreadyInUse();
}
class InvalidEmailAndPasswordCombination extends AuthFailure {
const InvalidEmailAndPasswordCombination();
}
class UnknownError extends AuthFailure {
const UnknownError();
}
Yes.
The exhaustiveness-checking algorithm isn't completely implemented yet, but it's intended that class hierarchies like the above will work.
You need to write the
casepatterns differently, though.Use of:
The
case CancelledByUser:is actually comparing the switch value to theTypeobject for the typeCancelledByUser(which will never succeed, because theCancelledByUserobject is not aTypeobject and not equal to one), it's not actually doing a type check. Thecase CancelledByUser _:orcase CancelledByUser():patterns do type checks.You can nest switches, using the promoted/checked type of the outer match as the match value, and you can use a switch expression in an expression position: