import 'dart:developer'; import 'package:dartz/dartz.dart'; import 'package:data_channel/data_channel.dart'; import 'package:injectable/injectable.dart'; import '../../../domain/wallet/wallet.dart'; import '../datasources/voucher_remote_data_provider.dart'; @Injectable(as: IVoucherRepository) class VoucherRepository implements IVoucherRepository { final VoucherRemoteDataProvider _remoteDataProvider; final String _logName = 'VoucherRepository'; VoucherRepository(this._remoteDataProvider); @override Future>> getVouchers() => _run( 'getVouchers', _remoteDataProvider.fetchVouchers, (dtos) => dtos.map((e) => e.toDomain()).toList(), ); @override Future> redeem({ required String voucherId, required String pin, required String idempotencyKey, }) => _run( 'redeem', () => _remoteDataProvider.redeem( voucherId: voucherId, pin: pin, idempotencyKey: idempotencyKey, ), (dto) => dto.toRedeemResult(), ); @override Future> getRedemptions({ required int page, int limit = 20, }) => _run( 'getRedemptions', () => _remoteDataProvider.fetchRedemptions(page: page, limit: limit), (dto) => dto.toDomain(), ); Future> _run( String name, Future> Function() call, R Function(D dto) toDomain, ) async { try { final result = await call(); if (result.hasError) return left(result.error!); return right(toDomain(result.data as D)); } catch (e, s) { log(name, name: _logName, error: e, stackTrace: s); return left(const WalletFailure.unexpectedError()); } } }