diff --git a/packages/auto_mappr/CHANGELOG.md b/packages/auto_mappr/CHANGELOG.md index b9eaeb5..f3dbbd0 100644 --- a/packages/auto_mappr/CHANGELOG.md +++ b/packages/auto_mappr/CHANGELOG.md @@ -1,7 +1,9 @@ [//]: # (## Unreleased) +## 2.2.0 - Improve error messages. [#147](https://github.com/netglade/auto_mappr/pull/147) - When the source is not null, `TypeConverter` and `TypeConverter` now support mapping of source field `Object?` -> target field `Object?`. [#142](https://github.com/netglade/auto_mappr/pull/142) +- Support Field's field name mapping in reverse. [#157](https://github.com/netglade/auto_mappr/pull/157) ## 2.1.1 - Fix auto_mappr_annotation dependency. [#130](https://github.com/netglade/auto_mappr/pull/131) diff --git a/packages/auto_mappr/README.md b/packages/auto_mappr/README.md index 6115d43..dda6913 100644 --- a/packages/auto_mappr/README.md +++ b/packages/auto_mappr/README.md @@ -45,12 +45,12 @@ Heavily inspired by [C# AutoMapper][auto_mapper_net_link]. - [Mapping from source](#mapping-from-source) - [Nullability handling](#nullability-handling) - [Forced non-nullable field for nullable source](#forced-non-nullable-field-for-nullable-source) - - [Type converters](#type-converters) - [Generics](#generics) - [Library import aliases](#library-import-aliases) - [Modules](#modules) - [Including](#including) - - [Delegating](#delegating) + - [Delegating](#delegating) + - [Type converters](#type-converters) - [Reverse mapping](#reverse-mapping) - [Records](#records) - [Works with `equatable`](#works-with-equatable) @@ -748,8 +748,32 @@ you can use `reverse` option on `MapType`. Note that it's your responsibility to make sure those objects support normal and reverse mapping and to keep them in sync. + +When `Field`'s mapping with `from` parameter is used, in `reverse` mapping those properties are automatically switched too. + +For example + +```dart +class A { + final String a; +} + +class B { + final String b; +} + +// Mapping +MapType(fields: [ + Field('b', from: 'a') +], reverse: true) + +// generated mapping +A.a mapts to B.b +B.b maps to A.a +``` + Also note that reverse mapping might not work properly when additional configuration -such as [whenSourceIsNull] or [constructor] is used. +such as `whenSourceIsNull` or `constructor` is used. For more complicated scenarios two separate mappings are recommended instead. diff --git a/packages/auto_mappr/lib/src/generator/auto_mappr_generator.dart b/packages/auto_mappr/lib/src/generator/auto_mappr_generator.dart index 1acf3c0..6fcebd6 100644 --- a/packages/auto_mappr/lib/src/generator/auto_mappr_generator.dart +++ b/packages/auto_mappr/lib/src/generator/auto_mappr_generator.dart @@ -166,7 +166,21 @@ class AutoMapprGenerator extends GeneratorForAnnotation { TypeMapping( source: targetType, target: sourceType, - fieldMappings: fieldMappings ?? [], + fieldMappings: fieldMappings + ?.map( + (f) => f.from != null + ? FieldMapping( + field: f.from!, + from: f.field, + customExpression: f.customExpression, + whenNullExpression: f.whenNullExpression, + ignore: f.ignore, + ignoreNull: f.ignoreNull, + ) + : f, + ) + .toList() ?? + [], typeConverters: [..._toTypeConverters(mapTypeConverters), ...globalConverters], whenSourceIsNullExpression: whenSourceIsNull, constructor: constructor, diff --git a/packages/auto_mappr/pubspec.yaml b/packages/auto_mappr/pubspec.yaml index 89e355f..b82a51a 100644 --- a/packages/auto_mappr/pubspec.yaml +++ b/packages/auto_mappr/pubspec.yaml @@ -1,6 +1,6 @@ name: auto_mappr description: Code generation for mapping between different objects with ease. -version: 2.1.2 +version: 2.2.0 repository: https://github.com/netglade/auto_mappr issue_tracker: https://github.com/netglade/auto_mappr/issues screenshots: diff --git a/packages/auto_mappr/test/integration/fixture/reverse.dart b/packages/auto_mappr/test/integration/fixture/reverse.dart index 58acf2d..e84db5d 100644 --- a/packages/auto_mappr/test/integration/fixture/reverse.dart +++ b/packages/auto_mappr/test/integration/fixture/reverse.dart @@ -7,6 +7,13 @@ import 'reverse.auto_mappr.dart'; MapType(reverse: true), MapType(reverse: true), MapType(reverse: true), + MapType( + fields: [ + Field('specialStreet', from: 'street'), + Field('specialCity', from: 'city'), + ], + reverse: true, + ), ]) class Mappr extends $Mappr { const Mappr(); @@ -77,3 +84,13 @@ class AddressDto extends Equatable { const AddressDto({required this.street, required this.city}); } + +class SpecialAddress extends Equatable { + final String specialStreet; + final String specialCity; + + @override + List get props => [specialStreet, specialCity]; + + const SpecialAddress({required this.specialStreet, required this.specialCity}); +} diff --git a/packages/auto_mappr/test/integration/reverse_test.dart b/packages/auto_mappr/test/integration/reverse_test.dart index 05d1e64..b7309d9 100644 --- a/packages/auto_mappr/test/integration/reverse_test.dart +++ b/packages/auto_mappr/test/integration/reverse_test.dart @@ -93,4 +93,22 @@ void main() { ); }); }); + + group('Reverse mapping with custom fields', () { + test('AddressDto to SpecialAddress', () { + const dto = fixture.AddressDto(street: 'Street 14', city: 'Wakanda'); + + final converted = mappr.convert(dto); + + expect(converted, equals(const fixture.SpecialAddress(specialStreet: 'Street 14', specialCity: 'Wakanda'))); + }); + + test('SpecialAddress to AddressDto', () { + const dto = fixture.SpecialAddress(specialStreet: 'Street 14', specialCity: 'Wakanda'); + + final converted = mappr.convert(dto); + + expect(converted, equals(const fixture.AddressDto(street: 'Street 14', city: 'Wakanda'))); + }); + }); }