Skip to content

Commit

Permalink
Add support for From and To method conversions (#1117)
Browse files Browse the repository at this point in the history
  • Loading branch information
TonEnfer committed Dec 1, 2024
1 parent c941b66 commit 2d82323
Show file tree
Hide file tree
Showing 25 changed files with 1,152 additions and 115 deletions.
42 changes: 22 additions & 20 deletions docs/docs/configuration/conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,28 @@ description: A list of conversions supported by Mapperly

Mapperly implements several types of automatic conversions (in order of priority):

| Name | Description | Conditions |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Direct assignment | Directly assigns the source object to the target | Source type is assignable to the target type and `UseDeepCloning` is `false` |
| Queryable | Projects the source queryable to the target queryable | Source and target types are `IQueryable<>` |
| Dictionary | Maps a source dictionary to an enumerable target | Source type is an `IDictionary<,>` or an `IReadOnlyDictionary<,>` |
| Enumerable | Maps an enumerable source to an enumerable target | Source type is an `IEnumerable<>` |
| Span | Maps a `Span<>`, `ReadOnlySpan<>` to or from `Span<>`, `ReadOnlySpan<>` or enumerable | Source or target type is a `Span<>`, `ReadOnlySpan<>` |
| Tuple | Create a new instance of a `ValueTuple` or tuple expression i.e. `(10, 12)` | Target type is a `ValueTuple<>` or tuple expression |
| Memory | Maps a `Memory<>`, `ReadOnlyMemory<>` to or from `Memory<>`, `ReadOnlyMemory<>`, `Span<>`, `ReadOnlySpan<>` or enumerable | Source or target type is a `Memory<>` or `ReadOnlyMemory<>` |
| Implicit cast | Implicit cast operator | An implicit cast operator is defined to cast from the source type to the target type |
| Parse method | Uses a static `Parse` method on the target type | Source type is a `string` and target has a static method with the following signature: `TTarget Parse(string)`. |
| Constructor | Uses a constructor on the target type with the source as single parameter | Target type has a visible constructor with a single parameter of the source type. |
| String to enum | Maps a string to an enum member name | Source type is a `string` and the target type is an enum |
| Enum to string | Maps an enum member name to a string | Source type is an enum and the target type is a `string` |
| Enum to enum | Maps an enum to another enum either by value or by member name | Source and target types are enums |
| DateTime to DateOnly | Maps a `DateTime` to a `DateOnly` | Source type is a `DateTime` and target type is a `DateOnly` |
| DateTime to TimeOnly | Maps a `DateTime` to a `TimeOnly` | Source type is a `DateTime` and target type is a `TimeOnly` |
| Explicit cast | Explicit cast operator | An explicit cast operator is defined to cast from the source type to the target type |
| ToString | `ToString` method of an object | Target type is a `string` |
| New instance | Create a new instance of the target type and map all properties | The target type has a visible constructor or an object factory exists for the target type |
| Name | Description | Conditions |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Direct assignment | Directly assigns the source object to the target | Source type is assignable to the target type and `UseDeepCloning` is `false` |
| Queryable | Projects the source queryable to the target queryable | Source and target types are `IQueryable<>` |
| Dictionary | Maps a source dictionary to an enumerable target | Source type is an `IDictionary<,>` or an `IReadOnlyDictionary<,>` |
| Enumerable | Maps an enumerable source to an enumerable target | Source type is an `IEnumerable<>` |
| Span | Maps a `Span<>`, `ReadOnlySpan<>` to or from `Span<>`, `ReadOnlySpan<>` or enumerable | Source or target type is a `Span<>`, `ReadOnlySpan<>` |
| Tuple | Create a new instance of a `ValueTuple` or tuple expression i.e. `(10, 12)` | Target type is a `ValueTuple<>` or tuple expression |
| Memory | Maps a `Memory<>`, `ReadOnlyMemory<>` to or from `Memory<>`, `ReadOnlyMemory<>`, `Span<>`, `ReadOnlySpan<>` or enumerable | Source or target type is a `Memory<>` or `ReadOnlyMemory<>` |
| Implicit cast | Implicit cast operator | An implicit cast operator is defined to cast from the source type to the target type |
| Parse method | Uses a static `Parse` method on the target type | Source type is a `string` and target has a static method with the following signature: `TTarget Parse(string)`. |
| Constructor | Uses a constructor on the target type with the source as single parameter | Target type has a visible constructor with a single parameter of the source type. |
| String to enum | Maps a string to an enum member name | Source type is a `string` and the target type is an enum |
| Enum to string | Maps an enum member name to a string | Source type is an enum and the target type is a `string` |
| Enum to enum | Maps an enum to another enum either by value or by member name | Source and target types are enums |
| Explicit cast | Explicit cast operator | An explicit cast operator is defined to cast from the source type to the target type |
| ToString | `ToString` method of an object | Target type is a `string` |
| ToTarget | `ToTTarget` method of an object, excluded `ToString` | Source object contains method with signature `TTarget ToTTarget()` |
| DateTime to DateOnly | Maps a `DateTime` to a `DateOnly` | Source type is a `DateTime` and target type is a `DateOnly` |
| DateTime to TimeOnly | Maps a `DateTime` to a `TimeOnly` | Source type is a `DateTime` and target type is a `TimeOnly` |
| Static method | Convert source uses source type static `ToTTarget` method or target type static `Create`, `CreateFrom`, `FromTSource` except for converting `DateTime` to `DateOnly` or `TimeOnly` | The source type contains a static method with signature `TTarget ToTTarget()` or the target type contains one of the following static methods `TTarget Create(TSource)`, `TTarget CreateFrom (TSource)`, `TTarget FromTSource(TSource)` |
| New instance | Create a new instance of the target type and map all properties | The target type has a visible constructor or an object factory exists for the target type |

## Disable all automatic conversions

Expand Down
40 changes: 34 additions & 6 deletions src/Riok.Mapperly.Abstractions/MappingConversionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public enum MappingConversionType

/// <summary>
/// If the source type is a <see cref="string"/>,
/// uses a a static visible method named `Parse` on the target type
/// uses a static visible method named `Parse` on the target type
/// with a return type equal to the target type and a string as single parameter.
/// </summary>
ParseMethod = 1 << 3,
Expand Down Expand Up @@ -64,26 +64,26 @@ public enum MappingConversionType

/// <summary>
/// If the source is a <see cref="DateTime"/>
/// and the target is a DateOnly
/// and the target is a <c>DateOnly</c>
/// uses the `FromDateTime` method on the target type with the source as single parameter.
/// </summary>
DateTimeToDateOnly = 1 << 8,

/// <summary>
/// If the source is a <see cref="DateTime"/>
/// and the target is a TimeOnly
/// and the target is a <c>TimeOnly</c>
/// uses the `FromDateTime` method on the target type with the source as single parameter.
/// </summary>
DateTimeToTimeOnly = 1 << 9,

/// <summary>
/// If the source and the target is a <see cref="IQueryable{T}"/>.
/// If the source and the target are a <see cref="IQueryable{T}"/>.
/// Only uses object initializers and inlines the mapping code.
/// </summary>
Queryable = 1 << 10,

/// <summary>
/// If the source and the target is an <see cref="IEnumerable{T}"/>
/// If the source and the target are an <see cref="IEnumerable{T}"/>
/// Maps each element individually.
/// </summary>
Enumerable = 1 << 11,
Expand Down Expand Up @@ -115,10 +115,38 @@ public enum MappingConversionType
Tuple = 1 << 15,

/// <summary>
/// Allow using the underlying type of an enum to map from or to an enum type.
/// Allow using the underlying type of enum to map from or to an enum type.
/// </summary>
EnumUnderlyingType = 1 << 16,

/// <summary>
/// If the source type contains a `ToTarget` method other than `ToString`, use it
/// </summary>
ToTargetMethod = 1 << 17,

/// <summary>
/// Combination of <see cref="ToStringMethod"/> and <see cref="ToTargetMethod"/>
/// </summary>
AllToTargetMethods = ToStringMethod | ToTargetMethod,

/// <summary>
/// If the source type contains a static `ToTarget` method
/// or the target type contains a static methods
/// `Create(TSource)`,
/// `CreateFrom(TSource)`
/// `From(TSource)`
/// `FromTSource(TSource)`
/// or similar methods with <langword>params</langword> keyword, use it.
/// The exception is <see cref="DateTime"/> conversions,
/// which are enabled by separate options (<seealso cref="DateTimeToTimeOnly"/>, <seealso cref="DateTimeToDateOnly"/>).
/// </summary>
StaticConvertMethods = 1 << 18,

/// <summary>
/// Combination of <see cref="DateTimeToDateOnly"/>, <see cref="DateTimeToTimeOnly"/> and <see cref="StaticConvertMethods"/>
/// </summary>
AllStaticMethods = DateTimeToDateOnly | DateTimeToTimeOnly | StaticConvertMethods,

/// <summary>
/// Enables all supported conversions.
/// </summary>
Expand Down
Loading

0 comments on commit 2d82323

Please sign in to comment.