diff --git a/packages/validate/CHANGELOG.md b/packages/validate/CHANGELOG.md index a4d11370..fb09e21b 100644 --- a/packages/validate/CHANGELOG.md +++ b/packages/validate/CHANGELOG.md @@ -1,5 +1,5 @@ # 3.0.0-alpha.1 -* Add `MapField`. +* Add `MapField` and `UriField`. # 3.0.0-alpha * Rewrite, based on `Field` and `Form`, rather than strings. diff --git a/packages/validate/README.md b/packages/validate/README.md index dd890cdb..d2469275 100644 --- a/packages/validate/README.md +++ b/packages/validate/README.md @@ -52,6 +52,7 @@ There are several included field types: * `FileField` - Validates a file in `req.uploadedFiles`. * `ImageField` - Uses `package:image` to decode an `UploadedFile` into an image. * `MapField` - Validates a Map using a Form. +* `UriField` - Parses text input into a `Uri` object. # Forms The `Form` class lets you combine `Field` instances, and decode diff --git a/packages/validate/lib/src/common_fields.dart b/packages/validate/lib/src/common_fields.dart index fa1a3ed6..8af80601 100644 --- a/packages/validate/lib/src/common_fields.dart +++ b/packages/validate/lib/src/common_fields.dart @@ -393,3 +393,37 @@ class MapField extends Field> { return form.readFromMap(mapValue); } } + +/// A [Field] that parses plain text as a [Uri]. +class UriField extends Field { + // Reuse text validation logic. + TextField _textField; + + UriField(String name, + {String label, String type = 'url', bool isRequired = true}) + : super(name, type, label: label, isRequired: isRequired) { + _textField = TextField(name, label: label, isRequired: isRequired); + } + + @override + FutureOr accept(FormRenderer renderer) => + renderer.visitUriField(this); + + @override + FutureOr> read( + Map fields, Iterable files) async { + var result = await _textField.read(fields, files); + if (result == null) { + return null; + } else if (result.isSuccess != true) { + return FieldReadResult.failure(result.errors); + } else { + var value = Uri.tryParse(result.value); + if (value != null) { + return FieldReadResult.success(value); + } else { + return FieldReadResult.failure(['"$name" must be a valid URI.']); + } + } + } +} diff --git a/packages/validate/lib/src/form_renderer.dart b/packages/validate/lib/src/form_renderer.dart index b703841b..e20f0784 100644 --- a/packages/validate/lib/src/form_renderer.dart +++ b/packages/validate/lib/src/form_renderer.dart @@ -20,4 +20,6 @@ abstract class FormRenderer { FutureOr visitTextField(TextField field); FutureOr visitMapField(MapField field); + + FutureOr visitUriField(UriField field); }