Last active
October 23, 2024 11:16
-
-
Save eric-taix/57ee386ccbe1b7c60cc27e9282185527 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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