import 'package:dartz/dartz.dart'; import '../errors/failures.dart'; /// Classe utilitaire pour convertir et valider les entrées utilisateur. /// /// Cette classe fournit des méthodes pour convertir des chaînes en types /// numériques et valider les entrées utilisateur de manière fonctionnelle. /// /// **Usage:** /// ```dart /// final converter = InputConverter(); /// final result = converter.stringToUnsignedInteger('123'); /// result.fold( /// (failure) => print('Erreur: $failure'), /// (value) => print('Valeur: $value'), /// ); /// ``` class InputConverter { /// Convertit une chaîne en entier non signé. /// /// [str] La chaîne à convertir /// /// Returns [Right] avec l'entier si la conversion réussit, /// [Left] avec [InvalidInputFailure] si la conversion échoue. /// /// **Exemple:** /// ```dart /// final result = converter.stringToUnsignedInteger('123'); /// // Right(123) /// /// final result2 = converter.stringToUnsignedInteger('-5'); /// // Left(InvalidInputFailure) /// ``` Either stringToUnsignedInteger(String str) { try { final trimmed = str.trim(); if (trimmed.isEmpty) { return Left(const InvalidInputFailure(message: 'La chaîne est vide')); } final integer = int.parse(trimmed); if (integer < 0) { return Left(const InvalidInputFailure(message: 'Le nombre doit être positif')); } return Right(integer); } on FormatException { return Left(InvalidInputFailure(message: 'Format invalide: "$str"')); } catch (e) { return Left(InvalidInputFailure(message: 'Erreur de conversion: $e')); } } /// Convertit une chaîne en entier signé. /// /// [str] La chaîne à convertir /// /// Returns [Right] avec l'entier si la conversion réussit, /// [Left] avec [InvalidInputFailure] si la conversion échoue. Either stringToInteger(String str) { try { final trimmed = str.trim(); if (trimmed.isEmpty) { return Left(const InvalidInputFailure(message: 'La chaîne est vide')); } final integer = int.parse(trimmed); return Right(integer); } on FormatException { return Left(InvalidInputFailure(message: 'Format invalide: "$str"')); } catch (e) { return Left(InvalidInputFailure(message: 'Erreur de conversion: $e')); } } /// Convertit une chaîne en nombre décimal (double). /// /// [str] La chaîne à convertir /// /// Returns [Right] avec le double si la conversion réussit, /// [Left] avec [InvalidInputFailure] si la conversion échoue. Either stringToDouble(String str) { try { final trimmed = str.trim(); if (trimmed.isEmpty) { return Left(const InvalidInputFailure(message: 'La chaîne est vide')); } final doubleValue = double.parse(trimmed); return Right(doubleValue); } on FormatException { return Left(InvalidInputFailure(message: 'Format invalide: "$str"')); } catch (e) { return Left(InvalidInputFailure(message: 'Erreur de conversion: $e')); } } /// Convertit une chaîne en nombre décimal non négatif. /// /// [str] La chaîne à convertir /// /// Returns [Right] avec le double si la conversion réussit, /// [Left] avec [InvalidInputFailure] si la conversion échoue ou si négatif. Either stringToUnsignedDouble(String str) { try { final trimmed = str.trim(); if (trimmed.isEmpty) { return Left(const InvalidInputFailure(message: 'La chaîne est vide')); } final doubleValue = double.parse(trimmed); if (doubleValue < 0) { return Left(const InvalidInputFailure(message: 'Le nombre doit être positif')); } return Right(doubleValue); } on FormatException { return Left(InvalidInputFailure(message: 'Format invalide: "$str"')); } catch (e) { return Left(InvalidInputFailure(message: 'Erreur de conversion: $e')); } } /// Valide qu'une chaîne n'est pas vide. /// /// [str] La chaîne à valider /// /// Returns [Right] avec la chaîne si valide, /// [Left] avec [InvalidInputFailure] si vide. Either validateNonEmpty(String str) { final trimmed = str.trim(); if (trimmed.isEmpty) { return Left(const InvalidInputFailure(message: 'La chaîne ne peut pas être vide')); } return Right(trimmed); } } /// Erreur levée lorsque l'entrée utilisateur est invalide. /// /// Cette classe représente une erreur de validation ou de conversion /// des entrées utilisateur. class InvalidInputFailure extends Failure { /// Crée une nouvelle [InvalidInputFailure]. /// /// [message] Message décrivant l'erreur const InvalidInputFailure({ super.message = 'Entrée invalide', super.code, }); @override String toString() => 'InvalidInputFailure: $message'; }