Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for From and To method conversions (#1117) #1616

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if these combinations really add user-value or just increase the API surface. I think I'd remove them for now.


/// <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
Loading