Pattern matching
Let's take this Username
modddel again as an example :
The 'form' validationStep contains two validations : 'length' validation and 'characters' validation. The 'availability' validationStep contains only one validation : 'reserved' validation.
There are multiple pattern matching methods generated by the modddels generator.
/// Use the [map] method to do pattern matching between all the concrete
/// union-cases : the valid union-case + the invalid-step union-cases
///
String message1 = username.map(
valid: (ValidUsername validUsername) => 'The username is valid',
invalidForm: (InvalidUsernameForm invalidUsernameForm) =>
'The username has an invalid form',
invalidAvailability: (InvalidUsernameAvailability invalidUsernameAvailability) =>
'The username is not available');
/// Use the [maybeMap] method when you only want to handle a few cases. It
/// returns the result of [orElse] for unhandled cases.
///
bool isAvailable = username.maybeMap(
invalidAvailability: (InvalidUsernameAvailability invalidUsernameAvailability) => false,
orElse: () => true,
);
/// Use the [mapOrNull] method when you only want to handle a few cases. It
/// returns null for unhandled cases.
///
String? message2 = username.mapOrNull(
invalidAvailability: (InvalidUsernameAvailability invalidUsernameAvailability) =>
'The username is not available',
);
/// Use the [mapValidity] method to do pattern matching between the valid
/// union-case and the abstract invalid union-case
///
username.mapValidity(
valid: (ValidUsername validUsername) {
print('Valid username');
},
invalid: (InvalidUsername invalidUsername) {
print('Invalid username');
},
);
/// The [maybeMapValidity] method is similar to the [maybeMap] method,
/// but :
/// - The [valid] callback parameter is required
/// - The [orElse] callback parameter is required too and has [invalid] as a
/// parameter.
///
String message3 = username.maybeMapValidity(
valid: (ValidUsername validUsername) => 'Valid',
invalidAvailability: (InvalidUsernameAvailability invalidUsernameAvailability) =>
'Not available',
orElse: (InvalidUsername invalidUsername) => 'Invalid for some other reason',
);
For the abstract invalid union-case (in this example it's InvalidUsername
), there are other pattern matching methods you can use to map between the different invalid-step union-cases.
username.mapValidity(
valid: (ValidUsername validUsername) {},
invalid: (InvalidUsername invalidUsername) {
/// Use the [mapInvalid] method to do pattern matching between all the
/// invalid-step union-cases.
///
String message1 = invalidUsername.mapInvalid(
invalidForm: (InvalidUsernameForm invalidUsernameForm) =>
'The username has an invalid form',
invalidAvailability: (InvalidUsernameAvailability invalidUsernameAvailability) =>
'The username is not available');
/// Use the [maybeMapInvalid] method when you don't want to handle all
/// invalid cases separately. The [orElse] callback parameter is required.
///
invalidUsername.maybeMapInvalid(
invalidAvailability: (InvalidUsernameAvailability invalidUsernameAvailability) =>
print('Unavailable'),
orElse: () => print('Invalid'),
);
/// The [mapOrNullInvalid] method is similar to [maybeMapInvalid], but it
/// returns null for unhandled cases.
///
String? message2 = invalidUsername.mapOrNullInvalid(
invalidAvailability: (InvalidUsernameAvailability invalidUsernameAvailability) =>
'Unavailable',
);
/// [whenInvalid], [maybeWhenInvalid], and [whenOrNullInvalid] give you a
/// direct access to the failures of each invalid-step union-case.
///
invalidUsername.whenInvalid(
formFailures: (lengthFailure, charactersFailure) {},
availabilityFailures: (reservedFailure) {},
);
invalidUsername.maybeWhenInvalid(
availabilityFailures: (reservedFailure) {},
orElse: () {},
);
invalidUsername.whenOrNullInvalid(
availabilityFailures: (reservedFailure) {},
);
},
);
Last updated