Skip to content

Commit

Permalink
Merge pull request #157 from netglade/feat/field-reverse-mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
petrnymsa authored Nov 26, 2023
2 parents 0807f4b + 10096e3 commit 5c9fbf7
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 5 deletions.
2 changes: 2 additions & 0 deletions packages/auto_mappr/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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<Object, Object>` and `TypeConverter<Object, Object?>` 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)
Expand Down
30 changes: 27 additions & 3 deletions packages/auto_mappr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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<A,B>(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.

Expand Down
16 changes: 15 additions & 1 deletion packages/auto_mappr/lib/src/generator/auto_mappr_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,21 @@ class AutoMapprGenerator extends GeneratorForAnnotation<annotation.AutoMappr> {
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,
Expand Down
2 changes: 1 addition & 1 deletion packages/auto_mappr/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
17 changes: 17 additions & 0 deletions packages/auto_mappr/test/integration/fixture/reverse.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import 'reverse.auto_mappr.dart';
MapType<PrimitiveDto, Primitive>(reverse: true),
MapType<UserDto, User>(reverse: true),
MapType<AddressDto, Address>(reverse: true),
MapType<AddressDto, SpecialAddress>(
fields: [
Field('specialStreet', from: 'street'),
Field('specialCity', from: 'city'),
],
reverse: true,
),
])
class Mappr extends $Mappr {
const Mappr();
Expand Down Expand Up @@ -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<Object?> get props => [specialStreet, specialCity];

const SpecialAddress({required this.specialStreet, required this.specialCity});
}
18 changes: 18 additions & 0 deletions packages/auto_mappr/test/integration/reverse_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<fixture.AddressDto, fixture.SpecialAddress>(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<fixture.SpecialAddress, fixture.AddressDto>(dto);

expect(converted, equals(const fixture.AddressDto(street: 'Street 14', city: 'Wakanda')));
});
});
}

0 comments on commit 5c9fbf7

Please sign in to comment.