### Basic Validation Chain with trust_but_verify Source: https://pub.dev/packages/trust_but_verify/versions/0.6.0/changelog Demonstrates a simple validation chain using the trust_but_verify package. It starts with `trust()`, adds a rule, and then executes validation with `verify()`. This example is suitable for basic string validation. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; void main() { final String? name = 'John Doe'; final result = trust(name) .isNotEmpty() .verify(); if (result.isSuccess) { print('Validation successful: ${result.value}'); } else { print('Validation failed: ${result.errors.first}'); } } ``` -------------------------------- ### Starting Validation from fpdart TaskEither Source: https://pub.dev/packages/trust_but_verify/index Illustrates how to start a `trust_but_verify` validation chain from an `fpdart` `TaskEither`. This method seamlessly integrates validation into asynchronous functional workflows, propagating any upstream failures. The example validates an email asynchronously. ```dart import 'package:fpdart/fpdart'; // Start validation from a TaskEither (propagates upstream failures) final taskInput = TaskEither.right('test@example.com'); final asyncValidated = await taskInput .trust('Email') .verifyEither(); ``` -------------------------------- ### Example pubspec.yaml Dependency Source: https://pub.dev/packages/trust_but_verify/install Illustrates how the trust_but_verify package is listed as a dependency in a Dart or Flutter project's pubspec.yaml file. This ensures the package is correctly managed by the Dart pub system. ```yaml dependencies: trust_but_verify: ^0.6.1 ``` -------------------------------- ### Starting Validation from fpdart Either Source: https://pub.dev/packages/trust_but_verify/versions/0.6 Explains how to initiate a validation chain directly from an existing fpdart `Either` type. The `trust` extension method can be applied to the value within the `Either`, allowing seamless integration of validation into existing functional data flows. This example validates an email from a `Right` value. ```dart // Start validation from an existing Either final Either input = Right('test@example.com'); final validated = input .trust('Email') .isNotEmpty() .isEmail() .verifyEither(); ``` -------------------------------- ### Error Handling with Stack Traces Source: https://pub.dev/packages/trust_but_verify/versions/0.6 Illustrates how validation errors, particularly from operations like `tryMap`, include optional stack traces for detailed debugging. The example shows how to catch a `TryMapValidationError` and access its message, field name, and stack trace. ```dart try { final result = email .trust('Email') .tryMap( (value) => throw Exception('Custom error'), (fieldName) => '$fieldName transformation failed', ) .verify(); } catch (e) { if (e is TryMapValidationError) { print('Error: ${e.message}'); print('Field: ${e.fieldName}'); print('Stack trace: ${e.stackTrace}'); } } ``` -------------------------------- ### Starting Validation from fpdart TaskEither Source: https://pub.dev/packages/trust_but_verify/versions/0.6 Illustrates starting a validation chain from an fpdart `TaskEither`. This is useful for validating values that are already part of an asynchronous functional computation. The validation chain will propagate any upstream failures from the `TaskEither`. ```dart // Start validation from a TaskEither (propagates upstream failures) final taskInput = TaskEither.right('test@example.com'); final asyncValidated = await taskInput .trust('Email') .verifyEither(); ``` -------------------------------- ### Starting Validation from fpdart Either Source: https://pub.dev/packages/trust_but_verify/index Demonstrates how to initiate a `trust_but_verify` validation chain directly from an `fpdart` `Either` type. This is useful for integrating validation into existing functional data flows. The example shows validating an email within an `Either`. ```dart import 'package:fpdart/fpdart'; // Start validation from an existing Either final Either input = Right('test@example.com'); final validated = input .trust('Email') .isNotEmpty() .isEmail() .verifyEither(); ``` -------------------------------- ### Example pubspec.yaml Dependency Source: https://pub.dev/packages/trust_but_verify/versions/0.6.0/install An example of how the trust_but_verify package dependency is declared in a Dart or Flutter project's pubspec.yaml file. This ensures the package is included in the project's dependencies. ```yaml dependencies: trust_but_verify: ^0.6.0 ``` -------------------------------- ### Creating Custom String Validation Extensions in Dart Source: https://pub.dev/packages/trust_but_verify/versions/0.6 Custom extensions can be created for `SyncValidationStep` to add domain-specific validators. This example shows an `isStrongPassword()` validator for strings, using `bind()`, `fail()`, and `pass()` helper methods. ```dart // Custom extension for String validation extension CustomStringExtension on SyncValidationStep { /// Validates that the string is a strong password SyncValidationStep isStrongPassword() => bind((value) { if (value.length < 8) { return fail('$fieldName must be at least 8 characters long'); } if (!RegExp(r'[A-Z]').hasMatch(value)) { return fail('$fieldName must contain at least one uppercase letter'); } if (!RegExp(r'[a-z]').hasMatch(value)) { return fail('$fieldName must contain at least one lowercase letter'); } if (!RegExp(r'[0-9]').hasMatch(value)) { return fail('$fieldName must contain at least one number'); } if (!RegExp(r'[!@#$%^&*(),.?":{}|<>]').hasMatch(value)) { return fail('$fieldName must contain at least one special character'); } return pass(value); }); } ``` -------------------------------- ### Import trust_but_verify in Dart Code Source: https://pub.dev/packages/trust_but_verify/install How to import the trust_but_verify library into your Dart files to start using its validation functionalities. This import statement makes all exported members of the package available. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; ``` -------------------------------- ### Add trust_but_verify to Flutter Project Source: https://pub.dev/packages/trust_but_verify/install Command to add the trust_but_verify package as a dependency to a Flutter project. This command updates the pubspec.yaml file and runs flutter pub get. ```bash $ flutter pub add trust_but_verify ``` -------------------------------- ### Validation with fpdart Either and TaskEither Source: https://pub.dev/packages/trust_but_verify/versions/0.6.0/changelog Shows how to integrate trust_but_verify with fpdart's `Either` and `TaskEither`. You can start validation chains directly from `Right`, `Left`, `TaskEither`, allowing for functional error handling throughout your application. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; import 'package:fpdart/fpdart.dart'; void main() { final Either eitherValue = right(10); final result = trust(eitherValue) .isRight() .verify(); if (result.isSuccess) { print('Either is Right.'); } else { print('Either validation error: ${result.errors.first}'); } } ``` -------------------------------- ### Creating Custom Numeric Validation Extensions in Dart Source: https://pub.dev/packages/trust_but_verify/versions/0.6 Custom extensions for numeric types (`T extends num`) can be defined to add specific validation rules. This example includes `isEmploymentAge()` and `isPercentage()` validators. ```dart // Custom extension for numeric validation extension CustomNumExtension on SyncValidationStep { /// Validates that the number is a valid age for employment SyncValidationStep isEmploymentAge() => bind((value) { if (value < 16) { return fail('$fieldName must be at least 16 years old for employment'); } if (value > 70) { return fail('$fieldName must be under 70 years old for employment'); } return pass(value); }); /// Validates that the number is a valid percentage (0-100) SyncValidationStep isPercentage() => bind((value) { if (value < 0 || value > 100) { return fail('$fieldName must be between 0 and 100'); } return pass(value); }); } ``` -------------------------------- ### Validating Either and TaskEither from fpdart Source: https://pub.dev/packages/trust_but_verify/changelog Shows how to integrate validation with `Either` and `TaskEither` types from the `fpdart` library. The package provides extensions to start validation chains directly from these functional types, allowing for seamless validation within functional programming paradigms. ```dart import 'package:dartz/dartz.dart'; import 'package:trust_but_verify/trust_but_verify.dart'; void main() { // Example with Either final resultEither = Right(10).validate().isEven().verify(); print('Either validation: $resultEither'); // Example with TaskEither (requires async context) Future validateTaskEither() async { final resultTaskEither = await (await Future.value(Right(10))) .validate() .isOdd() .verifyTaskEither(); print('TaskEither validation: $resultTaskEither'); } validateTaskEither(); } ``` -------------------------------- ### trust_but_verify with fpdart: Standard Dart Verification Source: https://pub.dev/packages/trust_but_verify/index Demonstrates the standard Dart way of using `trust_but_verify` with the `.verify()` method. This method throws a `ValidationError` if the validation fails, which is suitable for traditional imperative Dart code. The example shows validating an email string. ```dart import 'package:fpdart/fpdart'; // 1. Standard Dart (Throws on failure) final email = 'test@example.com'.trust('Email').isEmail().verify(); ``` -------------------------------- ### Partially Override Validation Messages with Mixin Source: https://pub.dev/packages/trust_but_verify/index This example demonstrates how to partially override validation messages using the `ValidationMessagesMixin` in Dart. A `CustomValidationMessages` class is defined, inheriting from the mixin, and only specific methods like `emptyField` and `invalidEmail` are overridden to provide custom error strings. All other validation messages will automatically fall back to the default English implementation provided by the mixin, ensuring a balance between customization and code simplicity. ```dart // Use the ValidationMessagesMixin to override only the messages you want to customize class CustomValidationMessages with ValidationMessagesMixin { @override String emptyField(String fieldName) => 'The $fieldName field cannot be empty'; @override String invalidEmail(String fieldName) => 'Please enter a valid email address for $fieldName'; // All other messages will use the default English implementation } // Configure the package to use your custom messages ValidationStep.configureMessages(CustomValidationMessages()); ``` -------------------------------- ### Usage of Custom Validation Extensions in Dart Source: https://pub.dev/packages/trust_but_verify/versions/0.6 Demonstrates how to use the previously defined custom extensions (`isStrongPassword` and `isEmploymentAge`) in Dart validation chains. ```dart // Usage of custom extensions final passwordResult = 'MyP@ssw0rd' .trust('Password') .isStrongPassword() .verify(); final ageResult = 25 .trust('Age') .isEmploymentAge() .verify(); ``` -------------------------------- ### Configure Custom Validation Messages Globally Source: https://pub.dev/packages/trust_but_verify/versions/0.6 Shows how to globally configure custom validation messages for the `trust_but_verify` package. By creating a class that extends `ValidationMessages` (or uses `ValidationMessagesMixin`) and passing it to `ValidationStep.configureMessages()`, all subsequent validations will use these custom messages. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; // Configure custom messages globally ValidationStep.configureMessages(CustomValidationMessages()); // All validation operations will now use your custom messages final result = email .trust('Email') .isNotEmpty() .isEmail() .verify(); ``` -------------------------------- ### Basic String Validation and Transformation in Dart Source: https://pub.dev/packages/trust_but_verify/example Demonstrates basic string validation and transformation using the trust_but_verify library. It covers checking for whitespace, converting to an integer, and validating against a list of allowed values. Errors are caught and printed if validation fails. ```dart print('Form validator result: ${formValidatorResult ?? 'No error'}'); // Additional validators with verify() try { final whitespace = ' ' .trust('Whitespace String') .isNotEmpty(allowWhitespace: true) .verify(); print('✅ Whitespace validation passed: $whitespace'); final intVal = '123'.trust('Number String').toInt().verify(); print('✅ Int conversion passed: $intVal'); final role = 'admin'.trust('Role').isNotEmpty().isOneOf([ 'admin', 'user', 'moderator', ]).verify(); print('✅ Valid role: $role'); } catch (e) { if (e is ValidationError) { print('❌ Validation failed: ${e.message}'); } } ``` -------------------------------- ### Creating Custom Validation Extensions in Dart Source: https://pub.dev/packages/trust_but_verify/index Shows how to create custom extensions for `SyncValidationStep` in Dart to add domain-specific validators. These extensions use `bind()`, `pass()`, and `fail()` to define reusable validation logic for types like String and numeric types. ```dart // Custom extension for String validation extension CustomStringExtension on SyncValidationStep { /// Validates that the string is a strong password SyncValidationStep isStrongPassword() => bind((value) { if (value.length < 8) { return fail('$fieldName must be at least 8 characters long'); } if (!RegExp(r'[A-Z]').hasMatch(value)) { return fail('$fieldName must contain at least one uppercase letter'); } if (!RegExp(r'[a-z]').hasMatch(value)) { return fail('$fieldName must contain at least one lowercase letter'); } if (!RegExp(r'[0-9]').hasMatch(value)) { return fail('$fieldName must contain at least one number'); } if (!RegExp(r'[!@#$%^&*(),.?":{}|<>]').hasMatch(value)) { return fail('$fieldName must contain at least one special character'); } return pass(value); }); } // Custom extension for numeric validation extension CustomNumExtension on SyncValidationStep { /// Validates that the number is a valid age for employment SyncValidationStep isEmploymentAge() => bind((value) { if (value < 16) { return fail('$fieldName must be at least 16 years old for employment'); } if (value > 70) { return fail('$fieldName must be under 70 years old for employment'); } return pass(value); }); /// Validates that the number is a valid percentage (0-100) SyncValidationStep isPercentage() => bind((value) { if (value < 0 || value > 100) { return fail('$fieldName must be between 0 and 100'); } return pass(value); }); } // Usage of custom extensions final passwordResult = 'MyP@ssw0rd' .trust('Password') .isStrongPassword() .verify(); final ageResult = 25 .trust('Age') .isEmploymentAge() .verify(); ``` -------------------------------- ### Basic String and Numeric Validation in Dart Source: https://pub.dev/packages/trust_but_verify/versions/0.6.0/example Demonstrates basic string and numeric validation using methods like isNotEmpty, isEmail, min, max, and isEven. It shows how to use verify() for exceptions and verifyEither() for fold operations. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; void main() async { print('=== trust_but_verify Examples ===\n'); // Basic string validation try { final email = 'test@example.com' .trust('Email') .isNotEmpty() .isEmail() .verify(); print('✅ Valid email: $email'); } catch (e) { if (e is ValidationError) { print('❌ Email validation failed: ${e.message}'); } } // Functional validation with Either final uuidResult = '550e8400-e29b-41d4-a716-446655440000' .trust('UUID') .isUuid() .verifyEither() .fold( (error) => '❌ UUID validation failed: ${error.message}', (value) => '✅ Valid UUID: $value', ); print(uuidResult); // Numeric validation final ageResult = 25 .trust('Age') .min(18) .max(65) .isEven() .verifyEither() .fold( (error) => '❌ Age validation failed: ${error.message}', (value) => '✅ Valid age: $value', ); print(ageResult); // String validators final urlResult = 'https://example.com/api' .trust('URL') .startsWith('https') .contains('api') .isUrl() .verifyEither() .fold( (error) => '❌ URL validation failed: ${error.message}', (value) => '✅ Valid URL: $value', ); print(urlResult); // Nullable validation try { // ignore: avoid-unnecessary-type-casts final optionalEmail = ('optional@example.com' as String?) .trust('Optional Email') .isNotNull() .verify(); print('✅ Valid optional email: $optionalEmail'); } catch (e) { if (e is ValidationError) { print('❌ Optional email validation failed: ${e.message}'); } } // Batch validation final batchResult = [ 'user@example.com'.trust('Email').isNotEmpty().isEmail(), 'password123'.trust('Password').isNotEmpty().minLength(8), 30.trust('Age').min(18).max(65), ].verifyEither().fold( (error) => '❌ Batch validation failed: ${error.message}', (values) => // ignore: avoid-unsafe-collection-methods '✅ All fields valid: Email=${values[0]}, Password=${values[1]}, Age=${values[2]}', ); print(batchResult); // Custom validation with check() final customResult = 'hello world' .trust('Custom String') .ensure( (value) => value.contains('world'), (fieldName) => '$fieldName must contain "world"', ) .verifyEither() .fold( (error) => '❌ Custom validation failed: ${error.message}', (value) => '✅ Custom validation passed: $value', ); print(customResult); // Date and time validation try { final date = '2023-12-25'.trust('Date').isIsoDate().verify(); print('✅ Valid date: $date'); final time = '14:30'.trust('Time').isTime24Hour().verify(); print('✅ Valid time: $time'); } catch (e) { if (e is ValidationError) { print('❌ Date/Time validation failed: ${e.message}'); } } // Error handling with errorOrNull final errorOrNullResult = ''.trust('Empty String').isNotEmpty().errorOrNull(); print('Error or null result: ${errorOrNullResult ?? 'No error'}'); // Form validator convenience method final formValidatorResult = 'test@example.com' .trust('Form Email') .isNotEmpty() .isEmail() .asFormValidator(); } ``` -------------------------------- ### Basic Error Handling with trust_but_verify in Dart Source: https://pub.dev/packages/trust_but_verify/index Illustrates basic error handling using the trust_but_verify package in Dart. The `errorOrNull()` method is shown, which is useful for obtaining the validation error message or null if the validation passes, commonly used in UI frameworks like Flutter. ```dart // Get error message or null (useful for Flutter forms) final error = email .trust('Email') .isNotEmpty() .isEmail() .errorOrNull(); if (error != null) { // Display error in UI print('Error: $error'); } ``` -------------------------------- ### Chaining Validations with bind() in Dart Source: https://pub.dev/packages/trust_but_verify/index Demonstrates how to use the bind() method to chain multiple validation steps in Dart. The bind() method accepts a function that returns an Either, allowing for complex or conditional validation logic. It's useful for sequentially applying checks and returning early on failure. ```dart // Complex validation with bind() final result = 'user@example.com' .trust('Email') .bind((email) { // Check if email is from allowed domains final allowedDomains = ['example.com', 'company.org']; final domain = email.split('@').last; if (!allowedDomains.contains(domain)) { return Left(ValidationError('Email', 'Email must be from an allowed domain')); } // Check if email is not too long if (email.length > 50) { return Left(ValidationError('Email', 'Email must be less than 50 characters')); } return Right(email); }) .verifyEither(); // Conditional validation with bind() final result = age .trust('Age') .bind((value) { if (value < 18) { return Left(ValidationError('Age', 'Must be at least 18 years old')); } if (value > 65) { return Left(ValidationError('Age', 'Must be under 65 years old')); } // Additional business logic if (value == 25) { return Left(ValidationError('Age', 'Age 25 is not allowed for this application')); } return Right(value); }) .verifyEither(); ``` -------------------------------- ### Basic Field Validation with Trust and Verify Source: https://pub.dev/packages/trust_but_verify/changelog Demonstrates the fundamental usage of the `trust()` and `verify()` methods for synchronous field validation. `trust()` initializes a validation chain for a field, and `verify()` executes the chain, returning a result that indicates success or failure with associated errors. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; void main() { final result = trust('email') .isEmail() .verify(); if (result.isSuccess) { print('Email is valid!'); } else { print('Email validation failed: ${result.errors}'); } } ``` -------------------------------- ### Numeric Validation with Trust But Verify Source: https://pub.dev/packages/trust_but_verify/index Illustrates numeric validation capabilities of the Trust But Verify package. These methods check for minimum/maximum values, ranges, positivity, integer status, even/odd numbers, powers of two, and port numbers. They also support validation against specific lists and exclusion lists. ```dart age.trust('Age') .min(0) // Minimum value .max(120) // Maximum value .inRange(13, 65) // Value within range .isPositive() // Must be positive .isNonNegative() // Must be non-negative .isInt() // Must be an integer .isEven() // Must be even .isOdd() // Must be odd .isPowerOfTwo() // Must be a power of 2 .isPortNumber() // Must be a valid port number (1-65535) .isWithinPercentage(target, 5.0) // Within 5% of target value .isOneOf([1, 2, 3, 4, 5]) // Must be one of specified values .isNoneOf([80, 443, 8080]) // Must not be one of specified values .verify(); ``` -------------------------------- ### String Validation with Trust But Verify Source: https://pub.dev/packages/trust_but_verify/index Demonstrates various string validation methods available in the Trust But Verify package. These validators ensure data integrity by checking for emptiness, format, length, patterns, and specific content. They also support case-insensitive comparisons and exclusion lists. ```dart email.trust('Email') .isNotEmpty() // Ensures field is not empty .isNotEmpty(allowWhitespace: true) // Allows whitespace-only strings .isEmail() // Validates email format .minLength(5) // Minimum length .maxLength(100) // Maximum length .isPattern(RegExp(r'^[a-z]+$'), 'lowercase letters only') // Custom regex .isUrl() // Validates URL format .isPhone() // Validates phone number format .contains('required') // Must contain substring .startsWith('https') // Must start with prefix .endsWith('.com') // Must end with suffix .alphanumeric() // Only alphanumeric characters .lettersOnly() // Only letters .digitsOnly() // Only digits .isUuid() // Valid UUID format .isCreditCard() // Valid credit card number .isPostalCode() // Valid postal code format .isIsoDate() // Valid ISO date (YYYY-MM-DD) .isTime24Hour() // Valid 24-hour time (HH:MM) .isOneOf(['active', 'inactive', 'pending']) // Must be one of specified values .isOneOf(['ACTIVE', 'INACTIVE'], caseInsensitive: true) // Case-insensitive comparison .isNoneOf(['admin', 'root', 'system']) // Must not be one of specified values .isNoneOf(['ADMIN', 'ROOT'], caseInsensitive: true) // Case-insensitive comparison .verify(); ``` -------------------------------- ### Basic Single Field Validation in Dart Source: https://pub.dev/packages/trust_but_verify/index Illustrates how to perform basic validation on a single field using the trust_but_verify library. It covers validation with exception handling, without a field name, using custom error messages, and functional validation with Either from fpdart. ```dart // Simple validation with exception handling try { final validatedEmail = email .trust('Email') .isNotEmpty() .isEmail() .verify(); print('Valid email: $validatedEmail'); } catch (e) { if (e is ValidationError) { print('Validation failed: ${e.message}'); } } // Validation without field name (uses generic messages like "Value cannot be empty") final result = email .trust() .isNotEmpty() .isEmail() .verify(); // Custom error message at verification time final value = email .trust('Email') .isNotEmpty() .isEmail() .verify((fieldName) => 'Please enter a valid $fieldName'); // Functional validation with Either (from fpdart package) final status = email .trust('Email') .isNotEmpty() .isEmail() .verifyEither() .fold( (error) => 'Validation failed: ${error.message}', (validEmail) => 'Valid email: $validEmail', ); ``` -------------------------------- ### Internationalization of Validation Messages Source: https://pub.dev/packages/trust_but_verify/versions/0.6.0/changelog Explains how to configure and use internationalized validation messages. The `ValidationStep.configureMessages()` method allows setting a custom `ValidationMessages` implementation, enabling localized error reporting. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; class CustomMessages extends EnglishValidationMessages { @override String get isNotEmpty => '{{fieldName}} cannot be blank!'; } void main() { ValidationStep.configureMessages(CustomMessages()); final String? value = null; final result = trust(value).isNotEmpty().verify(); print(result.errors.first); // Output: The value cannot be blank! ValidationStep.resetMessages(); // Reset to default messages } ``` -------------------------------- ### Partially Override Validation Messages with Mixin Source: https://pub.dev/packages/trust_but_verify/versions/0.6 Demonstrates how to selectively override specific validation messages while retaining the default English messages for others. This is achieved by using the `ValidationMessagesMixin` and implementing only the desired message methods in a custom class. ```dart // Use the ValidationMessagesMixin to override only the messages you want to customize class CustomValidationMessages with ValidationMessagesMixin { @override String emptyField(String fieldName) => 'The $fieldName field cannot be empty'; @override String invalidEmail(String fieldName) => 'Please enter a valid email address for $fieldName'; // All other messages will use the default English implementation } // Configure the package to use your custom messages ValidationStep.configureMessages(CustomValidationMessages()); ``` -------------------------------- ### Add trust_but_verify to pubspec.yaml Source: https://pub.dev/packages/trust_but_verify/index This snippet shows how to add the trust_but_verify package and optionally the fpdart package to your project's dependencies in the pubspec.yaml file. ```yaml dependencies: trust_but_verify: ^0.6.0 fpdart: ^1.1.1 # Optional - for Either/TaskEither support ``` -------------------------------- ### Handle Specific Errors and Modify Messages Source: https://pub.dev/packages/trust_but_verify/versions/0.6 Demonstrates how to handle specific validation errors and provide custom messages based on the error type. It uses a switch statement on the error to return a user-friendly message. This approach is useful for providing targeted feedback to users. ```dart final result = 'test@example.com' .trust('Email') .isNotEmpty() .isEmail() .verifyEither() .fold( (error) => switch (error) { EmptyStringValidationError _ => 'Email field is empty', InvalidEmailValidationError _ => 'Email format is invalid', StringValidationError e => 'Email transformation failed: $e', _ => 'Validation failed: ${error.message}', }, (validEmail) => 'Valid email: $validEmail', ); print(result); ``` -------------------------------- ### Nullable Field Validation with Trust But Verify Source: https://pub.dev/packages/trust_but_verify/index Shows how to validate nullable fields using the Trust But Verify package. The `isNotNull()` validator ensures that a nullable field is not null before proceeding with other validations. This is crucial for handling optional data safely. ```dart optionalField.trust('Optional Field') .isNotNull() .verify(); ``` -------------------------------- ### Custom Validation and Transformation with Trust But Verify Source: https://pub.dev/packages/trust_but_verify/index Explains advanced custom validation and transformation techniques using Trust But Verify. The `ensure()` method allows for custom validation logic based on a provided condition and error message. `tryMap()` is used for custom type transformations, allowing for complex data manipulation and validation. ```dart // Custom validation with ensure() final result = 'hello world' .trust('Custom String') .ensure( (value) => value.contains('world'), (fieldName) => '$fieldName must contain "world"', ) .verifyEither(); // Custom transformation with tryMap() final result = '123' .trust('Number String') .tryMap( (value) => int.tryParse(value) ?? throw Exception('Invalid number'), (fieldName) => '$fieldName must be a valid number', ) .verifyEither(); ``` -------------------------------- ### Multiple Field Validation with trust_but_verify Source: https://pub.dev/packages/trust_but_verify/index Shows how to validate multiple fields simultaneously using the `.verify()` method. This approach throws the first encountered `ValidationError` if any validation fails, allowing for quick error detection. The `values` variable will hold the validated results if all checks pass. ```dart // Validate all fields and throw on first error try { final values = [ email.trust('Email').isNotEmpty().isEmail(), password.trust('Password').isNotEmpty().minLength(8), age.trust('Age').min(13).max(120), ].verify(); // values contains [validatedEmail, validatedPassword, validatedAge] } catch (e) { if (e is ValidationError) { print('Validation failed: ${e.message}'); } } ``` -------------------------------- ### Add trust_but_verify to Dart Project Source: https://pub.dev/packages/trust_but_verify/install Command to add the trust_but_verify package as a dependency to a Dart project using the Dart SDK. This command automatically updates the pubspec.yaml file and fetches the package. ```bash $ dart pub add trust_but_verify ``` -------------------------------- ### Basic and Functional Validation with Trust But Verify (Dart) Source: https://pub.dev/packages/trust_but_verify/example Demonstrates basic and functional validation patterns using the 'trust_but_verify' library in Dart. This includes validating email, UUID, age ranges, and URLs, showcasing both synchronous `verify()` and `verifyEither()` methods for immediate or error-or-value results. It also covers nullable types and custom validation logic. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; void main() async { print('=== trust_but_verify Examples ===\n'); // Basic string validation try { final email = 'test@example.com' .trust('Email') .isNotEmpty() .isEmail() .verify(); print('✅ Valid email: $email'); } catch (e) { if (e is ValidationError) { print('❌ Email validation failed: ${e.message}'); } } // Functional validation with Either final uuidResult = '550e8400-e29b-41d4-a716-446655440000' .trust('UUID') .isUuid() .verifyEither() .fold( (error) => '❌ UUID validation failed: ${error.message}', (value) => '✅ Valid UUID: $value', ); print(uuidResult); // Numeric validation final ageResult = 25 .trust('Age') .min(18) .max(65) .isEven() .verifyEither() .fold( (error) => '❌ Age validation failed: ${error.message}', (value) => '✅ Valid age: $value', ); print(ageResult); // String validators final urlResult = 'https://example.com/api' .trust('URL') .startsWith('https') .contains('api') .isUrl() .verifyEither() .fold( (error) => '❌ URL validation failed: ${error.message}', (value) => '✅ Valid URL: $value', ); print(urlResult); // Nullable validation try { // ignore: avoid-unnecessary-type-casts final optionalEmail = ('optional@example.com' as String?) .trust('Optional Email') .isNotNull() .verify(); print('✅ Valid optional email: $optionalEmail'); } catch (e) { if (e is ValidationError) { print('❌ Optional email validation failed: ${e.message}'); } } // Batch validation final batchResult = [ 'user@example.com'.trust('Email').isNotEmpty().isEmail(), 'password123'.trust('Password').isNotEmpty().minLength(8), 30.trust('Age').min(18).max(65), ].verifyEither().fold( (error) => '❌ Batch validation failed: ${error.message}', (values) => // ignore: avoid-unsafe-collection-methods '✅ All fields valid: Email=${values[0]}, Password=${values[1]}, Age=${values[2]}', ); print(batchResult); // Custom validation with check() final customResult = 'hello world' .trust('Custom String') .ensure( (value) => value.contains('world'), (fieldName) => '$fieldName must contain "world"', ) .verifyEither() .fold( (error) => '❌ Custom validation failed: ${error.message}', (value) => '✅ Custom validation passed: $value', ); print(customResult); // Date and time validation try { final date = '2023-12-25'.trust('Date').isIsoDate().verify(); print('✅ Valid date: $date'); final time = '14:30'.trust('Time').isTime24Hour().verify(); print('✅ Valid time: $time'); } catch (e) { if (e is ValidationError) { print('❌ Date/Time validation failed: ${e.message}'); } } // Error handling with errorOrNull final errorOrNullResult = ''.trust('Empty String').isNotEmpty().errorOrNull(); print('Error or null result: ${errorOrNullResult ?? 'No error'}'); // Form validator convenience method final formValidatorResult = 'test@example.com' .trust('Form Email') .isNotEmpty() .isEmail() .asFormValidator(); } ``` -------------------------------- ### Error Handling with Stack Traces in trust_but_verify Source: https://pub.dev/packages/trust_but_verify/index This code illustrates how to catch and inspect validation errors that include stack traces. It uses a `try-catch` block to handle potential `TryMapValidationError` exceptions, printing the error message, the associated field name, and the stack trace for detailed debugging. This is crucial for diagnosing issues during complex validation or transformation steps. ```dart try { final result = email .trust('Email') .tryMap( (value) => throw Exception('Custom error'), (fieldName) => '$fieldName transformation failed', ) .verify(); } catch (e) { if (e is TryMapValidationError) { print('Error: ${e.message}'); print('Field: ${e.fieldName}'); print('Stack trace: ${e.stackTrace}'); } } ``` -------------------------------- ### Configure Global Custom Validation Messages Source: https://pub.dev/packages/trust_but_verify/index This Dart snippet shows how to globally configure custom validation messages for the `trust_but_verify` package. By creating a class that extends `CustomValidationMessages` (or implementing `ValidationMessagesMixin`) and overriding specific message methods, you can personalize error feedback. The `ValidationStep.configureMessages()` method is then used to apply these custom messages across all validation operations in the application. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; // Configure custom messages globally ValidationStep.configureMessages(CustomValidationMessages()); // All validation operations will now use your custom messages final result = email .trust('Email') .isNotEmpty() .isEmail() .verify(); ``` -------------------------------- ### Internationalization of Validation Messages Source: https://pub.dev/packages/trust_but_verify/changelog Explains how to configure and use internationalized validation messages. The library supports global configuration of messages via `ValidationStep.configureMessages()` and allows for partial overrides using `ValidationMessagesMixin` or complete custom implementations, ensuring validation messages can be localized. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; // Define custom messages (example for Spanish) class SpanishValidationMessages extends EnglishValidationMessages { @override String get typeMismatch => 'El tipo no coincide'; @override String get notEmpty => 'El campo no puede estar vacío'; } void main() { ValidationStep.configureMessages(SpanishValidationMessages()); final result = trust('name').verify(); if (result.isFailure) { print('Validation error: ${result.errors.first.message}'); // Should print 'El campo no puede estar vacío' } // Reset to default messages if needed ValidationStep.resetMessages(); } ``` -------------------------------- ### Asynchronous Validation with Trust But Verify (Dart) Source: https://pub.dev/packages/trust_but_verify/example Illustrates asynchronous validation capabilities of the 'trust_but_verify' library in Dart. This snippet shows how to perform async checks using `.toAsync().ensure()` and `.tryMap()`, and how to handle results with both synchronous `verify()` and the `verifyEither().then()` pattern for async operations. It demonstrates handling futures and potential exceptions during async validation. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; void main() async { // Async validation with Future try { final asyncResult = await 'async@example.com' .trust('Async Email') .isNotEmpty() .isEmail() .toAsync() .ensure( (email) => Future.value(email.contains('async')), (fieldName) => '$fieldName must contain "async"', ) .tryMap((email) async { // Simulate async validation await Future.delayed(Duration(milliseconds: 100)); if (email.contains('async')) { return email; } throw Exception('Email must contain "async"'); }, (fieldName) => '$fieldName must contain "async"') .verify(); print('✅ Async validation passed: $asyncResult'); } catch (e) { if (e is ValidationError) { print('❌ Async validation failed: ${e.message}'); } } // Async validation with Either final asyncEitherResult = await 'async@example.com' .trust('Async Email Either') .isNotEmpty() .isEmail() .toAsync() .verifyEither() .then( (either) => either.fold( (error) => '❌ Async Either validation failed: ${error.message}', (value) => '✅ Async Either validation passed: $value', ), ); print(asyncEitherResult); } ``` -------------------------------- ### Validate API Response with fpdart Either and Async Operations Source: https://pub.dev/packages/trust_but_verify/versions/0.6 Demonstrates validating an API response asynchronously. It uses `toAsync()` and `verifyTaskEither()` to handle asynchronous validation steps, such as checking if a user exists via a service. The function returns a `Future>`. ```dart Future> validateUserResponse(Map json) async { return await json['email'] .toString() .trust('Email') .isNotEmpty() .isEmail() .toAsync() .tryMap((email) async { // Additional async validation final userExists = await userService.exists(email); if (!userExists) { throw Exception('User not found'); } return User(email: email); }, (fieldName) => '$fieldName not found') .verifyTaskEither() .run(); } ``` -------------------------------- ### Implement Custom Spanish Validation Messages Source: https://pub.dev/packages/trust_but_verify/index Provides a complete custom implementation of validation messages by extending the `ValidationMessages` interface. This allows for multilingual support. Ensure all required methods are overridden for full functionality. ```dart // Implement the ValidationMessages interface to provide your own complete translations class SpanishValidationMessages implements ValidationMessages { @override String emptyField(String fieldName) => 'El campo $fieldName está vacío'; @override String minLength(String fieldName, int length) => '$fieldName debe tener al menos $length caracteres'; @override String invalidEmail(String fieldName) => '$fieldName debe ser una dirección de correo válida'; // ... implement all other methods } // Configure the package to use Spanish messages ValidationStep.configureMessages(SpanishValidationMessages()); ``` -------------------------------- ### Asynchronous Validation with trust_but_verify Source: https://pub.dev/packages/trust_but_verify/index Illustrates asynchronous validation, such as checking if an email already exists in a database. The `.toAsync()` method enables asynchronous operations within the validation chain, and `.tryMap()` allows for custom asynchronous logic. The validation returns a `Future` and can throw exceptions, which are handled by the calling code. ```dart // Async validation with API call final result = await email .trust('Email') .isNotEmpty() .isEmail() .toAsync() .tryMap((email) async { // Check if email exists in database final exists = await userService.emailExists(email); if (exists) { throw Exception('Email already registered'); } return email; }, (fieldName) => '$fieldName already registered') .verify(); ``` -------------------------------- ### Type Casting and Transformation Validation Source: https://pub.dev/packages/trust_but_verify/index Demonstrates type casting and transformation validators in Trust But Verify. These validators not only check types but also transform values (e.g., String to int, nullable to non-nullable), enabling subsequent validation chains. `tryMap` allows custom transformations, and `isType` safely casts dynamic types. ```dart // String to Integer transformation final result = '123' .trust('Number String') .toInt() // Converts String to int, enables numeric validators .min(100) // Now we can use numeric validators .max(200) .isEven() .verify(); // Nullable to Non-nullable transformation final result = (someNullableString as String?) .trust('Optional String') .isNotNull() // Converts String? to String, enables string validators .isNotEmpty() // Now we can use string validators .isEmail() .verify(); // Type validation with isType() // NOTE: isType() works on Object? or more specific types. // It does NOT work directly on dynamic types due to Dart limitations. // If you have a dynamic value, cast it to Object? first. final result = (someDynamicValue as Object?) .trust('Dynamic Field') .isType() // Validates type is int and returns SyncValidationStep .min(10) // Now we can use numeric validators .verify(); // Custom transformation with tryMap final result = '2023-12-25' .trust('Date String') .tryMap( (value) => DateTime.parse(value), // Converts String to DateTime (fieldName) => '$fieldName must be a valid date', ) .verify(); ``` -------------------------------- ### Validate Form Data Object with fpdart Either Source: https://pub.dev/packages/trust_but_verify/versions/0.6 Shows how to validate a `UserRegistrationForm` object using a series of `trust_but_verify` steps chained together. The `validate` method returns an `Either` type, where the left side contains a `ValidationError` if any validation fails, and the right side contains the validated form object. ```dart class UserRegistrationForm { final String email; final String password; final int age; final String? phone; UserRegistrationForm({ required this.email, required this.password, required this.age, this.phone, }); Either validate() { return [ email.trust('Email').isNotEmpty().isEmail(), password.trust('Password').isNotEmpty().minLength(8), age.trust('Age').min(13).max(120), if (phone != null) phone!.trust('Phone').isPhone(), ].verifyEither().map((_) => this); } } ``` -------------------------------- ### Type Casting with CastingExtension Source: https://pub.dev/packages/trust_but_verify/changelog Demonstrates the use of `CastingExtension` for type-safe validation chains. The `isType()` method allows for checking and casting values to a specific type `T` within the validation pipeline, ensuring type safety and preventing runtime errors. ```dart import 'package:trust_but_verify/trust_but_verify.dart'; void main() { final dynamic data = '123'; final result = trust('value') .isType() .ensure((value) => value.isNotEmpty) .verify(); if (result.isSuccess) { print('Value is a non-empty string: ${result.value}'); } else { print('Validation failed: ${result.errors}'); } } ``` -------------------------------- ### trust_but_verify with fpdart: TaskEither Verification Source: https://pub.dev/packages/trust_but_verify/index Shows how to perform asynchronous validation within a functional programming paradigm using `trust_but_verify` and `fpdart`'s `TaskEither`. The `.verifyTaskEither()` method returns a `TaskEither`, which is suitable for composing asynchronous operations and handling errors in a functional way. ```dart import 'package:fpdart/fpdart'; // 3. Async functional style with TaskEither final task = 'test@example.com'.trust('Email').isEmail().toAsync().verifyTaskEither(); ``` -------------------------------- ### Reset Validation Messages to Defaults Source: https://pub.dev/packages/trust_but_verify/index Resets the validation messages to the default English fallback messages provided by the package. This is useful for reverting custom configurations to the standard settings. ```dart // Reset to default English messages ValidationStep.resetMessages(); ```