MapsterMapper / Mapster

A fast, fun and stimulating object to object Mapper
MIT License
4.25k stars 326 forks source link

Add Support Custom mapping from Mapping To Primitive #650

Open DocSvartz opened 8 months ago

DocSvartz commented 8 months ago

before: When you mapping To primitive and string always using converter logic

now You can use Custom Conversion logic supported: .MapWith() .MapToTargetWith()

Supporting primitive type from source code

typeof(bool) typeof(short) typeof(int) typeof(long) typeof(float) typeof(double) typeof(decimal) typeof(ushort) typeof(uint) typeof(ulong) typeof(byte) typeof(sbyte) typeof(DateTime) + typeof(string)

Example:

[TestMethod]
public void CustomMappingDateTimeToPrimitive()
{
    TypeAdapterConfig<DateTime, long>
       .NewConfig()
       .MapWith(src => new DateTimeOffset(src).ToUnixTimeSeconds());

    TypeAdapterConfig<DateTime, string>
       .NewConfig()
       .MapWith(src => src.ToShortDateString());

    var _source = new DateTime(2023, 10, 27, 0, 0, 0, DateTimeKind.Utc);

    var _resultToLong = _source.Adapt<long>();
    var _resultToString = _source.Adapt<string>();

    _resultToLong.ShouldBe(new DateTimeOffset(new DateTime(2023, 10, 27, 0, 0, 0, DateTimeKind.Utc)).ToUnixTimeSeconds());
    _resultToString.ShouldNotBe(_source.ToString());
    _resultToString.ShouldBe(_source.ToShortDateString());
}

/// <summary>
/// https://github.com/MapsterMapper/Mapster/issues/407
/// </summary>
[TestMethod]
public void MappingDatetimeToLongWithCustomMapping()
{
    TypeAdapterConfig<DateTime, long>
       .NewConfig()
       .MapWith(src => new DateTimeOffset(src).ToUnixTimeSeconds());

    TypeAdapterConfig<long, DateTime>
      .NewConfig()
      .MapWith(src => new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(src).Date);

    var emptySource = new Source407() { Time = DateTime.UtcNow.Date };
    var fromC1 = new DateTime(2023, 10, 27,0,0,0,DateTimeKind.Utc);
    var fromC2 = new DateTimeOffset(new DateTime(2025, 11, 23, 0, 0, 0, DateTimeKind.Utc)).ToUnixTimeSeconds();
    var c1 = new Source407 { Time = fromC1 };
    var c2 = new Destination407 { Time = fromC2 };

    var _result = c1.Adapt<Destination407>(); // Work 
    var _resultLongtoDateTime = c2.Adapt<Source407>();

    _result.Time.ShouldBe(new DateTimeOffset(new DateTime(2023, 10, 27, 0, 0, 0, DateTimeKind.Utc)).ToUnixTimeSeconds());               
    _resultLongtoDateTime.Time.ShouldBe(new DateTime(2025, 11, 23).Date);
}