Skip to content

Instantly share code, notes, and snippets.

@eric-taix
Last active October 23, 2024 11:16
Show Gist options
  • Save eric-taix/57ee386ccbe1b7c60cc27e9282185527 to your computer and use it in GitHub Desktop.
Save eric-taix/57ee386ccbe1b7c60cc27e9282185527 to your computer and use it in GitHub Desktop.
sealed class User {
// Private constructor
User._();
// Factory constructor
factory User.fromJson(Map<String, dynamic) {
return switch(json['type']) {
'external' => ExternalUser(name: json['name'] as String),
'privileged' => PrivilegedUser(name: json['name'] as String, json['roles'] as List<String>),
_ => UnknowUserType(),
};
}
class UnknowUserType extends User {
}
class ExternalUser {
final String name;
// Private constructor
ExternalUser._({required this.name});
}
class PrivilegedUser {
final String name;
final List<String> roles;
// Private constructor
PrivilegedUser._({this.name, this.roles});
}
// Creation of a user
final User user = User.fromJson(json);
// Exaustive switch expression with pattern matching and destructuration
// With a sealed class, you can't miss any case as the compiler already knows all possible implementation
// which is not the case with an abstract class as it can be implemented outside your code (typically if
// your code is a library). So if you add another concrete class (ie RootedUser) the compiler will claim you
// to add another case to be exaustive: no more missed cases
final exaustiveExample = switch(user) {
UnknownTypeUser() => 'Unknow user type',
ExternalUser(:final name) => 'External user $name',
PrivilegedUser(:final name, :final roles) => 'Privileged user $name with roles $roles',
}
// Here the compiler will claims to add another case as this is not exaustive
final nonExaustiveExample = switch(user) {
UnknownTypeUser() => 'Unknow user type',
ExternalUser(:final name) => 'External user $name',
PrivilegedUser(name: 'Eric, :final roles) => 'Yeah this is me',
// Another case must be added here as there's no case for a PrivilegedUser with a name which is not 'Eric'
// This must be added => PrivilegedUser(:final name, :final roles) => 'This is not me but $name with roles $roles',
}
print(exaustiveExample);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment